ASMRManager 2.3.2__tar.gz → 2.4.0__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.
Files changed (70) hide show
  1. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/PKG-INFO +1 -1
  2. asmrmanager-2.4.0/asmrmanager/_version.py +1 -0
  3. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/dl.py +20 -0
  4. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/asmrapi.py +29 -1
  5. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/downloader.py +24 -8
  6. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/interface.py +13 -7
  7. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/pyproject.toml +1 -1
  8. asmrmanager-2.3.2/asmrmanager/_version.py +0 -1
  9. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/LICENSE +0 -0
  10. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/README.md +0 -0
  11. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/__init__.py +0 -0
  12. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/__main__.py +0 -0
  13. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/core.py +0 -0
  14. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/file.py +0 -0
  15. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/hold.py +0 -0
  16. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/info.py +0 -0
  17. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/main.py +0 -0
  18. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/pl.py +0 -0
  19. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/play.py +0 -0
  20. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/query.py +0 -0
  21. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/review.py +0 -0
  22. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/sql.py +0 -0
  23. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/utils.py +0 -0
  24. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/view.py +0 -0
  25. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/cli/which.py +0 -0
  26. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/__init__.py +0 -0
  27. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/browse_params.py +0 -0
  28. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/download_params.py +0 -0
  29. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/fileconverter.py +0 -0
  30. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/output.py +0 -0
  31. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/parse_filter.py +0 -0
  32. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/rj_parse.py +0 -0
  33. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/select.py +0 -0
  34. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/types.py +0 -0
  35. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/common/vtt2lrc.py +0 -0
  36. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/config.py +0 -0
  37. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/__init__.py +0 -0
  38. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/database.py +0 -0
  39. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/engine.py +0 -0
  40. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/manage.py +0 -0
  41. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/orm_type.py +0 -0
  42. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/q_func.py +0 -0
  43. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/utils/__init__.py +0 -0
  44. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/utils/add2db.py +0 -0
  45. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/database/utils/uuid_sqlite.py +0 -0
  46. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/__init__.py +0 -0
  47. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/appdirs_.py +0 -0
  48. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/exceptions.py +0 -0
  49. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/file_zipper.py +0 -0
  50. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/manager.py +0 -0
  51. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/config.example.toml +0 -0
  52. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/circle_name.sql +0 -0
  53. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/score.sql +0 -0
  54. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/search.sql +0 -0
  55. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/tags.sql +0 -0
  56. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/test.sql +0 -0
  57. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/resources/sqls.example/vas.sql +0 -0
  58. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/filemanager/utils.py +0 -0
  59. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/logger/__init__.py +0 -0
  60. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/__init__.py +0 -0
  61. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/lrcparse.py +0 -0
  62. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/main.css +0 -0
  63. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/main.py +0 -0
  64. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/player/base.py +0 -0
  65. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/player/mpdplayer.py +0 -0
  66. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/lrcplayer/player/pygameplayer.py +0 -0
  67. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/__init__.py +0 -0
  68. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/playlist.py +0 -0
  69. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/utils/IDMHelper.py +0 -0
  70. {asmrmanager-2.3.2 → asmrmanager-2.4.0}/asmrmanager/spider/utils/aria2_downloader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ASMRManager
3
- Version: 2.3.2
3
+ Version: 2.4.0
4
4
  Summary: download, manage and play the voices on asmr.one
5
5
  Keywords: asmr,downloader,music,player,manager,cli,tui,commandline,terminal
6
6
  Author-Email: SLQY <sqiyel@gmail.com>
@@ -0,0 +1 @@
1
+ __version__ = "2.4.0"
@@ -243,7 +243,27 @@ def search(
243
243
  db.commit()
244
244
 
245
245
 
246
+ @click.command()
247
+ @download_param_options
248
+ def rec(download_params: DownloadParams):
249
+ """download recommendations of the current account"""
250
+ spider, db = create_downloader_and_database(download_params)
251
+ spider.run(spider.get_recommendations())
252
+ db.commit()
253
+
254
+
255
+ @click.command()
256
+ @download_param_options
257
+ def popular(download_params: DownloadParams):
258
+ """download current popular ASMRs"""
259
+ spider, db = create_downloader_and_database(download_params)
260
+ spider.run(spider.get_popular())
261
+ db.commit()
262
+
263
+
246
264
  dl.add_command(get)
247
265
  dl.add_command(check)
248
266
  dl.add_command(search)
249
267
  dl.add_command(update)
268
+ dl.add_command(rec)
269
+ dl.add_command(popular)
@@ -45,6 +45,7 @@ class ASMRAPI:
45
45
  self.password = password
46
46
  self.proxy = proxy
47
47
  self.limit = limit
48
+ self.recommender_uuid: str = ""
48
49
 
49
50
  async def login(self) -> None:
50
51
  try:
@@ -54,12 +55,14 @@ class ASMRAPI:
54
55
  headers=self.headers,
55
56
  proxy=self.proxy,
56
57
  ) as resp:
57
- token = (await resp.json())["token"]
58
+ resp = await resp.json()
59
+ token = resp["token"]
58
60
  self.headers.update(
59
61
  {
60
62
  "Authorization": f"Bearer {token}",
61
63
  }
62
64
  )
