cinnamon-cli 0.2.30__tar.gz → 0.2.32__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 (35) hide show
  1. {cinnamon_cli-0.2.30/cinnamon_cli.egg-info → cinnamon_cli-0.2.32}/PKG-INFO +1 -1
  2. cinnamon_cli-0.2.32/cinnamon/__init__.py +1 -0
  3. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/player.py +31 -21
  4. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/webstream.py +9 -21
  5. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32/cinnamon_cli.egg-info}/PKG-INFO +1 -1
  6. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/pyproject.toml +1 -1
  7. cinnamon_cli-0.2.30/cinnamon/__init__.py +0 -1
  8. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/LICENSE +0 -0
  9. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/README.md +0 -0
  10. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/anilist.py +0 -0
  11. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/cli.py +0 -0
  12. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/config.py +0 -0
  13. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/downloads.py +0 -0
  14. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/errors.py +0 -0
  15. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/history.py +0 -0
  16. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/__init__.py +0 -0
  17. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/anime.py +0 -0
  18. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/base.py +0 -0
  19. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/torrentio.py +0 -0
  20. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/scrapers/vidsrc.py +0 -0
  21. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/tmdb.py +0 -0
  22. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon/tui.py +0 -0
  23. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon_cli.egg-info/SOURCES.txt +0 -0
  24. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon_cli.egg-info/dependency_links.txt +0 -0
  25. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon_cli.egg-info/entry_points.txt +0 -0
  26. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon_cli.egg-info/requires.txt +0 -0
  27. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/cinnamon_cli.egg-info/top_level.txt +0 -0
  28. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/setup.cfg +0 -0
  29. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream.py +0 -0
  30. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream2.py +0 -0
  31. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream3.py +0 -0
  32. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream4.py +0 -0
  33. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream5.py +0 -0
  34. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_directstream6.py +0 -0
  35. {cinnamon_cli-0.2.30 → cinnamon_cli-0.2.32}/tests/test_ui_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cinnamon-cli
3
- Version: 0.2.30
3
+ Version: 0.2.32
4
4
  Summary: CLI to search TV shows, movies & anime via TMDB/AniList, scrape m3u8 links, and play in VLC/mpv
5
5
  Author: pizza-droid
6
6
  License: CC BY-NC 4.0
@@ -0,0 +1 @@
1
+ __version__ = "0.2.32"
@@ -472,6 +472,10 @@ def download_video(url, title="", referer=None, output_dir=".", track_id=None):
472
472
 
473
473
  cmd = [
474
474
  exe, "--no-mtime", "--no-warnings", "-o", outtmpl,
475
+ "--retries", "10",
476
+ "--fragment-retries", "10",
477
+ "--retry-sleep", "2",
478
+ "--socket-timeout", "60",
475
479
  ]
476
480
  if referer:
477
481
  cmd += ["--referer", referer]
@@ -489,28 +493,31 @@ def download_video(url, title="", referer=None, output_dir=".", track_id=None):
489
493
 
490
494
  import re
491
495
  last_pct = -1
496
+ last_error = ""
492
497
  try:
493
498
  for line in proc.stdout:
494
- if "[download]" not in line:
495
- continue
496
- m = re.search(r"(\d+\.?\d*)%\s+of\s+~?\s*([\d.]+)(\w+).*ETA\s+(\S+)", line)
497
- if not m:
498
- m = re.search(r"(\d+\.?\d*)%\s+of\s+~?\s*([\d.]+)(\w+)", line)
499
- if m:
500
- pct = float(m.group(1))
501
- if int(pct) == last_pct:
502
- continue
503
- last_pct = int(pct)
504
- size_val = float(m.group(2))
505
- unit = m.group(3)
506
- eta = m.group(4) if m.lastindex >= 4 else ""
507
- bar_width = 25
508
- filled = int(bar_width * pct / 100)
509
- bar = "" * filled + "" * (bar_width - filled)
510
- eta_str = f" ETA {eta}" if eta else ""
511
- print(f"\r {bar} {pct:>5.1f}% {size_val:.1f}{unit}{eta_str} ", end="", file=sys.stderr, flush=True)
512
- else:
513
- print(f"\r {line.rstrip():<50}", file=sys.stderr, flush=True)
499
+ if "[download]" in line:
500
+ m = re.search(r"(\d+\.?\d*)%\s+of\s+~?\s*([\d.]+)(\w+).*ETA\s+(\S+)", line)
501
+ if not m:
502
+ m = re.search(r"(\d+\.?\d*)%\s+of\s+~?\s*([\d.]+)(\w+)", line)
503
+ if m:
504
+ pct = float(m.group(1))
505
+ if int(pct) == last_pct:
506
+ continue
507
+ last_pct = int(pct)
508
+ size_val = float(m.group(2))
509
+ unit = m.group(3)
510
+ eta = m.group(4) if m.lastindex >= 4 else ""
511
+ bar_width = 25
512
+ filled = int(bar_width * pct / 100)
513
+ bar = "█" * filled + "░" * (bar_width - filled)
514
+ eta_str = f" ETA {eta}" if eta else ""
515
+ print(f"\r {bar} {pct:>5.1f}% {size_val:.1f}{unit}{eta_str} ", end="", file=sys.stderr, flush=True)
516
+ else:
517
+ print(f"\r {line.rstrip():<50}", file=sys.stderr, flush=True)
518
+ elif "ERROR:" in line or "WARNING:" in line:
519
+ last_error = line.strip()
520
+ print(f" {line.rstrip()}", file=sys.stderr, flush=True)
514
521
 
