Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ ⎇ branch:  streamtuner2


Diff

Differences From Artifact [296b5551ad]:

To Artifact [5f9e55387f]:


1
2
3
4
5
6
7
8
9
10
11
12
13
# encoding: UTF-8
# api: streamtuner2
# title: Youtube
# description: Channel, playlist and video browsing for youtube.
# type: channel
# version: 0.2
# url: http://www.youtube.com/
# category: video
# config:
#    { name: youtube_channels,  type: text,  value: "Key Of Awesome, Pentatonix",  description: "Preferred channels to list videos from.",  category: select }
#    { name: youtube_region,  type: select,  select: "=No Region|AR=Argentina|AU=Australia|AT=Austria|BE=Belgium|BR=Brazil|CA=Canada|CL=Chile|CO=Colombia|CZ=Czech Republic|EG=Egypt|FR=France|DE=Germany|GB=Great Britain|HK=Hong Kong|HU=Hungary|IN=India|IE=Ireland|IL=Israel|IT=Italy|JP=Japan|JO=Jordan|MY=Malaysia|MX=Mexico|MA=Morocco|NL=Netherlands|NZ=New Zealand|PE=Peru|PH=Philippines|PL=Poland|RU=Russia|SA=Saudi Arabia|SG=Singapore|ZA=South Africa|KR=South Korea|ES=Spain|SE=Sweden|CH=Switzerland|TW=Taiwan|AE=United Arab Emirates|US=United States",  value: GB,  description: "Filter by region id.",  category: auth }
#    { name: youtube_wadsworth,  type: boolean,  value: 0,  description: "Apply Wadsworth constant.",  category: filter }
# priority: default





|







1
2
3
4
5
6
7
8
9
10
11
12
13
# encoding: UTF-8
# api: streamtuner2
# title: Youtube
# description: Channel, playlist and video browsing for youtube.
# type: channel
# version: 0.3
# url: http://www.youtube.com/
# category: video
# config:
#    { name: youtube_channels,  type: text,  value: "Key Of Awesome, Pentatonix",  description: "Preferred channels to list videos from.",  category: select }
#    { name: youtube_region,  type: select,  select: "=No Region|AR=Argentina|AU=Australia|AT=Austria|BE=Belgium|BR=Brazil|CA=Canada|CL=Chile|CO=Colombia|CZ=Czech Republic|EG=Egypt|FR=France|DE=Germany|GB=Great Britain|HK=Hong Kong|HU=Hungary|IN=India|IE=Ireland|IL=Israel|IT=Italy|JP=Japan|JO=Jordan|MY=Malaysia|MX=Mexico|MA=Morocco|NL=Netherlands|NZ=New Zealand|PE=Peru|PH=Philippines|PL=Poland|RU=Russia|SA=Saudi Arabia|SG=Singapore|ZA=South Africa|KR=South Korea|ES=Spain|SE=Sweden|CH=Switzerland|TW=Taiwan|AE=United Arab Emirates|US=United States",  value: GB,  description: "Filter by region id.",  category: auth }
#    { name: youtube_wadsworth,  type: boolean,  value: 0,  description: "Apply Wadsworth constant.",  category: filter }
# priority: default
194
195
196
197
198
199
200
201




202
203
204
205
206
207
208
209
210
211




212
213
214
215
216
217
218
        # My Channels
        # - searches channel id for given title
        # - iterates over playlist
        # - then over playlistitems to get videos
        elif cat in channels:
            # channel id, e.g. UCEmCXnbNYz-MOtXi3lZ7W1Q
            UC = self.channel_id(cat)
            




            # playlist
            for i,playlist in enumerate(self.api("playlists", fields="items(id,snippet/title)", channelId=UC, maxResults=15)):

                # items (videos)
                for row in self.api("playlistItems", playlistId=playlist["id"], fields="items(snippet(title,resourceId/videoId,description))"):
                    entries.append(self.wrap3(row, {"genre": cat, "playing": playlist["snippet"]["title"]}))

                self.update_streams_partially_done(entries)
                self.parent.status(i / 15.0)
            




        
        # empty entries
        else:
            return self.placeholder
 
        # done    
        return entries







