Example #1
0
    def attach_context_menu(self, item, menu):
        colorCaution = getSetting('item_caution_color')
        login = getSetting('username')
        isOwner = True
        cmd = containerUpdate(self.make_url(nt=Flag.USERPLAYLISTS,
                                            id='', mode=Mode.VIEW))
        menu.add(path='playlist', pos=1,
                 label="Playlist", cmd=cmd, mode=Mode.VIEW)
        if login != self.get_property('owner/name'):
            isOwner = False

        if isOwner:
            url = self.make_url(nt=Flag.PLAYLIST, mode=Mode.VIEW,
                                nm='set_as_current')
            menu.add(path='playlist/set_as_current', label=lang(30163),
                     cmd=containerUpdate(url))

            url = self.make_url(nt=Flag.PLAYLIST, nm='gui_rename')
            menu.add(path='playlist/rename', label=lang(30165),
                     cmd=runPlugin(url))

        else:
            url = self.make_url(nt=Flag.PLAYLIST, nm='subscribe')
            menu.add(path='playlist/subscribe', label=lang(30168),
                     cmd=runPlugin(url))

        url = self.make_url(nt=Flag.PLAYLIST, nm='gui_remove')
        menu.add(path='playlist/remove', label=lang(30166),
                 cmd=runPlugin(url), color=colorCaution)
        super(Node_playlist, self).attach_context_menu(item, menu)
Example #2
0
 def makeListItem(self, replaceItems=False):
     colorItem = getSetting('item_default_color')
     colorPl = getSetting('item_section_color')
     label = self.get_label()
     image = self.get_image()
     owner = self.get_owner()
     url = self.make_url()
     if not self.is_my_playlist:
         label = '%s - %s' % (color(colorItem, owner), label)
     if self.b_is_current:
         fmt = getSetting('playlist_current_format')
         label = fmt % (color(colorPl, label))
     item = xbmcgui.ListItem(label,
                             owner,
                             image,
                             image,
                             url)
     if not item:
         warn(self, "Error: Cannot make xbmc list item")
         return None
     item.setPath(url)
     ctxMenu = contextMenu()
     self.attach_context_menu(item, ctxMenu)
     item.addContextMenuItems(ctxMenu.getTuples(), replaceItems)
     return item
Example #3
0
 def get_ttl(self, key, *a, **ka):
     if len(a) > 0:
         if a[0] == '/track/getFileUrl':
             return 60 * 15
     if 'user_id' in ka:
         return getSetting('cache_duration_middle', asInt=True) * 60
     return getSetting('cache_duration_long', asInt=True) * 60
Example #4
0
 def __init__(self):
     self.data = {}
     self.defaultSection = "qobuz"
     self.color_default = getSetting("item_default_color")
     self.color_section = getSetting("item_section_color")
     formatStr = getSetting("item_section_format")
     try:
         test = formatStr % ("plop")
     except:
         formatStr = "[ %s ]"
     self.format_section = formatStr
Example #5
0
 def bootstrap_registry(self):
     from qobuz.api import api
     cache.base_path = config.path.cache
     api.stream_format = 6 if getSetting('streamtype') == 'flac' else 5
     if not api.login(getSetting('username'), getSetting('password')):
         if api.status_code == 503:
             dialogServiceTemporarilyUnavailable()
         else:
             dialogLoginFailure()
         #@TODO sys.exit killing XBMC? FRODO BUG ?
         # sys.exit(1)
         containerRefresh()
         raise QobuzXbmcError(
             who=self, what='invalid_login', additional=None)
Example #6
0
 def __getFileUrl(self):
     hires = getSetting('hires_enabled', asBool=True)
     format_id = 6 if getSetting('streamtype') == 'flac' else 5
     if hires and self.get_hires():
         format_id = 27
     if self.get_property('purchased') or self.get_parameter('purchased') == '1' or self.purchased:
         intent = "download"
     else:
         intent = "stream"
     data = api.get('/track/getFileUrl', format_id=format_id,
                    track_id=self.nid, user_id=api.user_id, intent=intent)
     if not data:
         warn(self, "Cannot get stream type for track (network problem?)")
         return None
     return data
Example #7
0
 def __add_pagination_node(self, Dir, lvl=1, whiteFlag=Flag.NODE):
     """Helper/Called by build_down to add special node when pagination is
     required
     """
     if self.pagination_next:
         colorItem = getSetting('color_item')
         params = config.app.bootstrap.params
         params['offset'] = self.pagination_next_offset
         params['nid'] = self.nid
         node = getNode(self.nt, params)
         node.data = self.data
         label = self.get_label()
         if label is None:
             if self.label2 is not None:
                 label = self.label2
             elif self.parent is not None:
                 label = self.parent.get_label()
             else:
                 label = '[no-label]'
         nextLabel = u'[ {}  {} / {} ]'.format(color(colorItem, label),
                                             self.pagination_next_offset,
                                             self.pagination_total)
         node.label = nextLabel
         node.label2 = label
         self.add_child(node)
