def get_my_library_artists(self, from_cache=True):
        _cache = os.path.join(utils.get_cache_dir(['library']), 'artists.json')

        artists = []
        if os.path.exists(_cache) and from_cache:
            with open(_cache, 'r') as f:
                artists = json.loads(f.read())
        else:
            songs = self.get_my_library_songs()
            songs = self._uniquify(songs, 'albumArtist')

            for song in songs:
                if ('artistId' not in song or 'title' not in song):
                    utils.log('Skipping broken entry:',
                              json.dumps(song),
                              lvl=xbmc.LOGERROR)
                    continue

                _art = thumbs.IMG_ARTIST
                if 'artistArtRef' in song and len(song['artistArtRef']) > 0:
                    _art = song['artistArtRef'][0]['url']

                artist = {
                    'artistId': song['artistId'][0],
                    'name': song['albumArtist'],
                    'artistArtRef': _art
                }

                artists.append(artist)

            artists = sorted(artists, key=itemgetter('name'))
            with open(_cache, 'w+') as f:
                f.write(json.dumps(artists))

        return artists
Ejemplo n.º 2
0
def on_call_started(data):
    utils.log('Received call start event')
    addon = xbmcaddon.Addon()
    player = xbmc.Player()

    data = utils.execute_jsonrpc('Application.GetProperties',
                                 {'properties': ['volume']})

    if data and 'volume' in data:
        volume = data['volume']
        addon.setSetting('saved_volume', str(volume))

    action = Action.NOTHING
    volume = 0
    if player.isPlayingAudio():
        action = int(addon.getSetting('music.on_call'))
        volume = int(addon.getSetting('music.volume'))

    elif player.isPlayingVideo():
        action = int(addon.getSetting('video.on_call'))
        volume = int(addon.getSetting('video.volume'))

    if action == Action.MUTE:
        if not xbmc.getCondVisibility('Player.Muted'):
            xbmc.executebuiltin('Mute')

    elif action == Action.PAUSE:
        if not xbmc.getCondVisibility('Player.Paused'):
            player.pause()

    elif action == Action.VOLUME and volume:
        xbmc.executebuiltin('XBMC.SetVolume({}, showvolumebar)'.format(volume))

    return True
    def _serve(self):
        utils.log('Server started, handling requests now')
        while not self._exit.is_set():
            self._is_alive.set()
            self.handle_request()

        self._is_alive.clear()
    def is_authorized(self):
        try:
            addon = xbmcaddon.Addon()
        except RuntimeError:
            # When the addon gets disabled and the dummy request get sent,
            # this will happen
            return False

        is_auth_enabled = addon.getSetting('server.auth_enabled')

        if is_auth_enabled == 'false':
            return True

        username = addon.getSetting('server.username')
        password = addon.getSetting('server.password')

        if 'Authorization' in self.headers:
            auth = self.headers['Authorization'].split()[1].decode('base64')
            user = auth.split(':')[0]
            pwd = auth.split(':')[1]

            if user == username and pwd == password:
                return True

        utils.log('Not authorized')
        return False
    def _make_call(self, protocol, *args, **kwargs):
        try:
            return super(GMusic, self)._make_call(protocol, *args, **kwargs)

        except:
            utils.notify(utils.translate(30050), utils.translate(30051))
            utils.log(traceback.format_exc(), lvl=xbmc.LOGERROR)
            return None
    def serve_forever(self):
        if self.is_alive():
            utils.log('Server already running. Skipping!')
            return

        t = threading.Thread(target=self._serve)
        t.daemon = True
        t.start()
def on_notification_posted(data):
    utils.log('Received new notification')

    # Get title and message
    title = data['title']

    message = ''
    if data['bigText']:
        message = data['bigText']

    elif data['text']:
        message = data['text']

    elif data['tickerText']:
        message = data['tickerText']

    if data['subText']:
        message = '{} {}'.format(message, data['subText'])

    message = message.replace('\n', ' ').replace('\r', ' ')

    # Get an icon to display
    large_icon_data = data['largeIcon']['data']
    app_icon_data = data['appIcon']['data']
    small_icon_data = data['smallIcon']['data']

    icon = None
    icon_path = None
    if large_icon_data:
        icon = large_icon_data
        icon_path = os.path.join(CACHE_DIR,
                                 hashlib.md5(large_icon_data).hexdigest())

    elif app_icon_data:
        icon = app_icon_data
        icon_path = os.path.join(CACHE_DIR,
                                 hashlib.md5(app_icon_data).hexdigest())

    elif small_icon_data:
        icon = small_icon_data
        icon_path = os.path.join(CACHE_DIR,
                                 hashlib.md5(small_icon_data).hexdigest())

    if not os.path.exists(icon_path):
        with open(icon_path, 'wb') as f:
            f.write(icon.decode('base64'))

    addon = xbmcaddon.Addon()

    play_sound = addon.getSetting('notification.play_sound') == 'true'
    display_time = int(addon.getSetting('notification.display_time')) * 1000

    xbmcgui.Dialog().notification(title, message, icon_path, display_time,
                                  play_sound)

    return True
