yutipy 1.1.0__tar.gz → 1.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yutipy might be problematic. Click here for more details.
- yutipy-1.2.1/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
- yutipy-1.2.1/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/.github/workflows/release.yml +0 -24
- {yutipy-1.1.0 → yutipy-1.2.1}/PKG-INFO +3 -2
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/api_reference.rst +6 -0
- yutipy-1.2.1/tests/test_kkbox.py +44 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/deezer.py +1 -1
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/itunes.py +1 -1
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/kkbox.py +54 -1
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/spotify.py +1 -1
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/PKG-INFO +3 -2
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/SOURCES.txt +2 -0
- yutipy-1.1.0/tests/test_kkbox.py +0 -28
- {yutipy-1.1.0 → yutipy-1.2.1}/.gitattributes +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/.github/FUNDING.yml +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/.github/workflows/pytest-unit-testing.yml +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/.gitignore +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/.readthedocs.yaml +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/LICENSE +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/MANIFEST.in +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/README.md +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/Makefile +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/_static/yutipy_header.png +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/_static/yutipy_logo.png +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/available_platforms.rst +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/conf.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/faq.rst +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/index.rst +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/installation.rst +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/make.bat +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/requirements.txt +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/docs/usage_examples.rst +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/pyproject.toml +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/requirements-dev.txt +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/requirements.txt +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/setup.cfg +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/__init__.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_deezer.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_itunes.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_models.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_musicyt.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_spotify.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_utils.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/__init__.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/exceptions.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/models.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/musicyt.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/utils/__init__.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/utils/cheap_utils.py +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/dependency_links.txt +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/requires.txt +0 -0
- {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: CheapNightbot
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce**
|
|
14
|
+
Steps to reproduce the behavior:
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '....'
|
|
17
|
+
3. Scroll down to '....'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
**Expected behavior**
|
|
21
|
+
A clear and concise description of what you expected to happen.
|
|
22
|
+
|
|
23
|
+
**Screenshots**
|
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
|
25
|
+
|
|
26
|
+
**Additional context**
|
|
27
|
+
Add any other context about the problem here.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: ''
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
12
|
+
|
|
13
|
+
**Describe the solution you'd like**
|
|
14
|
+
A clear and concise description of what you want to happen.
|
|
15
|
+
|
|
16
|
+
**Describe alternatives you've considered**
|
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
|
18
|
+
|
|
19
|
+
**Additional context**
|
|
20
|
+
Add any other context or screenshots about the feature request here.
|
|
@@ -94,27 +94,3 @@ jobs:
|
|
|
94
94
|
gh release upload
|
|
95
95
|
"$GITHUB_REF_NAME" dist/**
|
|
96
96
|
--repo "$GITHUB_REPOSITORY"
|
|
97
|
-
publish-to-testpypi:
|
|
98
|
-
name: Publish Python 🐍 distribution 📦 to TestPyPI
|
|
99
|
-
needs:
|
|
100
|
-
- build
|
|
101
|
-
runs-on: ubuntu-latest
|
|
102
|
-
|
|
103
|
-
environment:
|
|
104
|
-
name: testpypi-release
|
|
105
|
-
url: https://test.pypi.org/project/yutipy
|
|
106
|
-
|
|
107
|
-
permissions:
|
|
108
|
-
id-token: write # IMPORTANT: mandatory for trusted publishing
|
|
109
|
-
|
|
110
|
-
steps:
|
|
111
|
-
- name: Download all the dists
|
|
112
|
-
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
|
113
|
-
with:
|
|
114
|
-
name: python-package-distributions
|
|
115
|
-
path: dist/
|
|
116
|
-
- name: Publish distribution 📦 to TestPyPI
|
|
117
|
-
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
|
|
118
|
-
with:
|
|
119
|
-
repository-url: https://test.pypi.org/legacy/
|
|
120
|
-
verbose: true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: yutipy
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: A simple package for retrieving music information from various music platforms APIs.
|
|
5
5
|
Author: Cheap Nightbot
|
|
6
6
|
Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
@@ -54,6 +54,7 @@ Requires-Dist: requests==2.32.3
|
|
|
54
54
|
Requires-Dist: ytmusicapi==1.10.1
|
|
55
55
|
Provides-Extra: dev
|
|
56
56
|
Requires-Dist: pytest; extra == "dev"
|
|
57
|
+
Dynamic: license-file
|
|
57
58
|
|
|
58
59
|
<p align="center">
|
|
59
60
|
<img src="https://raw.githubusercontent.com/CheapNightbot/yutipy/main/docs/_static/yutipy_header.png" alt="yutipy" />
|
|
@@ -116,3 +116,9 @@ Exceptions
|
|
|
116
116
|
:inherited-members:
|
|
117
117
|
:noindex:
|
|
118
118
|
:exclude-members: add_note, args, with_traceback
|
|
119
|
+
|
|
120
|
+
.. autoclass:: yutipy.exceptions.KKBoxException
|
|
121
|
+
:members:
|
|
122
|
+
:inherited-members:
|
|
123
|
+
:noindex:
|
|
124
|
+
:exclude-members: add_note, args, with_traceback
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from pytest import raises
|
|
3
|
+
|
|
4
|
+
from yutipy.exceptions import KKBoxException, InvalidValueException
|
|
5
|
+
from yutipy.models import MusicInfo
|
|
6
|
+
from yutipy.kkbox import KKBox
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="module")
|
|
10
|
+
def kkbox():
|
|
11
|
+
try:
|
|
12
|
+
return KKBox()
|
|
13
|
+
except KKBoxException:
|
|
14
|
+
pytest.skip("KKBOX credentials not found")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_search(kkbox):
|
|
18
|
+
artist = "Porter Robinson"
|
|
19
|
+
song = "Shelter"
|
|
20
|
+
result = kkbox.search(artist, song)
|
|
21
|
+
assert result is not None
|
|
22
|
+
assert isinstance(result, MusicInfo)
|
|
23
|
+
assert result.title == song
|
|
24
|
+
assert artist in result.artists
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_get_html_widget(kkbox):
|
|
28
|
+
html_widget = kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="song")
|
|
29
|
+
assert html_widget is not None
|
|
30
|
+
assert isinstance(html_widget, str)
|
|
31
|
+
|
|
32
|
+
with raises(InvalidValueException):
|
|
33
|
+
kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="track")
|
|
34
|
+
|
|
35
|
+
with raises(InvalidValueException):
|
|
36
|
+
kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="song", territory="US")
|
|
37
|
+
|
|
38
|
+
with raises(InvalidValueException):
|
|
39
|
+
kkbox.get_html_widget(id="8rceGrek59bDS0HmQH", content_type="song", widget_lang="JP")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_close_session(kkbox):
|
|
43
|
+
kkbox.close_session()
|
|
44
|
+
assert kkbox.is_session_closed
|
|
@@ -28,7 +28,7 @@ class Deezer:
|
|
|
28
28
|
|
|
29
29
|
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
|
|
30
30
|
"""Exits the runtime context related to this object."""
|
|
31
|
-
self.
|
|
31
|
+
self.close_session()
|
|
32
32
|
|
|
33
33
|
def close_session(self) -> None:
|
|
34
34
|
"""Closes the current session."""
|
|
@@ -29,7 +29,7 @@ class Itunes:
|
|
|
29
29
|
|
|
30
30
|
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
|
|
31
31
|
"""Exits the runtime context related to this object."""
|
|
32
|
-
self.
|
|
32
|
+
self.close_session()
|
|
33
33
|
|
|
34
34
|
def close_session(self) -> None:
|
|
35
35
|
"""Closes the current session."""
|
|
@@ -56,6 +56,7 @@ class KKBox:
|
|
|
56
56
|
self.__header, self.__expires_in = self.__authenticate()
|
|
57
57
|
self.__start_time = time.time()
|
|
58
58
|
self._is_session_closed = False
|
|
59
|
+
self.valid_territories = ["HK", "JP", "MY", "SG", "TW"]
|
|
59
60
|
|
|
60
61
|
def __enter__(self):
|
|
61
62
|
"""Enters the runtime context related to this object."""
|
|
@@ -63,7 +64,7 @@ class KKBox:
|
|
|
63
64
|
|
|
64
65
|
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
65
66
|
"""Exits the runtime context related to this object."""
|
|
66
|
-
self.
|
|
67
|
+
self.close_session()
|
|
67
68
|
|
|
68
69
|
def close_session(self) -> None:
|
|
69
70
|
"""Closes the current session."""
|
|
@@ -174,6 +175,58 @@ class KKBox:
|
|
|
174
175
|
|
|
175
176
|
return self._find_music_info(artist, song, response.json())
|
|
176
177
|
|
|
178
|
+
def get_html_widget(
|
|
179
|
+
self,
|
|
180
|
+
id: str,
|
|
181
|
+
content_type: str,
|
|
182
|
+
territory: str = "TW",
|
|
183
|
+
widget_lang: str = "EN",
|
|
184
|
+
autoplay: bool = False,
|
|
185
|
+
loop: bool = False,
|
|
186
|
+
) -> str:
|
|
187
|
+
"""
|
|
188
|
+
Return KKBOX HTML widget for "Playlist", "Album" or "Song". It does not return actual HTML code,
|
|
189
|
+
the URL returned can be used in an HTML ``iframe`` with the help of ``src`` attribute.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
id : str
|
|
194
|
+
``ID`` of playlist, album or track.
|
|
195
|
+
content_type : str
|
|
196
|
+
Content type can be ``playlist``, ``album`` or ``song``.
|
|
197
|
+
territory : str, optional
|
|
198
|
+
Territory code, i.e. "TW", "HK", "JP", "SG", "MY", by default "TW"
|
|
199
|
+
widget_lang : str, optional
|
|
200
|
+
The display language of the widget. Can be "TC", "SC", "JA", "EN", "MS", by default "EN"
|
|
201
|
+
autoplay : bool, optional
|
|
202
|
+
Whether to start playing music automatically in widget, by default False
|
|
203
|
+
loop : bool, optional
|
|
204
|
+
Repeat/loop song(s), by default False
|
|
205
|
+
|
|
206
|
+
Returns
|
|
207
|
+
-------
|
|
208
|
+
str
|
|
209
|
+
KKBOX HTML widget URL.
|
|
210
|
+
"""
|
|
211
|
+
valid_content_types = ["playlist", "album", "song"]
|
|
212
|
+
valid_widget_langs = ["TC", "SC", "JA", "EN", "MS"]
|
|
213
|
+
if content_type not in valid_content_types:
|
|
214
|
+
raise InvalidValueException(
|
|
215
|
+
f"`content_type` must be one of these: {valid_content_types} !"
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if territory not in self.valid_territories:
|
|
219
|
+
raise InvalidValueException(
|
|
220
|
+
f"`territory` must be one of these: {self.valid_territories} !"
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if widget_lang not in valid_widget_langs:
|
|
224
|
+
raise InvalidValueException(
|
|
225
|
+
f"`widget_lang` must be one of these: {valid_widget_langs} !"
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
return f"https://widget.kkbox.com/v1/?id={id}&type={content_type}&terr={territory}&lang={widget_lang}&autoplay={autoplay}&loop={loop}"
|
|
229
|
+
|
|
177
230
|
def _find_music_info(
|
|
178
231
|
self, artist: str, song: str, response_json: dict
|
|
179
232
|
) -> Optional[MusicInfo]:
|
|
@@ -69,7 +69,7 @@ class Spotify:
|
|
|
69
69
|
|
|
70
70
|
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
71
71
|
"""Exits the runtime context related to this object."""
|
|
72
|
-
self.
|
|
72
|
+
self.close_session()
|
|
73
73
|
|
|
74
74
|
def close_session(self) -> None:
|
|
75
75
|
"""Closes the current session."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: yutipy
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: A simple package for retrieving music information from various music platforms APIs.
|
|
5
5
|
Author: Cheap Nightbot
|
|
6
6
|
Author-email: Cheap Nightbot <hi@cheapnightbot.slmail.me>
|
|
@@ -54,6 +54,7 @@ Requires-Dist: requests==2.32.3
|
|
|
54
54
|
Requires-Dist: ytmusicapi==1.10.1
|
|
55
55
|
Provides-Extra: dev
|
|
56
56
|
Requires-Dist: pytest; extra == "dev"
|
|
57
|
+
Dynamic: license-file
|
|
57
58
|
|
|
58
59
|
<p align="center">
|
|
59
60
|
<img src="https://raw.githubusercontent.com/CheapNightbot/yutipy/main/docs/_static/yutipy_header.png" alt="yutipy" />
|
yutipy-1.1.0/tests/test_kkbox.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from yutipy.exceptions import KKBoxException
|
|
4
|
-
from yutipy.models import MusicInfo
|
|
5
|
-
from yutipy.kkbox import KKBox
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@pytest.fixture(scope="module")
|
|
9
|
-
def kkbox():
|
|
10
|
-
try:
|
|
11
|
-
return KKBox()
|
|
12
|
-
except KKBoxException:
|
|
13
|
-
pytest.skip("KKBOX credentials not found")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def test_search(kkbox):
|
|
17
|
-
artist = "Porter Robinson"
|
|
18
|
-
song = "Shelter"
|
|
19
|
-
result = kkbox.search(artist, song)
|
|
20
|
-
assert result is not None
|
|
21
|
-
assert isinstance(result, MusicInfo)
|
|
22
|
-
assert result.title == song
|
|
23
|
-
assert artist in result.artists
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def test_close_session(kkbox):
|
|
27
|
-
kkbox.close_session()
|
|
28
|
-
assert kkbox.is_session_closed
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|