Skip to content
This repository has been archived by the owner on Jul 26, 2021. It is now read-only.

Commit

Permalink
Merge pull request #41 from Danfocus/optimization_v1
Browse files Browse the repository at this point in the history
PEP8 fixes. Some optimizations
  • Loading branch information
phrawzty authored Mar 10, 2020
2 parents 1581f47 + 9814f4e commit 6f339b2
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 201 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.swp
*.pyc
.vscode/
28 changes: 16 additions & 12 deletions Contents/Code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,23 @@

####################################################################################################


def Start():
"""This is called when the plugin is loaded."""

## set some defaults so that you don't have to
## pass these parameters to these object types
## every single time
## see also:
## http://dev.plexapp.com/docs/Objects.html
# set some defaults so that you don't have to
# pass these parameters to these object types
# every single time
# see also:
# http://dev.plexapp.com/docs/Objects.html
ObjectContainer.title1 = NAME
DirectoryObject.thumb = R(ICON)

HTTP.CacheTime = CACHE_1HOUR


def ValidatePrefs():
"""This doesn't do anything useful yet."""

pass


Expand All @@ -54,14 +55,15 @@ def MusicMainMenu():

return oc


@route(MUSIC_PREFIX + '/service')
def GetChannels(serv):
"""This produces the list of channels for a given service."""

# Set some preferences. It really makes life easier if they're set.
AA.set_service(serv)
AA.set_listenkey(Prefs['listen_key'])
AA.set_streampref(Prefs['stream_pref_' + serv])
AA.set_streampref(Prefs['stream_pref'])
AA.set_sourcepref(Prefs['source_pref'])

oc = ObjectContainer(title1=AA.get_servicename(serv))
Expand All @@ -72,15 +74,15 @@ def GetChannels(serv):
for channel in AA.get_batchinfo(refresh=True):
# Use the handy internal Dict api to avoid re-generating the streamurl
# over and over.
if (not channel['key'] in Dict) or (Prefs['force_refresh'] == True):
Dict[channel['key']] = AA.get_streamurl(channel['key'])
if (not channel['key'] in Dict) or (Prefs['force_refresh'] is True):
Dict[channel['key']] = channel['streamurl']
if Prefs['debug']:
Log.Debug('saving %s' % Dict[channel['key']])

