git-cli-yt 2.0.1 → 2.0.2

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.
package/app.py CHANGED
@@ -3,7 +3,6 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import threading
6
- import os
7
6
  import time
8
7
  from typing import Any, Optional
9
8
 
@@ -582,17 +581,8 @@ class YouTubePlayer(App):
582
581
  "Faça login para ver suas playlists.",
583
582
  )
584
583
  return
585
- channel = auth.get_channel_info()
586
- if not channel:
587
- self.call_from_thread(
588
- self._show_user_playlists_error,
589
- generation,
590
- "Não foi possível identificar o canal.",
591
- )
592
- return
593
584
  items = youtube_playlist.fetch_user_playlists(
594
- channel["id"],
595
- cookies_file=os.environ.get("YTDLP_COOKIES_FILE"),
585
+ auth.get_youtube_service(interactive=False)
596
586
  )
597
587
  self.call_from_thread(self._show_user_playlists, generation, items)
598
588
  except Exception as exc:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-cli-yt",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "YouTube TUI Player V2 executável via Python ou NPX",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -1,4 +1,4 @@
1
- """Listagem de playlists do YouTube via yt-dlp."""
1
+ """Listagem de playlists do YouTube via API de dados e yt-dlp."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
  from typing import Any, Optional
7
7
 
8
8
  import yt_dlp
9
+ from googleapiclient.errors import HttpError
9
10
 
10
11
  from youtube.search import normalize_ytdlp_entry
11
12
 
@@ -14,31 +15,18 @@ class PlaylistError(RuntimeError):
14
15
  """Erro ao enumerar uma playlist."""
15
16
 
16
17
 
17
-
18
- def fetch_user_playlists(
19
- channel_id: str,
20
- cookies_file: Optional[str] = None,
21
- ) -> list[dict[str, Any]]:
18
+ def fetch_user_playlists(youtube_service: Any) -> list[dict[str, Any]]:
22
19
  """Retorna Curtidas primeiro e depois as playlists do canal."""
23
- channel_id = channel_id.strip()
24
- if not channel_id:
25
- raise PlaylistError("Não foi possível identificar o canal do usuário.")
26
-
27
- options: Any = {
28
- "quiet": True,
29
- "no_warnings": True,
30
- "skip_download": True,
31
- "extract_flat": True,
32
- }
33
- cookie_path = Path(cookies_file) if cookies_file else None
34
- if cookie_path and cookie_path.exists():
35
- options["cookiefile"] = str(cookie_path)
20
+ if youtube_service is None:
21
+ return []
36
22
 
37
- url = f"https://www.youtube.com/channel/{channel_id}/playlists"
38
23
  try:
39
- with yt_dlp.YoutubeDL(options) as downloader:
40
- info = downloader.extract_info(url, download=False)
41
- except Exception as exc:
24
+ response = (
25
+ youtube_service.playlists()
26
+ .list(mine=True, part="snippet,contentDetails", maxResults=50)
27
+ .execute()
28
+ )
29
+ except HttpError as exc:
42
30
  raise PlaylistError("Não foi possível listar as playlists do usuário.") from exc
43
31
 
44
32
  results: list[dict[str, Any]] = [
@@ -51,31 +39,24 @@ def fetch_user_playlists(
51
39
  "thumbnail": "",
52
40
  }
53
41
  ]
54
- for entry in (info.get("entries") if isinstance(info, dict) else None) or []:
55
- if not isinstance(entry, dict):
56
- continue
57
- playlist_id = str(entry.get("id", "")).strip()
58
- playlist_url = str(
59
- entry.get("webpage_url")
60
- or entry.get("url")
61
- or (f"https://www.youtube.com/playlist?list={playlist_id}" if playlist_id else "")
62
- )
63
- title = str(entry.get("title") or "Playlist sem título").strip()
64
- if not playlist_id and not playlist_url:
42
+ for item in response.get("items", []):
43
+ playlist_id = str(item.get("id", "")).strip()
44
+ if not playlist_id:
65
45
  continue
66
- thumbnails = entry.get("thumbnails") or []
46
+ snippet = item.get("snippet", {})
47
+ thumbnails = snippet.get("thumbnails", {}) or {}
67
48
  thumbnail = max(
68
- thumbnails,
69
- key=lambda item: item.get("width", 0) if isinstance(item, dict) else 0,
49
+ thumbnails.values(),
50
+ key=lambda value: value.get("width", 0),
70
51
  default={},
71
52
  )
72
53
  results.append(
73
54
  {
74
- "id": playlist_id or playlist_url,
55
+ "id": playlist_id,
75
56
  "kind": "playlist",
76
- "title": title,
77
- "url": playlist_url,
78
- "count": entry.get("playlist_count"),
57
+ "title": str(snippet.get("title") or "Playlist sem título").strip(),
58
+ "url": f"https://www.youtube.com/playlist?list={playlist_id}",
59
+ "count": item.get("contentDetails", {}).get("itemCount"),
79
60
  "thumbnail": thumbnail.get("url", "")
80
61
  if isinstance(thumbnail, dict)
81
62
  else "",
package/youtube/search.py CHANGED
@@ -231,7 +231,7 @@ def _build_results(
231
231
  response: dict[str, Any],
232
232
  service: Any = None,
233
233
  api_key: Optional[str] = None,
234
- ) -> tuple[list[dict[str, Any]], Optional[str]]:
234
+ ) -> list[dict[str, Any]]:
235
235
  items = response.get("items", [])
236
236
  video_ids = [
237
237
  item.get("id", {}).get("videoId", "")
@@ -281,8 +281,7 @@ def _build_results(
281
281
  }
282
282
  )
283
283
 
284
- next_page = response.get("nextPageToken")
285
- return results, str(next_page) if next_page else None
284
+ return results
286
285
 
287
286
 
288
287
  def _video_details(