Check-in [8b3cd06ff7]
Overview
Comment: | Adapted Live365 channel plugin for /cgi-bin/play.pls?stationid=123457&direct=1 stream URLs instead of extraction, works again |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8b3cd06ff708ba014f3e677c8f2973da |
User & Date: | mario on 2014-07-31 17:22:46 |
Other Links: | manifest | tags |
Context
2014-08-01
| ||
01:34 | catmap{} cache handling now by _generic module check-in: cda3504633 user: mario tags: trunk | |
2014-07-31
| ||
17:22 | Adapted Live365 channel plugin for /cgi-bin/play.pls?stationid=123457&direct=1 stream URLs instead of extraction, works again check-in: 8b3cd06ff7 user: mario tags: trunk | |
03:23 | Fixed invalid encoding in (manually edited) releases.json check-in: e5effdd595 user: mario tags: trunk | |
Changes
Modified _package.epm from [81c1d8ed48] to [84031fd279].
1 | %product streamtuner2 - internet radio browser | | | 1 2 3 4 5 6 7 8 9 | %product streamtuner2 - internet radio browser %version 2.1.2 %vendor Mario Salzer %license %copyright Placed into the Public Domain, 2009-2014 %readme README %description Browser for Internet Radio Stations %description . |
︙ | ︙ | |||
29 30 31 32 33 34 35 | f 755 root root /usr/bin/streamtuner2 ./st2.py f 644 root root /usr/share/applications/streamtuner2.desktop ./streamtuner2.desktop d 755 root root /usr/share/streamtuner2 - f 644 root root /usr/share/streamtuner2/streamtuner2.png ./streamtuner2.png f 644 root root /usr/share/pixmaps/streamtuner2.png ./logo.png f 644 root root /usr/share/streamtuner2/gtk2.xml ./gtk2.xml f 644 root root /usr/share/streamtuner2/gtk3.xml ./gtk3.xml | | > > > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | f 755 root root /usr/bin/streamtuner2 ./st2.py f 644 root root /usr/share/applications/streamtuner2.desktop ./streamtuner2.desktop d 755 root root /usr/share/streamtuner2 - f 644 root root /usr/share/streamtuner2/streamtuner2.png ./streamtuner2.png f 644 root root /usr/share/pixmaps/streamtuner2.png ./logo.png f 644 root root /usr/share/streamtuner2/gtk2.xml ./gtk2.xml f 644 root root /usr/share/streamtuner2/gtk3.xml ./gtk3.xml #f 644 root root /usr/share/streamtuner2/pson.py ./pson.py #f 644 root root /usr/share/streamtuner2/processing.py ./processing.py f 644 root root /usr/share/streamtuner2/compat2and3.py ./compat2and3.py f 644 root root /usr/share/streamtuner2/action.py ./action.py f 644 root root /usr/share/streamtuner2/config.py ./config.py f 644 root root /usr/share/streamtuner2/ahttp.py ./ahttp.py f 644 root root /usr/share/streamtuner2/cli.py ./cli.py f 644 root root /usr/share/streamtuner2/mygtk.py ./mygtk.py f 644 root root /usr/share/streamtuner2/favicon.py ./favicon.py f 644 root root /usr/share/streamtuner2/pq.py ./pq.py #-- channels d 755 root root /usr/share/streamtuner2/channels - f 644 root root /usr/share/streamtuner2/channels/__init__.py ./channels/__init__.py f 644 root root /usr/share/streamtuner2/channels/_generic.py ./channels/_generic.py f 644 root root /usr/share/streamtuner2/channels/icast.py ./channels/icast.py f 644 root root /usr/share/streamtuner2/channels/icast.png ./channels/icast.png f 644 root root /usr/share/streamtuner2/channels/internet_radio.py ./channels/internet_radio.py f 644 root root /usr/share/streamtuner2/channels/internet_radio.png ./channels/internet_radio.png f 644 root root /usr/share/streamtuner2/channels/itunes.py ./channels/itunes.py f 644 root root /usr/share/streamtuner2/channels/itunes.png ./channels/itunes.png f 644 root root /usr/share/streamtuner2/channels/jamendo.py ./channels/jamendo.py f 644 root root /usr/share/streamtuner2/channels/jamendo.png ./channels/jamendo.png f 644 root root /usr/share/streamtuner2/channels/live365.py ./channels/live365.py f 644 root root /usr/share/streamtuner2/channels/live365.png ./channels/live365.png f 644 root root /usr/share/streamtuner2/channels/modarchive.py ./channels/modarchive.py f 644 root root /usr/share/streamtuner2/channels/modarchive.png ./channels/modarchive.png f 644 root root /usr/share/streamtuner2/channels/musicgoal.py ./channels/musicgoal.py |
︙ | ︙ | |||
71 72 73 74 75 76 77 | f 644 root root /usr/share/streamtuner2/channels/youtube.png ./channels/youtube.png f 644 root root /usr/share/streamtuner2/channels/global_key.py ./channels/global_key.py f 644 root root /usr/share/streamtuner2/channels/links.py ./channels/links.py f 644 root root /usr/share/streamtuner2/channels/timer.py ./channels/timer.py #-- scripts #d 755 root root /usr/share/streamtuner2/scripts - #f 644 root root /usr/share/streamtuner2/scripts/radiotop40_de.py ./scripts/radiotop40_de.py | < < | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | f 644 root root /usr/share/streamtuner2/channels/youtube.png ./channels/youtube.png f 644 root root /usr/share/streamtuner2/channels/global_key.py ./channels/global_key.py f 644 root root /usr/share/streamtuner2/channels/links.py ./channels/links.py f 644 root root /usr/share/streamtuner2/channels/timer.py ./channels/timer.py #-- scripts #d 755 root root /usr/share/streamtuner2/scripts - #f 644 root root /usr/share/streamtuner2/scripts/radiotop40_de.py ./scripts/radiotop40_de.py #-- help files f 644 root root /usr/share/man/man1/streamtuner2.1 ./help/streamtuner2.1 d 755 root root /usr/share/doc/streamtuner2/help - f 644 root root /usr/share/doc/streamtuner2/help/action_homepage.page ./help/action_homepage.page f 644 root root /usr/share/doc/streamtuner2/help/action_playing.page ./help/action_playing.page f 644 root root /usr/share/doc/streamtuner2/help/action_recording.page ./help/action_recording.page f 644 root root /usr/share/doc/streamtuner2/help/action_saving.page ./help/action_saving.page |
︙ | ︙ |
Modified ahttp.py from [31cf3bd93f] to [0fe1c60aea].
︙ | ︙ | |||
52 53 54 55 56 57 58 | #-- Retrieve data via HTTP # # Well, it says "get", but it actually does POST and AJAXish GET requests too. # | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #-- Retrieve data via HTTP # # Well, it says "get", but it actually does POST and AJAXish GET requests too. # def get(url, params={}, referer="", post=0, ajax=0, binary=0, feedback=None, content=True): __print__( dbg.HTTP, "GET", url, params ) # statusbar info progress_feedback(url) # combine headers headers = {} |
︙ | ︙ | |||
74 75 76 77 78 79 80 | r = session.post(url, params=params, headers=headers) else: r = session.get(url, params=params, headers=headers) __print__( dbg.HTTP, r.request.headers ); __print__( dbg.HTTP, r.headers ); | | | | < | | > | > > > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | r = session.post(url, params=params, headers=headers) else: r = session.get(url, params=params, headers=headers) __print__( dbg.HTTP, r.request.headers ); __print__( dbg.HTTP, r.headers ); # finish, clean statusbar #progress_feedback(0.9) progress_feedback("") # result __print__( dbg.INFO, "Content-Length", len(r.content) ) if not content: return r elif binary: return r.content else: return r.text #-- Append missing trailing slash to URLs def fix_url(url): if url is None: |
︙ | ︙ |
Modified channels/file.py from [a8e2e93dda] to [f92686b376].
1 2 3 4 5 6 7 8 | # # api: streamtuner2 # title: File browser # description: Displays mp3/oggs or m3u/pls files from local media file directories. # type: channel # category: media # version: 0.0 # priority: optional | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # # api: streamtuner2 # title: File browser # description: Displays mp3/oggs or m3u/pls files from local media file directories. # type: channel # category: media # version: 0.0 # priority: optional # depends: mutagen # # # Local file browser. # # |
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 | def update_categories(self): self.scan_dirs() # same as init def update_streams(self, cat, x=0): self.scan_dirs() return self.streams.get(os.path.basename(cat)) | > > | 176 177 178 179 180 181 182 183 184 185 186 187 | def update_categories(self): self.scan_dirs() # same as init def update_streams(self, cat, x=0): self.scan_dirs() print(self.streams) print(self.categories) return self.streams.get(os.path.basename(cat)) |
Modified channels/live365.py from [861e1f12f9] to [be1047f842].
1 2 3 4 5 6 7 8 9 | # api: streamtunter2 # title: Live365 # description: Around 5000 categorized internet radio streams, some paid ad-free ones. # type: channel # category: radio # version: 0.3 # priority: optional # | < < | < > > > | | < < > | < | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # api: streamtunter2 # title: Live365 # description: Around 5000 categorized internet radio streams, some paid ad-free ones. # type: channel # category: radio # version: 0.3 # priority: optional # # # # We're currently extracting from the JavaScript; # # stn.set("param", "value"); # # And using a HTML5 player direct URL now: # # /cgi-bin/play.pls?stationid=%s&direct=1&file=%s.pls # # # # streamtuner2 modules from config import conf from mygtk import mygtk import ahttp as http from channels import * from config import __print__, dbg import action # python modules import re import xml.dom.minidom from xml.sax.saxutils import unescape as entity_decode, escape as xmlentities import gtk import copy import urllib from itertools import groupby from time import time from xml.dom.minidom import parseString # channel live365 class live365(ChannelPlugin): # desc module = "live365" title = "Live365" |
︙ | ︙ | |||
79 80 81 82 83 84 85 | # fixed for now def update_categories(self): pass # extract stream infos def update_streams(self, cat): | | > > > | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > > | | > > | > > > > > > | > > > > > > > > | > > > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | # fixed for now def update_categories(self): pass # extract stream infos def update_streams(self, cat): # Retrieve genere index pages html = "" for i in [1, 17, 33, 49]: url = "http://www.live365.com/cgi-bin/directory.cgi?first=%i&site=web&mode=3&genre=%s&charset=UTF-8&target=content" % (i, cat.lower()) html += http.get(url, feedback=self.parent.status) # Extract from JavaScript rx = re.compile(r""" stn.set\( " (\w+) ", \s+ " ((?:[^"\\]+|\\.)*) "\); \s+ """, re.X|re.I|re.S|re.M) # Group entries before adding them ls = [] for i,row in groupby(rx.findall(html), self.group_by_station): row = dict(row) ls.append({ "name": row["stationName"], "title": row["title"], "playing": "n/a", "id": row["id"], "access": row["listenerAccess"], "status": row["status"], "mode": row["serverMode"], "rating": int(row["rating"]), #"rating": row["ratingCount"], "listeners": int(row["tlh"]), "location": row["location"], "favicon": row["imgUrl"], "format": self.mediatype, "url": "%scgi-bin/play.pls?stationid=%s&direct=1&file=%s.pls" % (self.base_url, row["id"], row["stationName"]) }) return ls # itertools.groupby filter gi = 0 def group_by_station(self, kv): if kv[0] == "stationName": self.gi += 1 return self.gi # inject session id etc. into direct audio url def UNUSED_play(self, row): if row.get("url"): # params id = row["id"] name = row["name"] # get mini.cgi station resource mini_url = "http://www.live365.com/cgi-bin/mini.cgi?version=3&templateid=xml&from=web&site=web" \ + "&caller=&tag=web&station_name=%s&_=%i111" % (name, time()) mini_r = http.get(mini_url, content=False) mini_xml = parseString(mini_r.text).getElementsByTagName("LIVE365_PLAYER_WINDOW")[0] mini = lambda name: mini_xml.getElementsByTagName(name)[0].childNodes[0].data # authorize with play.cgi play_url = "" # mk audio url play = "http://%s/play" % mini("STREAM_URL") \ + "?now=0&" \ + mini("NANOCASTER_PARAMS") \ + "&token=" + mini("TOKEN") \ + "&AuthType=NORMAL&lid=276006-deu&SaneID=178.24.130.71-1406763621701" # let's see what happens action.action.play(play, self.mediatype, self.listformat) |
Modified st2.py from [a922a58f51] to [3d89c6ea6f].
1 2 3 4 5 6 7 | #!/usr/bin/env python # encoding: UTF-8 # api: python # type: application # title: streamtuner2 # description: Directory browser for internet radio / audio streams # depends: pygtk | pygi, threading, pyquery, kronos, requests | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!/usr/bin/env python # encoding: UTF-8 # api: python # type: application # title: streamtuner2 # description: Directory browser for internet radio / audio streams # depends: pygtk | pygi, threading, pyquery, kronos, requests # version: 2.1.2 # author: mario salzer # license: public domain # url: http://freshmeat.net/projects/streamtuner2 # config: <env name="http_proxy" value="" description="proxy for HTTP access" /> <env name="XDG_CONFIG_HOME" description="relocates user .config subdirectory" /> # category: multimedia # # |
︙ | ︙ | |||
92 93 94 95 96 97 98 | import ahttp import action # needs workaround... (action.main=main) import channels from channels import * import favicon | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import ahttp import action # needs workaround... (action.main=main) import channels from channels import * import favicon __version__ = "2.1.2" # this represents the main window # and also contains most application behaviour main = None class StreamTunerTwo(gtk.Builder): |
︙ | ︙ |