Index: ahttp.py ================================================================== --- ahttp.py +++ ahttp.py @@ -63,10 +63,14 @@ headers = {} if ajax: headers["X-Requested-With"] = "XMLHttpRequest" if referer: headers["Referer"] = (referer if referer else url) + +#ifdef BLD_DEBUG +#srcout raise Exception("Simulated HTTP error") +#endif # read if post: r = session.post(url, params=params, headers=headers, timeout=7.5) else: Index: channels/__init__.py ================================================================== --- channels/__init__.py +++ channels/__init__.py @@ -7,15 +7,14 @@ # version: 1.1 # license: public domain # author: mario # url: http://fossil.include-once.org/streamtuner2/ # pack: -# bookmarks.py configwin.py global_key.py history.py -# icast.py internet_radio.py itunes.py jamendo.py links.py live365.py -# modarchive.py myoggradio.py punkcast.py radiotray.py search.py -# shoutcast.py streamedit.py surfmusik.py timer.py tunein.py xiph.py -# youtube.py *.png +# bookmarks.py configwin.py streamedit.py history.py search.py links.py +# icast.py internet_radio.py itunes.py jamendo.py live365.py global_key.py +# modarchive.py myoggradio.py punkcast.py radiobrowser.py radiotray.py +# shoutcast.py surfmusik.py timer.py tunein.py xiph.py youtube.py # config: - # priority: core # # # Just exports GenericChannel and ChannelPlugin. @@ -97,10 +96,14 @@ [False, 0, ["search_col", str, None, {}], ], [False, 0, ["search_set", bool, None, {}], ], ] rowmap = [] # [state,genre,title,...] field enumeration still needed separately titles = {} # for easier adapting of column titles in datamap + + # for empty grouping / categories + placeholder = [dict(genre="./.", title="Subcategory placeholder", playing="./.", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-folder")] + empty_stub = [dict(genre="./.", title="No categories found (HTTP error)", playing="Try Channel→Reload Categories later..", url="none:", listeners=0, bitrate=0, homepage="", state="gtk-stop")] # regex rx_www_url = re.compile("""(www(\.\w+[\w-]+){2,}|(\w+[\w-]+[ ]?\.)+(com|FM|net|org|de|PL|fr|uk))""", re.I) @@ -195,17 +198,20 @@ # switch stream category, # load data, # update treeview content def load(self, category, force=False): - + # get data from cache or download if (force or not category in self.streams): __print__(dbg.PROC, "load", "update_streams") self.parent.status("Updating streams...") self.parent.status(-0.1) - new_streams = self.update_streams(category) + if category == "empty": + new_streams = self.empty_stub + else: + new_streams = self.update_streams(category) if new_streams: # check and modify entry; # assert that title and url are present @@ -354,32 +360,36 @@ self.reload() # display .current category, once notebook/channel tab is first opened def first_show(self): - __print__(dbg.PROC, "first_show ", self.module, self.shown) if (self.shown != 55555): + __print__(dbg.PROC, self.module+".first_show()") # if category tree is empty, initialize it if not self.categories: - __print__(dbg.PROC, "first_show: reload_categories"); + __print__(dbg.PROC, self.module+"first_show: reload_categories"); #self.parent.thread(self.reload_categories) - self.reload_categories() + try: + self.reload_categories() + except: + __print__(dbg.ERR, "HTTP Error or something") + self.categories = ["empty"] self.display_categories() self.current = self.categories.keys()[0] - __print__(dbg.STAT, self.current) + __print__(dbg.STAT, "Use first category as current =", self.current) self.load(self.current) # load current category else: - __print__(dbg.STAT, "first_show: load current category"); + __print__(dbg.STAT, self.module+".first_show(): load current category =", self.current); self.load(self.current) # put selection/cursor on last position try: - __print__(dbg.STAT, "first_show: select last known category treelist position") + __print__(dbg.STAT, self.module+".first_show()", "select last known category treelist position =", self.shown) self.gtk_list.get_selection().select_path(self.shown) except: pass # this method will only be invoked once @@ -396,10 +406,11 @@ if self.catmap: conf.save("cache/catmap_" + self.module, self.catmap); # display outside of this non-main thread uikit.do(self.display_categories) + # insert content into gtk category list def display_categories(self): # remove any existing columns Index: channels/punkcast.py ================================================================== --- channels/punkcast.py +++ channels/punkcast.py @@ -14,11 +14,11 @@ # H9uewu01+OPJDle9AY//O+Dj++9yr3wHUnl8PyCTyzL2PE5aPUgYaFlNPDKigGe7VW6U1iDwcXuXzBbz+K5PThMEvQ6xjJjEAi2Z4Wn1mP03FyR1DaU0jUbnGj81IZXLkckoSpUV7JTB0HF4urvH3IMN # jG6XbGGWemeAkc+hNEE0DtCSmngUCkFSixn321iWyVzGImEIVssllAh5e9kkCDV2T05pD4dMTeWpv6ohwghp6opCOOHh1kfcXZzm8S/bPNs/ZOC4mELj4eYGWiT54Z896qMJ9vws4XBE3lRIBeqmDmk/ # Qmnw+YNNlsur/PrbDqv5NFm7SHMwpNbuMggClmYL5JWkqytErKGPPVQmilhLSpbtBE1nxMFhjedHrymkNUrv3KHTuqLvjWl7MQevL+gNXaqNLlGzSyUvUVuEzMzkWVhZYqd6xPc//o6MBfWrAZcdBxnH # zOcy/F1rsf3yFFmtEcWwOZ2h1R8hP5jATGmRQE+wXz0gjiMWihnO2z1qjS6ZQoF76yuU7DSxFFhJC10phmHIhVT8D1yefHn5PzXrAAAAAElFTkSuQmCC # priority: obsolete -# config: { name: punkcast_img, type: boolean, value: 0, desciption: Load banners. (Channel > Update favicons) } +# config: { name: punkcast_img, type: boolean, value: 0, description: Load banners. (Channel - Update favicons) } # # Punkcast is no longer updated. This plugin is kept for # historic reasons. It was one of the default streamtuner1 # channels. Index: channels/surfmusik.py ================================================================== --- channels/surfmusik.py +++ channels/surfmusik.py @@ -112,11 +112,11 @@ max = int(conf.max_streams) is_tv = 0 # placeholder category if cat in ["Genres"]: - path = None + return self.placeholder # separate elif cat in ["Poli", "Flug"]: path = "" # tv elif cat in ["SurfTV", "MusikTV", "NewsTV"]: