Check-in [b042a5112f]
Overview
Comment: | Add dirble search (but keep disabled: error "504 not allowed"). Reintroduce pagination (slower, but with progress bar now). Add "Popular" and "Recent" categories. Reenable thumbnail fetching rather than plain favicons. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b042a5112fe7223f0e3a476b85162456 |
User & Date: | mario on 2017-02-25 00:06:23 |
Other Links: | manifest | tags |
Context
2017-02-26
| ||
21:42 | Support json= POST requests. check-in: ef2604c3a4 user: mario tags: trunk | |
2017-02-25
| ||
00:06 | Add dirble search (but keep disabled: error "504 not allowed"). Reintroduce pagination (slower, but with progress bar now). Add "Popular" and "Recent" categories. Reenable thumbnail fetching rather than plain favicons. check-in: b042a5112f user: mario tags: trunk | |
2017-02-23
| ||
22:12 | Relabel record option tabs to options/meta/network; regroup flags roughly. Add more options for wget and youtube-dl. check-in: e6fe0f52d5 user: mario tags: trunk | |
Changes
Modified channels/dirble.py from [3e36e0af87] to [8ed175109e].
1 2 3 4 5 | # encoding: UTF-8 # api: streamtuner2 # title: Dirble # description: Song history tracker for Internet radio stations. # url: http://dirble.com/ | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | # encoding: UTF-8 # api: streamtuner2 # title: Dirble # description: Song history tracker for Internet radio stations. # url: http://dirble.com/ # version: 2.3 # type: channel # category: radio # config: # { name: dirble_api_key, value: "", type: text, description: Alternative API access key., hidden: 1 } # png: # iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAACP0lE # QVQokVVSO0+UURA9M/d+jyWbBVcQFSQhPqJSYBRFA5pVoFGURApjYYWtvYUNP8FKOwsttDFq |
︙ | ︙ | |||
23 24 25 26 27 28 29 | # u+uAt1KkwvVxAGJsEEWxEWzGm4iV8l1HM9K0BmEkrP8BlhoAUfmOxecAAAAASUVORK5CYII= # priority: optional # documentation: http://dirble.com/developer/api # extraction-method: json # # # Dirble is a user-contributed list of radio stations, | | | < | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | # u+uAt1KkwvVxAGJsEEWxEWzGm4iV8l1HM9K0BmEkrP8BlhoAUfmOxecAAAAASUVORK5CYII= # priority: optional # documentation: http://dirble.com/developer/api # extraction-method: json # # # Dirble is a user-contributed list of radio stations, # auto-updating song titles and station information. # Homepages are there now, and thus favicons readily # available. Extra station banners aren't fetched. # # It provides a JSON API. Since plugin version 2.3 # we're back to slower pagination requests however. # # Response times are fixed now by overriding the HTTP # encoding. (A python-requests issue mostly). import json from config import * |
︙ | ︙ | |||
59 60 61 62 63 64 65 | # station banners are not accessible per CDN. # class dirble (ChannelPlugin): # control flags has_search = False listformat = "srv" | | | | | | > > | < > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | # station banners are not accessible per CDN. # class dirble (ChannelPlugin): # control flags has_search = False listformat = "srv" titles = dict(playing="Location") base = "http://api.dirble.com/v2/{}" key = "a0bdd7b8efc2f5d1ebdf1728b65a07ece4c73de5" # Retrieve cat list and map def update_categories(self): cats = [] for row in self.api("categories/tree"): cats += [row["title"]] self.catmap[row["title"]] = row["id"] if row.get("children"): cats += [[c["title"] for c in row["children"]]] for c in row["children"]: self.catmap[c["title"]] = c["id"] self.categories = ["Popular", "Recent"] + cats # Fetch entries def update_streams(self, cat, search=None): self.progress(1) if search: r = self.api("search", query=search, page=0, pages=1) elif cat in ("Popular", "Recent"): r = self.api("stations/{}".format(cat.lower()), pages=15) else: r = self.api("category/{}/stations".format(self.catmap.get(cat, 0)), pages=10) return [self.unpack(row) for row in r] # Extract rows def unpack(self, r): listeners = 0 # find stream if len(r.get("streams", [])): # compare against first entry s = r["streams"][0] # select "best" stream if there are alternatives if len(r["streams"]) > 0: for alt in r["streams"]: listeners += alt.get("listeners", 0) # set defaults if not alt.get("content_type"): alt["content_type"] = "?" if not alt.get("bitrate"): alt["bitrate"] = 16 alt["content_type"] = alt["content_type"].strip() # There's a "\r\n" in nearly every entry :? |
︙ | ︙ | |||
135 136 137 138 139 140 141 | genre = " ".join(c["slug"] for c in r["categories"]), title = r["name"], playing = "{} {}".format(r.get("country"), r.get("description", "")), homepage = ahttp.fix_url(r["website"]), url = s["stream"], format = s["content_type"], bitrate = s["bitrate"], | > | > | > > > > > > > > > | | | > | > | > > | > > | | | 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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | genre = " ".join(c["slug"] for c in r["categories"]), title = r["name"], playing = "{} {}".format(r.get("country"), r.get("description", "")), homepage = ahttp.fix_url(r["website"]), url = s["stream"], format = s["content_type"], bitrate = s["bitrate"], listeners = listeners, img = r.get("image", {}).get("thumb", {}).get("url", ""), # CDN HTTPS trip up requests.get img_resize = 32, state = self.state_map.get(int(s["status"]), ""), deleted = s.get("timedout", False), ) # Streams contain a `status`, here mapped onto arbitrary Gtk icons state_map = {0:"gtk-media-pause", 1:"gtk-media-next", 2:"gtk-media-rewind"} # Weighting bitrate and audio format for alternative stream URLs format_q = {"?":0.75, "audio/mpeg":1.0, "audio/aac":1.25, "audio/aacp":1.35, "audio/ogg":1.50} # Patch API url together, send request, decode JSON list def api(self, method, pages=1, **params): # pagination parameters if pages > 1: params["page"] = 0 params["per_page"] = 30 params["offset"] = 0 params["token"] = conf.dirble_api_key or self.key try: r = [] # paginate results for params["page"] in range(0, pages): self.progress(pages) # send HTTP request and extract JSON add = ahttp.get(self.base.format(method), params, encoding="utf-8") add = json.loads(add) # check for errors if isinstance(add, dict) and add.get("error"): if r: log.WARN(add["error"]) break else: raise Exception(add) r += add # cut down stream list self.progress(0) #if len(r) > int(conf.max_streams): # del r[int(conf.max_streams):] except Exception as e: log.ERR("Dirble API retrieval failure:", e) r = [] return r |