65
+ self.recommender_uuid = resp["user"]["recommenderUuid"]
63
66
  except ClientConnectorError as err:
64
67
  logger.error(f"Login failed, {err}")
65
68
 
@@ -143,6 +146,31 @@ class ASMRAPI:
143
146
  async def _delete_playlist(self, pl_id: str):
144
147
  return await self.post("playlist/delete-playlist", data={"id": pl_id})
145
148
 
149
+ async def get_recommendations(self, page: int = 1):
150
+ return await self.post(
151
+ "recommender/recommend-for-user",
152
+ data={
153
+ "keyword": " ",
154
+ "recommenderUuid": self.recommender_uuid,
155
+ "page": page,
156
+ "subtitle": 0,
157
+ "localSubtitledWorks": [],
158
+ "withPlaylistStatus": [],
159
+ },
160
+ )
161
+
162
+ async def get_popular(self, page: int = 1):
163
+ return await self.post(
164
+ "recommender/popular",
165
+ data={
166
+ "keyword": " ",
167
+ "page": page,
168
+ "subtitle": 0,
169
+ "localSubtitledWorks": [],
170
+ "withPlaylistStatus": [],
171
+ },
172
+ )
173
+
146
174
  async def get_search_result(
147
175
  self, content: str, params: dict
148
176
  ) -> Dict[str, Any]:
@@ -131,13 +131,11 @@ class ASMRDownloadAPI(ASMRAPI):
131
131
  self.create_info_file(voice_info, voice_path=voice_path)
132
132
 
133
133
  tracks = await self.get_voice_tracks(voice_id)
134
- if isinstance(tracks, dict):
135
- if error_info := tracks.get("error"):
136
- logger.error(f"RJ{voice_id} not found, {error_info}")
137
- return
138
- else:
139
- logger.error("Unexpected track type: dict")
140
- return
134
+ if tracks is None:
135
+ logger.error(
136
+ f"Remote id {voice_id} error: failed to get tracks, skip download"
137
+ )
138
+ return
141
139
 
142
140
  file_list = self.get_file_list(
143
141
  tracks,
@@ -187,7 +185,25 @@ class ASMRDownloadAPI(ASMRAPI):
187
185
  return voice_info
188
186
 
189
187
  async def get_voice_tracks(self, voice_id: RemoteSourceID):
190
- return await self.get(f"tracks/{voice_id}")
188
+ tracks: list[dict] | dict = await self.get(
189
+ f"tracks/{voice_id}", params={"v": 1}
190
+ )
191
+ if isinstance(tracks, dict):
192
+ if error_info := tracks.get("error"):
193
+ logger.error(f"Remote id {voice_id} error, {error_info}")
194
+ if error_info.strip() == "No tracks found":
195
+ asmr_web_url = self.base_api_url.replace(
196
+ "/api/", ""
197
+ ).replace("api.", "")
198
+ logger.error(
199
+ "I seems to be a problem with the server that has missing files.\n"
200
+ f"Try giving feedback there: {asmr_web_url}/work/{voice_id}"
201
+ )
202
+ return None
203
+ else:
204
+ logger.error("Unexpected track type: dict")
205
+ return None
206
+ return tracks
191
207
 
192
208
  @staticmethod
193
209
  async def download_by_idm(
@@ -230,13 +230,9 @@ class ASMRDownloadManager(AsyncManager):
230
230
  self.downloader.create_info_file(voice_info, voice_path)
231
231
 
232
232
  tracks = await self.downloader.get_voice_tracks(source_id_)
233
- if isinstance(tracks, dict):
234
- if error_info := tracks.get("error"):
235
- logger.error(f"RJ{source_id_} not found, {error_info}")
236
- return
237
- else:
238
- logger.error("Unexpected track type: dict")
239
- return
233
+ if tracks is None:
234
+ logger.error(f"Failed to get tracks for {source_id_}.")
235
+ return
240
236
 
241
237
  file_list = self.downloader.get_file_list(tracks, voice_path)
242
238
  self.downloader.create_recover_file(file_list, voice_path)
@@ -247,6 +243,16 @@ class ASMRDownloadManager(AsyncManager):
247
243
 
248
244
  await asyncio.gather(*tasks)
249
245
 
246
+ async def get_recommendations(self, page: int = 1):
247
+ res = await self.downloader.get_recommendations(page)
248
+ ids = [work["id"] for work in res["works"]]
249
+ await self.get(ids)
250
+
251
+ async def get_popular(self, page: int = 1):
252
+ res = await self.downloader.get_popular(page)
253
+ ids = [work["id"] for work in res["works"]]
254
+ await self.get(ids)
255
+
250
256
 
251
257
  class ASMRPlayListManager(AsyncManager):
252
258
  def __init__(
@@ -33,7 +33,7 @@ dependencies = [
33
33
  ]
34
34
  requires-python = ">=3.10"
35
35
  readme = "README.md"
36
- version = "2.3.2"
36
+ version = "2.4.0"
37
37
 
38
38
  [project.license]
39
39
  text = "MIT"
@@ -1 +0,0 @@
1
- __version__ = "2.3.2"
File without changes
File without changes