wi1-bot 1.4.4__tar.gz → 1.4.5__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 (46) hide show
  1. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/PKG-INFO +1 -1
  2. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/pyproject.toml +1 -0
  3. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/_version.py +2 -2
  4. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/radarr.py +2 -2
  5. wi1-bot-1.4.5/wi1_bot/scripts/rescan.py +57 -0
  6. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/transcoder/transcoder.py +28 -29
  7. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/PKG-INFO +1 -1
  8. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/SOURCES.txt +1 -0
  9. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/entry_points.txt +1 -0
  10. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.dockerignore +0 -0
  11. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.github/workflows/pypi-publish.yml +0 -0
  12. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.gitignore +0 -0
  13. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.pre-commit-config.yaml +0 -0
  14. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.vscode/launch.json +0 -0
  15. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/.vscode/settings.json +0 -0
  16. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/Dockerfile +0 -0
  17. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/LICENSE +0 -0
  18. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/README.md +0 -0
  19. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/compose.yaml +0 -0
  20. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/config.yaml.template +0 -0
  21. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/setup.cfg +0 -0
  22. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/tests/movie_downloaded.py +0 -0
  23. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/__init__.py +0 -0
  24. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/__init__.py +0 -0
  25. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/download.py +0 -0
  26. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/episode.py +0 -0
  27. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/movie.py +0 -0
  28. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/arr/sonarr.py +0 -0
  29. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/config.py +0 -0
  30. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/__init__.py +0 -0
  31. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/bot.py +0 -0
  32. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/cogs/__init__.py +0 -0
  33. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/cogs/movie.py +0 -0
  34. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/cogs/series.py +0 -0
  35. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/discord/helpers.py +0 -0
  36. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/push.py +0 -0
  37. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/scripts/__init__.py +0 -0
  38. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/scripts/add_tag.py +0 -0
  39. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/scripts/start.py +0 -0
  40. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/scripts/transcode_item.py +0 -0
  41. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/transcoder/__init__.py +0 -0
  42. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/transcoder/transcode_queue.py +0 -0
  43. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot/webhook.py +0 -0
  44. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/dependency_links.txt +0 -0
  45. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/requires.txt +0 -0
  46. {wi1-bot-1.4.4 → wi1-bot-1.4.5}/wi1_bot.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wi1-bot
3
- Version: 1.4.4
3
+ Version: 1.4.5
4
4
  Summary: Discord bot for Radarr/Sonarr integration
5
5
  Home-page: https://github.com/wthueb/wi1-bot
6
6
  Author-email: William Huebner <wilhueb@gmail.com>
@@ -27,6 +27,7 @@ Homepage = "https://github.com/wthueb/wi1-bot"
27
27
  wi1-bot = "wi1_bot.scripts.start:main"
28
28
  transcode-item = "wi1_bot.scripts.transcode_item:main"
29
29
  add-tag = "wi1_bot.scripts.add_tag:main"
30
+ rescan = "wi1_bot.scripts.rescan:main"
30
31
 
31
32
  [project.optional-dependencies]