Ejemplo n.º 8
0
def list_shows_schedule(network, page=1):
    aa = addict.AudioAddict.get(PROFILE_DIR, network)
    xbmcplugin.setPluginCategory(HANDLE, aa.name)

    shows = aa.get_upcoming()
    shows = sorted(shows, key=lambda s: s['start_at'])

    # Shows for "get_upcoming" have "following" always set to False
    # Have to work around this for now :/
    followed_shows = aa.get_shows_followed()
    followed_slugs = [s.get('slug') for s in followed_shows]

    now = addict.datetime_now()
    active = utils.get_playing() or {}
    utils.log('active item', active)
    items = []
    for show in shows:
        end_at = addict.parse_datetime(show.get('end_at'))

        if end_at < now:
            continue

        start_at = addict.parse_datetime(show.get('start_at'))

        show = show.get('show', {})
        channel = show.get('channels', [])[0]

        item = utils.build_show_item(network, show, followed_slugs)
        item.setPath(
            utils.build_path('play',
                             'channel',
                             network,
                             channel.get('key'),
                             live=show.get('now_playing', False)))

        if show.get('now_playing', False):
            label_prefix = utils.translate(30333)  # Live now

            item.setProperty('IsPlayable', 'false')

            if (active.get('is_live', False)
                    and active.get('channel') == channel.get('key')):
                item.select(True)
        else:
            label_prefix = '{} - {}'.format(start_at.strftime('%H:%M'),
                                            end_at.strftime('%H:%M'))

        item.setLabel('[B]{}[/B] - {} [I]({})[/I]'.format(
            label_prefix, _enc(show.get('name')), _enc(channel.get('name'))))

        items.append((item.getPath(), item, False))

    utils.list_items(items)
Ejemplo n.º 9
0
def on_call_ended(data):
    utils.log('Received call end event')
    addon = xbmcaddon.Addon()
    player = xbmc.Player()

    action = Action.NOTHING
    reset_vol = False

    if player.isPlayingAudio():
        action = int(addon.getSetting('music.on_call'))

        unmute = addon.getSetting('music.unmute') == 'true'
        play_after = addon.getSetting('music.play_after') == 'true'
        reset_vol = addon.getSetting('music.reset_volume') == 'true'

    elif player.isPlayingVideo():
        action = int(addon.getSetting('video.on_call'))

        unmute = addon.getSetting('video.unmute') == 'true'
        play_after = addon.getSetting('video.play_after') == 'true'
        reset_vol = addon.getSetting('video.reset_volume') == 'true'

    if action == Action.MUTE and unmute:
        if xbmc.getCondVisibility('Player.Muted'):
            xbmc.executebuiltin('Mute')

    elif action == Action.PAUSE and play_after:
        if xbmc.getCondVisibility('Player.Paused'):
            player.pause()

    elif action == Action.VOLUME and reset_vol:
        try:
            volume = int(addon.getSetting('saved_volume'))
            xbmc.executebuiltin(
                'XBMC.SetVolume({}, showvolumebar)'.format(volume))
        except Exception:
            pass

    return True
    def exit(self):
        utils.log('Exit requested')
        self._exit.set()
        self._exit.wait()

        utils.log('Exit flag was set')
        try:
            addr = 'http://{}:{}'.format(self.server_address[0],
                                         self.server_address[1])

            utils.log('Sending dummy request to:', addr)
            xmlrpclib.Server(addr).ping()
        except Exception:
            pass

        utils.log('Shutdown complete')