Example #8
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit', asInt=True)
     self.data = None
     query = self.query
     if not query:
         from gui.util import Keyboard
         k = Keyboard('', 'My %s' % self.search_type)
         k.doModal()
         if not k.isConfirmed():
             return False
         query = k.getText()
     query.strip()
     info(self, 'search_type: %s, query: %s' % (self.search_type, query))
     source = self.source
     kwargs = {'query': query,
               'limit': limit,
               }
     if source is not None:
         kwargs['source'] = source
     data = None
     if self.search_type == 'albums':
         data = api.get('/collection/getAlbums', **kwargs)
     elif self.search_type == 'artists':
         data = api.get('/collection/getArtists', **kwargs)
     elif self.search_type == 'tracks':
         data = api.get('/collection/getTracks', **kwargs)
     if data is None:
         return False
     self.data = data
     return True
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting("pagination_limit")
     data = qobuz.registry.get(name="article_listrubrics", id=self.nid, offset=self.offset, limit=limit)
     if not data:
         return False
     self.data = data["data"]
     return True
Example #10
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/artist/getSimilarArtists', artist_id=self.nid,
                    offset=self.offset, limit=limit)
     if not data:
         return False
     self.data = data
     return len(data['artists']['items'])
Example #11
0
 def delete_cache(self, playlist_id):
     limit = getSetting('pagination_limit')
     upkey = cache.make_key('/playlist/getUserPlaylists', limit=limit,
                            offset=self.offset, user_id=api.user_id)
     pkey = cache.make_key('/playlist/get', playlist_id=playlist_id,
                           offset=self.offset, limit=limit, extra='tracks')
     cache.delete(upkey)
     cache.delete(pkey)
Example #12
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/purchase/getUserPurchases', limit=limit,
                    offset=self.offset, user_id=api.user_id)
     if not data:
         warn(self, "Cannot fetch purchases data")
         return False
     self.data = data
     return True
Example #13
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/artist/get', artist_id=self.nid, limit=limit,
                    offset=self.offset, extra='albums')
     if not data:
         warn(self, "Build-down: Cannot fetch artist data")
         return False
     self.data = data
     return True
Example #14
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/artist/getSimilarArtist', artist_id=self.nid,
                    limit=limit, offset=self.offset, extra='albums')
     if not data:
         warn(self, "Cannot fetch albums for artist: " + self.get_label())
         return False
     self.data = data
     return True
Example #15
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit', asInt=True)
     data = api.get('/playlist/get', playlist_id=self.nid,
                    offset=self.offset, limit=limit, extra='tracks')
     if not data:
         warn(self, "Build-down: Cannot fetch playlist data")
         return False
     self.data = data
     self.get_image() # Buld thumbnail if neeeded
     return True
Example #16
0
    def attach_context_menu(self, item, menu):
        colorWarn = getSetting('item_caution_color')
        url = self.make_url()
        menu.add(path='friend', label=self.name, cmd=containerUpdate(url))
        cmd = runPlugin(self.make_url(nt=Flag.FRIEND, nm="remove"))
        menu.add(path='friend/remove', label='Remove', cmd=cmd,
                 color=colorWarn)

        ''' Calling base class '''
        super(Node_friend, self).attach_context_menu(item, menu)
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting("pagination_limit")
     data = api.get("/playlist/getPublicPlaylists", offset=self.offset, limit=limit, type="last-created")
     if not data:
         return False
     # @bug: we use pagination_limit as limit for the search so we don't
     # need offset... (Fixed if qobuz fix it :p)
     if not "total" in data["playlists"]:
         data["playlists"]["total"] = data["playlists"]["limit"]
     self.data = data
     return True
Example #18
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/playlist/getUserPlaylists',
                    limit=limit,
                    offset=self.offset,
                    user_id=api.user_id)
     if data is None:
         warn(self, "Build-down: Cannot fetch user playlists data")
         return False
     self.data = data
     return True
Example #19
0
 def __init__(self, parent=None, parameters=None):
     super(Node_user_playlists, self).__init__(parent, parameters)
     self.label = lang(30021)
     self.image = getImage('userplaylists')
     self.nt = Flag.USERPLAYLISTS
     self.content_type = 'files'
     display_by = self.get_parameter('display-by', default=None)
     if display_by is None:
         display_by = 'songs'
     self.set_display_by(display_by)
     display_cover = getSetting('userplaylists_display_cover', asBool=True)
     self.display_product_cover = display_cover
