yutipy 1.4.0__py3-none-any.whl → 1.4.2__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from .deezer import Deezer
2
2
  from .itunes import Itunes
3
+ from .kkbox import KKBox
3
4
  from .models import MusicInfo
4
5
  from .musicyt import MusicYT
5
6
  from .spotify import Spotify
@@ -8,6 +9,7 @@ from .yutipy_music import YutipyMusic
8
9
  __all__ = [
9
10
  "Deezer",
10
11
  "Itunes",
12
+ "KKBox",
11
13
  "MusicInfo",
12
14
  "MusicYT",
13
15
  "Spotify",
yutipy/itunes.py CHANGED
@@ -1,17 +1,21 @@
1
1
  from datetime import datetime
2
2
  from pprint import pprint
3
- from typing import Optional, Dict
3
+ from typing import Dict, Optional
4
4
 
5
5
  import requests
6
6
 
7
7
  from yutipy.exceptions import (
8
8
  InvalidResponseException,
9
9
  InvalidValueException,
10
- NetworkException,
11
10
  ItunesException,
11
+ NetworkException,
12
12
  )
13
13
  from yutipy.models import MusicInfo
14
- from yutipy.utils.cheap_utils import are_strings_similar, is_valid_string
14
+ from yutipy.utils.cheap_utils import (
15
+ are_strings_similar,
16
+ guess_album_type,
17
+ is_valid_string,
18
+ )
15
19
 
16
20
 
17
21
  class Itunes:
@@ -180,7 +184,13 @@ class Itunes:
180
184
  album_title, album_type = result["collectionName"].split("-")
181
185
  return album_title.strip(), album_type.strip()
182
186
  except ValueError:
183
- return result["collectionName"], result["wrapperType"]
187
+ guess = guess_album_type(result.get("trackCount", 1))
188
+ guessed_right = are_strings_similar(
189
+ result.get("wrapperType", "x"), guess, use_translation=False
190
+ )
191
+ return result["collectionName"], (
192
+ result["wrapperType"] if guessed_right else guess
193
+ )
184
194
 
185
195
  def _format_release_date(self, release_date: str) -> str:
186
196
  """
yutipy/spotify.py CHANGED
@@ -17,6 +17,7 @@ from yutipy.exceptions import (
17
17
  from yutipy.models import MusicInfo
18
18
  from yutipy.utils.cheap_utils import (
19
19
  are_strings_similar,
20
+ guess_album_type,
20
21
  is_valid_string,
21
22
  separate_artists,
22
23
  )
@@ -175,6 +176,7 @@ class Spotify:
175
176
  self.normalize_non_english = normalize_non_english
176
177
 
177
178
  music_info = None
179
+ artist_ids = None
178
180
  queries = [
179
181
  f"?q=artist:{artist} track:{song}&type=track&limit={limit}",
180
182
  f"?q=artist:{artist} album:{song}&type=album&limit={limit}",
@@ -199,7 +201,7 @@ class Spotify:
199
201
  if response.status_code != 200:
200
202
  raise SpotifyException(f"Failed to search for music: {response.json()}")
201
203
 
202
- artist_ids = self._get_artists_ids(artist)
204
+ artist_ids = artist_ids if artist_ids else self._get_artists_ids(artist)
203
205
  music_info = self._find_music_info(
204
206
  artist, song, response.json(), artist_ids
205
207
  )
@@ -449,10 +451,15 @@ class Spotify:
449
451
  ]
450
452
 
451
453
  if matching_artists:
454
+ guess = guess_album_type(album.get("total_tracks", 1))
455
+ guessed_right = are_strings_similar(
456
+ album.get("album_type", "x"), guess, use_translation=False
457
+ )
458
+
452
459
  return MusicInfo(
453
460
  album_art=album["images"][0]["url"],
454
461
  album_title=album["name"],
455
- album_type=album["album_type"],
462
+ album_type=album.get("album_type") if guessed_right else guess,
456
463
  artists=", ".join(artists_name),
457
464
  genre=None,
458
465
  id=album["id"],
@@ -461,7 +468,7 @@ class Spotify:
461
468
  release_date=album["release_date"],
462
469
  tempo=None,
463
470
  title=album["name"],
464
- type="album",
471
+ type=album.get("type"),
465
472
  upc=None,
466
473
  url=album["external_urls"]["spotify"],
467
474
  )
yutipy/utils/__init__.py CHANGED
@@ -1,6 +1,12 @@
1
- from .cheap_utils import are_strings_similar, is_valid_string, separate_artists
1
+ from .cheap_utils import (
2
+ guess_album_type,
3
+ are_strings_similar,
4
+ is_valid_string,
5
+ separate_artists,
6
+ )
2
7
 
3
8
  __all__ = [
9
+ "guess_album_type",
4
10
  "are_strings_similar",
5
11
  "is_valid_string",
6
12
  "separate_artists",
@@ -1,7 +1,10 @@
1
+ import pykakasi
1
2
  import requests
2
3
  from rapidfuzz import fuzz
3
4
  from rapidfuzz.utils import default_process
4
5
 
6
+ kakasi = pykakasi.kakasi()
7
+
5
8
 
6
9
  def translate_text(
7
10
  text: str,
@@ -72,18 +75,29 @@ def are_strings_similar(
72
75
  Returns:
73
76
  bool: True if the strings are similar, otherwise False.
74
77
  """
78
+
75
79
  if use_translation:
76
- str1 = (
80
+ translated_str1 = (
77
81
  translate_text(str1, session=translation_session)["destination-text"]
78
82
  if translation_session
79
83
  else translate_text(str1)["destination-text"]
80
84
  )
81
- str2 = (
85
+ translated_str2 = (
82
86
  translate_text(str2, session=translation_session)["destination-text"]
83
87
  if translation_session
84
88
  else translate_text(str2)["destination-text"]
85
89
  )
86
90
 
91
+ similarity_score = fuzz.WRatio(
92
+ translated_str1, translated_str2, processor=default_process
93
+ )
94
+ if similarity_score > threshold:
95
+ return True
96
+
97
+ # Use transliterated strings for comparison
98
+ str1 = "".join(item["hepburn"] for item in kakasi.convert(str1)) or str1
99
+ str2 = "".join(item["hepburn"] for item in kakasi.convert(str2)) or str2
100
+
87
101
  similarity_score = fuzz.WRatio(str1, str2, processor=default_process)
88
102
  return similarity_score > threshold
89
103
 
@@ -117,5 +131,15 @@ def is_valid_string(string: str) -> bool:
117
131
  return bool(string and (string.isalnum() or not string.isspace()))
118
132
 
119
133
 
134
+ def guess_album_type(total_tracks: int):
135
+ """Just guessing the album type (i.e. single, ep or album) by total track counts."""
136
+ if total_tracks == 1:
137
+ return "single"
138
+ if 3 <= total_tracks <= 5:
139
+ return "ep"
140
+ if total_tracks >= 7:
141
+ return "album"
142
+
143
+
120
144
  if __name__ == "__main__":
121
145
  separate_artists("Artist A ft. Artist B")
yutipy/yutipy_music.py CHANGED
@@ -98,6 +98,20 @@ class YutipyMusic:
98
98
 
99
99
  self.normalize_non_english = normalize_non_english
100
100
 
101
+ attributes = [
102
+ "album_title",
103
+ "album_type",
104
+ "artists",
105
+ "genre",
106
+ "isrc",
107
+ "lyrics",
108
+ "release_date",
109
+ "tempo",
110
+ "title",
111
+ "type",
112
+ "upc",
113
+ ]
114
+
101
115
  with ThreadPoolExecutor() as executor:
102
116
  futures = {
103
117
  executor.submit(
@@ -113,14 +127,16 @@ class YutipyMusic:
113
127
  for future in as_completed(futures):
114
128
  service_name = futures[future]
115
129
  result = future.result()
116
- self._combine_results(result, service_name)
130
+ self._combine_results(result, service_name, attributes)
117
131
 
118
132
  if len(self.music_info.url) == 0:
119
133
  return None
120
134
 
121
135
  return self.music_info
122
136
 
123
- def _combine_results(self, result: Optional[MusicInfo], service_name: str) -> None:
137
+ def _combine_results(
138
+ self, result: Optional[MusicInfo], service_name: str, attributes: list
139
+ ) -> None:
124
140
  """
125
141
  Combines the results from different services.
126
142
 
@@ -134,25 +150,16 @@ class YutipyMusic:
134
150
  if not result:
135
151
  return
136
152
 
137
- attributes = [
138
- "album_title",
139
- "album_type",
140
- "artists",
141
- "genre",
142
- "isrc",
143
- "lyrics",
144
- "release_date",
145
- "tempo",
146
- "title",
147
- "type",
148
- "upc",
149
- ]
150
-
151
153
  for attr in attributes:
152
154
  if getattr(result, attr) and (
153
- not getattr(self.music_info, attr) or service_name == "spotify"
155
+ not getattr(self.music_info, attr)
156
+ or (attr in ["genre", "album_type"] and service_name == "itunes")
154
157
  ):
155
- setattr(self.music_info, attr, getattr(result, attr))
158
+ setattr(
159
+ self.music_info,
160
+ attr,
161
+ getattr(result, attributes.pop(attributes.index(attr))),
162
+ )
156
163
 
157
164
  if result.album_art:
158
165
  current_priority = self.album_art_priority.index(service_name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yutipy
3
- Version: 1.4.0
3
+ Version: 1.4.2
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>
@@ -33,7 +33,7 @@ Project-URL: Repository, https://github.com/CheapNightbot/yutipy.git
33
33
  Project-URL: Issues, https://github.com/CheapNightbot/yutipy/issues
34
34
  Project-URL: Changelog, https://github.com/CheapNightbot/yutipy/blob/master/CHANGELOG.md
35
35
  Project-URL: funding, https://ko-fi.com/cheapnightbot
36
- Keywords: music,API,Deezer,iTunes,Spotify,YouTube Music,search,retrieve,information,yutify
36
+ Keywords: music,API,Deezer,iTunes,Spotify,YouTube Music,search,retrieve,information,yutify,KKBox
37
37
  Classifier: Development Status :: 4 - Beta
38
38
  Classifier: Intended Audience :: Developers
39
39
  Classifier: Topic :: Software Development :: Libraries
@@ -0,0 +1,17 @@
1
+ yutipy/__init__.py,sha256=ucXbhRgNpLo-G0TeDGCaKyCK9Ftc13hUqB8POWdUY1c,327
2
+ yutipy/deezer.py,sha256=cTQpnOgS81mUw_EJ0b2Z1r9CG9ircHCxl9vL-oAJ9Lg,9622
3
+ yutipy/exceptions.py,sha256=4L0Oe1PwFP34LoFTy-Fruipk7uB-JkaackRmkjlaZJU,1138
4
+ yutipy/itunes.py,sha256=SZOCShlIyutIWQ2KI9WLqxc4gN4Cu2gilqxYwuXugUU,7059
5
+ yutipy/kkbox.py,sha256=V-A7nFa1oNrTBOEu7DFzMHAHFZ5cPz55GInEuYfTSfg,13466
6
+ yutipy/models.py,sha256=si_qgaApAYDfSyE8cl_Yg4IfWOtxk1I5JCT8bZsmV4U,1931
7
+ yutipy/musicyt.py,sha256=igqz99bJYGtUGyZAmEJoQbdGIF-1YFmeaV5HmlhwqkA,8441
8
+ yutipy/spotify.py,sha256=P-MCOny1ZXK75_jdQKRI_jgUrK7B9xbBFOvRu6NOjxk,15620
9
+ yutipy/yutipy_music.py,sha256=I4581MvcTTclSwVtAfMEsOujxmhZzqKyG7eX8zuEsEY,6424
10
+ yutipy/utils/__init__.py,sha256=o6lk01FHwhFmNHV0HjGG0qe2azTaQT_eviiLgNV5fHw,232
11
+ yutipy/utils/cheap_utils.py,sha256=ttNu566ybTQ3BzQ2trBgpvpNthB6Da-KnkBbFiK3pw4,5282
12
+ yutipy/utils/logger.py,sha256=2_b2FlDwUVpdPdqiwweR8Xr2tZOq0qGUGcekC5lXq2M,130
13
+ yutipy-1.4.2.dist-info/licenses/LICENSE,sha256=_89JsS2QnBG8tAb5-VWbJDj_uJ002zPJAYBJJdh3DPY,1071
14
+ yutipy-1.4.2.dist-info/METADATA,sha256=nxBwtRJFWpM7gsgH9-RZIP239hna-PirfWJ2WIBxXB4,6495
15
+ yutipy-1.4.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
16
+ yutipy-1.4.2.dist-info/top_level.txt,sha256=t2A5V2_mUcfnHkbCy6tAQlb3909jDYU5GQgXtA4756I,7
17
+ yutipy-1.4.2.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- yutipy/__init__.py,sha256=UIymi9iT8s1nGuqcQcFudZYNsJDR4RzXe6LUaN9V8l0,289
2
- yutipy/deezer.py,sha256=cTQpnOgS81mUw_EJ0b2Z1r9CG9ircHCxl9vL-oAJ9Lg,9622
3
- yutipy/exceptions.py,sha256=4L0Oe1PwFP34LoFTy-Fruipk7uB-JkaackRmkjlaZJU,1138
4
- yutipy/itunes.py,sha256=9VOcIfjezj8WAVpsne9bbBPoIUbn0GO0UWrCrXzbrE4,6758
5
- yutipy/kkbox.py,sha256=V-A7nFa1oNrTBOEu7DFzMHAHFZ5cPz55GInEuYfTSfg,13466
6
- yutipy/models.py,sha256=si_qgaApAYDfSyE8cl_Yg4IfWOtxk1I5JCT8bZsmV4U,1931
7
- yutipy/musicyt.py,sha256=igqz99bJYGtUGyZAmEJoQbdGIF-1YFmeaV5HmlhwqkA,8441
8
- yutipy/spotify.py,sha256=IrtCtay8UWh8zsa7d1JKrDUuZLa-PDwh8zb3K629tLo,15294
9
- yutipy/yutipy_music.py,sha256=zwnJWKy6Kdh-ewz2jHzRSo4ntKoigJa7MMKMzwgcr7A,6214
10
- yutipy/utils/__init__.py,sha256=7UFcFZ7fBtNXOTngjnRD3MeobT3x5UT2Gag94TXVgLk,169
11
- yutipy/utils/cheap_utils.py,sha256=TMas4QwOXxdIZ0t3bxxvLAQdeFCGZyzuxicbpzWJ0a0,4542
12
- yutipy/utils/logger.py,sha256=2_b2FlDwUVpdPdqiwweR8Xr2tZOq0qGUGcekC5lXq2M,130
13
- yutipy-1.4.0.dist-info/licenses/LICENSE,sha256=_89JsS2QnBG8tAb5-VWbJDj_uJ002zPJAYBJJdh3DPY,1071
14
- yutipy-1.4.0.dist-info/METADATA,sha256=U9Zl_5_k8p7xkzDGlfHGEIJuh1vR_HsmHqDIC8O4qTo,6489
15
- yutipy-1.4.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
16
- yutipy-1.4.0.dist-info/top_level.txt,sha256=t2A5V2_mUcfnHkbCy6tAQlb3909jDYU5GQgXtA4756I,7
17
- yutipy-1.4.0.dist-info/RECORD,,
File without changes