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.

Files changed (52) hide show
  1. yutipy-1.2.1/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  2. yutipy-1.2.1/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  3. {yutipy-1.1.0 → yutipy-1.2.1}/.github/workflows/release.yml +0 -24
  4. {yutipy-1.1.0 → yutipy-1.2.1}/PKG-INFO +3 -2
  5. {yutipy-1.1.0 → yutipy-1.2.1}/docs/api_reference.rst +6 -0
  6. yutipy-1.2.1/tests/test_kkbox.py +44 -0
  7. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/deezer.py +1 -1
  8. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/itunes.py +1 -1
  9. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/kkbox.py +54 -1
  10. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/spotify.py +1 -1
  11. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/PKG-INFO +3 -2
  12. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/SOURCES.txt +2 -0
  13. yutipy-1.1.0/tests/test_kkbox.py +0 -28
  14. {yutipy-1.1.0 → yutipy-1.2.1}/.gitattributes +0 -0
  15. {yutipy-1.1.0 → yutipy-1.2.1}/.github/FUNDING.yml +0 -0
  16. {yutipy-1.1.0 → yutipy-1.2.1}/.github/workflows/pytest-unit-testing.yml +0 -0
  17. {yutipy-1.1.0 → yutipy-1.2.1}/.gitignore +0 -0
  18. {yutipy-1.1.0 → yutipy-1.2.1}/.readthedocs.yaml +0 -0
  19. {yutipy-1.1.0 → yutipy-1.2.1}/LICENSE +0 -0
  20. {yutipy-1.1.0 → yutipy-1.2.1}/MANIFEST.in +0 -0
  21. {yutipy-1.1.0 → yutipy-1.2.1}/README.md +0 -0
  22. {yutipy-1.1.0 → yutipy-1.2.1}/docs/Makefile +0 -0
  23. {yutipy-1.1.0 → yutipy-1.2.1}/docs/_static/yutipy_header.png +0 -0
  24. {yutipy-1.1.0 → yutipy-1.2.1}/docs/_static/yutipy_logo.png +0 -0
  25. {yutipy-1.1.0 → yutipy-1.2.1}/docs/available_platforms.rst +0 -0
  26. {yutipy-1.1.0 → yutipy-1.2.1}/docs/conf.py +0 -0
  27. {yutipy-1.1.0 → yutipy-1.2.1}/docs/faq.rst +0 -0
  28. {yutipy-1.1.0 → yutipy-1.2.1}/docs/index.rst +0 -0
  29. {yutipy-1.1.0 → yutipy-1.2.1}/docs/installation.rst +0 -0
  30. {yutipy-1.1.0 → yutipy-1.2.1}/docs/make.bat +0 -0
  31. {yutipy-1.1.0 → yutipy-1.2.1}/docs/requirements.txt +0 -0
  32. {yutipy-1.1.0 → yutipy-1.2.1}/docs/usage_examples.rst +0 -0
  33. {yutipy-1.1.0 → yutipy-1.2.1}/pyproject.toml +0 -0
  34. {yutipy-1.1.0 → yutipy-1.2.1}/requirements-dev.txt +0 -0
  35. {yutipy-1.1.0 → yutipy-1.2.1}/requirements.txt +0 -0
  36. {yutipy-1.1.0 → yutipy-1.2.1}/setup.cfg +0 -0
  37. {yutipy-1.1.0 → yutipy-1.2.1}/tests/__init__.py +0 -0
  38. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_deezer.py +0 -0
  39. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_itunes.py +0 -0
  40. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_models.py +0 -0
  41. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_musicyt.py +0 -0
  42. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_spotify.py +0 -0
  43. {yutipy-1.1.0 → yutipy-1.2.1}/tests/test_utils.py +0 -0
  44. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/__init__.py +0 -0
  45. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/exceptions.py +0 -0
  46. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/models.py +0 -0
  47. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/musicyt.py +0 -0
  48. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/utils/__init__.py +0 -0
  49. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy/utils/cheap_utils.py +0 -0
  50. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/dependency_links.txt +0 -0
  51. {yutipy-1.1.0 → yutipy-1.2.1}/yutipy.egg-info/requires.txt +0 -0
  52. {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.2
1
+ Metadata-Version: 2.4
2
2
  Name: yutipy
3
- Version: 1.1.0
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._close_session()
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._close_session()
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._close_session()
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._close_session()
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.2
1
+ Metadata-Version: 2.4
2
2
  Name: yutipy
3
- Version: 1.1.0
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" />
@@ -8,6 +8,8 @@ pyproject.toml
8
8
  requirements-dev.txt
9
9
  requirements.txt
10
10
  .github/FUNDING.yml
11
+ .github/ISSUE_TEMPLATE/bug_report.md
12
+ .github/ISSUE_TEMPLATE/feature_request.md
11
13
  .github/workflows/pytest-unit-testing.yml
12
14
  .github/workflows/release.yml
13
15
  docs/Makefile
@@ -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