在Spotify上连续实时获取当前正在播放的歌曲

时间:2018-12-14 15:06:11

标签: python python-3.x spotify api-design vk

我编写了脚本,将Spotify用户当前正在播放的歌曲置于vk.com上的状态。这就像是一次性的事情。运行脚本时,它将设置正确的状态。但是要更新它,显然您将需要再次运行该脚本。

我想知道是否有可能使其动态工作?新歌曲开始时更新状态。我只能考虑设置时间表以运行脚本或发送请求以检查歌曲是否已更改。但是我想,只有在用户的PC始终打开并且脚本可以运行的情况下,它才会起作用。

另一个问题是Spotify令牌持续一个小时,但我读过the refresh token is practically valid forever, or until it has been manually revoked。 Vk令牌具有使令牌永久有效的官方选项。

import config
import webbrowser
import requests
import furl
import secrets
import string
import time
import os
import simplejson as json


URL_CODE_BASE_VK = 'https://oauth.vk.com/authorize'
URL_CODE_BASE_SP = 'https://accounts.spotify.com/authorize'
URL_TOKEN_VK = 'https://oauth.vk.com/access_token'
URL_TOKEN_SP = 'https://accounts.spotify.com/api/token'
URL_TRACK = 'https://api.spotify.com/v1/me/player/currently-playing'
URL_STATUS = 'https://api.vk.com/method/status.set'
EXP_IN_TOKEN_SP = 3400
EXP_IN_TOKEN_VK = 86400
FILE_TOKEN_VK = 'vk_token.json'
FILE_TOKEN_SP = 'sp_token.json'


def get_auth_code_vk():
    url_code_params = {
                        'client_id': config.CLIENT_ID_VK,
                        'response_type': 'code',
                        'redirect_uri': 'https://oauth.vk.com/blank.html',
                        'v': 5.92,
                        'scope': 'status',
                        'state': gen_state(),
                        'display': 'page'
    }

    code = url_open(URL_CODE_BASE_VK, url_code_params)
    return parse_code(code)


def get_auth_code_sp():
    url_code_params = {
                        'client_id': config.CLIENT_ID_SP,
                        'response_type': 'code',
                        'redirect_uri': 'https://www.spotify.com/',
                        'scope': 'user-read-currently-playing',
                        'state': gen_state()
    }

    code = url_open(URL_CODE_BASE_SP, url_code_params)
    return parse_code(code)


def gen_state():
    symbols = string.ascii_lowercase + string.digits
    return ''.join(secrets.choice(symbols) for _ in range(12))


def url_open(url_base, url_params):
    url_code_full = furl.furl(url_base).add(url_params).url
    webbrowser.open_new_tab(url_code_full)
    input_url = input('Enter the whole URL, that you have been redirected on: ')

    return input_url


def parse_code(url):
    return (url.split("code=")[1]).split("&state=")[0]


def get_token_vk():
    data = {
            'grant_type': 'authorization_code',
            'code': get_auth_code_vk(),
            'redirect_uri': 'https://oauth.vk.com/blank.html',
            'client_id': 6782333,
            'client_secret': config.CLIENT_SECRET_VK
    }

    response = requests.post(url=URL_TOKEN_VK, data=data).json()
    write_file(FILE_TOKEN_VK, response)


def get_token_sp():
    data = {
            'grant_type': 'authorization_code',
            'code': get_auth_code_sp(),
            'redirect_uri': 'https://www.spotify.com/',
            'client_id': config.CLIENT_ID_SP,
            'client_secret': config.CLIENT_SECRET_SP
    }

    response = requests.post(url=URL_TOKEN_SP, data=data).json()
    write_file(FILE_TOKEN_SP, response)


def write_file(tkn_file, response):
    dict = {}
    dict['token'] = response["access_token"]
    dict['time'] = time.time()

    with open(tkn_file, 'w') as file:
        file.write(json.dumps(dict))


def load_file(tkn_file):
    with open(tkn_file) as file:
        data = json.load(file)
    return data


def set_status():
    params = {
              'v': 5.92,
              'access_token': load_file(FILE_TOKEN_VK)['token'],
              'text': current_track()
    }

    set_status = requests.get(url=URL_STATUS, params=params)


def track_data():
    tkn_file =  load_file(FILE_TOKEN_SP)['token']
    headers = {
               'Accept': 'application/json',
               'Authorization': f'Bearer {tkn_file}'
    }

    return requests.get(url=URL_TRACK, headers=headers)


def current_track():
    data = track_data().json()
    artist = data['item']['artists'][0]['name']
    track = data['item']['name']

    return(f'{artist} - {track}')


def check_playback():
    try:
        set_status()
        print(current_track())
    except json.decoder.JSONDecodeError:
        print('Not playing')


def token_missing(file):
    return not os.path.isfile(file)


def token_expired(file, exp_in):
    return time.time() - load_file(file)['time'] > exp_in


def token_not_valid(file, exp_in):
    return token_missing(file) or token_expired(file, exp_in)


def run_script():
    if token_not_valid(FILE_TOKEN_VK, EXP_IN_TOKEN_VK):
        get_token_vk()

    if token_not_valid(FILE_TOKEN_SP, EXP_IN_TOKEN_SP):
        get_token_sp()

    check_playback()


if __name__ == "__main__":
    run_script()

1 个答案:

答案 0 :(得分:0)

是的,您可以使用cron作业使进程按设置的时间间隔运行。另外,如果将其构建到flask应用程序中,则可以使用scheduler以设置的间隔运行作业。不过,cron可能是最快的方法。 要编辑cronjobs:

$ crontab -e

然后添加如下内容:

* * * * * python /tmp/spotify_update.py

每秒运行一次作业。星号表示分钟,小时,天,月和工作日。

相关问题