|
>
>
>
>
|









>
>
>
>







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
        # My Channels
        # - searches channel id for given title
        # - iterates over playlist
        # - then over playlistitems to get videos
        elif cat in channels:
            # channel id, e.g. UCEmCXnbNYz-MOtXi3lZ7W1Q
            UC = self.channel_id(cat)

            # fetches videos ordered by date
            for row in self.api("search", order="date", fields="pageInfo,nextPageToken,items(id,snippet(title,channelTitle,description))", channelId=UC, type="video"):
                entries.append( self.wrap3(row, {"genre": cat, "playing": cat}) )
            
            # augments with playlist entries
            for i,playlist in enumerate(self.api("playlists", fields="items(id,snippet/title)", channelId=UC, maxResults=15)):

                # items (videos)
                for row in self.api("playlistItems", playlistId=playlist["id"], fields="items(snippet(title,resourceId/videoId,description))"):
                    entries.append(self.wrap3(row, {"genre": cat, "playing": playlist["snippet"]["title"]}))

                self.update_streams_partially_done(entries)
                self.parent.status(i / 15.0)
            
            # unique entries
            e = []
            [e.append(v) for v in entries if v not in e]
            entries = e
        
        # empty entries
        else:
            return self.placeholder
 
        # done    
        return entries
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
        return id
    channel2id = {}



    #-- Retrieve Youtube API query results
    #
    def api(self, method, ver=3, pages=5, **params):
        items = []

        # URL and default parameters
        (base_url, defaults) = self.service[ver]
        params = dict( list(defaults.items()) + list(params.items())  )

        # Retrieve data set
        while pages > 0:
            j = ahttp.get(base_url + method, params=params)

            #log.DATA(j)
            if j:
                # json decode
                data = json.loads(j)
                
                # extract items
                if "items" in data:







|









>







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
        return id
    channel2id = {}



    #-- Retrieve Youtube API query results
    #
    def api(self, method, ver=3, pages=5, debug=False, **params):
        items = []

        # URL and default parameters
        (base_url, defaults) = self.service[ver]
        params = dict( list(defaults.items()) + list(params.items())  )

        # Retrieve data set
        while pages > 0:
            j = ahttp.get(base_url + method, params=params)
            #if debug:
            #log.DATA(j)
            if j:
                # json decode
                data = json.loads(j)
                
                # extract items
                if "items" in data:
289
290
291
292
293
294
295

296
297

298
299
300
301

302
303
304
305
306
307
308

        data.update(dict(
            url = "http://youtube.com/v/" + id,
            homepage = "http://youtu.be/" + id + ("?wadsworth=1" if conf.youtube_wadsworth else ""),
            format = self.audioformat,
            title = row["snippet"]["title"],
        ))

        
        # optional values

        if "playing" not in data:
            data["playing"] = row["snippet"]["channelTitle"]
        if "description" in row["snippet"]:
            data["description"] = row["snippet"]["description"],


        return data


    # API version 2.0s jsonified XML needs different unpacking:
    def wrap2(self, row):
        #log.DATA(row)







>


>
|
|
|
|
>







298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

        data.update(dict(
            url = "http://youtube.com/v/" + id,
            homepage = "http://youtu.be/" + id + ("?wadsworth=1" if conf.youtube_wadsworth else ""),
            format = self.audioformat,
            title = row["snippet"]["title"],
        ))
        #log.DATA(row)
        
        # optional values
        if "snippet" in row:
            if "playing" not in data and "channelTitle" in row["snippet"]:
                 data["playing"] = row["snippet"]["channelTitle"]
            if "description" in row["snippet"] and "description" in row["snippet"]:
                data["description"] = row["snippet"]["description"],
        #log.UI(data)

        return data


    # API version 2.0s jsonified XML needs different unpacking:
    def wrap2(self, row):
        #log.DATA(row)