Example #20
0
 def populate(self, Dir, lvl, whiteFlag, blackFlag):
     self.add_child(getNode(Flag.USERPLAYLISTS))
     if getSetting('show_recommendations', asBool=True):
         self.add_child(getNode(Flag.RECOMMENDATION))
     self.add_child(getNode(Flag.PURCHASES))
     self.add_child(getNode(Flag.FAVORITES))
     if getSetting('search_enabled', asBool=True):
         search = getNode(Flag.SEARCH)
         search.search_type = 'albums'
         self.add_child(search)
         search = getNode(Flag.SEARCH)
         search.search_type = 'tracks'
         self.add_child(search)
         search = getNode(Flag.SEARCH)
         search.search_type = 'artists'
         self.add_child(search)
         collections = getNode(Flag.COLLECTIONS)
         self.add_child(collections)
     self.add_child(getNode(Flag.FRIENDS))
     self.add_child(getNode(Flag.GENRE))
     self.add_child(getNode(Flag.PUBLIC_PLAYLISTS))
     return True
Example #21
0
 def __init__(self, parent, params):
     super(Node_album, self).__init__(parent, params)
     self.nt = Flag.ALBUM
     self.image = getImage('album')
     self.content_type = 'songs'
     self.is_special_purchase = False
     self.imageDefaultSize = 'large'
     self.label = 'Album'
     self.offset = self.get_parameter('offset') or 0
     try:
         self.imageDefaultSize = getSetting('image_default_size')
     except Exception as e:
         warn(self, 'Cannot set image default size, Error: {}', e)
Example #22
0
 def populate(self, Dir, lvl, whiteFlag, blackFlag):
     login = getSetting('username')
     cid = self.get_current_playlist_id()
     for data in self.data['playlists']['items']:
         node = getNode(Flag.PLAYLIST, data=data)
         #if self.display_product_cover:
         #    pass
         if cid and cid == node.nid:
             node.set_is_current(True)
         if node.get_owner() == login:
             node.set_is_my_playlist(True)
         self.add_child(node)
     return True
Example #23
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = api.get('/genre/list', parent_id=self.nid, offset=self.offset,
                    limit=limit)
     if not data:
         self.data = None
         return True  # Nothing returned trigger reco build in build_down
     self.data = data
     genres = self.data['genres']
     if 'parent' in genres and int(genres['parent']['level']) > 1:
         self.populate_reco(Dir, lvl, whiteFlag, blackFlag,
                            genres['parent']['id'])
     return True
Example #24
0
 def gui_remove(self, playlist_id=None):
     if not playlist_id:
         playlist_id = self.nid
     if not playlist_id:
         notify_error(dialogHeading,
                      'Invalid playlist %s' % (str(playlist_id)))
         return False
     login = getSetting('username')
     offset = 0
     limit = getSetting('pagination_limit')
     data = api.get('/playlist/get', playlist_id=playlist_id, limit=limit,
                    offset=offset)
     name = ''
     if 'name' in data:
         name = data['name']
     ok = xbmcgui.Dialog().yesno(lang(30166),
                                 lang(30054),
                                 color('FFFF0000', name))
     if not ok:
         info(self, "Deleting playlist aborted...")
         return False
     res = False
     if data['owner']['name'] == login:
         info(self, "Deleting playlist: " + str(playlist_id))
         res = api.playlist_delete(playlist_id=playlist_id)
     else:
         info(self, 'Unsuscribe playlist' + str(playlist_id))
         res = api.playlist_unsubscribe(playlist_id=playlist_id)
     if not res:
         warn(self, "Cannot delete playlist with id " + str(playlist_id))
         notify_error(lang(30183), lang(30186) + name)
         return False
     self.delete_cache(playlist_id)
     notify_log(lang(30183), (lang(30184) + "%s" + lang(30185)) % (name))
     url = self.make_url(nt=Flag.USERPLAYLISTS, mode=Mode.VIEW, nm='',
                         nid='')
     executeBuiltin(containerUpdate(url, True))
     return False
Example #25
0
    def attach_context_menu(self, item, menu):
        if self.parent and (self.parent.nt & Flag.PLAYLIST == Flag.PLAYLIST):
            colorCaution = getSetting('item_caution_color')
            url = self.parent.make_url(nt=Flag.PLAYLIST,
                                       id=self.parent.nid,
                                       qid=self.get_playlist_track_id(),
                                       nm='gui_remove_track',
                                       mode=Mode.VIEW)
            menu.add(path='playlist/remove',
                     label=lang(30075),
                     cmd=runPlugin(url), color=colorCaution)

        ''' Calling base class '''
        super(Node_track, self).attach_context_menu(item, menu)