def on_notification_removed(data):
    utils.log('Received notification delete event')
    return True
    def get_my_library_songs(self, from_cache=True):
        _cache = os.path.join(utils.get_cache_dir(['library']), 'songs.json')
        _song_cache_path = utils.get_cache_dir(['library', 'songs'])

        songs = None
        if os.path.exists(_cache) and from_cache:
            with open(_cache, 'r') as f:
                songs = json.loads(f.read())

        else:
            generator = self.get_all_songs(incremental=True,
                                           include_deleted=False)

            tmp = []
            for songs in generator:
                tmp += songs

            songs = tmp

            # Generate artistId and albumId in case they are
            # missing (applies to user uploaded songs without
            # a matching entry in googles database)
            for i, song in enumerate(songs):
                if ('title' not in song or 'album' not in song
                        or 'artist' not in song):
                    utils.log('Skipping broken entry:',
                              json.dumps(song),
                              lvl=xbmc.LOGERROR)
                    continue

                if 'artistId' not in song:
                    songs[i]['artistId'] = [str(uuid.uuid4())]

                if 'albumId' not in song:
                    songs[i]['albumId'] = str(uuid.uuid4())

            with open(_cache, 'w+') as f:
                f.write(json.dumps(songs))

            # Save each song as separate file
            # for easier and quicker access
            for song in songs:
                # Main id file
                _target = os.path.join(_song_cache_path, song['id'])
                with open(os.path.join(_target), 'w+') as f:
                    f.write(json.dumps(song))

                # Other available ids which we create symlinks for
                for _id in ['trackId', 'storeId']:
                    if _id not in song:
                        continue

                    _link = os.path.join(_song_cache_path, song[_id])
                    if os.path.exists(_link) and os.path.islink(_link):
                        continue

                    try:
                        # On unix systems we simply create a symlink
                        os.symlink(_target, _link)

                    except:
                        # On other systems (*cough* windows *cough*) we just
                        # write another version of the file
                        with open(os.path.join(_link), 'w+') as f:
                            f.write(json.dumps(song))

        return songs
 def get_new_releases(self, num_items=25, genre=None):
     res = self._make_call(mobileclient.GetNewReleases, num_items, genre)
     utils.log(json.dumps(res, indent=2), lvl=xbmc.LOGERROR)
     for tabs in res['tabs']:
         if tabs['tab_type'] == 'NEW_RELEASES':
             return tabs['groups'][0]['entities']
Ejemplo n.º 14
0
def monitor_live(skip_shows=None):
    if not skip_shows:
        skip_shows = []

    now = addict.datetime_now()
    addon = xbmcaddon.Addon()

    for network in addict.NETWORKS.keys():
        aa = addict.AudioAddict.get(PROFILE_DIR, network)

        if not aa.is_active or not aa.network['has_shows']:
            continue

        followed = [s.get('slug') for s in aa.get_shows_followed()]

        shows = aa.get_live_shows()
        live_show_ids = [s.get('id') for s in shows]

        # Remove shows which are not live anymore
        skip_shows = [i for i in skip_shows if i in live_show_ids]

        for show in shows:
            if show.get('id') in skip_shows:
                continue

            end_at = addict.parse_datetime(show.get('end_at'))
            if end_at < now:
                continue

            skip_shows.append(show.get('id'))

            _show = show.get('show')
            if _show.get('slug') in followed and addon.getSettingBool(
                    'addon.notify_live'):
                utils.notify('[B]{}[/B] is live!'.format(_show.get('name')))

            if addon.getSettingBool('addon.tune_in_live'):
                filename = xbmc.getInfoLabel('Player.Filenameandpath')
                if not filename:
                    continue

                playing = utils.get_playing()
                if not playing:
                    continue

                chan = _show.get('channels', [])[0]
                if (playing['network'] != network
                        or playing['channel'] != chan.get('key')):
                    utils.logd(
                        'Different network/channel playing, not tuning in.')
                    continue

                if playing['live']:
                    utils.logd('Live stream already playing.')
                    break

                time_left = (end_at - now).seconds
                if time_left < 2:
                    utils.log('Less than 2 minutes left, not tuning in.')
                    break

                utils.log('Tuning in to live stream...')
                xbmc.executebuiltin('RunPlugin({})'.format(
                    utils.build_path('play',
                                     network,
                                     playing['channel'],
                                     live=True)))

    return skip_shows
Ejemplo n.º 15
0
def on_call_missed(data):
    utils.log('Received call missed event')
    return True
 def log_message(self, format, *args):
     utils.log("{} - - [{}] {}\n".format(self.address_string(),
                                         self.log_date_time_string(),
                                         format % args))