515
522
  proc.wait()
516
523
  print(file=sys.stderr)
@@ -520,7 +527,10 @@ def download_video(url, title="", referer=None, output_dir=".", track_id=None):
520
527
  _track_update(track_id, status="completed")
521
528
  print(f" Done — {safe}", file=sys.stderr)
522
529
  else:
523
- raise PlayerLaunchError("yt-dlp", f"exit code {proc.returncode}")
530
+ detail = last_error or f"exit code {proc.returncode}"
531
+ if track_id:
532
+ _track_update(track_id, status="error")
533
+ raise PlayerLaunchError("yt-dlp", detail)
524
534
 
525
535
  except KeyboardInterrupt:
526
536
  print(file=sys.stderr)
@@ -42,9 +42,9 @@ class WebStreamScraper(BaseScraper):
42
42
  season = episode_info.get("season", 1)
43
43
  episode = episode_info.get("episode", 1)
44
44
  quality = episode_info.get("quality", "")
45
- # vidlink uses a different CDN that is not throttled like vixsrc's
46
- # segment edge, so prefer it when downloading to avoid 503 stalls.
47
- prefer_vidlink = bool(episode_info.get("download"))
45
+ # vixsrc first (sequential HLS that yt-dlp handles reliably); vidlink is the
46
+ # fallback. vidlink's .mp4 CDN (bcdn/stormvv) rate-limits aggressively (HTTP
47
+ # 429), so it is not preferred for downloads.
48
48
 
49
49
  if not tmdb_id:
50
50
  raise ScraperParseError(self.name, "Missing tmdb_id/movie_id/tv_id in episode_info")
@@ -52,16 +52,10 @@ class WebStreamScraper(BaseScraper):
52
52
  deadline = _time.time() + 30
53
53
 
54
54
  if media_type == "movie":
55
- if prefer_vidlink:
56
- vixsrc_fn, vidlink_fn = _try_vidlink_movie, _try_vixsrc_movie
57
- vixsrc_ref = f"https://vixsrc.to/embed/movie/{tmdb_id}"
58
- else:
59
- vixsrc_fn, vidlink_fn = _try_vixsrc_movie, _try_vidlink_movie
60
- vixsrc_ref = f"https://vixsrc.to/embed/movie/{tmdb_id}"
61
-
55
+ vixsrc_ref = f"https://vixsrc.to/embed/movie/{tmdb_id}"
62
56
  if _time.time() < deadline:
63
57
  try:
64
- result = vixsrc_fn(tmdb_id, quality)
58
+ result = _try_vixsrc_movie(tmdb_id, quality)
65
59
  if result:
66
60
  label = quality.upper() if quality else "Auto"
67
61
  return ScraperResult(
@@ -75,7 +69,7 @@ class WebStreamScraper(BaseScraper):
75
69
 
76
70
  if _time.time() < deadline:
77
71
  try:
78
- result = vidlink_fn(tmdb_id, quality)
72
+ result = _try_vidlink_movie(tmdb_id, quality)
79
73
  if result:
80
74
  label = quality.upper() if quality else "Auto"
81
75
  return ScraperResult(
@@ -90,16 +84,10 @@ class WebStreamScraper(BaseScraper):
90
84
  raise ScraperNoStreamError(self.name, f"No HTTP stream found for {show}")
91
85
 
92
86
  # TV
93
- if prefer_vidlink:
94
- vixsrc_fn, vidlink_fn = _try_vidlink, _try_vixsrc
95
- vixsrc_ref = f"https://vixsrc.to/embed/tv/{tmdb_id}/{season}/{episode}"
96
- else:
97
- vixsrc_fn, vidlink_fn = _try_vixsrc, _try_vidlink
98
- vixsrc_ref = f"https://vixsrc.to/embed/tv/{tmdb_id}/{season}/{episode}"
99
-
87
+ vixsrc_ref = f"https://vixsrc.to/embed/tv/{tmdb_id}/{season}/{episode}"
100
88
  if _time.time() < deadline:
101
89
  try:
102
- result = vixsrc_fn(tmdb_id, season, episode, quality)
90
+ result = _try_vixsrc(tmdb_id, season, episode, quality)
103
91
  if result:
104
92
  label = quality.upper() if quality else "Auto"
105
93
  return ScraperResult(
@@ -113,7 +101,7 @@ class WebStreamScraper(BaseScraper):
113
101
 
114
102
  if _time.time() < deadline:
115
103
  try:
116
- result = vidlink_fn(tmdb_id, season, episode, quality)
104
+ result = _try_vidlink(tmdb_id, season, episode, quality)
117
105
  if result:
118
106
  label = quality.upper() if quality else "Auto"
119
107
  return ScraperResult(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cinnamon-cli
3
- Version: 0.2.30
3
+ Version: 0.2.32
4
4
  Summary: CLI to search TV shows, movies & anime via TMDB/AniList, scrape m3u8 links, and play in VLC/mpv
5
5
  Author: pizza-droid
6
6
  License: CC BY-NC 4.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cinnamon-cli"
7
- version = "0.2.30"
7
+ version = "0.2.32"
8
8
  description = "CLI to search TV shows, movies & anime via TMDB/AniList, scrape m3u8 links, and play in VLC/mpv"
9
9
  license = { text = "CC BY-NC 4.0" }
10
10
  readme = "README.md"
@@ -1 +0,0 @@
1
- __version__ = "0.2.30"
File without changes
File without changes
File without changes