Example #26
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     if self.genre_type is  None or self.genre_id is None:
         return True
     offset = self.offset or 0
     limit = getSetting('pagination_limit')
     data = api.get('/album/getFeatured',
                    type=RECOS_TYPE_IDS[int(self.genre_type)],
                    genre_id=self.genre_id,
                    limit=10,
                    offset=offset)
     if data is None:
         warn(self, 'Cannot fetch data for recommendation')
         return False
     self.data = data
     return True
Example #27
0
 def run(self):
     """Building our tree, creating root node based on our node_type
     """
     if not self.set_root_node():
         warn(self,
              ("Cannot set root node (%s, %s)") %
              (str(self.node_type), str(self.root.get_parameter('nid'))))
         return False
     if self.root.hasWidget:
         return self.root.displayWidget()
     if self.has_method_parameter():
         return self.execute_method_parameter()
     from qobuz.gui.directory import Directory
     Dir = Directory(self.root, self.nodes,
                     withProgress=self.enable_progress)
     Dir.asList = self.asList
     Dir.handle = config.app.handle
     if getSetting('contextmenu_replaceitems', asBool=True):
         Dir.replaceItems = True
     try:
         ret = self.root.populating(Dir, self.depth,
                                    self.whiteFlag, self.blackFlag)
     except Qerror as e:
         Dir.end_of_directory(False)
         Dir = None
         warn(self,
              "Error while populating our directory: %s" % (repr(e)))
         return False
     if not self.asList:
         import xbmcplugin  # @UnresolvedImport
         Dir.set_content(self.root.content_type)
         methods = [
             xbmcplugin.SORT_METHOD_UNSORTED,
             xbmcplugin.SORT_METHOD_LABEL,
             xbmcplugin.SORT_METHOD_DATE,
             xbmcplugin.SORT_METHOD_TITLE,
             xbmcplugin.SORT_METHOD_VIDEO_YEAR,
             xbmcplugin.SORT_METHOD_GENRE,
             xbmcplugin.SORT_METHOD_ARTIST,
             xbmcplugin.SORT_METHOD_ALBUM,
             xbmcplugin.SORT_METHOD_PLAYLIST_ORDER,
             xbmcplugin.SORT_METHOD_TRACKNUM, ]
         [xbmcplugin.addSortMethod(handle=config.app.handle,
                                   sortMethod=method) for method in methods]
     return Dir.end_of_directory()
Example #28
0
 def _delete_cache(self):
     limit = getSetting('pagination_limit')
     keys = []
     keys.append(cache.make_key('/favorite/getUserFavorites',
                                user_id=api.user_id,
                                limit=limit,
                                offset=self.offset))
     for kind in ['artists', 'albums', 'tracks']:
         keys.append(cache.make_key('/favorite/getUserFavorites',
                                    user_id=api.user_id,
                                    limit=limit,
                                    type=kind,
                                    offset=self.offset))
     ret = False
     for key in keys:
         if cache.delete(key):
             ret = True
     return ret
Example #29
0
    def play(self, track_id, params={}):
        """Playing track given a track id
        """
        track = getNode(Flag.TRACK, {'nid': track_id})
        if not track.fetch(None, 1, Flag.TRACK, Flag.NONE):
            warn(self, "Cannot get track data")
            return False
        if not track.is_playable():
            warn(self, "Cannot get streaming URL")
            return False
        if 'purchased' in params:
            track.parameters['purchased']= True
        item = track.makeListItem()
        track.item_add_playing_property(item)
        """Some tracks are not authorized for stream and a 60s sample is
        returned, in that case we overwrite the song duration
        """
        if track.is_sample():
            item.setInfo(
                'music', infoLabels={
                    'duration': 60,
                })
            """Don't warn for free account (all songs except purchases are 60s
            limited)
            """
            if not isFreeAccount():
                notify_warn("Qobuz", "Sample returned")
        xbmcgui.Window(10000).setProperty(keyTrackId, track_id)
        """Notify
        """
        if getSetting('notification_playingsong', asBool=True):
            notify_restriction(track)
            notifyH(lang(30132), track.get_label(), image=track.get_image())

        """We are called from playlist...
        """
        if config.app.handle == -1:
            super(QobuzPlayer, self).play(track.get_streaming_url(),
                                          item, False)
        else:
            setResolvedUrl(handle=config.app.handle,
                           succeeded=True,
                           listitem=item)
        return True
Example #30
0
 def fetch(self, Dir, lvl, whiteFlag, blackFlag):
     limit = getSetting('pagination_limit')
     data = None
     if self.search_type != 'all':
         data = api.get('/favorite/getUserFavorites',
                        user_id=api.user_id,
                        type=self.search_type,
                        limit=limit,
                        offset=self.offset)
     else:
         data = api.get('/favorite/getUserFavorites',
                        user_id=api.user_id,
                        limit=limit,
                        offset=self.offset)
     if not data:
         warn(self, "Build-down: Cannot fetch favorites data")
         return False
     self.data = data
     return True