示例#1
0
def feed_playlist(username):
    """Fetch user playlists when using the -u option."""
    playlists = spotify.user_playlists(username)
    links = []
    check = 1

    while True:
        for playlist in playlists['items']:
            # in rare cases, playlists may not be found, so playlists['next']
            # is None. Skip these. Also see Issue #91.
            if playlist['name'] is not None:
                print(u'{0:>5}. {1:<30}  ({2} tracks)'.format(
                    check, playlist['name'],
                    playlist['tracks']['total']))
                links.append(playlist)
                check += 1
        if playlists['next']:
            playlists = spotify.next(playlists)
        else:
            break

    print('')
    playlist = misc.input_link(links)
    print('')
    write_playlist(playlist)
示例#2
0
def feed_playlist(username):
    # fetch all user playlists
    playlists = spotify.user_playlists(username)
    links = []
    check = 1
    # iterate over user playlists
    for playlist in playlists['items']:
        print(str(check) + '. ' + misc.fix_encoding(playlist['name']) + ' (' + str(playlist['tracks']['total']) + ' tracks)')
        links.append(playlist)
        check += 1
    print('')
    # let user select playlist
    playlist = misc.input_link(links)
    # fetch detailed information for playlist
    results = spotify.user_playlist(playlist['owner']['id'], playlist['id'], fields="tracks,next")
    print('')
    # slugify removes any special characters
    file = slugify(playlist['name'], ok='-_()[]{}') + '.txt'
    print('Feeding ' + str(playlist['tracks']['total']) + ' tracks to ' + file)
    tracks = results['tracks']
    # write tracks to file
    misc.feed_tracks(file, tracks)
    # check if there are more pages
    # 1 page = 50 results
    while tracks['next']:
        tracks = spotify.next(tracks)
        misc.feed_tracks(file, tracks)
示例#3
0
def generate_youtube_url(raw_song):
    """Search for the song on YouTube and generate a URL to its video."""
    meta_tags = generate_metadata(raw_song)
    if meta_tags is None:
        song = raw_song
        search_url = misc.generate_search_url(song, viewsort=False)
    else:
        song = generate_songname(meta_tags)
        search_url = misc.generate_search_url(song, viewsort=True)

    item = urllib.request.urlopen(search_url).read()
    # item = unicode(item, 'utf-8')
    items_parse = BeautifulSoup(item, "html.parser")

    videos = []
    for x in items_parse.find_all(
            'div', {'class': 'yt-lockup-dismissable yt-uix-tile'}):
        # confirm the video result is not an advertisement
        if x.find('channel') is None and x.find('googleads') is None:
            y = x.find('div', class_='yt-lockup-content')
            link = y.find('a')['href']
            title = y.find('a')['title']
            try:
                videotime = x.find('span', class_="video-time").get_text()
            except AttributeError:
                return generate_youtube_url(raw_song)
            youtubedetails = {
                'link': link,
                'title': title,
                'videotime': videotime,
                'seconds': misc.get_sec(videotime)
            }
            videos.append(youtubedetails)
            if meta_tags is None:
                break

    if not videos:
        return None

    if args.manual:
        print(song)
        print('')
        print('0. Skip downloading this song')
        # fetch all video links on first page on YouTube
        for i, v in enumerate(videos):
            print(u'{0}. {1} {2} {3}'.format(i + 1, v['title'], v['videotime'],
                                             "http://youtube.com" + v['link']))
        print('')
        # let user select the song to download
        result = misc.input_link(videos)
        if result is None:
            return None
    else:
        if meta_tags is not None:
            videos.sort(key=lambda x: abs(x['seconds'] - (int(meta_tags[
                'duration_ms']) / 1000)))
        result = videos[0]

    full_link = u'youtube.com{0}'.format(result['link'])
    return full_link
