Beispiel #1
0
    def model_get_cover(self, model):
        """Get the cover url of model

        :param model: model which has a 'cover' field.
        :return: cover url if exists, else ''.
        """
        cover = ''
        if MF.v2 in model.meta.flags:
            if MF.normal in model.meta.flags:
                cover = model.cover
            else:
                # TODO: upgrade artist model.
                # Currently supported model types: (ModelType.album, ModelType.video).
                if ModelType(model.meta.model_type) in V2SupportedModelTypes:
                    um = self._model_upgrade(model)
                    # FIXME: remove this hack lator.
                    if ModelType(model.meta.model_type) is ModelType.artist:
                        cover = um.pic_url
                    else:
                        cover = um.cover
        else:
            cover = model.cover
            # Check if cover is a media object.
            if cover and not isinstance(cover, str):
                cover = cover.url
        return cover
Beispiel #2
0
    def _model_upgrade(self, model):
        """
        Thinking: currently, the caller must catch the NotSupported error.
        """
        try_v1way = True
        upgraded_model = None
        if model.meta.flags & MF.v2:
            if MF.normal in model.meta.flags:
                upgraded_model = model
                try_v1way = False
            else:
                provider = self.getv2_or_raise(model.source)
                # When the provider does not support 'get' for this model.
                # Do not raise NotSupported here and try to use the v1 way.
                #
                # For example, provider X may support 'get' for SongModel, then
                # the song.artists can return list of BriefArtistModel.
                if self.check_flags_by_model(model, PF.get):
                    upgraded_model = provider.model_get(
                        model.meta.model_type, model.identifier)
                    try_v1way = False

        if try_v1way is True:
            v1model = self.cast_model_to_v1(model)
            modelcls = get_modelcls_by_type(ModelType(model.meta.model_type))
            fields = [f for f in list(modelcls.__fields__)
                      if f not in list(BaseModel.__fields__)]
            for field in fields:
                getattr(v1model, field)
            upgraded_model = v1model
        else:
            assert upgraded_model is not None
        return upgraded_model
Beispiel #3
0
    def _select_media(self, playable_model, policy=None):
        if ModelType(playable_model.meta.model_type) is ModelType.song:
            list_quality = self.song_list_quality
            QualityCls = Quality.Audio
            get_media = self.song_get_media
            policy = 'hq<>' if policy is None else policy
        else:
            list_quality = self.video_list_quality
            QualityCls = Quality.Video
            get_media = self.video_get_media
            policy = 'hd<>' if policy is None else policy

        # fetch available quality list
        available_q_set = set(list_quality(playable_model))
        if not available_q_set:
            raise MediaNotFound

        sorted_q_list = Quality.SortPolicy.apply(
            policy, [each.value for each in list(QualityCls)])

        # find the first available quality
        for quality in sorted_q_list:
            quality = QualityCls(quality)
            if quality not in available_q_set:
                continue
            media = get_media(playable_model, quality)
            if media is not None:
                media = cast(Media, media)
            else:
                # Media is not found for the quality. The provider show
                # a non-existing quality.
                raise MediaNotFound(
                    f'provider:{playable_model.source} has nonstandard implementation')
            return media, quality
        assert False, 'this should not happen'
Beispiel #4
0
async def render(req, **kwargs):
    app = req.ctx['app']
    model = req.ctx['model']

    app.ui.page_view.set_body(app.ui.page_view.table_container)

    # FIXME: handle NotSupported exception here and in renderer.
    # FIXME: handle ProviderIOError and RequestException.
    if ModelType(model.meta.model_type) in V2SupportedModelTypes:
        if model.meta.model_type == ModelType.album:
            album = await aio.run_fn(app.library.album_upgrade, model)
            tab_index = int(req.query.get('tab_index', 1))
            renderer = AlbumRenderer(album, tab_index)
            await app.ui.table_container.set_renderer(renderer)
        elif model.meta.model_type == ModelType.artist:
            artist = await aio.run_fn(app.library.artist_upgrade, model)
            tab_index = int(req.query.get('tab_index', 1))
            renderer = ArtistRenderer(artist, tab_index)
            await app.ui.table_container.set_renderer(renderer)
        elif model.meta.model_type == ModelType.playlist:
            playlist = await aio.run_fn(app.library.playlist_upgrade, model)
            renderer = PlaylistRenderer(playlist)
            await app.ui.table_container.set_renderer(renderer)
        else:
            assert False, "this should not be called"
            await app.ui.table_container.set_renderer(None)
    else:
        assert False, "can't render this type of model"
Beispiel #5
0
 def __eq__(self, other):
     """Implement __hash__ and __eq__ so that model can be a dict key"""
     if not isinstance(other, BaseModel):
         return False
     return all([
         other.source == self.source,
         str(other.identifier) == str(self.identifier),
         ModelType(other.meta.model_type) == self.meta.model_type
     ])
Beispiel #6
0
 async def show_model(self, model):
     model_type = ModelType(model.meta.model_type)
     if model_type == ModelType.album:
         renderer = AlbumRenderer(model)
     elif model_type == ModelType.artist:
         renderer = ArtistRenderer(model)
     elif model_type == ModelType.playlist:
         renderer = PlaylistRenderer(model)
     else:
         renderer = None
     await self.set_renderer(renderer)
Beispiel #7
0
 def _cast_model_to_v1_impl(self, model):
     provider = self.get_or_raise(model.source)
     ModelCls = provider.get_model_cls(model.meta.model_type)
     # The source of the default SongModel is None. When ModelCls.source
     # is None, it means that the provider does not has its own model class.
     if ModelCls.source is None:
         model_type_str = str(ModelType(model.meta.model_type))
         raise NotSupported(f'provider has no v1 model impl for {model_type_str}')
     kv = {}
     for field in ModelCls.meta.fields_display:
         kv[field] = getattr(model, field)
     return ModelCls.create_by_display(identifier=model.identifier, **kv)
Beispiel #8
0
 def check_flags_by_model(self, model: ModelProtocol, flags: PF) -> bool:
     """Alias for check_flags"""
     return self.check_flags(model.source, ModelType(model.meta.model_type),
                             flags)
Beispiel #9
0
def err_provider_not_support_flag(pid, model_type, op):
    op_str = str(op)
    if op is PF.get:
        op_str = 'get'
    mtype_str = str(ModelType(model_type))
    return NotSupported(f"provider:{pid} does't support '{op_str}' for {mtype_str}")
Beispiel #10
0
def get_model_mimetype(model):
    return model_mimetype_map[ModelType(model.meta.model_type).value]