oc.add(CreateChannelObject(
url=Dict[channel['key']],
title=channel['name'],
summary=channel['description'],
summary=channel['description_long'] or channel['description'],
fmt=fmt,
own=1,
bitrate=bitrate,
Expand All @@ -90,6 +92,7 @@ def GetChannels(serv):
oc.objects.sort(key=lambda obj: obj.title)
return oc


@route(MUSIC_PREFIX + '/channel')
def CreateChannelObject(
url,
Expand All @@ -101,7 +104,7 @@ def CreateChannelObject(
thumb,
include_container=False,
**kwargs
):
):
"""Build yon streamable object, ye mighty."""

if fmt == 'mp3':
Expand All @@ -119,7 +122,8 @@ def CreateChannelObject(
debug_summary.append('[%s]' % url)

track_object = TrackObject(
key=Callback(CreateChannelObject,
key=Callback(
CreateChannelObject,
url=url,
title=title,
summary=' '.join(debug_summary),
Expand Down
152 changes: 47 additions & 105 deletions Contents/Code/audioaddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import json
import random


class AudioAddict:
"""AudioAddict utility class."""

Expand All @@ -20,75 +21,19 @@ def __init__(self):
'di': 'DI.fm',
'jazzradio': 'JazzRadio.com',
'rockradio': 'RockRadio.com',
'classicalradio': 'ClassicalRadio.com'
'classicalradio': 'ClassicalRadio.com',
# 'zenradio': 'ZenRadio.com',
}

# Each service proposes a selection of stream types.
# It's worth noting that public3 is the *only* common type.
self.validstreams = {
'di': {
'android_low': {'codec': 'aac', 'bitrate': 40},
'android': {'codec': 'aac', 'bitrate': 64},
'android_high': {'codec': 'mp3', 'bitrate': 96},
'android_premium_low': {'codec': 'aac', 'bitrate': 40},
'android_premium_medium': {'codec': 'aac', 'bitrate': 64},
'android_premium': {'codec': 'aac', 'bitrate': 128},
'android_premium_high': {'codec': 'mp3', 'bitrate': 320},
'public1': {'codec': 'aac', 'bitrate': 64},
'public2': {'codec': 'aac', 'bitrate': 40},
'public3': {'codec': 'mp3', 'bitrate': 96},
'premium_low': {'codec': 'aac', 'bitrate': 40},
'premium_medium': {'codec': 'aac', 'bitrate': 64},
'premium': {'codec': 'aac', 'bitrate': 128},
'premium_high': {'codec': 'mp3', 'bitrate': 320}
},
'radiotunes': {
'appleapp_low': {'codec': 'aac', 'bitrate': 40},
'appleapp': {'codec': 'aac', 'bitrate': 64},
'appleapp_high': {'codec': 'mp3', 'bitrate': 96},
'appleapp_premium_medium': {'codec': 'aac', 'bitrate': 64},
'appleapp_premium': {'codec': 'aac', 'bitrate': 128},
'appleapp_premium_high': {'codec': 'mp3', 'bitrate': 320},
'public1': {'codec': 'aac', 'bitrate': 40},
'public3': {'codec': 'mp3', 'bitrate': 96},
'public5': {'codec': 'wma', 'bitrate': 40},
'premium_low': {'codec': 'aac', 'bitrate': 40},
'premium_medium': {'codec': 'aac', 'bitrate': 64},
'premium': {'codec': 'aac', 'bitrate': 128},
'premium_high': {'codec': 'mp3', 'bitrate': 320}
},
'jazzradio': {
'appleapp_low': {'codec': 'aac', 'bitrate': 40},
'appleapp': {'codec': 'aac', 'bitrate': 64},
'appleapp_premium_medium': {'codec': 'aac', 'bitrate': 64},
'appleapp_premium': {'codec': 'aac', 'bitrate': 128},
'appleapp_premium_high': {'codec': 'mp3', 'bitrate': 256},
'public1': {'codec': 'aac', 'bitrate': 40},
'public3': {'codec': 'mp3', 'bitrate': 64},
'premium_low': {'codec': 'aac', 'bitrate': 40},
'premium_medium': {'codec': 'aac', 'bitrate': 64},
'premium': {'codec': 'aac', 'bitrate': 128},
'premium_high': {'codec': 'mp3', 'bitrate': 256}
},
'rockradio': {
'android_low': {'codec': 'aac', 'bitrate': 40},
'android': {'codec': 'aac', 'bitrate': 64},
'android_premium_medium': {'codec': 'aac', 'bitrate': 64},
'android_premium': {'codec': 'aac', 'bitrate': 128},
'android_premium_high': {'codec': 'mp3', 'bitrate': 256},
'public3': {'codec': 'mp3', 'bitrate': 96},
},
'classicalradio': {
'public1': {'codec': 'aac', 'bitrate': 40},
'public3': {'codec': 'mp3', 'bitrate': 64},
'premium_low': {'codec': 'aac', 'bitrate': 40},
'premium_medium': {'codec': 'aac', 'bitrate': 64},
'premium': {'codec': 'aac', 'bitrate': 128},
'premium_high': {'codec': 'mp3', 'bitrate': 256}
}
'premium_medium': {'codec': 'aac', 'bitrate': 64},
'premium': {'codec': 'aac', 'bitrate': 128},
'premium_high': {'codec': 'mp3', 'bitrate': 320},
}

self.streampref = 'public3'
self.streampref = 'premium_high'
self.sourcepref = None

self.service = None
Expand All @@ -101,15 +46,15 @@ def __init__(self):
self.authheader = ['Authorization', 'Basic ZXBoZW1lcm9uOmRheWVpcGgwbmVAcHA=']
self.batchinfo = {}

def get_apihost(self, url=True, ssl=False):
def get_apihost(self, host_only=False, ssl=False):
"""Get the AA API host; normally used as part of a URL."""

if url == False:
if host_only:
return self.apihost

obj = '://' + self.apihost + '/v1'

if ssl == True:
if ssl:
obj = 'https' + obj
else:
obj = 'http' + obj
Expand All @@ -121,12 +66,12 @@ def set_listenkey(self, listenkey=None):

self.listenkey = listenkey

def get_listenkey(self, url=True):
def get_listenkey(self, key_only=False):
"""Get the listen_key; normally used as part of a URL."""

if self.listenkey == None:
if not self.listenkey:
return ''
elif url == False:
elif key_only:
return self.listenkey
else:
return '?listen_key=' + self.listenkey
Expand All @@ -139,7 +84,7 @@ def get_validservices(self):
def set_service(self, serv=None):
"""Set which service we're using."""

if not serv in self.validservices.keys():
if serv not in self.validservices.keys():
raise Exception('Invalid service')

self.service = serv
Expand All @@ -152,10 +97,10 @@ def get_service(self):
def get_servicename(self, serv=None):
"""Get the name of a given service."""

if serv == None:
if not serv:
serv = self.get_service()

if not serv in self.get_validservices().keys():
if serv not in self.get_validservices().keys():
raise Exception('Invalid service')

return self.validservices[serv]
Expand All @@ -168,7 +113,7 @@ def get_validstreams(self):
def get_serviceurl(self, serv=None, prefix='listen'):
"""Get the service URL for the service we're using."""

if serv == None:
if not serv:
serv = self.get_service()

url = 'http://' + prefix + '.' + self.get_servicename(serv)
Expand All @@ -179,7 +124,7 @@ def get_serviceurl(self, serv=None, prefix='listen'):
def set_streampref(self, stream=None):
"""Set the preferred stream."""

if not stream in self.get_validstreams()[self.get_service()]:
if stream not in self.get_validstreams():
raise Exception('Invalid stream')

self.streampref = stream
Expand All @@ -188,11 +133,10 @@ def get_streamdetails(self):
"""Get the details for a stream."""

details = {}
validstreams = self.get_validstreams()
stream = self.get_streampref()

if stream in validstreams[self.get_service()]:
details = validstreams[self.get_service()][stream]
if stream in self.get_validstreams():
details = self.get_validstreams()[stream]

return details

Expand All @@ -214,7 +158,7 @@ def get_sourcepref(self):
def get_chanlist(self, refresh=False):
"""Get the master channel list."""

if len(self.chanlist) < 1 or refresh == True:
if not self.chanlist or refresh:
try:
data = urllib2.urlopen(self.get_serviceurl() + '/' + self.get_streampref())
self.chanlist = json.loads(data.read())
Expand All @@ -232,37 +176,16 @@ def get_chaninfo(self, key):
if chan['key'] == key:
chaninfo = chan.copy()

if chaninfo == None:
if not chaninfo:
raise Exception('Invalid channel')

return chaninfo

def get_streamurl(self, key):
"""Generate a streamable URL for a channel."""

channelurl = self.get_serviceurl() + '/' + self.get_streampref() + '/' + key + self.get_listenkey()

data = urllib2.urlopen(channelurl)
sources = json.loads(data.read())

streamurl = None

# Look through the list for the preferred source.
if not self.get_sourcepref() == None:
for source in sources:
if self.get_sourcepref() in source:
streamurl = source

# If there is no preferred source or one was not found, pick at random.
if streamurl == None:
streamurl = (random.choice(sources))

return streamurl

def get_chanhist(self, key):
"""Get track history for a channel."""

servurl = self.get_apihost() + '/' + self.get_service() + '/' + 'track_history/channel/' + str(self.get_chaninfo(key)['id'])
servurl = self.get_apihost() + '/' + self.get_service() + '/track_history/channel/' + \
str(self.get_chaninfo(key)['id'])

data = urllib2.urlopen(servurl)
history = json.loads(data.read())
Expand All @@ -278,7 +201,7 @@ def get_nowplaying(self, key):

track = 'Unknown - Unknown'

if not 'ad' in self.get_chanhist(key)[0]:
if 'ad' not in self.get_chanhist(key)[0]:
track = self.get_chanhist(key)[0]['track']
else:
track = self.get_chanhist(key)[1]['track']
Expand All @@ -288,10 +211,11 @@ def get_nowplaying(self, key):
def get_batchinfo(self, refresh=False):
"""Get the massive batch info blob."""

if (len(self.batchinfo) > 0) and refresh == False:
if self.batchinfo and not refresh:
return self.batchinfo

url = self.get_apihost() + '/' + self.get_service() + '/mobile/batch_update?stream_set_key=' + self.get_streampref()
url = self.get_apihost() + '/' + self.get_service() + '/mobile/batch_update?stream_set_key=' + \
self.get_streampref()

req = urllib2.Request(url)
req.add_header(*self.authheader)
Expand All @@ -315,5 +239,23 @@ def get_batchinfo(self, refresh=False):
# Only the "All" channel filter is interesting for now.
for i in batch['channel_filters']:
if i['name'] == 'All':
self.batchinfo = i['channels']
batchinfo = i['channels']
for channel in batchinfo:
for ss_channel in batch['stream_sets'][0]['streamlist']['channels']:
if channel['id'] == ss_channel['id']:
streamurl = None
# Look through the list for the preferred source.
if self.get_sourcepref():
for stream in ss_channel['streams']:
if self.get_sourcepref() in stream['url']:
streamurl = stream['url']

# If there is no preferred source or one was not found, pick at random.
if not streamurl:
streamurl = random.choice([x['url'] for x in ss_channel['streams']])

if streamurl:
channel['streamurl'] = streamurl + '?' + self.get_listenkey(key_only=True)

self.batchinfo = batchinfo
return self.batchinfo
Loading

0 comments on commit 6f339b2

Please sign in to comment.