Index: _pack ================================================================== --- _pack +++ _pack @@ -13,10 +13,11 @@ streamtuner2/*.png streamtuner2/*.svg streamtuner2/*.desktop \ streamtuner2/README streamtuner2/help/* streamtuner2/contrib/* \ streamtuner2/PKG-INFO streamtuner2/version streamtuner2/_pack streamtuner2/*.epm # streamtuner2/scripts cd - +mv ../streamtuner2-*.txz linux-3.0-all/ echo "-------------------- .deb -----------------------" fakeroot epm -vvv -n -a all -f deb DEP=deb streamtuner2 _package.epm @@ -30,14 +31,21 @@ echo "-------------------- .rpm -----------------------" epm -vvv -n -a all -f rpm streamtuner2 _package.epm /usr/bin/rpmbuild -bb --buildroot "/home/mario/projects/streamtuner2/linux-3.0-all/buildroot" --target all linux-3.0-all/streamtuner2.spec -mv linux-3.0-all/RPMS/all/*.rpm linux-3.0-all +mv linux-3.0-all/RPMS/all/*.rpm linux-3.0-all/streamtuner2-$VERSION.rpm +rm -r linux-3.0-all/RPMS +rm -r linux-3.0-all/rpms +rm -r linux-3.0-all/buildroot +rmdir linux-3.0-all/streamtuner2-$VERSION +rm linux-3.0-all/streamtuner2.spec echo "-------------------- win32 -----------------------" for pkg in "win32" do epm-win32sfx -v streamtuner2 _package.epm done +mv win32/*exe linux-3.0-all/ +rmdir win32 Index: channels/shoutcast.py ================================================================== --- channels/shoutcast.py +++ channels/shoutcast.py @@ -121,88 +121,93 @@ next = 0 max = int(conf.max_streams) count = max rx_stream = None rx_next = re.compile("""onclick="showMoreGenre""") - while (next < max): - - # page - url = "http://www.shoutcast.com/genre-ajax/" + ucat - referer = url.replace("/genre-ajax", "/radio") - params = { "strIndex":"0", "count":str(count), "ajax":"true", "mode":"listeners", "order":"desc" } - html = http.ajax(url, params, referer) #,feedback=self.parent.status) - - __print__(html) - - # regular expressions - if not conf.get("pyquery") or not pq: - - # new extraction regex - if not rx_stream: - rx_stream = re.compile( - """ - ]+id="(\d+)".+? - ]+href="(http://[^">]+)"[^>]*>([^<>]+).+? - (?:Recently\s*played|Coming\s*soon|Now\s*playing):\s*([^<]*).+? - ners">(\d*)<.+? - bitrate">(\d*)<.+? - type">([MP3AAC]*) - """, - re.S|re.I|re.X - ) - - # extract entries - self.parent.status("parsing document...") - __print__("loop-rx") - for m in rx_stream.findall(html): - (id, homepage, title, playing, ls, bit, fmt) = m - __print__(uu) - entries += [{ - "title": self.entity_decode(title), - "url": "http://yp.shoutcast.com/sbin/tunein-station.pls?id=" + id, - "homepage": http.fix_url(homepage), - "playing": self.entity_decode(playing), - "genre": cat, #self.strip_tags(uu[4]), - "listeners": int(ls), - "max": 0, #int(uu[6]), - "bitrate": int(bit), - "format": self.mime_fmt(fmt), - }] - - # PyQuery parsing - else: - # iterate over DOM - for div in (pq(e) for e in pq(html).find("div.dirlist")): - - entries.append({ - "title": div.find("a.playbutton,a.playbutton1").attr("title"), - "url": div.find("a.playbutton,a.playbutton1").attr("href"), - "homepage": http.fix_url(div.find("a.div_website").attr("href")), - "playing": div.find("div.playingtext").attr("title"), -# "title": div.find("a.clickabletitleGenre, div.stationcol a").attr("title"), -# "url": div.find("a.playbutton, a.playbutton1, a.playimage").attr("href"), -# "homepage": http.fix_url(div.find("a.playbutton.clickabletitle, a[target=_blank], a.clickabletitleGenre, a.clickabletitle, div.stationcol a, a").attr("href")), -# "playing": div.find("div.playingtextGenre, div.playingtext").attr("title"), - "listeners": int(div.find("div.dirlistners").text()), - "bitrate": int(div.find("div.dirbitrate").text()), - "format": self.mime_fmt(div.find("div.dirtype").text()), - "max": 0, - "genre": cat, - # "title2": e.find("a.playbutton").attr("name"), - }) - - - # display partial results (not strictly needed anymore, because we fetch just one page) - self.parent.status() - self.update_streams_partially_done(entries) - - # more pages to load? - if (re.search(rx_next, html)): - next += count - else: - next = 99999 + + try: + while (next < max): + + # page + url = "http://www.shoutcast.com/genre-ajax/" + ucat + referer = url.replace("/genre-ajax", "/radio") + params = { "strIndex":"0", "count":str(count), "ajax":"true", "mode":"listeners", "order":"desc" } + html = http.ajax(url, params, referer) #,feedback=self.parent.status) + + __print__(html) + + # regular expressions + if not conf.get("pyquery") or not pq: + + # new extraction regex + if not rx_stream: + rx_stream = re.compile( + """ + ]+id="(\d+)".+? + ]+href="(http://[^">]+)"[^>]*>([^<>]+).+? + (?:Recently\s*played|Coming\s*soon|Now\s*playing):\s*([^<]*).+? + ners">(\d*)<.+? + bitrate">(\d*)<.+? + type">([MP3AAC]*) + """, + re.S|re.I|re.X + ) + + # extract entries + self.parent.status("parsing document...") + __print__("loop-rx") + for m in rx_stream.findall(html): + (id, homepage, title, playing, ls, bit, fmt) = m + __print__(uu) + entries += [{ + "title": self.entity_decode(title), + "url": "http://yp.shoutcast.com/sbin/tunein-station.pls?id=" + id, + "homepage": http.fix_url(homepage), + "playing": self.entity_decode(playing), + "genre": cat, #self.strip_tags(uu[4]), + "listeners": int(ls), + "max": 0, #int(uu[6]), + "bitrate": int(bit), + "format": self.mime_fmt(fmt), + }] + + # PyQuery parsing + else: + # iterate over DOM + for div in (pq(e) for e in pq(html).find("div.dirlist")): + + entries.append({ + "title": div.find("a.playbutton,a.playbutton1").attr("title"), + "url": div.find("a.playbutton,a.playbutton1").attr("href"), + "homepage": http.fix_url(div.find("a.div_website").attr("href")), + "playing": div.find("div.playingtext").attr("title"), + # "title": div.find("a.clickabletitleGenre, div.stationcol a").attr("title"), + # "url": div.find("a.playbutton, a.playbutton1, a.playimage").attr("href"), + # "homepage": http.fix_url(div.find("a.playbutton.clickabletitle, a[target=_blank], a.clickabletitleGenre, a.clickabletitle, div.stationcol a, a").attr("href")), + # "playing": div.find("div.playingtextGenre, div.playingtext").attr("title"), + "listeners": int(div.find("div.dirlistners").text()), + "bitrate": int(div.find("div.dirbitrate").text()), + "format": self.mime_fmt(div.find("div.dirtype").text()), + "max": 0, + "genre": cat, + # "title2": e.find("a.playbutton").attr("name"), + }) + + + # display partial results (not strictly needed anymore, because we fetch just one page) + self.parent.status() + self.update_streams_partially_done(entries) + + # more pages to load? + if (re.search(rx_next, html)): + next += count + else: + next = 99999 + + except: + return entries #fin __print__(entries) return entries Index: channels/timer.py ================================================================== --- channels/timer.py +++ channels/timer.py @@ -14,11 +14,11 @@ # stations at a programmed time and interval. It accepts a natural language time # string when registering a stream. (Via streams menu > extension > add timer) # # Programmed events are visible in "timer" under the "bookmarks" channel. Times # are stored in the description field, and can thus be edited. However, after editing -# times manuall, streamtuner2 must be restarted for the changes to take effect. +# times manually, streamtuner2 must be restarted for the changes to take effect. # from channels import * import kronos @@ -65,11 +65,11 @@ self.bookmarks.streams["timer"] = [{"title":"--- timer events ---"}] self.bookmarks.add_category("timer") self.streams = self.bookmarks.streams["timer"] # widgets - parent.signal_autoconnect({ + parent.add_signals.update({ "timer_ok": self.add_timer, "timer_cancel": lambda w,*a: self.parent.timer_dialog.hide() or 1, }) # prepare spool Index: st2.py ================================================================== --- st2.py +++ st2.py @@ -120,10 +120,11 @@ # object containers widgets = {} # non-glade widgets (the manually instantiated ones) channels = {} # channel modules features = {} # non-channel plugins working = [] # threads + add_signals = {} # channel gtk-handler signals # status variables channel_names = ["bookmarks"] # order of channel notebook tabs current_channel = "bookmarks" # currently selected channel name (as index in self.channels{}) @@ -171,11 +172,11 @@ except: print("channel .first_show() initialization error") # bind gtk/glade event names to functions gui_startup(0.95) - self.connect_signals({ + self.connect_signals(dict( { "gtk_main_quit" : self.gtk_main_quit, # close window # treeviews / notebook "on_stream_row_activated" : self.on_play_clicked, # double click in a streams list "on_category_clicked": self.on_category_clicked, # new selection in category list "on_notebook_channels_switch_page": self.channel_switch, # channel notebook tab changed @@ -221,11 +222,11 @@ "true": lambda w,*args: True, "streamedit_open": streamedit.open, "streamedit_save": streamedit.save, "streamedit_new": streamedit.new, "streamedit_cancel": streamedit.cancel, - }) + }.items() + self.add_signals.items() )) # actually display main window gui_startup(0.99) self.win_streamtuner2.show() @@ -470,12 +471,13 @@ # other plugin types else: self.features[module] = plugin_class(parent=self) except Exception, e: - print("error initializing:", module) - print(e) + print("error initializing:", module, ", exception:") + import traceback + traceback.print_exc() # default plugins conf.add_plugin_defaults(self.channels["bookmarks"].config, "bookmarks") #conf.add_plugin_defaults(self.channels["shoutcast"].config, "shoutcast")