32
33
  dev = [
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.4.4'
16
- __version_tuple__ = version_tuple = (1, 4, 4)
15
+ __version__ = version = '1.4.5'
16
+ __version_tuple__ = version_tuple = (1, 4, 5)
@@ -149,10 +149,10 @@ class Radarr:
149
149
  raise ValueError(f"no quality profile with the id {profile_id}")
150
150
 
151
151
  def rescan_movie(self, movie_id: int) -> None:
152
- self._radarr.post_command("RescanMovie", movieId=movie_id) # type: ignore
152
+ self._radarr.post_command("RescanMovie", movieId=movie_id)
153
153
 
154
154
  def refresh_movie(self, movie_id: int) -> None:
155
- self._radarr.post_command("RefreshMovie", movieIds=[movie_id]) # type: ignore
155
+ self._radarr.post_command("RefreshMovie", movieIds=[movie_id])
156
156
 
157
157
  def search_missing(self) -> None:
158
158
  self._radarr.post_command(name="MissingMoviesSearch")
@@ -0,0 +1,57 @@
1
+ import argparse
2
+ from time import sleep
3
+ from typing import cast
4
+
5
+ from wi1_bot.arr.radarr import Radarr
6
+ from wi1_bot.arr.sonarr import Sonarr
7
+ from wi1_bot.config import config
8
+
9
+
10
+ def rescan_radarr() -> None:
11
+ radarr = Radarr(config["radarr"]["url"], config["radarr"]["api_key"])
12
+
13
+ all_movies = radarr._radarr.get_movie()
14
+ assert isinstance(all_movies, list)
15
+ all_movies.sort(key=lambda m: cast(str, m["title"]))
16
+
17
+ for movie in all_movies:
18
+ assert isinstance(movie, dict)
19
+ print(f"Rescanning {movie['title']}...")
20
+ radarr.refresh_movie(movie["id"])
21
+ sleep(3)
22
+
23
+
24
+ def rescan_sonarr() -> None:
25
+ sonarr = Sonarr(config["sonarr"]["url"], config["sonarr"]["api_key"])
26
+
27
+ all_series = sonarr._sonarr.get_series()
28
+ assert isinstance(all_series, list)
29
+ all_series.sort(key=lambda s: cast(str, s["title"]))
30
+
31
+ for series in all_series:
32
+ assert isinstance(series, dict)
33
+ print(f"Rescanning {series['title']}...")
34
+ sonarr.rescan_series(series["id"])
35
+ sleep(5)
36
+
37
+
38
+ def main() -> None:
39
+ parser = argparse.ArgumentParser(description="Rescan all movies/shows")
40
+
41
+ parser.add_argument(
42
+ "service", nargs="?", choices=["radarr", "sonarr"], help="radarr or sonarr"
43
+ )
44
+
45
+ args = parser.parse_args()
46
+
47
+ if args.service == "radarr":
48
+ rescan_radarr()
49
+ elif args.service == "sonarr":
50
+ rescan_sonarr()
51
+ else:
52
+ rescan_radarr()
53
+ rescan_sonarr()
54
+
55
+
56
+ if __name__ == "__main__":
57
+ main()
@@ -46,17 +46,10 @@ class Transcoder:
46
46
  continue
47
47
 
48
48
  try:
49
- self._do_transcode(item)
50
- queue.remove(item)
51
- except SignalInterrupt:
52
- # retry when restarted
53
- pass
54
- except FileNotFoundError:
55
- # don't retry
56
- queue.remove(item)
57
- except UnknownError:
58
- # don't retry
59
- queue.remove(item)
49
+ remove = self._do_transcode(item)
50
+
51
+ if remove:
52
+ queue.remove(item)
60
53
  except Exception:
61
54
  self.logger.warning(
62
55
  "got exception when trying to transcode", exc_info=True
@@ -64,14 +57,14 @@ class Transcoder:
64
57
 
65
58
  sleep(3)
66
59
 
67
- def _do_transcode(self, item: TranscodeItem) -> None:
60
+ def _do_transcode(self, item: TranscodeItem) -> bool:
68
61
  path = pathlib.Path(item.path)
69
62
 
70
- self.logger.debug(f"attempting to transcode {path.name}")
63
+ self.logger.info(f"attempting to transcode {path.name}")
71
64
 
72
65
  if path.suffix == ".avi":
73
- self.logger.debug(f"cannot transcode {path.name}: .avi not supported")
74
- return
66
+ self.logger.info(f"cannot transcode {path.name}: .avi not supported")
67
+ return True
75
68
 
76
69
  # push.send(f"{basename}", title="starting transcode")
77
70
 
@@ -103,29 +96,32 @@ class Transcoder:
103
96
  tmp_log_path = tmp_folder / "wi1_bot.transcoder.log"
104
97
 
105
98
  with open(tmp_log_path, "w") as ffmpeg_log_file:
106
- for line in proc.stdout: # type: ignore
99
+ assert proc.stdout is not None
100
+ for line in proc.stdout:
107
101
  ffmpeg_log_file.write(line)
108
102
  last_output = line.strip()
109
103
 
110
104
  status = proc.wait()
111
105
 
112
106
  if status != 0:
113
- self.logger.error(f"ffmpeg failed (status {status}): {last_output}")
114
-
115
- if (
116
- "No such file or directory" in last_output
117
- and "shared object file" not in last_output
118
- ):
119
- self.logger.debug(
107
+ if "Error opening input files" in last_output:
108
+ self.logger.info(
120
109
  f"file does not exist: {path}, skipping transcoding"
121
110
  )
122
- raise FileNotFoundError
111
+ return True
123
112
 
124
113
  if "received signal 15" in last_output:
125
- self.logger.debug(
114
+ self.logger.info(
126
115
  f"transcoding interrupted by signal: {path}, will retry"
127
116
  )
128
- raise SignalInterrupt
117
+ return False
118
+
119
+ if "cannot open shared object file" in last_output:
120
+ self.logger.error(
121
+ "ffmpeg error: missing shared object file, will retry"
122
+ )
123
+ push.send(f"ffmpeg error: {last_output}", title="ffmpeg error")
124
+ return False
129
125
 
130
126
  perm_log_path = tmp_folder / f"{path.stem}.log"
131
127
 
@@ -136,6 +132,8 @@ class Transcoder:
136
132
  perm_log_path.parent.mkdir(parents=True, exist_ok=True)
137
133
 
138
134
  shutil.copy(tmp_log_path, perm_log_path)
135
+
136
+ self.logger.error(f"ffmpeg failed (status {status}): {last_output}")
139
137
  self.logger.error(f"log file: {perm_log_path}")
140
138
 
141
139
  push.send(
@@ -143,7 +141,7 @@ class Transcoder:
143
141
  title="transcoding error",
144
142
  )
145
143
 
146
- raise UnknownError
144
+ return True
147
145
 
148
146
  new_path = path.parent / transcode_to.name
149
147
 
@@ -153,7 +151,7 @@ class Transcoder:
153
151
  )
154
152
 
155
153
  transcode_to.unlink()
156
- return
154
+ return True
157
155
 
158
156
  shutil.move(transcode_to, new_path)
159
157
  path.unlink()
@@ -163,8 +161,9 @@ class Transcoder:
163
161
  self.logger.info(f"transcoded: {path.name} -> {new_path.name}")
164
162
  # push.send(f"{path.name} -> {new_path.name}", title="file transcoded")
165
163
 
164
+ return True
165
+
166
166
  def _rescan_content(self, item: TranscodeItem, new_path: str) -> None:
167
- # FIXME: don't hardcode library paths (config)
168
167
  if item.content_id is not None:
169
168
  if new_path.startswith(config["radarr"]["root_folder"]):
170
169
  self.radarr.rescan_movie(item.content_id)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wi1-bot
3
- Version: 1.4.4
3
+ Version: 1.4.5
4
4
  Summary: Discord bot for Radarr/Sonarr integration
5
5
  Home-page: https://github.com/wthueb/wi1-bot
6
6
  Author-email: William Huebner <wilhueb@gmail.com>
@@ -37,6 +37,7 @@ wi1_bot/discord/cogs/movie.py
37
37
  wi1_bot/discord/cogs/series.py
38
38
  wi1_bot/scripts/__init__.py
39
39
  wi1_bot/scripts/add_tag.py
40
+ wi1_bot/scripts/rescan.py
40
41
  wi1_bot/scripts/start.py
41
42
  wi1_bot/scripts/transcode_item.py
42
43
  wi1_bot/transcoder/__init__.py
@@ -1,4 +1,5 @@
1
1
  [console_scripts]
2
2
  add-tag = wi1_bot.scripts.add_tag:main
3
+ rescan = wi1_bot.scripts.rescan:main
3
4
  transcode-item = wi1_bot.scripts.transcode_item:main
4
5
  wi1-bot = wi1_bot.scripts.start:main
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