Merge pull request #346 from pylast/updates
This commit is contained in:
commit
91f79fd4b0
5
.github/workflows/lint.yml
vendored
5
.github/workflows/lint.yml
vendored
|
@ -2,9 +2,12 @@ name: Lint
|
|||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
|
@ -3,33 +3,28 @@ repos:
|
|||
rev: v2.7.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: ["--py3-plus"]
|
||||
args: ["--py36-plus"]
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 19.10b0
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: black
|
||||
args: ["--target-version", "py35"]
|
||||
args: ["--target-version", "py36"]
|
||||
# override until resolved: https://github.com/psf/black/issues/402
|
||||
files: \.pyi?$
|
||||
types: []
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.5.2
|
||||
hooks:
|
||||
- id: isort
|
||||
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.3
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
|
||||
|
||||
- repo: https://github.com/asottile/seed-isort-config
|
||||
rev: v2.2.0
|
||||
hooks:
|
||||
- id: seed-isort-config
|
||||
|
||||
- repo: https://github.com/timothycrosley/isort
|
||||
rev: 5.4.2
|
||||
hooks:
|
||||
- id: isort
|
||||
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.6.0
|
||||
hooks:
|
||||
|
|
|
@ -23,7 +23,6 @@ matrix:
|
|||
- python: 3.8
|
||||
- python: 3.7
|
||||
- python: 3.6
|
||||
- python: 3.5
|
||||
- python: 3.9-dev
|
||||
- python: 3.10-dev
|
||||
- python: pypy3
|
||||
|
|
13
README.md
13
README.md
|
@ -31,11 +31,13 @@ Or from requirements.txt:
|
|||
|
||||
Note:
|
||||
|
||||
* pylast 3.0.0+ supports Python 3.5+ ([#265](https://github.com/pylast/pylast/issues/265))
|
||||
* pyLast 2.2.0 - 2.4.0 supports Python 2.7.10+, 3.4, 3.5, 3.6, 3.7.
|
||||
* pyLast 2.0.0 - 2.1.0 supports Python 2.7.10+, 3.4, 3.5, 3.6.
|
||||
* pyLast 1.7.0 - 1.9.0 supports Python 2.7, 3.3, 3.4, 3.5, 3.6.
|
||||
* pyLast 1.0.0 - 1.6.0 supports Python 2.7, 3.3, 3.4.
|
||||
* pyLast 4.0.0+ supports Python 3.6+.
|
||||
* pyLast 3.2.0 - 3.3.0 supports Python 3.5-3.8.
|
||||
* pyLast 3.0.0 - 3.1.0 supports Python 3.5-3.7.
|
||||
* pyLast 2.2.0 - 2.4.0 supports Python 2.7.10+, 3.4-3.7.
|
||||
* pyLast 2.0.0 - 2.1.0 supports Python 2.7.10+, 3.4-3.6.
|
||||
* pyLast 1.7.0 - 1.9.0 supports Python 2.7, 3.3-3.6.
|
||||
* pyLast 1.0.0 - 1.6.0 supports Python 2.7, 3.3-3.4.
|
||||
* pyLast 0.5 supports Python 2, 3.
|
||||
* pyLast < 0.5 supports Python 2.
|
||||
|
||||
|
@ -49,7 +51,6 @@ Features
|
|||
* Proxy support.
|
||||
* Internal caching support for some web services calls (disabled by default).
|
||||
* Support for other API-compatible networks like Libre.fm.
|
||||
* Python 3-friendly (Starting from 0.5).
|
||||
|
||||
|
||||
Getting started
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[flake8]
|
||||
ignore = W503
|
||||
max_line_length = 88
|
||||
|
||||
[tool:isort]
|
||||
known_third_party = flaky,pkg_resources,pylast,pytest,setuptools
|
||||
profile = black
|
||||
|
|
3
setup.py
3
setup.py
|
@ -27,7 +27,7 @@ setup(
|
|||
extras_require={
|
||||
"tests": ["flaky", "pytest", "pytest-cov", "pytest-random-order", "pyyaml"]
|
||||
},
|
||||
python_requires=">=3.5",
|
||||
python_requires=">=3.6",
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
|
@ -35,7 +35,6 @@ setup(
|
|||
"Topic :: Multimedia :: Sound/Audio",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
|
|
|
@ -146,29 +146,29 @@ class _Network:
|
|||
token=None,
|
||||
):
|
||||
"""
|
||||
name: the name of the network
|
||||
homepage: the homepage URL
|
||||
ws_server: the URL of the webservices server
|
||||
api_key: a provided API_KEY
|
||||
api_secret: a provided API_SECRET
|
||||
session_key: a generated session_key or None
|
||||
username: a username of a valid user
|
||||
password_hash: the output of pylast.md5(password) where password is
|
||||
the user's password
|
||||
domain_names: a dict mapping each DOMAIN_* value to a string domain
|
||||
name
|
||||
urls: a dict mapping types to URLs
|
||||
token: an authentication token to retrieve a session
|
||||
name: the name of the network
|
||||
homepage: the homepage URL
|
||||
ws_server: the URL of the webservices server
|
||||
api_key: a provided API_KEY
|
||||
api_secret: a provided API_SECRET
|
||||
session_key: a generated session_key or None
|
||||
username: a username of a valid user
|
||||
password_hash: the output of pylast.md5(password) where password is
|
||||
the user's password
|
||||
domain_names: a dict mapping each DOMAIN_* value to a string domain
|
||||
name
|
||||
urls: a dict mapping types to URLs
|
||||
token: an authentication token to retrieve a session
|
||||
|
||||
if username and password_hash were provided and not session_key,
|
||||
session_key will be generated automatically when needed.
|
||||
if username and password_hash were provided and not session_key,
|
||||
session_key will be generated automatically when needed.
|
||||
|
||||
Either a valid session_key or a combination of username and
|
||||
password_hash must be present for scrobbling.
|
||||
Either a valid session_key or a combination of username and
|
||||
password_hash must be present for scrobbling.
|
||||
|
||||
You should use a preconfigured network object through a
|
||||
get_*_network(...) method instead of creating an object
|
||||
of this class, unless you know what you're doing.
|
||||
You should use a preconfigured network object through a
|
||||
get_*_network(...) method instead of creating an object
|
||||
of this class, unless you know what you're doing.
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
|
@ -209,56 +209,56 @@ class _Network:
|
|||
|
||||
def get_artist(self, artist_name):
|
||||
"""
|
||||
Return an Artist object
|
||||
Return an Artist object
|
||||
"""
|
||||
|
||||
return Artist(artist_name, self)
|
||||
|
||||
def get_track(self, artist, title):
|
||||
"""
|
||||
Return a Track object
|
||||
Return a Track object
|
||||
"""
|
||||
|
||||
return Track(artist, title, self)
|
||||
|
||||
def get_album(self, artist, title):
|
||||
"""
|
||||
Return an Album object
|
||||
Return an Album object
|
||||
"""
|
||||
|
||||
return Album(artist, title, self)
|
||||
|
||||
def get_authenticated_user(self):
|
||||
"""
|
||||
Returns the authenticated user
|
||||
Returns the authenticated user
|
||||
"""
|
||||
|
||||
return AuthenticatedUser(self)
|
||||
|
||||
def get_country(self, country_name):
|
||||
"""
|
||||
Returns a country object
|
||||
Returns a country object
|
||||
"""
|
||||
|
||||
return Country(country_name, self)
|
||||
|
||||
def get_user(self, username):
|
||||
"""
|
||||
Returns a user object
|
||||
Returns a user object
|
||||
"""
|
||||
|
||||
return User(username, self)
|
||||
|
||||
def get_tag(self, name):
|
||||
"""
|
||||
Returns a tag object
|
||||
Returns a tag object
|
||||
"""
|
||||
|
||||
return Tag(name, self)
|
||||
|
||||
def _get_language_domain(self, domain_language):
|
||||
"""
|
||||
Returns the mapped domain name of the network to a DOMAIN_* value
|
||||
Returns the mapped domain name of the network to a DOMAIN_* value
|
||||
"""
|
||||
|
||||
if domain_language in self.domain_names:
|
||||
|
@ -271,13 +271,13 @@ class _Network:
|
|||
|
||||
def _get_ws_auth(self):
|
||||
"""
|
||||
Returns an (API_KEY, API_SECRET, SESSION_KEY) tuple.
|
||||
Returns an (API_KEY, API_SECRET, SESSION_KEY) tuple.
|
||||
"""
|
||||
return self.api_key, self.api_secret, self.session_key
|
||||
|
||||
def _delay_call(self):
|
||||
"""
|
||||
Makes sure that web service calls are at least 0.2 seconds apart.
|
||||
Makes sure that web service calls are at least 0.2 seconds apart.
|
||||
"""
|
||||
now = time.time()
|
||||
|
||||
|
@ -1408,31 +1408,31 @@ class WSError(Exception):
|
|||
|
||||
def get_id(self):
|
||||
"""Returns the exception ID, from one of the following:
|
||||
STATUS_INVALID_SERVICE = 2
|
||||
STATUS_INVALID_METHOD = 3
|
||||
STATUS_AUTH_FAILED = 4
|
||||
STATUS_INVALID_FORMAT = 5
|
||||
STATUS_INVALID_PARAMS = 6
|
||||
STATUS_INVALID_RESOURCE = 7
|
||||
STATUS_OPERATION_FAILED = 8
|
||||
STATUS_INVALID_SK = 9
|
||||
STATUS_INVALID_API_KEY = 10
|
||||
STATUS_OFFLINE = 11
|
||||
STATUS_SUBSCRIBERS_ONLY = 12
|
||||
STATUS_TOKEN_UNAUTHORIZED = 14
|
||||
STATUS_TOKEN_EXPIRED = 15
|
||||
STATUS_TEMPORARILY_UNAVAILABLE = 16
|
||||
STATUS_LOGIN_REQUIRED = 17
|
||||
STATUS_TRIAL_EXPIRED = 18
|
||||
STATUS_NOT_ENOUGH_CONTENT = 20
|
||||
STATUS_NOT_ENOUGH_MEMBERS = 21
|
||||
STATUS_NOT_ENOUGH_FANS = 22
|
||||
STATUS_NOT_ENOUGH_NEIGHBOURS = 23
|
||||
STATUS_NO_PEAK_RADIO = 24
|
||||
STATUS_RADIO_NOT_FOUND = 25
|
||||
STATUS_API_KEY_SUSPENDED = 26
|
||||
STATUS_DEPRECATED = 27
|
||||
STATUS_RATE_LIMIT_EXCEEDED = 29
|
||||
STATUS_INVALID_SERVICE = 2
|
||||
STATUS_INVALID_METHOD = 3
|
||||
STATUS_AUTH_FAILED = 4
|
||||
STATUS_INVALID_FORMAT = 5
|
||||
STATUS_INVALID_PARAMS = 6
|
||||
STATUS_INVALID_RESOURCE = 7
|
||||
STATUS_OPERATION_FAILED = 8
|
||||
STATUS_INVALID_SK = 9
|
||||
STATUS_INVALID_API_KEY = 10
|
||||
STATUS_OFFLINE = 11
|
||||
STATUS_SUBSCRIBERS_ONLY = 12
|
||||
STATUS_TOKEN_UNAUTHORIZED = 14
|
||||
STATUS_TOKEN_EXPIRED = 15
|
||||
STATUS_TEMPORARILY_UNAVAILABLE = 16
|
||||
STATUS_LOGIN_REQUIRED = 17
|
||||
STATUS_TRIAL_EXPIRED = 18
|
||||
STATUS_NOT_ENOUGH_CONTENT = 20
|
||||
STATUS_NOT_ENOUGH_MEMBERS = 21
|
||||
STATUS_NOT_ENOUGH_FANS = 22
|
||||
STATUS_NOT_ENOUGH_NEIGHBOURS = 23
|
||||
STATUS_NO_PEAK_RADIO = 24
|
||||
STATUS_RADIO_NOT_FOUND = 25
|
||||
STATUS_API_KEY_SUSPENDED = 26
|
||||
STATUS_DEPRECATED = 27
|
||||
STATUS_RATE_LIMIT_EXCEEDED = 29
|
||||
"""
|
||||
|
||||
return self.status
|
||||
|
@ -2937,8 +2937,8 @@ def _url_safe(text):
|
|||
|
||||
def _number(string):
|
||||
"""
|
||||
Extracts an int from a string.
|
||||
Returns a 0 if None or an empty string was passed.
|
||||
Extracts an int from a string.
|
||||
Returns a 0 if None or an empty string was passed.
|
||||
"""
|
||||
|
||||
if not string:
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"""
|
||||
Integration (not unit) tests for pylast.py
|
||||
"""
|
||||
import pylast
|
||||
import pytest
|
||||
|
||||
import pylast
|
||||
|
||||
from .test_pylast import WRITE_TEST, TestPyLastWithLastFm
|
||||
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"""
|
||||
Integration (not unit) tests for pylast.py
|
||||
"""
|
||||
import pylast
|
||||
from flaky import flaky
|
||||
|
||||
import pylast
|
||||
|
||||
from .test_pylast import PyLastTestCase, load_secrets
|
||||
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ Integration (not unit) tests for pylast.py
|
|||
import re
|
||||
import time
|
||||
|
||||
import pylast
|
||||
import pytest
|
||||
|
||||
import pylast
|
||||
|
||||
from .test_pylast import WRITE_TEST, TestPyLastWithLastFm
|
||||
|
||||
|
||||
|
|
|
@ -6,10 +6,11 @@ import os
|
|||
import sys
|
||||
import time
|
||||
|
||||
import pylast
|
||||
import pytest
|
||||
from flaky import flaky
|
||||
|
||||
import pylast
|
||||
|
||||
WRITE_TEST = sys.version_info[:2] == (3, 8)
|
||||
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ Integration (not unit) tests for pylast.py
|
|||
"""
|
||||
import time
|
||||
|
||||
import pylast
|
||||
import pytest
|
||||
|
||||
import pylast
|
||||
|
||||
from .test_pylast import WRITE_TEST, TestPyLastWithLastFm
|
||||
|
||||
|
||||
|
|
|
@ -8,9 +8,10 @@ import os
|
|||
import re
|
||||
import warnings
|
||||
|
||||
import pylast
|
||||
import pytest
|
||||
|
||||
import pylast
|
||||
|
||||
from .test_pylast import TestPyLastWithLastFm
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from unittest import mock
|
||||
|
||||
import pylast
|
||||
import pytest
|
||||
|
||||
import pylast
|
||||
|
||||
|
||||
def mock_network():
|
||||
return mock.Mock(_get_ws_auth=mock.Mock(return_value=("", "", "")))
|
||||
|
|
Loading…
Reference in a new issue