Esempio n. 1
0
    def play(self, s):
        if s.startswith('fuo://'):
            song = resolve(s)
            if song is not None:
                self.player.play_song(song)
            return
        elif s.startswith('http'):
            return self.player.play(s, video=False)

        # 取每个提供方的第一个搜索结果
        source_song_map = defaultdict()
        for result in self.library.search(s):
            for song in result.songs:
                if song.source in source_song_map:
                    break
                source_song_map[song.source] = song
        songs = list(source_song_map.values())

        if songs:
            songs = sorted(songs,
                           key=lambda song: score(s, repr_song(song)),
                           reverse=True)
            msg = 'select:\t{}\n'.format(show_song(songs[0], brief=True))
            self.player.play_song(songs[0])
            lines = []
            for song in songs[1:]:
                lines.append('\t' + show_song(song, brief=True))
            if lines:
                msg += 'options::\n' + '\n'.join(lines)
            return msg
        else:
            return 'No song has been found.'
Esempio n. 2
0
    def play(self, s):  # pylint: disable=inconsistent-return-statements
        # pylint: disable=no-else-return
        if s.startswith('fuo://'):
            model = resolve(s)
            if model is None:
                return 'Invalid fuo uri.'
            self._app.playlist.play_model(model)
            return
        elif s.startswith('http'):
            return self.player.play(s, video=False)

        # 取每个提供方的第一个搜索结果
        source_song_map: Any = defaultdict()
        for result in self.library.search(s):
            for song in result.songs:
                if song.source in source_song_map:
                    break
                source_song_map[song.source] = song
        songs = list(source_song_map.values())

        if songs:
            songs = sorted(songs, key=lambda song: score(s, repr_song(song)),
                           reverse=True)
            msg = f'select:\t{reverse(songs[0], as_line=True)}\n'
            self.playlist.play_model(songs[0])
            lines = []
            for song in songs[1:]:
                lines.append('\t' + reverse(song, as_line=True))
            if lines:
                msg += 'options::\n' + '\n'.join(lines)
            return msg
        else:
            return 'No song has been found.'
Esempio n. 3
0
 def on_provider_added(self, provider):
     if not self._has_nonexistent_models:
         return
     for i, model in enumerate(self.models.copy()):
         if model.exists is ModelExistence.no and model.source == provider.identifier:
             new_model = resolve(reverse(model, as_line=True))
             # TODO: emit data changed signal
             self.models[i] = new_model
Esempio n. 4
0
    def load(self):
        """解析文件,初始化自己"""
        self.models = []
        filepath = Path(self.fpath)
        name = filepath.stem
        stat_result = filepath.stat()
        self.updated_at = datetime.fromtimestamp(stat_result.st_mtime)
        self.name = name
        if name == DEFAULT_COLL_SONGS:
            self.type = CollectionType.sys_song
        elif name == DEFAULT_COLL_ALBUMS:
            self.type = CollectionType.sys_album
        else:
            self.type = CollectionType.mixed

        # parse file content
        with filepath.open(encoding='utf-8') as f:
            first = f.readline()
            lines = []
            if first == TOML_DELIMLF:
                is_valid = True
                for line in f:
                    if line == TOML_DELIMLF:
                        break
                    else:
                        lines.append(line)
                else:
                    logger.warning('the metadata is invalid, will ignore it')
                    is_valid = False
                if is_valid is True:
                    toml_str = ''.join(lines)
                    metadata = tomlkit.parse(toml_str)
                    self._loads_metadata(metadata)
                    lines = []
            else:
                lines.append(first)

            for line in itertools.chain(lines, f):
                if not line.strip():  # ignore empty lines
                    continue
                try:
                    model = resolve(line)
                except ResolverNotFound:
                    logger.warning('resolver not found for line:%s', line)
                    model = None
                except ResolveFailed:
                    logger.warning('invalid line: %s', line)
                    model = None
                if model is not None:
                    if model.exists is ModelExistence.no:
                        self._has_nonexistent_models = True
                    self.models.append(model)
Esempio n. 5
0
 def add(self, furi_list):
     playlist = self.playlist
     for furi in furi_list:
         furi = furi.strip()
         obj = resolve(furi)
         if obj is not None:
             obj_type = obj.meta.model_type
             if obj_type == ModelType.song:
                 playlist.add(obj)
             elif obj_type == ModelType.playlist:
                 songs = to_readall_reader(obj, "songs").readall()
                 for song in songs:
                     playlist.add(song)
Esempio n. 6
0
 def _goto_page(self, page):
     # see if the page match the two special cases
     if page.startswith(MODEL_PAGE_PREFIX):
         try:
             # FIXME: resolve is temporarily too magic
             uri = 'fuo://' + page[len(MODEL_PAGE_PREFIX):]
             model, path = parse_line(uri)
             model = resolve(reverse(model))
         except ResolveFailed:
             model = None
             logger.warning(f'invalid model page:{page}')
         else:
             return self._goto_model_page(model, path)
     else:
         self._goto(page, {'app': self._app})
Esempio n. 7
0
 def on_link_activated(self, url):
     model = resolve(url)
     self._app.browser.goto(model=model)