示例#4
0
def generate_YouTube_URL(raw_song):
    # decode spotify http link to "[artist] - [song]"
    song = generate_songname(raw_song)
    # generate direct search YouTube URL
    searchURL = misc.generate_search_URL(song)
    item = urllib2.urlopen(searchURL).read()
    #item = unicode(item, 'utf-8')
    items_parse = BeautifulSoup(item, "html.parser")
    check = 1
    if args.manual:
        links = []
        print(song)
        print('')
        print('0. Skip downloading this song')
        # fetch all video links on first page on YouTube
        for x in items_parse.find_all('h3', {'class': 'yt-lockup-title'}):
            # confirm the video result is not an advertisement
            if not x.find('channel') == -1 or not x.find('googleads') == -1:
                print(str(check) + '. ' + x.get_text())
                links.append(x.find('a')['href'])
                check += 1
        print('')
        # let user select the song to download
        result = misc.input_link(links)
        if result is None:
            return None
    else:
        # get video link of the first YouTube result
        result = items_parse.find_all(attrs={'class': 'yt-uix-tile-link'})[0]['href']
        # confirm the video result is not an advertisement
        # otherwise keep iterating until it is not
        while not result.find('channel') == -1 or not result.find('googleads') == -1:
            result = items_parse.find_all(attrs={'class': 'yt-uix-tile-link'})[check]['href']
            check += 1
    full_link = "youtube.com" + result
    return full_link
示例#5
0
def generate_youtube_url(raw_song, meta_tags, tries_remaining=5):
    """Search for the song on YouTube and generate a URL to its video."""
    # prevents an infinite loop but allows for a few retries
    if tries_remaining == 0:
        return

    if meta_tags is None:
        song = raw_song
        search_url = misc.generate_search_url(song, viewsort=False)
    else:
        song = generate_songname(meta_tags)
        search_url = misc.generate_search_url(song, viewsort=True)

    item = urllib.request.urlopen(search_url).read()
    # item = unicode(item, 'utf-8')
    items_parse = BeautifulSoup(item, "html.parser")

    videos = []
    for x in items_parse.find_all(
            'div', {'class': 'yt-lockup-dismissable yt-uix-tile'}):
        # ensure result is not a channel
        if x.find('channel'
                  ) is not None or 'yt-lockup-channel' in x.parent.attrs[
                      'class'] or 'yt-lockup-channel' in x.attrs['class']:
            continue

        # ensure result is not a mix/playlist
        if 'yt-lockup-playlist' in x.parent.attrs['class']:
            continue

        # confirm the video result is not an advertisement
        if x.find('googleads') is not None:
            continue

        y = x.find('div', class_='yt-lockup-content')
        link = y.find('a')['href']
        title = y.find('a')['title']
        try:
            videotime = x.find('span', class_="video-time").get_text()
        except AttributeError:
            return generate_youtube_url(raw_song, meta_tags,
                                        tries_remaining - 1)

        youtubedetails = {
            'link': link,
            'title': title,
            'videotime': videotime,
            'seconds': misc.get_sec(videotime)
        }
        videos.append(youtubedetails)
        if meta_tags is None:
            break

    if not videos:
        return None

    if args.manual:
        print(song)
        print('')
        print('0. Skip downloading this song')
        # fetch all video links on first page on YouTube
        for i, v in enumerate(videos):
            print(u'{0}. {1} {2} {3}'.format(i + 1, v['title'], v['videotime'],
                                             "http://youtube.com" + v['link']))
        print('')
        # let user select the song to download
        result = misc.input_link(videos)
        if result is None:
            return None
    else:
        if meta_tags is not None:
            # filter out videos that do not have a similar length to the Spotify song
            duration_tolerance = 10
            max_duration_tolerance = 20
            possible_videos_by_duration = list()
            '''
            start with a reasonable duration_tolerance, and increment duration_tolerance
            until one of the Youtube results falls within the correct duration or
            the duration_tolerance has reached the max_duration_tolerance
            '''
            while len(possible_videos_by_duration) == 0:
                possible_videos_by_duration = list(
                    filter(
                        lambda x: abs(x['seconds'] - (int(meta_tags[
                            'duration_ms']) / 1000)) <= duration_tolerance,
                        videos))
                duration_tolerance += 1
                if duration_tolerance > max_duration_tolerance:
                    print(meta_tags['name'], 'by',
                          meta_tags['artists'][0]['name'], 'was not found')
                    return None

            result = possible_videos_by_duration[0]
        else:
            # if the metadata could not be acquired, take the first result from Youtube because the proper song length is unknown
            result = videos[0]

    full_link = None
    if result:
        full_link = u'youtube.com{0}'.format(result['link'])

    return full_link