Check-in [23bbd97989]
Overview
Comment: | Introduce action.handler{} callbacks to convert custom streaming URL types such as "audio/soundcloud". Unify backend code for .play/record/browser() calls. Reddit module just splits out domain name now, then checks for walledgarden links (filter option renamed). Introduce url_soundcloud plugin in favour of `soundcli` cmdline client setting. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
23bbd979893d140c1d5cdbd7e3f0ad46 |
User & Date: | mario on 2015-05-24 14:19:06 |
Other Links: | manifest | tags |
Context
2015-05-24
| ||
16:57 | Fix audioformat to audio/mpeg. check-in: fa5df72f08 user: mario tags: trunk | |
14:19 | Introduce action.handler{} callbacks to convert custom streaming URL types such as "audio/soundcloud". Unify backend code for .play/record/browser() calls. Reddit module just splits out domain name now, then checks for walledgarden links (filter option renamed). Introduce url_soundcloud plugin in favour of `soundcli` cmdline client setting. check-in: 23bbd97989 user: mario tags: trunk | |
10:02 | Move channel.save() after column updating. check-in: 3072c80d83 user: mario tags: trunk | |
Changes
Modified action.py from [005725eacf] to [0cb40c6df9].
︙ | ︙ | |||
116 117 118 119 120 121 122 123 124 125 | ] # Preferred probing order of known formats playlist_fmt_prio = [ "pls", "xspf", "asx", "smil", "jamj", "json", "m3u", "asf", "raw" ] # Exec wrapper | > > > > > < < < < < < < < < < < < | < | > > > > > | | | > > > | > > | > | < < | 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 156 157 158 159 160 161 162 163 164 165 166 167 168 | ] # Preferred probing order of known formats playlist_fmt_prio = [ "pls", "xspf", "asx", "smil", "jamj", "json", "m3u", "asf", "raw" ] # custom stream domain handlers handler = { # "soundcloud": callback(), } # Exec wrapper def run(cmd): log.EXEC(cmd) try: os.system("start \"%s\"" % cmd if conf.windows else cmd + " &") except: log.ERR("Command not found:", cmd) # Open help browser, streamtuner2 pages def help(*args): run("yelp /usr/share/doc/streamtuner2/help/") # Invokes player/recorder for stream url and format def run_fmt_url(row={}, audioformat="audio/mpeg", source="pls", url=None, assoc={}): if not url: url = row["url"] if audioformat in handler: handler[audioformat](row, audioformat, source, url, assoc) else: cmd = mime_app(audioformat, assoc) cmd = interpol(cmd, url, source, row) run(cmd) # Start web browser def browser(url): run_fmt_url({}, "url/http", "srv", url, conf.play) # Calls player for stream url and format def play(row={}, audioformat="audio/mpeg", source="pls", url=None): run_fmt_url(row, audioformat, source, url, conf.play) # Call streamripper / youtube-dl / wget def record(row={}, audioformat="audio/mpeg", source="href", url=None): run_fmt_url(row, audioformat, source, url, conf.record) # OS shell command escaping # def quote(ins): if type(ins) is list: return " ".join(["%r" % str(s) for s in ins]) |
︙ | ︙ |
Deleted contrib/cfg_soundcloud.py version [1301f5ed6f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified contrib/reddit.py from [74725ffeda] to [46f1758ac3].
1 2 3 4 5 6 7 8 9 10 | # encoding: UTF-8 # api: streamtuner2 # title: redditβ± # description: Music recommendations from reddit /r/music and associated subreddits. # version: 0.8 # type: channel # url: http://reddit.com/r/Music # category: playlist # config: # { name: reddit_pages, type: int, value: 2, description: Number of pages to fetch. } | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # encoding: UTF-8 # api: streamtuner2 # title: redditβ± # description: Music recommendations from reddit /r/music and associated subreddits. # version: 0.8 # type: channel # url: http://reddit.com/r/Music # category: playlist # config: # { name: reddit_pages, type: int, value: 2, description: Number of pages to fetch. } # { name: filter_walledgardens, type: boolean, value: 1, description: Filter walled gardens (soundcloud/spotify/β¦) if there's no player. } # { name: reddit_keep_all, type: boolean, value: 0, description: Keep all web links (starts a browser for websites/news). } # png: # iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJ1BMVEUAAAAcICX/AABHSk1jZ299hYz/bmajq6//lY/d0M3C1+3T7P38+/iaLhuGAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgF # HUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQffBRUXIyQbWArCAAAAh0lEQVQI12Pg3g0BDLtXrVq1eveq3Qy7gIxCU9dqEGO11/ZKbzBDenUIUM3u7cGi1UDFW0TE55wsdpZikAw/ # eebMnMmHGVxqDuUc0zzpynD4zIk5J3vOSDNsOQMG1gy7bI5HTq85Ws2wu/jM9PIzrkArdhmXlzuuXg00eVd5+epVqxmgrtgNAOWeS1KYtcY4AAAAAElFTkSuQmCC # priority: extra # |
︙ | ︙ | |||
31 32 33 34 35 36 37 38 39 40 41 42 43 44 | # is not very enticing. import json import re from config import * from channels import * import ahttp # reddit.com # # Uses old API requests such as: # β http://www.reddit.com/r/music/new.json?sort=new | > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | # is not very enticing. import json import re from config import * from channels import * import action import ahttp # reddit.com # # Uses old API requests such as: # β http://www.reddit.com/r/music/new.json?sort=new |
︙ | ︙ | |||
275 276 277 278 279 280 281 | elif text_urls: row["url"] = text_urls[0] format = "video/youtube" # check for specific web links (Soundcloud etc.) else: listformat = "srv" format = None | > > | < | | | | | | | | | < | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | elif text_urls: row["url"] = text_urls[0] format = "video/youtube" # check for specific web links (Soundcloud etc.) else: listformat = "srv" format = None # look for walled gardens urltype = re.findall("([\w-]+)\.\w+/", row["url"] + "/x-unknown.com/")[0] if urltype in ("soundcloud", "spotify", "bandcamp", "mixcloud"): # is a specific player configured? fmt = "audio/" + urltype if fmt in conf.play or fmt in action.handler: state = "gtk-media-forward" format = fmt # retain it as web link? elif not conf.filter_walledgardens: state = "gtk-media-pause" format = "url/http" # else skip entry completely if not format: if conf.reddit_keep_all: state = "gtk-page-setup" format = "url/http" else: log.DATA_SKIP(format, row["url"]) |
︙ | ︙ |
Added contrib/url_soundcloud.py version [18282e867b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | # api: streamtuner2 # title: Soundcloud streams # description: Convert soundcloud links from reddit to streamable tracks # version: 0.1 # type: filter # category: audio # depends: python:soundcloud, action >= 1.0, reddit >= 0.6 # priority: rare # # Overrides action.play() function to convert soundcloud URLs # to track/streaming address. Disables the reddit filter for # walled gardens, and overrides any custom player configured # for "audio/soundcloud" in settings. import re import soundcloud from config import * import ahttp import action fmt = "audio/soundcloud" rx_url = re.compile("^https?://(www\.)?soundcloud\.com/[\w-]+/[\w-]+$") conn = None # API connect def client(): global conn if not conn: conn = soundcloud.Client(client_id="f0aea6e0484043f6638cb5bf35d43312") return conn # Capture play events for faux MIME type def sndcl_convert(row={}, audioformat="audio/mpeg", source="pls", url=None, assoc={}): if audioformat==fmt or rx_url.match(url): # find streaming address try: log.DATA_CONVERT_SOUNDCLOUD(url) track = client().get('/resolve', url=url) track_str = "/tracks/{}/stream".format(track.id) url = client().get(track_str, allow_redirects=False).location # override attributes row["url"] = url source = "srv" audioformat = "audio/mpeg" except Exception as e: log.ERR_SOUNDCLOUD("URL resolving failed:", e) # let web browser run audioformat = "url/http" # let primary handler take over if audioformat != fmt: return action.run_fmt_url(row, audioformat, source, url, assoc) # Hook up custom action.handler for soundcloud URLs # # Still somewhat hodgepodge. The action module just lets .play() params # rewrite by above handler. Should turn faux "audio/soundcloud" URL into # plain/longwinded MP3 streaming address. # # Would need more generalized processing of custom URL schemes. But so # far only the reddit module uses them anyway. # class url_soundcloud(object): module = "url_soundcloud" # override action.play() with wrapper def __init__(self, parent, *a, **kw): conf.play[fmt] = "false / convert" #conf.filter_walledgardens = False action.handler[fmt] = sndcl_convert |