From 5462c45ef2666018a35fe881ca7195b649e60b37 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 5 Jul 2022 10:09:17 +0300 Subject: [PATCH 01/55] Add network_via_web_auth helper --- README.md | 8 +------- src/pylast/__init__.py | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index baa3cb3..24c65f5 100644 --- a/README.md +++ b/README.md @@ -74,15 +74,9 @@ import pylast API_KEY = "b25b959554ed76058ac220b7b2e0a026" # this is a sample key API_SECRET = "425b55975eed76058ac220b7b4e8a054" -# In order to perform a write operation you need to authenticate yourself -username = "your_user_name" -password_hash = pylast.md5("your_password") - -network = pylast.LastFMNetwork( +network = pylast.network_via_web_auth( api_key=API_KEY, api_secret=API_SECRET, - username=username, - password_hash=password_hash, ) # Now you can use that object everywhere diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index e152c31..4fbfec6 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -3,7 +3,7 @@ # A Python interface to Last.fm and Libre.fm # # Copyright 2008-2010 Amr Hassan -# Copyright 2013-2021 hugovk +# Copyright 2013-2022 hugovk # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ except ImportError: import importlib_metadata # type: ignore __author__ = "Amr Hassan, hugovk, Mice Pápai" -__copyright__ = "Copyright (C) 2008-2010 Amr Hassan, 2013-2021 hugovk, 2017 Mice Pápai" +__copyright__ = "Copyright (C) 2008-2010 Amr Hassan, 2013-2022 hugovk, 2017 Mice Pápai" __license__ = "apache2" __email__ = "amr.hassan@gmail.com" __version__ = importlib_metadata.version(__name__) @@ -782,6 +782,37 @@ class LibreFMNetwork(_Network): ) +def network_via_web_auth( + api_key: str, + api_secret: str, + network_class: _Network = LastFMNetwork, +) -> _Network: + session_key_file = os.path.join(os.path.expanduser("~"), ".session_key") + network = network_class(api_key, api_secret) + + if os.path.exists(session_key_file): + with open(session_key_file) as f: + network.session_key = f.read() + else: + skg = SessionKeyGenerator(network) + url = skg.get_web_auth_url() + + print(f"Please authorise to access your account: {url}\n") + import webbrowser + + webbrowser.open(url, new=2) + while True: + try: + network.session_key = skg.get_web_auth_session_key(url) + with open(session_key_file, "w") as f: + f.write(network.session_key) + break + except WSError: + time.sleep(1) + + return network + + class _ShelfCacheBackend: """Used as a backend for caching cacheable requests.""" @@ -1029,7 +1060,9 @@ class SessionKeyGenerator: return url - def get_web_auth_session_key_username(self, url, token: str = ""): + def get_web_auth_session_key_username( + self, url: str | None, token: str = "" + ) -> tuple[str, str]: """ Retrieves the session key/username of a web authorization process by its URL. """ @@ -1049,7 +1082,7 @@ class SessionKeyGenerator: username = doc.getElementsByTagName("name")[0].firstChild.data return session_key, username - def get_web_auth_session_key(self, url, token: str = ""): + def get_web_auth_session_key(self, url: str, token: str = "") -> str: """ Retrieves the session key of a web authorization process by its URL. """ From 7861fd55bdd412b30096641787598b0e22918625 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 18:09:58 +0000 Subject: [PATCH 02/55] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.1.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v3.1.0...v3.3.1) - [github.com/psf/black: 22.10.0 → 22.12.0](https://github.com/psf/black/compare/22.10.0...22.12.0) - [github.com/PyCQA/isort: 5.10.1 → 5.11.4](https://github.com/PyCQA/isort/compare/5.10.1...5.11.4) - [github.com/PyCQA/flake8: 5.0.4 → 6.0.0](https://github.com/PyCQA/flake8/compare/5.0.4...6.0.0) - [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0) - [github.com/tox-dev/pyproject-fmt: 0.3.5 → 0.4.1](https://github.com/tox-dev/pyproject-fmt/compare/0.3.5...0.4.1) --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 578769b..3c7c47d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 + rev: v3.3.1 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 22.12.0 hooks: - id: black args: [--target-version=py37] @@ -19,12 +19,12 @@ repos: additional_dependencies: [black==22.10.0] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.11.4 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 + rev: 6.0.0 hooks: - id: flake8 additional_dependencies: [flake8-2020, flake8-implicit-str-concat] @@ -35,7 +35,7 @@ repos: - id: python-check-blanket-noqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: check-json - id: check-merge-conflict @@ -45,7 +45,7 @@ repos: - id: requirements-txt-fixer - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.3.5 + rev: 0.4.1 hooks: - id: pyproject-fmt From a37ac22e6c74c41a6b88e26ef55b0654432debb5 Mon Sep 17 00:00:00 2001 From: ndm13 Date: Mon, 2 Jan 2023 15:09:16 -0500 Subject: [PATCH 03/55] Add code from pylast #407 to readme Describe authentication with OAuth token --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index baa3cb3..8676805 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,32 @@ network = pylast.LastFMNetwork( password_hash=password_hash, ) +# You can also authenticate with a session key +SESSION_KEY_FILE = os.path.join(os.path.expanduser("~"), ".session_key") +network = pylast.LastFMNetwork(API_KEY, API_SECRET) +if not os.path.exists(SESSION_KEY_FILE): + skg = pylast.SessionKeyGenerator(network) + url = skg.get_web_auth_url() + + print(f"Please authorize this script to access your account: {url}\n") + import time + import webbrowser + + webbrowser.open(url) + + while True: + try: + session_key = skg.get_web_auth_session_key(url) + with open(SESSION_KEY_FILE, "w") as f: + f.write(session_key) + break + except pylast.WSError: + time.sleep(1) +else: + session_key = open(SESSION_KEY_FILE).read() + +network.session_key = session_key + # Now you can use that object everywhere track = network.get_track("Iron Maiden", "The Nomad") track.love() From 8647cbdd4844dd80ab9762fc8e18c0cf225b2cc9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 5 Jan 2023 18:36:38 +0200 Subject: [PATCH 04/55] Make alternative clearer via own code blocks --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8676805..4c624ba 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,12 @@ network = pylast.LastFMNetwork( username=username, password_hash=password_hash, ) +``` -# You can also authenticate with a session key +Alternatively, instead of creating `network` with a username and password, +you can authenticate with a session key: + +```python SESSION_KEY_FILE = os.path.join(os.path.expanduser("~"), ".session_key") network = pylast.LastFMNetwork(API_KEY, API_SECRET) if not os.path.exists(SESSION_KEY_FILE): @@ -110,7 +114,11 @@ else: session_key = open(SESSION_KEY_FILE).read() network.session_key = session_key +``` +And away we go: + +```python # Now you can use that object everywhere track = network.get_track("Iron Maiden", "The Nomad") track.love() @@ -120,6 +128,7 @@ track.add_tags(("awesome", "favorite")) # to get more help about anything and see examples of how it works ``` + More examples in hugovk/lastfm-tools and [tests/](https://github.com/pylast/pylast/tree/main/tests). From 28403386a8438722226ece7081aac5944575ffc1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 5 Jan 2023 18:41:16 +0200 Subject: [PATCH 05/55] Bump Black --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3c7c47d..405505c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: hooks: - id: blacken-docs args: [--target-version=py37] - additional_dependencies: [black==22.10.0] + additional_dependencies: [black==22.12.0] - repo: https://github.com/PyCQA/isort rev: 5.11.4 From e63ecc7bea1bd4412d31736bf4266f9ce52afbda Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 5 Jan 2023 18:42:43 +0200 Subject: [PATCH 06/55] Autolabel pre-commit PRs with 'changelog: skip' --- .github/release-drafter.yml | 5 +++++ .github/workflows/release-drafter.yml | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 67eccf9..ba26220 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -22,6 +22,11 @@ categories: exclude-labels: - "changelog: skip" +autolabeler: + - label: "changelog: skip" + branch: + - "/pre-commit-ci-update-config/" + template: | $CHANGES diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index cb11924..3f24b79 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -5,11 +5,27 @@ on: # branches to consider in the event; optional, defaults to all branches: - main + # pull_request event is required only for autolabeler + pull_request: + # Only following types are handled by the action, but one can default to all as well + types: [opened, reopened, synchronize] + # pull_request_target event is required for autolabeler to support PRs from forks + # pull_request_target: + # types: [opened, reopened, synchronize] workflow_dispatch: +permissions: + contents: read + jobs: update_release_draft: if: github.repository_owner == 'pylast' + permissions: + # write permission is required to create a GitHub Release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write runs-on: ubuntu-latest steps: # Drafts your next release notes as pull requests are merged into "main" From f5ea06c6c9488b0f6ffeee52374f197f7a5d7224 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 6 Jan 2023 09:49:52 +0200 Subject: [PATCH 07/55] Include "import pylast" in both blocks --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4c624ba..0739ee7 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,8 @@ Alternatively, instead of creating `network` with a username and password, you can authenticate with a session key: ```python +import pylast + SESSION_KEY_FILE = os.path.join(os.path.expanduser("~"), ".session_key") network = pylast.LastFMNetwork(API_KEY, API_SECRET) if not os.path.exists(SESSION_KEY_FILE): From dab0a5b6614b5cdc9b9fd73fd47e81795377c671 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 29 Jan 2023 13:27:16 +0200 Subject: [PATCH 08/55] Bump isort to fix Poetry Re: https://github.com/PyCQA/isort/pull/2078 Committed via https://github.com/asottile/all-repos --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 405505c..86f2f3e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,7 +19,7 @@ repos: additional_dependencies: [black==22.12.0] - repo: https://github.com/PyCQA/isort - rev: 5.11.4 + rev: 5.12.0 hooks: - id: isort From 15f0ccfd58117bee8e04f41eabd4b53fa9e7ba4e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 19 Mar 2023 15:53:12 +0200 Subject: [PATCH 09/55] Replace deprecated repository_url with repository-url Committed via https://github.com/asottile/all-repos --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0c72ce1..95ae3da 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -48,4 +48,4 @@ jobs: with: user: __token__ password: ${{ secrets.test_pypi_password }} - repository_url: https://test.pypi.org/legacy/ + repository-url: https://test.pypi.org/legacy/ From 111334328e584875a71a789074a0fe5c2f54cf43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 09:06:18 +0000 Subject: [PATCH 10/55] chore(deps): update mheap/github-action-required-labels action to v4 --- .github/workflows/require-pr-label.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index d243fa6..3b997b2 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: mheap/github-action-required-labels@v3 + - uses: mheap/github-action-required-labels@v4 with: mode: minimum count: 1 From 6a7a23cd9a508a7e1ca7c48fc4f5ffa7da39930b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 19:10:46 +0000 Subject: [PATCH 11/55] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 22.12.0 → 23.3.0](https://github.com/psf/black/compare/22.12.0...23.3.0) - [github.com/asottile/blacken-docs: v1.12.1 → 1.13.0](https://github.com/asottile/blacken-docs/compare/v1.12.1...1.13.0) - [github.com/pre-commit/pygrep-hooks: v1.9.0 → v1.10.0](https://github.com/pre-commit/pygrep-hooks/compare/v1.9.0...v1.10.0) - [github.com/tox-dev/pyproject-fmt: 0.4.1 → 0.9.2](https://github.com/tox-dev/pyproject-fmt/compare/0.4.1...0.9.2) - [github.com/abravalheri/validate-pyproject: v0.10.1 → v0.12.2](https://github.com/abravalheri/validate-pyproject/compare/v0.10.1...v0.12.2) - [github.com/tox-dev/tox-ini-fmt: 0.5.2 → 1.0.0](https://github.com/tox-dev/tox-ini-fmt/compare/0.5.2...1.0.0) --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86f2f3e..41b6873 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,13 +6,13 @@ repos: args: [--py37-plus] - repo: https://github.com/psf/black - rev: 22.12.0 + rev: 23.3.0 hooks: - id: black args: [--target-version=py37] - repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 + rev: 1.13.0 hooks: - id: blacken-docs args: [--target-version=py37] @@ -30,7 +30,7 @@ repos: additional_dependencies: [flake8-2020, flake8-implicit-str-concat] - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 + rev: v1.10.0 hooks: - id: python-check-blanket-noqa @@ -45,17 +45,17 @@ repos: - id: requirements-txt-fixer - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.4.1 + rev: 0.9.2 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.10.1 + rev: v0.12.2 hooks: - id: validate-pyproject - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 0.5.2 + rev: 1.0.0 hooks: - id: tox-ini-fmt From 879591e1cc90c997d9d3c940686e255d91dae5bc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 19:10:56 +0000 Subject: [PATCH 12/55] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyproject.toml | 16 +++++++--------- src/pylast/__init__.py | 4 ---- tests/test_pylast.py | 1 - tox.ini | 8 ++++---- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 461b858..141679e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,13 +19,6 @@ license = {text = "Apache-2.0"} maintainers = [{name = "Hugo van Kemenade"}] authors = [{name = "Amr Hassan and Contributors", email = "amr.hassan@gmail.com"}] requires-python = ">=3.7" -dependencies = [ - "httpx", - 'importlib-metadata; python_version < "3.8"', -] -dynamic = [ - "version", -] classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", @@ -42,6 +35,13 @@ classifiers = [ "Topic :: Multimedia :: Sound/Audio", "Topic :: Software Development :: Libraries :: Python Modules", ] +dynamic = [ + "version", +] +dependencies = [ + "httpx", + 'importlib-metadata; python_version < "3.8"', +] [project.optional-dependencies] tests = [ "flaky", @@ -50,13 +50,11 @@ tests = [ "pytest-random-order", "pyyaml", ] - [project.urls] Changelog = "https://github.com/pylast/pylast/releases" Homepage = "https://github.com/pylast/pylast" Source = "https://github.com/pylast/pylast" - [tool.hatch] version.source = "vcs" diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index e152c31..c6cd8be 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -546,7 +546,6 @@ class _Network: context=None, mbid=None, ): - """Used to add a track-play to a user's profile. Parameters: @@ -600,7 +599,6 @@ class _Network: params = {} for i in range(len(tracks_to_scrobble)): - params[f"artist[{i}]"] = tracks_to_scrobble[i]["artist"] params[f"track[{i}]"] = tracks_to_scrobble[i]["title"] @@ -621,7 +619,6 @@ class _Network: } for arg in additional_args: - if arg in tracks_to_scrobble[i] and tracks_to_scrobble[i][arg]: if arg in args_map_to: maps_to = args_map_to[arg] @@ -736,7 +733,6 @@ class LibreFMNetwork(_Network): username: str = "", password_hash: str = "", ) -> None: - super().__init__( name="Libre.fm", homepage="https://libre.fm", diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 7125413..cdaf50e 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -47,7 +47,6 @@ def _no_xfail_rerun_filter(err, name, test, plugin) -> bool: @flaky(max_runs=3, min_passes=1, rerun_filter=_no_xfail_rerun_filter) class TestPyLastWithLastFm(PyLastTestCase): - secrets = None def unix_timestamp(self): diff --git a/tox.ini b/tox.ini index a06262e..de0b9da 100644 --- a/tox.ini +++ b/tox.ini @@ -5,23 +5,23 @@ envlist = isolated_build = true [testenv] +extras = + tests passenv = FORCE_COLOR PYLAST_API_KEY PYLAST_API_SECRET PYLAST_PASSWORD_HASH PYLAST_USERNAME -extras = - tests commands = pytest -v -s -W all --cov pylast --cov tests --cov-report term-missing --cov-report xml --random-order {posargs} [testenv:lint] -passenv = - PRE_COMMIT_COLOR skip_install = true deps = pre-commit +passenv = + PRE_COMMIT_COLOR commands = pre-commit run --all-files --show-diff-on-failure From cdb88b9bbbce884865755ead8112155fb230774b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 18 Apr 2023 05:28:30 -0600 Subject: [PATCH 13/55] Update pre-commit --- .pre-commit-config.yaml | 4 ++-- tox.ini | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 41b6873..b4d8bf3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: hooks: - id: blacken-docs args: [--target-version=py37] - additional_dependencies: [black==22.12.0] + additional_dependencies: [black==23.3.0] - repo: https://github.com/PyCQA/isort rev: 5.12.0 @@ -55,7 +55,7 @@ repos: - id: validate-pyproject - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 1.0.0 + rev: 1.3.0 hooks: - id: tox-ini-fmt diff --git a/tox.ini b/tox.ini index de0b9da..7c01999 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,14 @@ [tox] -envlist = +requires = + tox>=4.2 +env_list = lint py{py3, 311, 310, 39, 38, 37} -isolated_build = true [testenv] extras = tests -passenv = +pass_env = FORCE_COLOR PYLAST_API_KEY PYLAST_API_SECRET @@ -20,7 +21,7 @@ commands = skip_install = true deps = pre-commit -passenv = +pass_env = PRE_COMMIT_COLOR commands = pre-commit run --all-files --show-diff-on-failure From 9f59dd770c887aeee6da673422b788c53c7d5a4e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 18 Apr 2023 06:04:33 -0600 Subject: [PATCH 14/55] Add support for Python 3.12 --- README.md | 7 ++++--- pyproject.toml | 1 + tox.ini | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0739ee7..ce20f6b 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,10 @@ Or from requirements.txt: Note: -* pyLast 5.1+ supports Python 3.7-3.11. -* pyLast 5.0+ supports Python 3.7-3.10. -* pyLast 4.3+ supports Python 3.6-3.10. +* pyLast 5.2+ supports Python 3.7-3.12. +* pyLast 5.1 supports Python 3.7-3.11. +* pyLast 5.0 supports Python 3.7-3.10. +* pyLast 4.3 - 4.5 supports Python 3.6-3.10. * pyLast 4.0 - 4.2 supports Python 3.6-3.9. * pyLast 3.2 - 3.3 supports Python 3.5-3.8. * pyLast 3.0 - 3.1 supports Python 3.5-3.7. diff --git a/pyproject.toml b/pyproject.toml index 141679e..fc658ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet", diff --git a/tox.ini b/tox.ini index 7c01999..641e732 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ requires = tox>=4.2 env_list = lint - py{py3, 311, 310, 39, 38, 37} + py{py3, 312, 311, 310, 39, 38, 37} [testenv] extras = From 56fc2973717a4694ed8f5901380255f1a304dba2 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 18 Apr 2023 06:08:52 -0600 Subject: [PATCH 15/55] Publish to PyPI with a Trusted Publisher --- .github/workflows/deploy.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 95ae3da..3846d7e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,6 +14,10 @@ jobs: if: github.repository_owner == 'pylast' runs-on: ubuntu-latest + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + steps: - uses: actions/checkout@v3 with: @@ -39,13 +43,8 @@ jobs: - name: Publish package to PyPI if: github.event.action == 'published' uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.pypi_password }} - name: Publish package to TestPyPI uses: pypa/gh-action-pypi-publish@release/v1 with: - user: __token__ - password: ${{ secrets.test_pypi_password }} repository-url: https://test.pypi.org/legacy/ From b05b8454f5303050a73724a8207d4c6b9597a5d3 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 18 Apr 2023 06:09:25 -0600 Subject: [PATCH 16/55] Update pre-commit --- .pre-commit-config.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4d8bf3..5529b8d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,6 @@ repos: rev: 23.3.0 hooks: - id: black - args: [--target-version=py37] - repo: https://github.com/asottile/blacken-docs rev: 1.13.0 @@ -33,12 +32,14 @@ repos: rev: v1.10.0 hooks: - id: python-check-blanket-noqa + - id: python-no-log-warn - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - - id: check-json + - id: check-case-conflict - id: check-merge-conflict + - id: check-json - id: check-toml - id: check-yaml - id: end-of-file-fixer From dc4bd8474cfe45945120f012a6174561f0fdf9c7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 18 Apr 2023 06:19:54 -0600 Subject: [PATCH 17/55] Test newest PyPy --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 280b767..e3f067c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy-3.8", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"] + python-version: ["pypy3.9", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"] os: [ubuntu-latest] steps: From 0f59831dc21b51bcf5b4468bc822a84af3968dd5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sat, 3 Jun 2023 17:41:35 +0300 Subject: [PATCH 18/55] Drop support for EOL Python 3.7 --- .github/workflows/test.yml | 3 ++- .pre-commit-config.yaml | 10 +++++----- README.md | 2 +- pyproject.toml | 32 +++++++++++++++----------------- src/pylast/__init__.py | 10 ++-------- tox.ini | 2 +- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e3f067c..3fda04c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy3.9", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12-dev"] + python-version: ["pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12"] os: [ubuntu-latest] steps: @@ -21,6 +21,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + allow-prereleases: true cache: pip cache-dependency-path: pyproject.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5529b8d..0de09d9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,9 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 + rev: v3.4.0 hooks: - id: pyupgrade - args: [--py37-plus] + args: [--py38-plus] - repo: https://github.com/psf/black rev: 23.3.0 @@ -14,7 +14,7 @@ repos: rev: 1.13.0 hooks: - id: blacken-docs - args: [--target-version=py37] + args: [--target-version=py38] additional_dependencies: [black==23.3.0] - repo: https://github.com/PyCQA/isort @@ -46,12 +46,12 @@ repos: - id: requirements-txt-fixer - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.9.2 + rev: 0.10.0 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.12.2 + rev: v0.13 hooks: - id: validate-pyproject diff --git a/README.md b/README.md index ce20f6b..3d9e882 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Or from requirements.txt: Note: -* pyLast 5.2+ supports Python 3.7-3.12. +* pyLast 5.2+ supports Python 3.8-3.12. * pyLast 5.1 supports Python 3.7-3.11. * pyLast 5.0 supports Python 3.7-3.10. * pyLast 4.3 - 4.5 supports Python 3.6-3.10. diff --git a/pyproject.toml b/pyproject.toml index fc658ff..d1224dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,30 +18,28 @@ keywords = [ license = {text = "Apache-2.0"} maintainers = [{name = "Hugo van Kemenade"}] authors = [{name = "Amr Hassan and Contributors", email = "amr.hassan@gmail.com"}] -requires-python = ">=3.7" +requires-python = ">=3.8" classifiers = [ - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Internet", - "Topic :: Multimedia :: Sound/Audio", - "Topic :: Software Development :: Libraries :: Python Modules", + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Internet", + "Topic :: Multimedia :: Sound/Audio", + "Topic :: Software Development :: Libraries :: Python Modules", ] dynamic = [ "version", ] dependencies = [ "httpx", - 'importlib-metadata; python_version < "3.8"', ] [project.optional-dependencies] tests = [ diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index c6cd8be..60f9b5f 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -23,6 +23,7 @@ from __future__ import annotations import collections import hashlib import html.entities +import importlib.metadata import logging import os import re @@ -36,18 +37,11 @@ from xml.dom import Node, minidom import httpx -try: - # Python 3.8+ - import importlib.metadata as importlib_metadata -except ImportError: - # Python 3.7 and lower - import importlib_metadata # type: ignore - __author__ = "Amr Hassan, hugovk, Mice Pápai" __copyright__ = "Copyright (C) 2008-2010 Amr Hassan, 2013-2021 hugovk, 2017 Mice Pápai" __license__ = "apache2" __email__ = "amr.hassan@gmail.com" -__version__ = importlib_metadata.version(__name__) +__version__ = importlib.metadata.version(__name__) # 1 : This error does not exist diff --git a/tox.ini b/tox.ini index 641e732..b0d3588 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ requires = tox>=4.2 env_list = lint - py{py3, 312, 311, 310, 39, 38, 37} + py{py3, 312, 311, 310, 39, 38} [testenv] extras = From 1c669d8bb01c4274ced602816cf87337731f0d25 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sat, 3 Jun 2023 17:55:00 +0300 Subject: [PATCH 19/55] Fix test: now returns a png --- tests/test_album.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_album.py b/tests/test_album.py index ae2c1a0..a56faf1 100755 --- a/tests/test_album.py +++ b/tests/test_album.py @@ -94,8 +94,8 @@ class TestPyLastAlbum(TestPyLastWithLastFm): image = album.get_cover_image() # Assert - self.assert_startswith(image, "https://") - self.assert_endswith(image, ".gif") + assert image.startswith("https://") + assert image.endswith(".gif") or image.endswith(".png") def test_mbid(self) -> None: # Arrange From 7da76f49bdf4570906459d1ec135460b5863c364 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sat, 3 Jun 2023 18:03:05 +0300 Subject: [PATCH 20/55] Refactor: replace redundant helper methods, no need with pytest --- tests/test_library.py | 4 ++-- tests/test_librefm.py | 6 +++--- tests/test_network.py | 24 ++++++++++++------------ tests/test_pylast.py | 10 +--------- tests/test_user.py | 8 ++++---- 5 files changed, 22 insertions(+), 30 deletions(-) diff --git a/tests/test_library.py b/tests/test_library.py index e37b771..cc35233 100755 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -16,7 +16,7 @@ class TestPyLastLibrary(TestPyLastWithLastFm): representation = repr(library) # Assert - self.assert_startswith(representation, "pylast.Library(") + assert representation.startswith("pylast.Library(") def test_str(self) -> None: # Arrange @@ -26,7 +26,7 @@ class TestPyLastLibrary(TestPyLastWithLastFm): string = str(library) # Assert - self.assert_endswith(string, "'s Library") + assert string.endswith("'s Library") def test_library_is_hashable(self) -> None: # Arrange diff --git a/tests/test_librefm.py b/tests/test_librefm.py index 0647976..01c43d9 100755 --- a/tests/test_librefm.py +++ b/tests/test_librefm.py @@ -6,11 +6,11 @@ from flaky import flaky import pylast -from .test_pylast import PyLastTestCase, load_secrets +from .test_pylast import load_secrets @flaky(max_runs=3, min_passes=1) -class TestPyLastWithLibreFm(PyLastTestCase): +class TestPyLastWithLibreFm: """Own class for Libre.fm because we don't need the Last.fm setUp""" def test_libre_fm(self) -> None: @@ -38,4 +38,4 @@ class TestPyLastWithLibreFm(PyLastTestCase): representation = repr(network) # Assert - self.assert_startswith(representation, "pylast.LibreFMNetwork(") + assert representation.startswith("pylast.LibreFMNetwork(") diff --git a/tests/test_network.py b/tests/test_network.py index d10cc66..51f0b18 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -330,12 +330,12 @@ class TestPyLastNetwork(TestPyLastWithLastFm): # Assert assert len(images) == 4 - self.assert_startswith(images[pylast.SIZE_SMALL], "https://") - self.assert_endswith(images[pylast.SIZE_SMALL], ".png") + assert images[pylast.SIZE_SMALL].startswith("https://") + assert images[pylast.SIZE_SMALL].endswith(".png") assert "/34s/" in images[pylast.SIZE_SMALL] - self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") - self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") + assert images[pylast.SIZE_EXTRA_LARGE].startswith("https://") + assert images[pylast.SIZE_EXTRA_LARGE].endswith(".png") assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_artist_search(self) -> None: @@ -362,12 +362,12 @@ class TestPyLastNetwork(TestPyLastWithLastFm): # Assert assert len(images) == 5 - self.assert_startswith(images[pylast.SIZE_SMALL], "https://") - self.assert_endswith(images[pylast.SIZE_SMALL], ".png") + assert images[pylast.SIZE_SMALL].startswith("https://") + assert images[pylast.SIZE_SMALL].endswith(".png") assert "/34s/" in images[pylast.SIZE_SMALL] - self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") - self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") + assert images[pylast.SIZE_EXTRA_LARGE].startswith("https://") + assert images[pylast.SIZE_EXTRA_LARGE].endswith(".png") assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_track_search(self) -> None: @@ -396,12 +396,12 @@ class TestPyLastNetwork(TestPyLastWithLastFm): # Assert assert len(images) == 4 - self.assert_startswith(images[pylast.SIZE_SMALL], "https://") - self.assert_endswith(images[pylast.SIZE_SMALL], ".png") + assert images[pylast.SIZE_SMALL].startswith("https://") + assert images[pylast.SIZE_SMALL].endswith(".png") assert "/34s/" in images[pylast.SIZE_SMALL] - self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") - self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") + assert images[pylast.SIZE_EXTRA_LARGE].startswith("https://") + assert images[pylast.SIZE_EXTRA_LARGE].endswith(".png") assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_search_get_total_result_count(self) -> None: diff --git a/tests/test_pylast.py b/tests/test_pylast.py index cdaf50e..2c3c7c7 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -32,21 +32,13 @@ def load_secrets(): # pragma: no cover return doc -class PyLastTestCase: - def assert_startswith(self, s, prefix, start=None, end=None) -> None: - assert s.startswith(prefix, start, end) - - def assert_endswith(self, s, suffix, start=None, end=None) -> None: - assert s.endswith(suffix, start, end) - - def _no_xfail_rerun_filter(err, name, test, plugin) -> bool: for _ in test.iter_markers(name="xfail"): return False @flaky(max_runs=3, min_passes=1, rerun_filter=_no_xfail_rerun_filter) -class TestPyLastWithLastFm(PyLastTestCase): +class TestPyLastWithLastFm: secrets = None def unix_timestamp(self): diff --git a/tests/test_user.py b/tests/test_user.py index 6e0f3ba..12308eb 100755 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -24,7 +24,7 @@ class TestPyLastUser(TestPyLastWithLastFm): representation = repr(user) # Assert - self.assert_startswith(representation, "pylast.User('RJ',") + assert representation.startswith("pylast.User('RJ',") def test_str(self) -> None: # Arrange @@ -345,7 +345,7 @@ class TestPyLastUser(TestPyLastWithLastFm): url = user.get_image() # Assert - self.assert_startswith(url, "https://") + assert url.startswith("https://") def test_user_get_library(self) -> None: # Arrange @@ -428,8 +428,8 @@ class TestPyLastUser(TestPyLastWithLastFm): image = user.get_image() # Assert - self.assert_startswith(image, "https://") - self.assert_endswith(image, ".png") + assert image.startswith("https://") + assert image.endswith(".png") def test_get_url(self) -> None: # Arrange From 47eda3ea703de2bce5c701fe8492d1957c60a5b9 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sat, 3 Jun 2023 18:10:01 +0300 Subject: [PATCH 21/55] Refactor: make helper methods static --- tests/test_pylast.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 2c3c7c7..4beeed7 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -41,7 +41,8 @@ def _no_xfail_rerun_filter(err, name, test, plugin) -> bool: class TestPyLastWithLastFm: secrets = None - def unix_timestamp(self): + @staticmethod + def unix_timestamp() -> int: return int(time.time()) @classmethod @@ -62,7 +63,8 @@ class TestPyLastWithLastFm: password_hash=password_hash, ) - def helper_is_thing_hashable(self, thing) -> None: + @staticmethod + def helper_is_thing_hashable(thing) -> None: # Arrange things = set() @@ -73,7 +75,8 @@ class TestPyLastWithLastFm: assert thing is not None assert len(things) == 1 - def helper_validate_results(self, a, b, c) -> None: + @staticmethod + def helper_validate_results(a, b, c) -> None: # Assert assert a is not None assert b is not None @@ -97,27 +100,31 @@ class TestPyLastWithLastFm: # Assert self.helper_validate_results(result1, result2, result3) - def helper_at_least_one_thing_in_top_list(self, things, expected_type) -> None: + @staticmethod + def helper_at_least_one_thing_in_top_list(things, expected_type) -> None: # Assert assert len(things) > 1 assert isinstance(things, list) assert isinstance(things[0], pylast.TopItem) assert isinstance(things[0].item, expected_type) - def helper_only_one_thing_in_top_list(self, things, expected_type) -> None: + @staticmethod + def helper_only_one_thing_in_top_list(things, expected_type) -> None: # Assert assert len(things) == 1 assert isinstance(things, list) assert isinstance(things[0], pylast.TopItem) assert isinstance(things[0].item, expected_type) - def helper_only_one_thing_in_list(self, things, expected_type) -> None: + @staticmethod + def helper_only_one_thing_in_list(things, expected_type) -> None: # Assert assert len(things) == 1 assert isinstance(things, list) assert isinstance(things[0], expected_type) - def helper_two_different_things_in_top_list(self, things, expected_type) -> None: + @staticmethod + def helper_two_different_things_in_top_list(things, expected_type) -> None: # Assert assert len(things) == 2 thing1 = things[0] From 02da99f4b0347042d799e5c5becc1a974c667202 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 6 Jun 2023 19:20:56 +0300 Subject: [PATCH 22/55] Use hynek/build-and-inspect-python-package --- .flake8 | 2 +- .github/workflows/deploy.yml | 80 ++++++++++++++++---------- .github/workflows/lint.yml | 3 + .github/workflows/require-pr-label.yml | 3 + 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/.flake8 b/.flake8 index f4546ad..2bcd70e 100644 --- a/.flake8 +++ b/.flake8 @@ -1,2 +1,2 @@ [flake8] -max_line_length = 88 +max-line-length = 88 diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3846d7e..6594ecf 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,49 +2,71 @@ name: Deploy on: push: - branches: - - main + branches: [main] + tags: ["*"] + pull_request: + branches: [main] release: types: - published workflow_dispatch: -jobs: - deploy: - if: github.repository_owner == 'pylast' - runs-on: ubuntu-latest +permissions: + contents: read - permissions: - # IMPORTANT: this permission is mandatory for trusted publishing - id-token: write +jobs: + # Always build & lint package. + build-package: + name: Build & verify package + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v4 + - uses: hynek/build-and-inspect-python-package@v1 + + # Upload to Test PyPI on every commit on main. + release-test-pypi: + name: Publish in-dev package to test.pypi.org + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + needs: build-package + + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + + steps: + - name: Download packages built by build-and-inspect-python-package + uses: actions/download-artifact@v3 with: - python-version: "3.x" - cache: pip - cache-dependency-path: pyproject.toml + name: Packages + path: dist - - name: Install dependencies - run: | - python -m pip install -U pip - python -m pip install -U build twine wheel - - - name: Build package - run: | - python -m build - twine check --strict dist/* - - - name: Publish package to PyPI - if: github.event.action == 'published' - uses: pypa/gh-action-pypi-publish@release/v1 - - - name: Publish package to TestPyPI + - name: Upload package to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ + + # Upload to real PyPI on GitHub Releases. + release-pypi: + name: Publish released package to pypi.org + if: github.event.action == 'published' + runs-on: ubuntu-latest + needs: build-package + + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + + steps: + - name: Download packages built by build-and-inspect-python-package + uses: actions/download-artifact@v3 + with: + name: Packages + path: dist + + - name: Upload package to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c78a405..477218a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,6 +2,9 @@ name: Lint on: [push, pull_request, workflow_dispatch] +permissions: + contents: read + jobs: lint: runs-on: ubuntu-latest diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index 3b997b2..2d97091 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -8,6 +8,9 @@ jobs: label: runs-on: ubuntu-latest + permissions: + issues: write + steps: - uses: mheap/github-action-required-labels@v4 with: From f7a73aa62f0df79efab9ce583f2083d2f4f9333e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jun 2023 17:29:12 +0000 Subject: [PATCH 23/55] Update mheap/github-action-required-labels action to v5 --- .github/workflows/require-pr-label.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index 2d97091..85c3e3e 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -12,7 +12,7 @@ jobs: issues: write steps: - - uses: mheap/github-action-required-labels@v4 + - uses: mheap/github-action-required-labels@v5 with: mode: minimum count: 1 From c26c5f86aa4d575ddf5a74a17fdfdc397a30a5a4 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 8 Jun 2023 21:22:05 +0300 Subject: [PATCH 24/55] Update on the first day of the month --- .github/renovate.json | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/renovate.json b/.github/renovate.json index 92fd789..2d2f276 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,16 +1,13 @@ { - "extends": [ - "config:base" - ], - "labels": [ - "changelog: skip", - "dependencies" - ], + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:base"], + "labels": ["changelog: skip", "dependencies"], "packageRules": [ { "groupName": "github-actions", "matchManagers": ["github-actions"], "separateMajorMinor": "false" } - ] + ], + "schedule": ["on the first day of the month"] } From 68c0197028dd2fe6b43c423f044026e1a732a4b7 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 18 Jun 2023 14:42:29 +0300 Subject: [PATCH 25/55] CI: Replace pypy3.9 with pypy3.10 Committed via https://github.com/asottile/all-repos --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3fda04c..ef202d0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy3.9", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["pypy3.10", "3.8", "3.9", "3.10", "3.11", "3.12"] os: [ubuntu-latest] steps: From e4b7af41f936e8fa2c9d63e62c50ed62c9f807a1 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 24 Jul 2023 17:33:42 +0300 Subject: [PATCH 26/55] Remove default 'cache-dependency-path: pyproject.toml' Committed via https://github.com/asottile/all-repos --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef202d0..891e2cd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: python-version: ${{ matrix.python-version }} allow-prereleases: true cache: pip - cache-dependency-path: pyproject.toml + - name: Install dependencies run: | From 74392c4d718b5187004fb8eaf680ae81fadf6816 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Aug 2023 14:22:24 +0300 Subject: [PATCH 27/55] [pre-commit.ci] pre-commit autoupdate (#434) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Hugo van Kemenade --- .pre-commit-config.yaml | 17 ++++++++++------- COPYING | 6 +++--- pyproject.toml | 1 - src/pylast/__init__.py | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0de09d9..fe0a791 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,17 +1,17 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.4.0 + rev: v3.10.1 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.7.0 hooks: - id: black - repo: https://github.com/asottile/blacken-docs - rev: 1.13.0 + rev: 1.16.0 hooks: - id: blacken-docs args: [--target-version=py38] @@ -23,7 +23,7 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 additional_dependencies: [flake8-2020, flake8-implicit-str-concat] @@ -44,19 +44,22 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: requirements-txt-fixer + - id: trailing-whitespace + exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.10.0 + rev: 0.13.1 hooks: - id: pyproject-fmt + additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.13 + rev: v0.14 hooks: - id: validate-pyproject - repo: https://github.com/tox-dev/tox-ini-fmt - rev: 1.3.0 + rev: 1.3.1 hooks: - id: tox-ini-fmt diff --git a/COPYING b/COPYING index c4ff845..5b651ea 100644 --- a/COPYING +++ b/COPYING @@ -32,11 +32,11 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: -You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and +You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. diff --git a/pyproject.toml b/pyproject.toml index d1224dd..52292bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,6 @@ requires-python = ">=3.8" classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index 60f9b5f..d901c64 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -1505,7 +1505,7 @@ class _Opus(_Taggable): return f"{self.get_artist().get_name()} - {self.get_title()}" def __eq__(self, other): - if type(self) != type(other): + if type(self) is not type(other): return False a = self.get_title().lower() b = other.get_title().lower() From 47872dbb3288f2230c3d8d20cf18ac126dcdbd8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 08:37:46 +0300 Subject: [PATCH 28/55] Update actions/checkout action to v4 (#436) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/checkout](https://togithub.com/actions/checkout) | action | major | `v3` -> `v4` | --- ### Release Notes
actions/checkout (actions/checkout) ### [`v4`](https://togithub.com/actions/checkout/blob/HEAD/CHANGELOG.md#v400) [Compare Source](https://togithub.com/actions/checkout/compare/v3...v4) - [Support fetching without the --progress option](https://togithub.com/actions/checkout/pull/1067) - [Update to node20](https://togithub.com/actions/checkout/pull/1436)
--- ### Configuration 📅 **Schedule**: Branch creation - "on the first day of the month" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/pylast/pylast). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/deploy.yml | 2 +- .github/workflows/labels.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6594ecf..924a079 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 95156ef..9ca7454 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -12,7 +12,7 @@ jobs: sync: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: micnncim/action-label-syncer@v1 with: prune: false diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 477218a..4cf8d37 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.x" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 891e2cd..2e8f5f4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: os: [ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 From c0f9f4222a1fd82ae295bafb7528dc73ccc15ec1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:16:48 -0600 Subject: [PATCH 29/55] [pre-commit.ci] pre-commit autoupdate (#437) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fe0a791..bb81967 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + rev: v3.13.0 hooks: - id: pyupgrade args: [--py38-plus] - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.9.1 hooks: - id: black @@ -48,7 +48,7 @@ repos: exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/tox-dev/pyproject-fmt - rev: 0.13.1 + rev: 1.2.0 hooks: - id: pyproject-fmt additional_dependencies: [tox] From a91bac007d46fbb86d9b27726c293a6d6fb44f56 Mon Sep 17 00:00:00 2001 From: Mia Bilka Date: Thu, 26 Oct 2023 18:02:01 -0700 Subject: [PATCH 30/55] Fixed incorrect docstrings --- src/pylast/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index d901c64..0de19d7 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -1156,7 +1156,7 @@ class _BaseObject: def get_wiki_published_date(self): """ - Returns the summary of the wiki. + Returns the date on which the wiki was published. Only for Album/Track. """ return self.get_wiki("published") @@ -1170,7 +1170,7 @@ class _BaseObject: def get_wiki_content(self): """ - Returns the summary of the wiki. + Returns the content of the wiki. Only for Album/Track. """ return self.get_wiki("content") @@ -1543,7 +1543,7 @@ class _Opus(_Taggable): return self.info["image"][size] def get_title(self, properly_capitalized: bool = False): - """Returns the artist or track title.""" + """Returns the album or track title.""" if properly_capitalized: self.title = _extract( self._request(self.ws_prefix + ".getInfo", True), "name" From b4c8dc728237ff68956e376142bfd57a0d8ddae2 Mon Sep 17 00:00:00 2001 From: Eugene Simonov Date: Fri, 29 Dec 2023 21:00:10 +0200 Subject: [PATCH 31/55] Add type annotations to methods that take timestamp parameter (#442) Co-authored-by: Eugene Simonov Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Hugo van Kemenade --- src/pylast/__init__.py | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index 0de19d7..c94e714 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -529,25 +529,25 @@ class _Network: def scrobble( self, - artist, - title, - timestamp, - album=None, - album_artist=None, - track_number=None, - duration=None, - stream_id=None, - context=None, - mbid=None, + artist: str, + title: str, + timestamp: int, + album: str | None = None, + album_artist: str | None = None, + track_number: int | None = None, + duration: int | None = None, + stream_id: str | None = None, + context: str | None = None, + mbid: str | None = None, ): """Used to add a track-play to a user's profile. Parameters: artist (Required) : The artist name. title (Required) : The track name. - timestamp (Required) : The time the track started playing, in UNIX + timestamp (Required) : The time the track started playing, in Unix timestamp format (integer number of seconds since 00:00:00, - January 1st 1970 UTC). This must be in the UTC time zone. + January 1st 1970 UTC). album (Optional) : The album name. album_artist (Optional) : The album artist - if this differs from the track artist. @@ -2295,8 +2295,8 @@ class User(_Chartable): self, limit: int = 10, cacheable: bool = True, - time_from=None, - time_to=None, + time_from: int | None = None, + time_to: int | None = None, stream: bool = False, now_playing: bool = False, ): @@ -2307,13 +2307,11 @@ class User(_Chartable): Parameters: limit : If None, it will try to pull all the available data. from (Optional) : Beginning timestamp of a range - only display - scrobbles after this time, in UNIX timestamp format (integer - number of seconds since 00:00:00, January 1st 1970 UTC). This - must be in the UTC time zone. + scrobbles after this time, in Unix timestamp format (integer + number of seconds since 00:00:00, January 1st 1970 UTC). to (Optional) : End timestamp of a range - only display scrobbles - before this time, in UNIX timestamp format (integer number of - seconds since 00:00:00, January 1st 1970 UTC). This must be in - the UTC time zone. + before this time, in Unix timestamp format (integer number of + seconds since 00:00:00, January 1st 1970 UTC). stream: If True, it will yield tracks as soon as a page has been retrieved. This method uses caching. Enable caching only if you're pulling a @@ -2382,7 +2380,7 @@ class User(_Chartable): return _extract(doc, "registered") def get_unixtime_registered(self): - """Returns the user's registration date as a UNIX timestamp.""" + """Returns the user's registration date as a Unix timestamp.""" doc = self._request(self.ws_prefix + ".getInfo", True) From e90d717b66c01d9ddb0dac52d31d1c9a478b11e7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 01:18:15 +0000 Subject: [PATCH 32/55] Update github-actions --- .github/workflows/deploy.yml | 6 +++--- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 924a079..3e3174a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -25,7 +25,7 @@ jobs: with: fetch-depth: 0 - - uses: hynek/build-and-inspect-python-package@v1 + - uses: hynek/build-and-inspect-python-package@v2 # Upload to Test PyPI on every commit on main. release-test-pypi: @@ -40,7 +40,7 @@ jobs: steps: - name: Download packages built by build-and-inspect-python-package - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: Packages path: dist @@ -63,7 +63,7 @@ jobs: steps: - name: Download packages built by build-and-inspect-python-package - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: Packages path: dist diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4cf8d37..f8f9a2b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e8f5f4..bf80524 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true From d5fe263c239bdae27d733b90896dceedbf83f29c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 10:31:29 -0700 Subject: [PATCH 33/55] [pre-commit.ci] pre-commit autoupdate (#444) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Hugo van Kemenade --- .pre-commit-config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb81967..c5ed648 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v3.13.0 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py38-plus] - - repo: https://github.com/psf/black - rev: 23.9.1 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.12.1 hooks: - id: black @@ -18,7 +18,7 @@ repos: additional_dependencies: [black==23.3.0] - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort @@ -35,7 +35,7 @@ repos: - id: python-no-log-warn - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-case-conflict - id: check-merge-conflict @@ -48,13 +48,13 @@ repos: exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.2.0 + rev: 1.5.3 hooks: - id: pyproject-fmt additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.14 + rev: v0.15 hooks: - id: validate-pyproject From 370ff77f21635dc9579e1ab49b15010a84ffcef8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 22 Jan 2024 09:23:41 +0200 Subject: [PATCH 34/55] Double read timeout to fix 'The read operation timed out' 5 seconds is the default --- src/pylast/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index c94e714..d180a48 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -894,6 +894,7 @@ class _Request: username = "" if username is None else f"?username={username}" (host_name, host_subdir) = self.network.ws_server + timeout = httpx.Timeout(5, read=10) if self.network.is_proxy_enabled(): client = httpx.Client( @@ -901,12 +902,14 @@ class _Request: base_url=f"https://{host_name}", headers=HEADERS, proxies=self.network.proxy, + timeout=timeout, ) else: client = httpx.Client( verify=SSL_CONTEXT, base_url=f"https://{host_name}", headers=HEADERS, + timeout=timeout, ) try: From ffebde28e2948e44ccf94bcec70f2abd528ca425 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Feb 2024 18:59:28 +0000 Subject: [PATCH 35/55] Update github-actions --- .github/workflows/release-drafter.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 3f24b79..0910f73 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -29,6 +29,6 @@ jobs: runs-on: ubuntu-latest steps: # Drafts your next release notes as pull requests are merged into "main" - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf80524..f1cd738 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: PYLAST_USERNAME: ${{ secrets.PYLAST_USERNAME }} - name: Upload coverage - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: flags: ${{ matrix.os }} name: ${{ matrix.os }} Python ${{ matrix.python-version }} From 6c888343c81c853b285f96748e79a2230e58c6d8 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 12:00:33 -0700 Subject: [PATCH 36/55] Pin codecov/codecov-action to v3.1.5 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f1cd738..4e94e7a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: PYLAST_USERNAME: ${{ secrets.PYLAST_USERNAME }} - name: Upload coverage - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v3.1.5 with: flags: ${{ matrix.os }} name: ${{ matrix.os }} Python ${{ matrix.python-version }} From 36d89a69e8d88a762806ace12e876e1b5c10054d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 21:06:19 +0200 Subject: [PATCH 37/55] Replace Flake8 with Ruff --- .flake8 | 2 -- .pre-commit-config.yaml | 40 ++++++++++++++-------------------------- pyproject.toml | 27 +++++++++++++++++++++++++-- src/pylast/__init__.py | 12 +++++++----- tests/test_album.py | 2 ++ tests/test_artist.py | 2 ++ tests/test_country.py | 2 ++ tests/test_library.py | 2 ++ tests/test_librefm.py | 2 ++ tests/test_network.py | 3 +++ tests/test_pylast.py | 2 ++ tests/test_tag.py | 2 ++ tests/test_track.py | 3 +++ tests/test_user.py | 2 ++ tests/unicode_test.py | 4 +++- 15 files changed, 71 insertions(+), 36 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 2bcd70e..0000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 88 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c5ed648..5caa25a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.0 hooks: - - id: pyupgrade - args: [--py38-plus] + - id: ruff + args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.1 + rev: 24.1.1 hooks: - id: black @@ -15,24 +15,7 @@ repos: hooks: - id: blacken-docs args: [--target-version=py38] - additional_dependencies: [black==23.3.0] - - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: [flake8-2020, flake8-implicit-str-concat] - - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 - hooks: - - id: python-check-blanket-noqa - - id: python-no-log-warn + additional_dependencies: [black] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 @@ -42,19 +25,19 @@ repos: - id: check-json - id: check-toml - id: check-yaml + - id: debug-statements - id: end-of-file-fixer - - id: requirements-txt-fixer - id: trailing-whitespace exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.5.3 + rev: 1.7.0 hooks: - id: pyproject-fmt additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.15 + rev: v0.16 hooks: - id: validate-pyproject @@ -63,5 +46,10 @@ repos: hooks: - id: tox-ini-fmt + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + ci: autoupdate_schedule: quarterly diff --git a/pyproject.toml b/pyproject.toml index 52292bb..3413855 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,5 +59,28 @@ version.source = "vcs" [tool.hatch.version.raw-options] local_scheme = "no-local-version" -[tool.isort] -profile = "black" +[tool.ruff.lint] +select = [ + "C4", # flake8-comprehensions + "E", # pycodestyle errors + "EM", # flake8-errmsg + "F", # pyflakes errors + "I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "PGH", # pygrep-hooks + "RUF100", # unused noqa (yesqa) + "UP", # pyupgrade + "W", # pycodestyle warnings + "YTT", # flake8-2020 +] +extend-ignore = [ + "E203", # Whitespace before ':' + "E221", # Multiple spaces before operator + "E226", # Missing whitespace around arithmetic operator + "E241", # Multiple spaces after ',' +] + +[tool.ruff.lint.isort] +known-first-party = ["pylast"] +required-imports = ["from __future__ import annotations"] diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index d180a48..0396f5b 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -628,7 +628,6 @@ class _Network: class LastFMNetwork(_Network): - """A Last.fm network object api_key: a provided API_KEY @@ -1243,8 +1242,10 @@ class _Chartable(_BaseObject): from_date value to the to_date value. chart_kind should be one of "album", "artist" or "track" """ + import sys + method = ".getWeekly" + chart_kind.title() + "Chart" - chart_type = eval(chart_kind.title()) # string to type + chart_type = getattr(sys.modules[__name__], chart_kind.title()) params = self._get_params() if from_date and to_date: @@ -1356,11 +1357,11 @@ class _Taggable(_BaseObject): new_tags.append(tag) for i in range(0, len(old_tags)): - if not c_old_tags[i] in c_new_tags: + if c_old_tags[i] not in c_new_tags: to_remove.append(old_tags[i]) for i in range(0, len(new_tags)): - if not c_new_tags[i] in c_old_tags: + if c_new_tags[i] not in c_old_tags: to_add.append(new_tags[i]) self.remove_tags(to_remove) @@ -2778,7 +2779,8 @@ def _collect_nodes( main.getAttribute("totalPages") or main.getAttribute("totalpages") ) else: - raise PyLastError("No total pages attribute") + msg = "No total pages attribute" + raise PyLastError(msg) for node in main.childNodes: if not node.nodeType == xml.dom.Node.TEXT_NODE and ( diff --git a/tests/test_album.py b/tests/test_album.py index a56faf1..1146f12 100755 --- a/tests/test_album.py +++ b/tests/test_album.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_artist.py b/tests/test_artist.py index e72474e..d4f9134 100755 --- a/tests/test_artist.py +++ b/tests/test_artist.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pytest import pylast diff --git a/tests/test_country.py b/tests/test_country.py index 6d36ef3..1636b96 100755 --- a/tests/test_country.py +++ b/tests/test_country.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_library.py b/tests/test_library.py index cc35233..592436d 100755 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_librefm.py b/tests/test_librefm.py index 01c43d9..0d9e839 100755 --- a/tests/test_librefm.py +++ b/tests/test_librefm.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + from flaky import flaky import pylast diff --git a/tests/test_network.py b/tests/test_network.py index 51f0b18..05672d6 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -1,6 +1,9 @@ """ Integration (not unit) tests for pylast.py """ + +from __future__ import annotations + import re import time diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 4beeed7..c06a9c3 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import os import time diff --git a/tests/test_tag.py b/tests/test_tag.py index 89080f6..7a9675c 100755 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_track.py b/tests/test_track.py index dae2c9c..db9c69c 100755 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -1,6 +1,9 @@ """ Integration (not unit) tests for pylast.py """ + +from __future__ import annotations + import time import pytest diff --git a/tests/test_user.py b/tests/test_user.py index 12308eb..f5069d5 100755 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import calendar import datetime as dt import inspect diff --git a/tests/unicode_test.py b/tests/unicode_test.py index bc93dfa..67f234b 100644 --- a/tests/unicode_test.py +++ b/tests/unicode_test.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from unittest import mock import pytest @@ -25,7 +27,7 @@ def test_get_cache_key(artist) -> None: @pytest.mark.parametrize("obj", [pylast.Artist("B\xe9l", mock_network())]) def test_cast_and_hash(obj) -> None: - assert type(str(obj)) is str + assert isinstance(str(obj), str) assert isinstance(hash(obj), int) From 5bccda1102ca7b67c8b92b3fd18733f75df3225b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:02:41 +0200 Subject: [PATCH 38/55] Update config --- .github/workflows/deploy.yml | 11 +++++++---- .github/workflows/labels.yml | 3 +++ .github/workflows/lint.yml | 3 +++ .github/workflows/require-pr-label.yml | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3e3174a..8b9a278 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,12 +30,14 @@ jobs: # Upload to Test PyPI on every commit on main. release-test-pypi: name: Publish in-dev package to test.pypi.org - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'pylast' + && github.event_name == 'push' + && github.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: build-package permissions: - # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: @@ -53,12 +55,13 @@ jobs: # Upload to real PyPI on GitHub Releases. release-pypi: name: Publish released package to pypi.org - if: github.event.action == 'published' + if: | + github.repository_owner == 'pylast' + && github.event.action == 'published' runs-on: ubuntu-latest needs: build-package permissions: - # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 9ca7454..859c948 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -1,5 +1,8 @@ name: Sync labels +permissions: + pull-requests: write + on: push: branches: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f8f9a2b..dae63b0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,6 +2,9 @@ name: Lint on: [push, pull_request, workflow_dispatch] +env: + FORCE_COLOR: 1 + permissions: contents: read diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index 85c3e3e..0d910db 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -10,6 +10,7 @@ jobs: permissions: issues: write + pull-requests: write steps: - uses: mheap/github-action-required-labels@v5 From 3890cb4c04fa72bd1003ecaa42a8020b78e79e5d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:03:26 +0200 Subject: [PATCH 39/55] Add {envpython} and --cov-report html, multiline for clarity --- tox.ini | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b0d3588..e3972c0 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,14 @@ pass_env = PYLAST_PASSWORD_HASH PYLAST_USERNAME commands = - pytest -v -s -W all --cov pylast --cov tests --cov-report term-missing --cov-report xml --random-order {posargs} + {envpython} -m pytest -v -s -W all \ + --cov pylast \ + --cov tests \ + --cov-report html \ + --cov-report term-missing \ + --cov-report xml \ + --random-order \ + {posargs} [testenv:lint] skip_install = true From 77d1b0009c46410057d7b4a563c1c8968dd2ec75 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 29 Dec 2023 21:04:31 +0200 Subject: [PATCH 40/55] Add support for Python 3.13 --- .github/workflows/test.yml | 3 +-- README.md | 1 + pyproject.toml | 1 + tox.ini | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4e94e7a..7f09cba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["pypy3.10", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["pypy3.10", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] os: [ubuntu-latest] steps: @@ -24,7 +24,6 @@ jobs: allow-prereleases: true cache: pip - - name: Install dependencies run: | python -m pip install -U pip diff --git a/README.md b/README.md index 3d9e882..31ea52c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Or from requirements.txt: Note: +* pyLast 5.3+ supports Python 3.8-3.13. * pyLast 5.2+ supports Python 3.8-3.12. * pyLast 5.1 supports Python 3.7-3.11. * pyLast 5.0 supports Python 3.7-3.10. diff --git a/pyproject.toml b/pyproject.toml index 3413855..6857849 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet", diff --git a/tox.ini b/tox.ini index e3972c0..3ead5fc 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ requires = tox>=4.2 env_list = lint - py{py3, 312, 311, 310, 39, 38} + py{py3, 313, 312, 311, 310, 39, 38} [testenv] extras = From a14a50a333b0793f5a648384b257c8ed6634a58b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:22:18 +0200 Subject: [PATCH 41/55] Scrutinizer was removed in 2019 --- .scrutinizer.yml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .scrutinizer.yml diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 43dbfa3..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,9 +0,0 @@ -checks: - python: - code_rating: true - duplicate_code: true -filter: - excluded_paths: - - '*/test/*' -tools: - external_code_coverage: true From f4547a58213dc2520aff5f002d98092f1b285280 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:24:25 +0200 Subject: [PATCH 42/55] Add Prettier to pre-commit --- .pre-commit-config.yaml | 7 +++ CHANGELOG.md | 96 ++++++++++++++++++++++------------------ README.md | 48 ++++++++++---------- RELEASING.md | 7 +-- example_test_pylast.yaml | 8 ++-- 5 files changed, 90 insertions(+), 76 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5caa25a..028e611 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,13 @@ repos: hooks: - id: tox-ini-fmt + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + args: [--prose-wrap=always, --print-width=88] + exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md + - repo: meta hooks: - id: check-hooks-apply diff --git a/CHANGELOG.md b/CHANGELOG.md index 2518770..d424974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,117 +12,125 @@ See GitHub Releases: ## Changed -* Fix unsafe creation of temp file for caching, and improve exception raising (#356) @kvanzuijlen -* [pre-commit.ci] pre-commit autoupdate (#362) @pre-commit-ci - +- Fix unsafe creation of temp file for caching, and improve exception raising (#356) + @kvanzuijlen +- [pre-commit.ci] pre-commit autoupdate (#362) @pre-commit-ci ## [4.1.0] - 2021-01-04 + ## Added -* Add support for streaming (#336) @kvanzuijlen -* Add Python 3.9 final to Travis CI (#350) @sheetalsingala +- Add support for streaming (#336) @kvanzuijlen +- Add Python 3.9 final to Travis CI (#350) @sheetalsingala ## Changed -* Update copyright year (#360) @hugovk -* Replace Travis CI with GitHub Actions (#352) @hugovk -* [pre-commit.ci] pre-commit autoupdate (#359) @pre-commit-ci +- Update copyright year (#360) @hugovk +- Replace Travis CI with GitHub Actions (#352) @hugovk +- [pre-commit.ci] pre-commit autoupdate (#359) @pre-commit-ci ## Fixed -* Set limit to 50 by default, not 1 (#355) @hugovk - +- Set limit to 50 by default, not 1 (#355) @hugovk ## [4.0.0] - 2020-10-07 + ## Added -* Add support for Python 3.9 (#347) @hugovk +- Add support for Python 3.9 (#347) @hugovk ## Removed -* Remove deprecated `Artist.get_cover_image`, `User.get_artist_tracks` and `STATUS_TOKEN_ERROR` (#348) @hugovk -* Drop support for EOL Python 3.5 (#346) @hugovk - +- Remove deprecated `Artist.get_cover_image`, `User.get_artist_tracks` and + `STATUS_TOKEN_ERROR` (#348) @hugovk +- Drop support for EOL Python 3.5 (#346) @hugovk ## [3.3.0] - 2020-06-25 + ### Added -* `User.get_now_playing`: Add album and cover image to info (#330) @hugovk +- `User.get_now_playing`: Add album and cover image to info (#330) @hugovk ### Changed -* Improve handling of error responses from the API (#327) @spiritualized +- Improve handling of error responses from the API (#327) @spiritualized ### Deprecated -* Deprecate `Artist.get_cover_image`, they're no longer available from Last.fm (#332) @hugovk +- Deprecate `Artist.get_cover_image`, they're no longer available from Last.fm (#332) + @hugovk ### Fixed -* Fix `artist.get_bio_content()` to return `None` if bio is empty (#326) @hugovk - +- Fix `artist.get_bio_content()` to return `None` if bio is empty (#326) @hugovk ## [3.2.1] - 2020-03-05 + ### Fixed -* Only Python 3 is supported: don't create universal wheel (#318) @hugovk -* Fix regression calling `get_recent_tracks` with `limit=None` (#320) @hugovk -* Fix `DeprecationWarning`: Please use `assertRegex` instead (#323) @hugovk +- Only Python 3 is supported: don't create universal wheel (#318) @hugovk +- Fix regression calling `get_recent_tracks` with `limit=None` (#320) @hugovk +- Fix `DeprecationWarning`: Please use `assertRegex` instead (#323) @hugovk ## [3.2.0] - 2020-01-03 + ### Added -* Support for Python 3.8 -* Store album art URLs when you call `GetTopAlbums` ([#307]) -* Retry paging through results on exception ([#297]) -* More error status codes from https://last.fm/api/errorcodes ([#297]) +- Support for Python 3.8 +- Store album art URLs when you call `GetTopAlbums` ([#307]) +- Retry paging through results on exception ([#297]) +- More error status codes from https://last.fm/api/errorcodes ([#297]) ### Changed -* Respect `get_recent_tracks`' limit when there's a now playing track ([#310]) -* Move installable code to `src/` ([#301]) -* Update `get_weekly_artist_charts` docstring: only for `User` ([#311]) -* Remove Python 2 warnings, `python_requires` should be enough ([#312]) -* Use setuptools_scm to simplify versioning during release ([#316]) -* Various lint and test updates +- Respect `get_recent_tracks`' limit when there's a now playing track ([#310]) +- Move installable code to `src/` ([#301]) +- Update `get_weekly_artist_charts` docstring: only for `User` ([#311]) +- Remove Python 2 warnings, `python_requires` should be enough ([#312]) +- Use setuptools_scm to simplify versioning during release ([#316]) +- Various lint and test updates ### Deprecated -* Last.fm's `user.getArtistTracks` has now been deprecated by Last.fm and is no longer +- Last.fm's `user.getArtistTracks` has now been deprecated by Last.fm and is no longer available. Last.fm returns a "Deprecated - This type of request is no longer supported" error when calling it. A future version of pylast will remove its `User.get_artist_tracks` altogether. ([#305]) -* `STATUS_TOKEN_ERROR` is deprecated and will be removed in a future version. - Use `STATUS_OPERATION_FAILED` instead. +- `STATUS_TOKEN_ERROR` is deprecated and will be removed in a future version. Use + `STATUS_OPERATION_FAILED` instead. ## [3.1.0] - 2019-03-07 + ### Added -* Extract username from session via new +- Extract username from session via new `SessionKeyGenerator.get_web_auth_session_key_username` ([#290]) -* `User.get_track_scrobbles` ([#298]) +- `User.get_track_scrobbles` ([#298]) ### Deprecated -* `User.get_artist_tracks`. Use `User.get_track_scrobbles` as a partial replacement. - ([#298]) +- `User.get_artist_tracks`. Use `User.get_track_scrobbles` as a partial replacement. + ([#298]) ## [3.0.0] - 2019-01-01 + ### Added -* This changelog file ([#273]) + +- This changelog file ([#273]) ### Removed -* Support for Python 2.7 ([#265]) +- Support for Python 2.7 ([#265]) -* Constants `COVER_SMALL`, `COVER_MEDIUM`, `COVER_LARGE`, `COVER_EXTRA_LARGE` - and `COVER_MEGA`. Use `SIZE_SMALL` etc. instead. ([#282]) +- Constants `COVER_SMALL`, `COVER_MEDIUM`, `COVER_LARGE`, `COVER_EXTRA_LARGE` and + `COVER_MEGA`. Use `SIZE_SMALL` etc. instead. ([#282]) ## [2.4.0] - 2018-08-08 + ### Deprecated -* Support for Python 2.7 ([#265]) +- Support for Python 2.7 ([#265]) [4.2.0]: https://github.com/pylast/pylast/compare/4.1.0...4.2.0 [4.1.0]: https://github.com/pylast/pylast/compare/4.0.0...4.1.0 diff --git a/README.md b/README.md index 31ea52c..93bd9b6 100644 --- a/README.md +++ b/README.md @@ -35,31 +35,30 @@ Or from requirements.txt: Note: -* pyLast 5.3+ supports Python 3.8-3.13. -* pyLast 5.2+ supports Python 3.8-3.12. -* pyLast 5.1 supports Python 3.7-3.11. -* pyLast 5.0 supports Python 3.7-3.10. -* pyLast 4.3 - 4.5 supports Python 3.6-3.10. -* pyLast 4.0 - 4.2 supports Python 3.6-3.9. -* pyLast 3.2 - 3.3 supports Python 3.5-3.8. -* pyLast 3.0 - 3.1 supports Python 3.5-3.7. -* pyLast 2.2 - 2.4 supports Python 2.7.10+, 3.4-3.7. -* pyLast 2.0 - 2.1 supports Python 2.7.10+, 3.4-3.6. -* pyLast 1.7 - 1.9 supports Python 2.7, 3.3-3.6. -* pyLast 1.0 - 1.6 supports Python 2.7, 3.3-3.4. -* pyLast 0.5 supports Python 2, 3. -* pyLast < 0.5 supports Python 2. +- pyLast 5.3+ supports Python 3.8-3.13. +- pyLast 5.2+ supports Python 3.8-3.12. +- pyLast 5.1 supports Python 3.7-3.11. +- pyLast 5.0 supports Python 3.7-3.10. +- pyLast 4.3 - 4.5 supports Python 3.6-3.10. +- pyLast 4.0 - 4.2 supports Python 3.6-3.9. +- pyLast 3.2 - 3.3 supports Python 3.5-3.8. +- pyLast 3.0 - 3.1 supports Python 3.5-3.7. +- pyLast 2.2 - 2.4 supports Python 2.7.10+, 3.4-3.7. +- pyLast 2.0 - 2.1 supports Python 2.7.10+, 3.4-3.6. +- pyLast 1.7 - 1.9 supports Python 2.7, 3.3-3.6. +- pyLast 1.0 - 1.6 supports Python 2.7, 3.3-3.4. +- pyLast 0.5 supports Python 2, 3. +- pyLast < 0.5 supports Python 2. ## Features - * Simple public interface. - * Access to all the data exposed by the Last.fm web services. - * Scrobbling support. - * Full object-oriented design. - * Proxy support. - * Internal caching support for some web services calls (disabled by default). - * Support for other API-compatible networks like Libre.fm. - +- Simple public interface. +- Access to all the data exposed by the Last.fm web services. +- Scrobbling support. +- Full object-oriented design. +- Proxy support. +- Internal caching support for some web services calls (disabled by default). +- Support for other API-compatible networks like Libre.fm. ## Getting started @@ -88,8 +87,8 @@ network = pylast.LastFMNetwork( ) ``` -Alternatively, instead of creating `network` with a username and password, -you can authenticate with a session key: +Alternatively, instead of creating `network` with a username and password, you can +authenticate with a session key: ```python import pylast @@ -132,7 +131,6 @@ track.add_tags(("awesome", "favorite")) # to get more help about anything and see examples of how it works ``` - More examples in hugovk/lastfm-tools and [tests/](https://github.com/pylast/pylast/tree/main/tests). diff --git a/RELEASING.md b/RELEASING.md index 9a4d1bc..9b2e38a 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,8 +1,8 @@ # Release Checklist - [ ] Get `main` to the appropriate code release state. - [GitHub Actions](https://github.com/pylast/pylast/actions) should be running cleanly for - all merges to `main`. + [GitHub Actions](https://github.com/pylast/pylast/actions) should be running + cleanly for all merges to `main`. [![Test](https://github.com/pylast/pylast/workflows/Test/badge.svg)](https://github.com/pylast/pylast/actions) - [ ] Edit release draft, adjust text if needed: @@ -12,7 +12,8 @@ - [ ] Publish release -- [ ] Check the tagged [GitHub Actions build](https://github.com/pylast/pylast/actions/workflows/deploy.yml) +- [ ] Check the tagged + [GitHub Actions build](https://github.com/pylast/pylast/actions/workflows/deploy.yml) has deployed to [PyPI](https://pypi.org/project/pylast/#history) - [ ] Check installation: diff --git a/example_test_pylast.yaml b/example_test_pylast.yaml index a8fa045..00b09f1 100644 --- a/example_test_pylast.yaml +++ b/example_test_pylast.yaml @@ -1,4 +1,4 @@ -username: TODO_ENTER_YOURS_HERE -password_hash: TODO_ENTER_YOURS_HERE -api_key: TODO_ENTER_YOURS_HERE -api_secret: TODO_ENTER_YOURS_HERE +username: TODO_ENTER_YOURS_HERE +password_hash: TODO_ENTER_YOURS_HERE +api_key: TODO_ENTER_YOURS_HERE +api_secret: TODO_ENTER_YOURS_HERE From d5f1c3d3ac6dac984de011c47aa346616ac1dfe7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 01:13:50 +0000 Subject: [PATCH 43/55] Update github-actions --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dae63b0..88c0c7c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,4 +17,4 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.x" - - uses: pre-commit/action@v3.0.0 + - uses: pre-commit/action@v3.0.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7f09cba..9c2c1a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: PYLAST_USERNAME: ${{ secrets.PYLAST_USERNAME }} - name: Upload coverage - uses: codecov/codecov-action@v3.1.5 + uses: codecov/codecov-action@v4.1.0 with: flags: ${{ matrix.os }} name: ${{ matrix.os }} Python ${{ matrix.python-version }} From e4d2ebc4a06e598fcaa7254f75868af04dae5753 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Fri, 1 Mar 2024 08:02:36 +0200 Subject: [PATCH 44/55] Update test.yml --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9c2c1a3..7f09cba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: PYLAST_USERNAME: ${{ secrets.PYLAST_USERNAME }} - name: Upload coverage - uses: codecov/codecov-action@v4.1.0 + uses: codecov/codecov-action@v3.1.5 with: flags: ${{ matrix.os }} name: ${{ matrix.os }} Python ${{ matrix.python-version }} From 82cb5048717f460d7da658ff367690e1ab696999 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:16:48 +0000 Subject: [PATCH 45/55] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.2.0 → v0.3.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.0...v0.3.4) - [github.com/psf/black-pre-commit-mirror: 24.1.1 → 24.3.0](https://github.com/psf/black-pre-commit-mirror/compare/24.1.1...24.3.0) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 028e611..89f4d05 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.0 + rev: v0.3.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.1.1 + rev: 24.3.0 hooks: - id: black From fa68aa4ae867ab65f99ba21b5898668fb54ec669 Mon Sep 17 00:00:00 2001 From: Christian McKinnon Date: Wed, 22 May 2024 11:48:48 +0700 Subject: [PATCH 46/55] Update example_test_pylast.yaml Link in README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 93bd9b6..7653b86 100644 --- a/README.md +++ b/README.md @@ -141,9 +141,10 @@ The [tests/](https://github.com/pylast/pylast/tree/main/tests) directory contain integration and unit tests with Last.fm, and plenty of code examples. For integration tests you need a test account at Last.fm that will become cluttered with -test data, and an API key and secret. Either copy -[example_test_pylast.yaml](example_test_pylast.yaml) to test_pylast.yaml and fill out -the credentials, or set them as environment variables like: +test data, and an API key and secret. Either copy [example_test_pylast.yaml]( +https://github.com/pylast/pylast/blob/main/example_test_pylast.yaml) to +test_pylast.yaml and fill out the credentials, or set them as environment +variables like: ```sh export PYLAST_USERNAME=TODO_ENTER_YOURS_HERE From 90c3614d6ac969d471e5e6e8d5d022496fef4cad Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 05:10:35 +0000 Subject: [PATCH 47/55] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7653b86..de2987f 100644 --- a/README.md +++ b/README.md @@ -141,10 +141,10 @@ The [tests/](https://github.com/pylast/pylast/tree/main/tests) directory contain integration and unit tests with Last.fm, and plenty of code examples. For integration tests you need a test account at Last.fm that will become cluttered with -test data, and an API key and secret. Either copy [example_test_pylast.yaml]( -https://github.com/pylast/pylast/blob/main/example_test_pylast.yaml) to -test_pylast.yaml and fill out the credentials, or set them as environment -variables like: +test data, and an API key and secret. Either copy +[example_test_pylast.yaml](https://github.com/pylast/pylast/blob/main/example_test_pylast.yaml) +to test_pylast.yaml and fill out the credentials, or set them as environment variables +like: ```sh export PYLAST_USERNAME=TODO_ENTER_YOURS_HERE From 353e32bd6b7eb9cf3cd7be2797d344255df74707 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 22 May 2024 22:26:42 +0300 Subject: [PATCH 48/55] Fix expected result in test --- tests/test_track.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_track.py b/tests/test_track.py index db9c69c..8d8a275 100755 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -140,7 +140,7 @@ class TestPyLastTrack(TestPyLastWithLastFm): # Assert found = False for track in similar: - if str(track.item) == "Madonna - Vogue": + if str(track.item) == "Cher - Strong Enough": found = True break assert found From 35b264bae471cfef1f13663d17ea4777c166240a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 22 May 2024 22:29:05 +0300 Subject: [PATCH 49/55] Refactor --- tests/test_track.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_track.py b/tests/test_track.py index 8d8a275..db04d15 100755 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -138,11 +138,7 @@ class TestPyLastTrack(TestPyLastWithLastFm): similar = track.get_similar() # Assert - found = False - for track in similar: - if str(track.item) == "Cher - Strong Enough": - found = True - break + found = any(str(track.item) == "Cher - Strong Enough" for track in similar) assert found def test_track_get_similar_limits(self) -> None: From 6f97f93dcc9b5f16c0da8a59c42adde9593ee61c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 22 May 2024 22:46:47 +0300 Subject: [PATCH 50/55] Update config --- .github/workflows/lint.yml | 2 ++ .pre-commit-config.yaml | 23 ++++++++++++++++++----- pyproject.toml | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 88c0c7c..d553e49 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,6 +4,7 @@ on: [push, pull_request, workflow_dispatch] env: FORCE_COLOR: 1 + PIP_DISABLE_PIP_VERSION_CHECK: 1 permissions: contents: read @@ -17,4 +18,5 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.x" + cache: pip - uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 89f4d05..3d54f50 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.4 + rev: v0.4.4 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix] + args: [--exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.3.0 + rev: 24.4.2 hooks: - id: black @@ -18,8 +18,9 @@ repos: additional_dependencies: [black] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: + - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict - id: check-json @@ -27,9 +28,21 @@ repos: - id: check-yaml - id: debug-statements - id: end-of-file-fixer + - id: forbid-submodules - id: trailing-whitespace exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.28.4 + hooks: + - id: check-github-workflows + - id: check-renovate + + - repo: https://github.com/rhysd/actionlint + rev: v1.7.0 + hooks: + - id: actionlint + - repo: https://github.com/tox-dev/pyproject-fmt rev: 1.7.0 hooks: @@ -37,7 +50,7 @@ repos: additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.16 + rev: v0.18 hooks: - id: validate-pyproject diff --git a/pyproject.toml b/pyproject.toml index 6857849..9887d1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,6 +71,7 @@ select = [ "LOG", # flake8-logging "PGH", # pygrep-hooks "RUF100", # unused noqa (yesqa) + "RUF022", # unsorted-dunder-all "UP", # pyupgrade "W", # pycodestyle warnings "YTT", # flake8-2020 From aceaa69c9afab935858820491169e251ee2e0b06 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:24:06 +0000 Subject: [PATCH 51/55] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.4.4 → v0.5.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.4...v0.5.0) - [github.com/asottile/blacken-docs: 1.16.0 → 1.18.0](https://github.com/asottile/blacken-docs/compare/1.16.0...1.18.0) - [github.com/python-jsonschema/check-jsonschema: 0.28.4 → 0.28.6](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.4...0.28.6) - [github.com/rhysd/actionlint: v1.7.0 → v1.7.1](https://github.com/rhysd/actionlint/compare/v1.7.0...v1.7.1) - [github.com/tox-dev/pyproject-fmt: 1.7.0 → 2.1.3](https://github.com/tox-dev/pyproject-fmt/compare/1.7.0...2.1.3) --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3d54f50..0895936 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.4.4 + rev: v0.5.0 hooks: - id: ruff args: [--exit-non-zero-on-fix] @@ -11,7 +11,7 @@ repos: - id: black - repo: https://github.com/asottile/blacken-docs - rev: 1.16.0 + rev: 1.18.0 hooks: - id: blacken-docs args: [--target-version=py38] @@ -33,18 +33,18 @@ repos: exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.28.4 + rev: 0.28.6 hooks: - id: check-github-workflows - id: check-renovate - repo: https://github.com/rhysd/actionlint - rev: v1.7.0 + rev: v1.7.1 hooks: - id: actionlint - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.7.0 + rev: 2.1.3 hooks: - id: pyproject-fmt additional_dependencies: [tox] From 184d0328a97f76572da2e89c0ba8d6c5b2d9eada Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:29:20 +0300 Subject: [PATCH 52/55] Configure pyproject-fmt to add Python 3.13 classifier --- .pre-commit-config.yaml | 1 - pyproject.toml | 63 +++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0895936..477419b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,6 @@ repos: rev: 2.1.3 hooks: - id: pyproject-fmt - additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject rev: v0.18 diff --git a/pyproject.toml b/pyproject.toml index 9887d1f..0586bb1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,9 +15,13 @@ keywords = [ "scrobble", "scrobbling", ] -license = {text = "Apache-2.0"} -maintainers = [{name = "Hugo van Kemenade"}] -authors = [{name = "Amr Hassan and Contributors", email = "amr.hassan@gmail.com"}] +license = { text = "Apache-2.0" } +maintainers = [ + { name = "Hugo van Kemenade" }, +] +authors = [ + { name = "Amr Hassan and Contributors", email = "amr.hassan@gmail.com" }, +] requires-python = ">=3.8" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -41,18 +45,16 @@ dynamic = [ dependencies = [ "httpx", ] -[project.optional-dependencies] -tests = [ +optional-dependencies.tests = [ "flaky", "pytest", "pytest-cov", "pytest-random-order", "pyyaml", ] -[project.urls] -Changelog = "https://github.com/pylast/pylast/releases" -Homepage = "https://github.com/pylast/pylast" -Source = "https://github.com/pylast/pylast" +urls.Changelog = "https://github.com/pylast/pylast/releases" +urls.Homepage = "https://github.com/pylast/pylast" +urls.Source = "https://github.com/pylast/pylast" [tool.hatch] version.source = "vcs" @@ -60,29 +62,36 @@ version.source = "vcs" [tool.hatch.version.raw-options] local_scheme = "no-local-version" -[tool.ruff.lint] -select = [ - "C4", # flake8-comprehensions - "E", # pycodestyle errors - "EM", # flake8-errmsg - "F", # pyflakes errors - "I", # isort - "ISC", # flake8-implicit-str-concat - "LOG", # flake8-logging - "PGH", # pygrep-hooks - "RUF100", # unused noqa (yesqa) +[tool.ruff] +fix = true + +lint.select = [ + "C4", # flake8-comprehensions + "E", # pycodestyle errors + "EM", # flake8-errmsg + "F", # pyflakes errors + "I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "PGH", # pygrep-hooks "RUF022", # unsorted-dunder-all - "UP", # pyupgrade - "W", # pycodestyle warnings - "YTT", # flake8-2020 + "RUF100", # unused noqa (yesqa) + "UP", # pyupgrade + "W", # pycodestyle warnings + "YTT", # flake8-2020 ] -extend-ignore = [ +lint.extend-ignore = [ "E203", # Whitespace before ':' "E221", # Multiple spaces before operator "E226", # Missing whitespace around arithmetic operator "E241", # Multiple spaces after ',' ] +lint.isort.known-first-party = [ + "pylast", +] +lint.isort.required-imports = [ + "from __future__ import annotations", +] -[tool.ruff.lint.isort] -known-first-party = ["pylast"] -required-imports = ["from __future__ import annotations"] +[tool.pyproject-fmt] +max_supported_python = "3.13" From c260d7b83fe3938a6163db2d3efd2cd734b060c2 Mon Sep 17 00:00:00 2001 From: Hirad Date: Sun, 7 Jul 2024 09:03:18 +0330 Subject: [PATCH 53/55] change libre.fm to music.lonestar.it --- src/pylast/__init__.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index 0396f5b..bd856bc 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -1,6 +1,6 @@ # # pylast - -# A Python interface to Last.fm and Libre.fm +# A Python interface to Last.fm and music.lonestar.it # # Copyright 2008-2010 Amr Hassan # Copyright 2013-2021 hugovk @@ -705,7 +705,7 @@ class LastFMNetwork(_Network): class LibreFMNetwork(_Network): """ - A preconfigured _Network object for Libre.fm + A preconfigured _Network object for music.lonestar.it api_key: a provided API_KEY api_secret: a provided API_SECRET @@ -727,27 +727,27 @@ class LibreFMNetwork(_Network): password_hash: str = "", ) -> None: super().__init__( - name="Libre.fm", - homepage="https://libre.fm", - ws_server=("libre.fm", "/2.0/"), + name="music.lonestar.it", + homepage="https://music.lonestar.it", + ws_server=("music.lonestar.it", "/2.0/"), api_key=api_key, api_secret=api_secret, session_key=session_key, username=username, password_hash=password_hash, domain_names={ - DOMAIN_ENGLISH: "libre.fm", - DOMAIN_GERMAN: "libre.fm", - DOMAIN_SPANISH: "libre.fm", - DOMAIN_FRENCH: "libre.fm", - DOMAIN_ITALIAN: "libre.fm", - DOMAIN_POLISH: "libre.fm", - DOMAIN_PORTUGUESE: "libre.fm", - DOMAIN_SWEDISH: "libre.fm", - DOMAIN_TURKISH: "libre.fm", - DOMAIN_RUSSIAN: "libre.fm", - DOMAIN_JAPANESE: "libre.fm", - DOMAIN_CHINESE: "libre.fm", + DOMAIN_ENGLISH: "music.lonestar.it", + DOMAIN_GERMAN: "music.lonestar.it", + DOMAIN_SPANISH: "music.lonestar.it", + DOMAIN_FRENCH: "music.lonestar.it", + DOMAIN_ITALIAN: "music.lonestar.it", + DOMAIN_POLISH: "music.lonestar.it", + DOMAIN_PORTUGUESE: "music.lonestar.it", + DOMAIN_SWEDISH: "music.lonestar.it", + DOMAIN_TURKISH: "music.lonestar.it", + DOMAIN_RUSSIAN: "music.lonestar.it", + DOMAIN_JAPANESE: "music.lonestar.it", + DOMAIN_CHINESE: "music.lonestar.it", }, urls={ "album": "artist/%(artist)s/album/%(album)s", From 6ae051157fbfd3daa91bcd54663804277cf054ec Mon Sep 17 00:00:00 2001 From: Hirad Date: Sun, 7 Jul 2024 09:16:25 +0330 Subject: [PATCH 54/55] Update README.md --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index de2987f..2b569d3 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,10 @@ Use the pydoc utility for help on usage or see [tests/](tests/) for examples. ## Installation -Install via pip: - -```sh -python3 -m pip install pylast -``` - Install latest development version: ```sh -python3 -m pip install -U git+https://github.com/pylast/pylast +python3 -m pip install -U git+https://git.hirad.it/Hirad/pylast ``` Or from requirements.txt: From 88bb8ea78919d4178e52a07eb45db9e13ed73b1b Mon Sep 17 00:00:00 2001 From: Hirad Date: Sun, 7 Jul 2024 09:16:54 +0330 Subject: [PATCH 55/55] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b569d3..c22fbec 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ python3 -m pip install -U git+https://git.hirad.it/Hirad/pylast Or from requirements.txt: ```txt --e https://github.com/pylast/pylast.git#egg=pylast +-e https://git.hirad.it/Hirad/pylast#egg=pylast ``` Note: