from constants import CONF_ENABLED
import taglib
from modules.cache import use_cache
+import base64
def setup(mass):
async def get_artist(self, prov_item_id) -> Artist:
''' get full artist details by id '''
- if not os.path.isdir(prov_item_id):
- LOGGER.error("artist path does not exist: %s" % prov_item_id)
- return None
- if "\\" in prov_item_id:
- name = prov_item_id.split("\\")[-1]
+ if not os.sep in prov_item_id:
+ itempath = base64.b64decode(prov_item_id).decode('utf-8')
else:
- name = prov_item_id.split("/")[-1]
+ itempath = prov_item_id
+ prov_item_id = base64.b64encode(itempath.encode('utf-8')).decode('utf-8')
+ if not os.path.isdir(itempath):
+ LOGGER.error("artist path does not exist: %s" % itempath)
+ return None
+ name = itempath.split(os.sep)[-1]
artist = Artist()
artist.item_id = prov_item_id
artist.provider = self.prov_id
artist.name = name
artist.provider_ids.append({
"provider": self.prov_id,
- "item_id": prov_item_id
+ "item_id": artist.item_id
})
return artist
async def get_album(self, prov_item_id) -> Album:
''' get full album details by id '''
- if not os.path.isdir(prov_item_id):
- LOGGER.error("album path does not exist: %s" % prov_item_id)
- return None
- if "\\" in prov_item_id:
- name = prov_item_id.split("\\")[-1]
- artistpath = prov_item_id.rsplit("\\", 1)[0]
+ if not os.sep in prov_item_id:
+ itempath = base64.b64decode(prov_item_id).decode('utf-8')
else:
- name = prov_item_id.split("/")[-1]
- artistpath = prov_item_id.rsplit("/", 1)[0]
+ itempath = prov_item_id
+ prov_item_id = base64.b64encode(itempath.encode('utf-8')).decode('utf-8')
+ if not os.path.isdir(itempath):
+ LOGGER.error("album path does not exist: %s" % itempath)
+ return None
+ name = itempath.split(os.sep)[-1]
+ artistpath = itempath.rsplit(os.sep, 1)[0]
album = Album()
album.item_id = prov_item_id
album.provider = self.prov_id
async def get_track(self, prov_item_id) -> Track:
''' get full track details by id '''
- if not os.path.isfile(prov_item_id):
- LOGGER.error("track path does not exist: %s" % prov_item_id)
+ if not os.sep in prov_item_id:
+ itempath = base64.b64decode(prov_item_id).decode('utf-8')
+ else:
+ itempath = prov_item_id
+ if not os.path.isfile(itempath):
+ LOGGER.error("track path does not exist: %s" % itempath)
return None
- return await self.__parse_track(prov_item_id)
+ return await self.__parse_track(itempath)
async def get_playlist(self, prov_item_id) -> Playlist:
''' get full playlist details by id '''
- if not os.path.isfile(prov_item_id):
- LOGGER.error("playlist path does not exist: %s" % prov_item_id)
+ if not os.sep in prov_item_id:
+ itempath = base64.b64decode(prov_item_id).decode('utf-8')
+ else:
+ itempath = prov_item_id
+ prov_item_id = base64.b64encode(itempath.encode('utf-8')).decode('utf-8')
+ if not os.path.isfile(itempath):
+ LOGGER.error("playlist path does not exist: %s" % itempath)
return None
- filepath = prov_item_id
playlist = Playlist()
- playlist.item_id = filepath
+ playlist.item_id = prov_item_id
playlist.provider = self.prov_id
- playlist.name = filepath.split('\\')[-1].split('/')[-1].replace('.m3u', '')
+ playlist.name = itempath.split(os.sep)[-1].replace('.m3u', '')
playlist.is_editable = True
playlist.provider_ids.append({
"provider": self.prov_id,
- "item_id": filepath
+ "item_id": prov_item_id
})
playlist.owner = 'disk'
return playlist
async def get_album_tracks(self, prov_album_id) -> List[Track]:
''' get album tracks for given album id '''
result = []
- albumpath = prov_album_id
+ if not os.sep in prov_album_id:
+ albumpath = base64.b64decode(prov_album_id).decode('utf-8')
+ else:
+ albumpath = prov_album_id
if not os.path.isdir(albumpath):
LOGGER.error("album path does not exist: %s" % albumpath)
return []
async def get_playlist_tracks(self, prov_playlist_id, limit=50, offset=0) -> List[Track]:
''' get playlist tracks for given playlist id '''
tracks = []
- if not os.path.isfile(prov_playlist_id):
- LOGGER.error("playlist path does not exist: %s" % prov_playlist_id)
+ if not os.sep in prov_playlist_id:
+ itempath = base64.b64decode(prov_playlist_id).decode('utf-8')
+ else:
+ itempath = prov_playlist_id
+ if not os.path.isfile(itempath):
+ LOGGER.error("playlist path does not exist: %s" % itempath)
return []
counter = 0
- with open(prov_playlist_id) as f:
+ with open(itempath) as f:
for line in f.readlines():
line = line.strip()
if line and not line.startswith('#'):
async def get_artist_albums(self, prov_artist_id) -> List[Album]:
''' get a list of albums for the given artist '''
result = []
- artistpath = prov_artist_id
+ if not os.sep in prov_artist_id:
+ artistpath = base64.b64decode(prov_artist_id).decode('utf-8')
+ else:
+ artistpath = prov_artist_id
if not os.path.isdir(artistpath):
LOGGER.error("artist path does not exist: %s" % artistpath)
return []
async def get_stream_content_type(self, track_id):
''' return the content type for the given track when it will be streamed'''
+ if not os.sep in track_id:
+ track_id = base64.b64decode(track_id).decode('utf-8')
return track_id.split('.')[-1]
- async def get_stream(self, track_id):
+ async def get_audio_stream(self, track_id):
''' get audio stream for a track '''
+ if not os.sep in track_id:
+ track_id = base64.b64decode(track_id).decode('utf-8')
with open(track_id) as f:
while True:
line = f.readline()
song = taglib.File(filename)
except:
return None # not a media file ?
+ prov_item_id = base64.b64encode(filename.encode('utf-8')).decode('utf-8')
track.duration = song.length
- track.item_id = filename
+ track.item_id = prov_item_id
track.provider = self.prov_id
name = song.tags['TITLE'][0]
track.name, track.version = parse_track_title(name)
- if "\\" in filename:
- albumpath = filename.rsplit("\\",1)[0]
- else:
- albumpath = filename.rsplit("/",1)[0]
+ albumpath = filename.rsplit(os.sep,1)[0]
track.album = await self.get_album(albumpath)
artists = []
for artist_str in song.tags['ARTIST']:
artist.item_id = fake_artistpath # temporary id
artist.provider_ids.append({
"provider": self.prov_id,
- "item_id": fake_artistpath
+ "item_id": base64.b64encode(fake_artistpath.encode('utf-8')).decode('utf-8')
})
artists.append(artist)
track.artists = artists
quality_details = "%s kbps" % (song.bitrate)
track.provider_ids.append({
"provider": self.prov_id,
- "item_id": filename,
+ "item_id": prov_item_id,
"quality": quality,
"details": quality_details
})
player.volume_level = new_volume
return True
+ async def __check_player_group_power(self, player_details, player_childs):
+ ''' handle group power '''
+ childs_powered = False
+ for child_player in player_childs:
+ if child_player.powered:
+ childs_powered = True
+ break
+ if player_details.powered and not childs_powered:
+ # all childs turned off so turn off group player
+ LOGGER.info('all childs turned off so turn off group player %s' % player_details.name)
+ await self.player_command(player_details.player_id, 'power', 'off')
+ player_details.powered = False
+ elif not player_details.powered and childs_powered:
+ # all childs turned off but group player still off, so turn it on
+ LOGGER.info('child(s) turned on but group player still off, so turn it on %s' % player_details.name)
+ await self.player_command(player_details.player_id, 'power', 'on')
+ player_details.powered = True
+
async def remove_player(self, player_id):
''' handle a player remove '''
self._players.pop(player_id, None)
if player_details.is_group and player.settings['apply_group_volume']:
await self.__update_player_group_volume(player_details, player_childs)
if player_details.is_group and player.settings['apply_group_power']:
- await self.__update_player_group_power(player_details, player_childs)
+ await self.__check_player_group_power(player_details, player_childs)
# compare values to detect changes
if player.cur_item and player_details.cur_item and player.cur_item.name != player_details.cur_item.name:
player_changed = True
group_volume = group_volume / active_players if active_players else 0
player_details.volume_level = group_volume
- async def __update_player_group_power(self, player_details, player_childs):
- ''' handle group power '''
- player_powered = False
- for child_player in player_childs:
- if child_player.powered:
- player_powered = True
- break
- if player_details.powered and not player_powered:
- # all childs turned off so turn off group player
- LOGGER.info('all childs turned off so turn off group player %s' % player_details.name)
- await self. player_command(player_details.player_id, 'power', 'off')
- player_details.powered = False
- elif not player_details.powered and player_powered:
- # all childs turned off but group player still off, so turn it on
- LOGGER.info('all childs turned off but group player still off, so turn it on %s' % player_details.name)
- await self. player_command(player_details.player_id, 'power', 'on')
- player_details.powered = True
-
async def __get_player_settings(self, player_id):
''' get (or create) player config '''
player_settings = self.mass.config['player_settings'].get(player_id,{})
cmd = '%s %s --xml --ebu -f %s' % (bs1770_binary, tmpfile, analysis_file)
process = await asyncio.create_subprocess_shell(cmd)
await process.wait()
- if self.mass.config['base']['http_streamer']['enable_cache']:
+ if self.mass.config['base']['http_streamer']['enable_cache'] and not os.path.isfile(cachefile):
# use sox to store cache file (optionally strip silence from start and end)
if self.mass.config['base']['http_streamer']['trim_silence']:
cmd = 'sox -t %s %s -t flac -C5 %s silence 1 0.1 1%% reverse silence 1 0.1 1%% reverse' %(content_type, tmpfile, cachefile)