def __init__(self,
                 site='qq',
                 use_cache=True,
                 log_level=10,
                 timeout=10,
                 override=False):
        self.home = 'http://music.sonimei.cn/'
        self.ac = AsyncCrawler(
            site_init_url=self.home,
            base_dir=os.path.expanduser('~/.crawler'),
            timeout=timeout,
            log_level=log_level,
        )
        self.use_cache = use_cache
        self.music_save_dir = os.path.expanduser(
            cfg.get('snm.save_dir', '~/Music/sonimei'))
        self.site = site

        self._album_handler = album_factory.get(site,
                                                MockAlbum)(log_level=log_level,
                                                           use_cache=use_cache)
        self._downloader = Downloader(self.music_save_dir,
                                      self.ac.cache['site_media'], override)
        self.store = MusicStore(self.music_save_dir, log_level)
        self._song_name = ''
        self.failure_handle = FailureHandle()

        self._spawn()
 def __init__(self,
              site='163',
              use_cache=True,
              log_level=20,
              timeout=10,
              override=False):
     super().__init__(site, use_cache, log_level, timeout, override)
     self.log_dir = os.path.expanduser(cfg.get('163.log_dir'))
Exemple #3
0
def bar_thermometer(current, total, width=80):
    """Return thermometer style progress bar string. `total` argument
    can not be zero. The minimum size of bar returned is 3. Example:

        [..........            ]

    Control and trailing symbols (\r and spaces) are not included.
    See `bar_adaptive` for more information.
    """
    # number of dots on thermometer scale
    progress_symbol = cfg.get('snm.progress_symbol', '.')
    avail_dots = width - 2
    shaded_dots = int(int(math.floor(float(current) / total * avail_dots)) / len(progress_symbol))
    avail_dots = width - avail_dots // 2 - shaded_dots - 2
    # print('{},{},{},{},{},{}'.format(
    #     current, total, width,
    #     len(progress_symbol), avail_dots, shaded_dots
    # ))
    return '[{}{}]'.format(progress_symbol * shaded_dots, ' ' * avail_dots)
 def search_it(self, name='', page=1):
     try:
         _cmd = "tail -n {} {} | grep songName".format(
             cfg.get('163.log_count'), self.log_dir)
         songs = helper.os_cmd(_cmd)
         line = [x for x in songs.split('\n') if x][-1]
         line = '{' + line.split('{')[1]
         song = json.loads(line)
         # update according to the caller, artistName may has '/' if with multiple singers
         song['author'] = song['artistName'].replace('/', '-')
         song['title'] = song['songName']
         self._song_name = '{}-{}'.format(song['author'], song['title'])
         song['pic'] = song[
             'url'] + '?imageView&enlarge=1&quality=90&thumbnail=440y440'
         # m8.music may not available all time, so use m7
         song['url'] = song['musicurl'].replace('m8.music.126.net',
                                                'm7.music.126.net')
         zlog.debug('song: {}'.format(song))
         return song
     except Exception as e:
         zlog.error('{}'.format(e))
         return ''
Exemple #5
0
def run(
        name, site, multiple, no_cache, log_level,
        scan_mode, timeout, override,
        auto_mode, failure_songs, clear_failure_songs,
        from_163_logs,
):
    """ a lovely script use sonimei search qq/netease songs """
    # if scan_mode, will be all songs local
    # else will be the name passed in
    scanned_songs = []
    timeout = timeout or cfg.get('snm.timeout')
    force_netease = False
    if clear_failure_songs:
        FailureHandle().dump_failure_songs([], action='clear')
        os._exit(0)

    if auto_mode:
        force_netease, scanned_songs = check_player(auto_mode)

    if failure_songs:
        scanned_songs = check_failure(failure_songs)

    if from_163_logs:
        force_netease = from_163_logs

    if force_netease:
        _client = NeteaseDL(not no_cache, log_level=log_level * 10, timeout=timeout, override=override)
    else:
        _client = Sonimei(site, not no_cache, log_level=log_level * 10, timeout=timeout, override=override)

    if scan_mode:
        _client.store.scan_all_songs()
        scanned_songs = _client.store.all_songs

    if name:
        scanned_songs = [x for x in name.split('#') if x]

    if not scanned_songs:
        error_hint('{0}>>> use -h for details <<<{0}'.format('' * 16), quit_out=None)

    for i, name in enumerate(scanned_songs):
        songs_store = {}
        page = 1
        is_searched_from_site = False
        CP.F((PRETTY.symbols['right'] + ' ') * 2, 'processing/total: {}/{}'.format(i + 1, len(scanned_songs)))

        while True:
            if not is_searched_from_site and check_local(scan_mode, _client.store, name):
                CP.G(PRETTY.symbols['end'], 'quit')
                break

            status, song_pth = _client.store.is_file_id3_ok(name)
            if status:
                CP.G(PRETTY.symbols['music'], '[{}] is found and updated'.format(song_pth))
                if not override:
                    error_hint('>>> you can do force download with -o <<<',
                               empty_line=False,
                               bg='black', fg='yellow')
                    break

            songs = songs_store.get(page)
            if not songs:
                zlog.info('from sonimei({}) try: {}/{}'.format(helper.G.format(site), name, page))
                songs = _client.search_it(name, page=page)
                if not isinstance(songs, list):
                    songs = [songs]
                songs_store[page] = songs

            is_searched_from_site = True
            song_info = [x['author'] + '-' + x['title'] for x in songs]

            c = helper.num_choice(
                song_info, valid_keys='p,n,s', depth=page,
                extra_hints='n-next,p-pre,s-skip',
                clear_previous=True,
            )
            if isinstance(c, str):
                if c in 'qQ':
                    return
                if c in 'bp':
                    if page > 1:
                        page -= 1
                    continue
                if c == 'n':
                    page += 1
                    continue
                if c == 's':  # skip current song
                    break
            _client.save_song(songs[c])

            # multiple mode is only worked in none scanned mode
            if not multiple:
                break
 def __init__(self):
     self.failure_store = cfg.get('snm.failure_store')