Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*.exe
*.o
*.so
*.pyc
*.py[cod]
__pycache__/

# Packages #
############
# Packages & packaging #
########################
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
Expand All @@ -20,6 +21,35 @@
*.rar
*.tar
*.zip
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.manifest
*.spec
pip-log.txt
pip-delete-this-directory.txt

# Unit tests #
##############
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Logs and databases #
######################
Expand All @@ -38,8 +68,12 @@ ehthumbs.db
Thumbs.db

# appkey and temp data #
####################################
########################
spotify_appkey.key
*.mp3
tmp/*
*~

# PyCharm #
###########
.idea/
100 changes: 100 additions & 0 deletions autokey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python
# -*- coding: utf8 -*-

import splinter
import requests

# Constants
SPOTIFY_LOGIN_URL = "https://devaccount.spotify.com/login/"
SPOTIFY_KEYS_URL = "https://devaccount.spotify.com/my-account/keys/"


def get_key(username, password, name="Spotify player", description="Spotify player for linux"):
"""Downloads API key and returns it.

:param username: Spotify username
:type username: str
:param password: Spotify password
:type password: str
:param name: Application name for API key
:type name: str
:param description: Description of application for API key
:type description: str

:returns: bytes -- API key
:raises ScrapperException:
"""

br = splinter.Browser()
login(br, username, password)
return key(br, name, description)


# Local functions/classes
class ScrapperException(Exception):
pass


def login(br, username, password):
br.visit(SPOTIFY_LOGIN_URL)

# Fill form
uname = br.find_by_id("name")
uname.click()
uname.fill(username)

passwd = br.find_by_css("html body div.wrapper section form.p-login fieldset ul li input#password").first
passwd.click()
passwd.fill(password)

# Login
br.find_by_xpath("/html/body/div[1]/section/form/fieldset/ul/li[3]/input[3]").first.click()

# If login failed
if br.is_text_present("Invalid username/password combination"):
raise ScrapperException("Invalid credentials")

# Accept TOS
if br.is_text_present("Please accept our terms of use for Spotify apps developers before continuing"):
br.find_by_xpath("/html/body/div/div/section/form/ul/li[1]/fieldset/ul/li/input").click() # Check checkbox
br.find_by_xpath("/html/body/div/div/section/form/ul/li[2]/input").click() # Send form


def key(br, name, description):
br.visit(SPOTIFY_KEYS_URL)

if br.is_text_present("You need to have a Spotify Premium"):
raise ScrapperException("Account is not premium")

# Create key
if not br.is_text_present("You have registered the following application keys"):
# Fill out app details
app_name = br.find_by_xpath("/html/body/div/div/section/div[6]/form/div[1]/input").first
app_name.click()
app_name.fill(name)

app_desc = br.find_by_xpath("/html/body/div/div/section/div[6]/form/div[2]/textarea").first
app_desc.click()
app_desc.fill(description)

# Tick TOS checkbox
br.find_by_xpath("/html/body/div/div/section/div[6]/form/div[3]/input").click()

# Send query
br.find_by_xpath("/html/body/div/div/section/div[6]/form/input[4]").click()

# Go to "my keys"
br.visit(SPOTIFY_KEYS_URL)

while not br.is_text_present("You have registered the following application keys"):
br.reload()

# Download key
url = br.find_by_xpath("/html/body/div/div/section/div[3]/table/tbody/tr/td[3]/a[1]")['href']

result = requests.get(url, cookies=br.cookies.all())

if result.status_code != 200:
raise ScrapperException("Failed to download key. Status code: {0}".format(result.status_code))

return result.content