Source code for athena.api_library.spotify_api

"""
    A wrapper API for Spotify Web Player (requires Firefox)
"""
import traceback

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

from athena.classes.api import Api

BASE_URL = 'https://play.spotify.com/browse'

SAVE_DATA = [
    ('username', 'Username: '      , True),
    ('password', 'Password: '      , True),
]

[docs]class SpotifyApi(Api): def __init__(self): super().__init__('spotify_api', SAVE_DATA) self.frame = None self.driver = None
[docs] def login(self): self.driver = webdriver.Firefox() self.driver.get(BASE_URL) self.driver.find_element_by_id('has-account').click() self.driver.find_element_by_id('login-usr').clear() self.driver.find_element_by_id('login-usr').send_keys(self.username) self.driver.find_element_by_id('login-pass').clear() self.driver.find_element_by_id('login-pass').send_keys(self.password) self.driver.find_element_by_id('login-pass').submit() main_frame = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, '//div[@id="section-browse"]/descendant::iframe')) ) self.ensure_frame(main_frame) WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.ID, 'nav')) ) self.driver.switch_to_default_content()
[docs] def ensure_frame(self, frame): if self.frame is not frame: self.driver.switch_to_default_content() self.driver.switch_to_frame(frame) self.frame = frame
[docs] def ensure_login(self): if not self.driver or 'play.spotify' not in self.driver.current_url: self.login()
[docs] def play_pause_track(self): self.ensure_login() self.ensure_frame('app-player') self.driver.find_element_by_id('play-pause').click()
[docs] def prev_track(self): self.ensure_login() self.ensure_frame('app-player') self.driver.find_element_by_id('previous').click()
[docs] def next_track(self): self.ensure_login() self.ensure_frame('app-player') self.driver.find_element_by_id('next').click()
[docs] def search(self, query): self.ensure_login() self.driver.switch_to_default_content() try: nav_search = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.ID, 'nav-search')) ) nav_search.click() self.ensure_frame('suggest') form = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'form')) ) search_bar = form.find_element_by_tag_name('input') search_bar.send_keys(query) show_results = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, '//*[@class="results"]/descendant::a')) ) show_results.click() self.driver.switch_to_default_content() wrapper = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, 'front')) ) iframe = wrapper.find_element_by_tag_name('iframe') self.driver.switch_to_frame(iframe) songs = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'tbody')) ) first_song = songs.find_element_by_tag_name('tr') first_song.click() first_song.send_keys(Keys.RETURN) except: print('Can\'t find element...') print(traceback.format_exc())