wi1-bot 1.4.0__tar.gz → 1.4.2__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 (45) hide show
  1. wi1-bot-1.4.2/.pre-commit-config.yaml +18 -0
  2. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/PKG-INFO +1 -1
  3. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/config.yaml.template +5 -2
  4. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/pyproject.toml +19 -33
  5. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/_version.py +2 -2
  6. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/config.py +6 -0
  7. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/transcoder/transcoder.py +11 -5
  8. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/webhook.py +36 -3
  9. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot.egg-info/PKG-INFO +1 -1
  10. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot.egg-info/SOURCES.txt +0 -1
  11. wi1-bot-1.4.2/wi1_bot.egg-info/requires.txt +13 -0
  12. wi1-bot-1.4.0/.flake8 +0 -4
  13. wi1-bot-1.4.0/.pre-commit-config.yaml +0 -29
  14. wi1-bot-1.4.0/wi1_bot.egg-info/requires.txt +0 -15
  15. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/.github/workflows/pypi-publish.yml +0 -0
  16. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/.gitignore +0 -0
  17. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/.vscode/launch.json +0 -0
  18. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/.vscode/settings.json +0 -0
  19. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/LICENSE +0 -0
  20. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/README.md +0 -0
  21. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/setup.cfg +0 -0
  22. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/tests/movie_downloaded.py +0 -0
  23. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/__init__.py +0 -0
  24. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/__init__.py +0 -0
  25. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/download.py +0 -0
  26. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/episode.py +0 -0
  27. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/movie.py +0 -0
  28. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/radarr.py +0 -0
  29. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/arr/sonarr.py +0 -0
  30. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/__init__.py +0 -0
  31. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/bot.py +0 -0
  32. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/cogs/__init__.py +0 -0
  33. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/cogs/movie.py +0 -0
  34. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/cogs/series.py +0 -0
  35. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/discord/helpers.py +0 -0
  36. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/push.py +0 -0
  37. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/scripts/__init__.py +0 -0
  38. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/scripts/add_tag.py +0 -0
  39. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/scripts/start.py +0 -0
  40. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/scripts/transcode_item.py +0 -0
  41. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/transcoder/__init__.py +0 -0
  42. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot/transcoder/transcode_queue.py +0 -0
  43. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot.egg-info/dependency_links.txt +0 -0
  44. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot.egg-info/entry_points.txt +0 -0
  45. {wi1-bot-1.4.0 → wi1-bot-1.4.2}/wi1_bot.egg-info/top_level.txt +0 -0
@@ -0,0 +1,18 @@
1
+ fail_fast: false
2
+
3
+ repos:
4
+ - repo: https://github.com/astral-sh/ruff-pre-commit
5
+ rev: v0.3.0
6
+ hooks:
7
+ - id: ruff
8
+ args: [ --fix ]
9
+ - id: ruff-format
10
+
11
+ - repo: local
12
+ hooks:
13
+ - id: mypy
14
+ name: mypy
15
+ language: system
16
+ entry: mypy
17
+ pass_filenames: false
18
+ types: [python]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wi1-bot
3
- Version: 1.4.0
3
+ Version: 1.4.2
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>
@@ -2,6 +2,10 @@
2
2
  general:
3
3
  # log file directory, optional
4
4
  log_dir: /var/log/wi1-bot
5
+ # remote path mappings, optional
6
+ remote_path_mappings:
7
+ - remote: /data
8
+ local: /mnt/plex
5
9
 
6
10
  radarr:
7
11
  # radarr url you use to get to the dashboard
@@ -49,14 +53,13 @@ pushover:
49
53
  transcoding:
50
54
  # -hwaccel in ffmpeg, optional
51
55
  hwaccel: cuda
52
-
53
56
  profiles:
54
57
  # name of profile must match name in radarr/sonarr
55
58
  good:
56
59
  # copy all video and audio streams
57
- # default is only to copy the first stream and any streams with the languages listed below
58
60
  copy_all_streams: false
59
61
  # comma separated ISO 639-2 codes, optional
62
+ # currently only applies to choosing which subtitle streams to copy
60
63
  languages: eng,spa
61
64
  # -c:v in ffmpeg, optional
62
65
  video_codec: hevc_nvenc
@@ -1,7 +1,3 @@
1
- [build-system]
2
- requires = ["setuptools==61.*", "setuptools-scm"]
3
- build-backend = "setuptools.build_meta"
4
-
5
1
  [project]
6
2
  name = "wi1-bot"
7
3
  description = "Discord bot for Radarr/Sonarr integration"
@@ -16,25 +12,14 @@ classifiers = [
16
12
  dynamic = ["version"]
17
13
  requires-python = ">=3.10"
18
14
  dependencies = [
19
- "discord.py==2.3.1",
20
- "Flask==2.3.2",
21
- "mongoengine==0.27.0",
15
+ "discord.py==2.3.2",
16
+ "Flask==3.0.2",
17
+ "mongoengine==0.28.0",
22
18
  "pyarr==5.2.0",
23
19
  "PyYAML==6.0.1",
24
20
  "requests==2.31.0"
25
21
  ]
26
22
 
27
- [project.optional-dependencies]
28
- dev = [
29
- "black==23.3.0",
30
- "flake8==6.0.0",
31
- "isort==5.12.0",
32
- "mongo-types==0.15.1",
33
- "mypy==1.2.0",
34
- "pre-commit==3.2.2",
35
- "types-PyYAML==6.0.12.9",
36
- ]
37
-
38
23
  [project.urls]
39
24
  Homepage = "https://github.com/wthueb/wi1-bot"
40
25
 
@@ -43,27 +28,28 @@ wi1-bot = "wi1_bot.scripts.start:main"
43
28
  transcode-item = "wi1_bot.scripts.transcode_item:main"
44
29
  add-tag = "wi1_bot.scripts.add_tag:main"
45
30
 
31
+ [project.optional-dependencies]
32
+ dev = [
33
+ "mongo-types==0.15.1",
34
+ "mypy==1.3.0",
35
+ "pre-commit==3.6.2",
36
+ "ruff==0.3.0",
37
+ "types-PyYAML==6.0.12.12",
38
+ ]
39
+
40
+ [build-system]
41
+ requires = ["setuptools==61.*", "setuptools-scm"]
42
+ build-backend = "setuptools.build_meta"
43
+
46
44
  [tool.setuptools]
47
45
  packages = ["wi1_bot"]
48
46
 
49
47
  [tool.setuptools_scm]
50
48
  write_to = "wi1_bot/_version.py"
51
49
 
50
+ [tool.ruff.lint]
51
+ select = ["E", "F", "I"]
52
+
52
53
  [tool.mypy]
53
54
  packages = "wi1_bot"
54
55
  strict = true
55
-
56
- [[tool.mypy.overrides]]
57
- module = [
58
- "pushover",
59
- "pyarr",
60
- ]
61
- ignore_missing_imports = true
62
-
63
- [tool.black]
64
- line-length = 88
65
- target-version = ["py310"]
66
-
67
- [tool.isort]
68
- profile = "black"
69
- known_first_party = ["wi1_bot"]
@@ -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.0'
16
- __version_tuple__ = version_tuple = (1, 4, 0)
15
+ __version__ = version = '1.4.2'
16
+ __version_tuple__ = version_tuple = (1, 4, 2)
@@ -99,8 +99,14 @@ class TranscodingConfig(TranscodingConfigOptional):
99
99
  profiles: dict[str, TranscodingProfile]
100
100
 
101
101
 
102
+ class RemotePathMapping(TypedDict):
103
+ remote: str
104
+ local: str
105
+
106
+
102
107
  class GeneralConfigOptional(TypedDict, total=False):
103
108
  log_dir: str
109
+ remote_path_mappings: list[RemotePathMapping]
104
110
 
105
111
 
106
112
  class GeneralConfig(GeneralConfigOptional):
@@ -219,16 +219,24 @@ class Transcoder:
219
219
  if item.languages:
220
220
  langs = item.languages.split(",")
221
221
 
222
+ # TODO: use ffprobe to figure out what streams we should copy
223
+ # always copy first video stream
224
+ # always copy first audio stream
225
+ # always copy all subtitle streams
226
+ # if languages is specified in the config:
227
+ # copy all audio streams in one of those languages
228
+ # ffprobe -show_streams -print_format json {input_file} 2>/dev/null
222
229
  if item.copy_all_streams:
223
230
  command.extend(["-map", "0"])
224
231
  else:
225
232
  command.extend(["-map", "0:v:0"])
226
233
 
227
234
  command.extend(["-map", "0:a:0?"])
228
- command.extend(["-map", f"0:a:m:language:{lang}?"] for lang in langs)
229
235
 
230
- command.extend(["-map", "0:s?"])
231
- command.extend(["-map", f"0:s:m:language:{lang}?"] for lang in langs)
236
+ if langs:
237
+ command.extend([["-map", f"0:s:m:language:{lang}?"] for lang in langs])
238
+ else:
239
+ command.extend(["-map", "0:s?"])
232
240
 
233
241
  if item.video_codec:
234
242
  command.extend(["-vcodec", item.video_codec])
@@ -253,8 +261,6 @@ class Transcoder:
253
261
  if item.audio_bitrate:
254
262
  command.extend(["-b:a", item.audio_bitrate])
255
263
 
256
- # TODO: use ffprobe to figure out if we can copy subs,
257
- # or implement some form of retry functionality if ffmpeg errors out
258
264
  command.extend(["-scodec", "copy"])
259
265
 
260
266
  command.extend([transcode_to])
@@ -8,7 +8,7 @@ from flask import Flask, request
8
8
 
9
9
  from wi1_bot import push, transcoder
10
10
  from wi1_bot.arr import Radarr, Sonarr
11
- from wi1_bot.config import config
11
+ from wi1_bot.config import RemotePathMapping, config
12
12
 
13
13
  app = Flask(__name__)
14
14
 
@@ -26,6 +26,37 @@ def on_grab(req: dict[str, Any]) -> None:
26
26
  )
27
27
 
28
28
 
29
+ def replace_remote_paths(path: pathlib.Path) -> pathlib.Path:
30
+ if "general" not in config or "remote_path_mappings" not in config["general"]:
31
+ return path
32
+
33
+ mappings = config["general"]["remote_path_mappings"]
34
+
35
+ most_specific: RemotePathMapping | None = None
36
+
37
+ for mapping in mappings:
38
+ if path.is_relative_to(mapping["remote"]):
39
+ mapping_len = len(pathlib.Path(mapping["remote"]).parts)
40
+ most_specific_len = (
41
+ len(pathlib.Path(most_specific["remote"]).parts)
42
+ if most_specific is not None
43
+ else 0
44
+ )
45
+
46
+ if mapping_len > most_specific_len:
47
+ most_specific = mapping
48
+
49
+ if most_specific is not None:
50
+ remote_path = path
51
+ path = pathlib.Path(most_specific["local"]) / path.relative_to(
52
+ most_specific["remote"]
53
+ )
54
+
55
+ logger.debug(f"replaced remote path mapping: {remote_path} -> {path}")
56
+
57
+ return path
58
+
59
+
29
60
  def on_download(req: dict[str, Any]) -> None:
30
61
  path: pathlib.Path
31
62
  content_id: int
@@ -65,6 +96,8 @@ def on_download(req: dict[str, Any]) -> None:
65
96
  else:
66
97
  raise ValueError("unknown download request")
67
98
 
99
+ path = replace_remote_paths(path)
100
+
68
101
  try:
69
102
  quality_options = config["transcoding"]["profiles"][quality_profile]
70
103
  except KeyError:
@@ -119,10 +152,10 @@ def index() -> Any:
119
152
  def start() -> None:
120
153
  logger.info("starting webhook listener")
121
154
 
122
- t = threading.Thread(target=app.run, kwargs={"host": "localhost", "port": 9000})
155
+ t = threading.Thread(target=app.run, kwargs={"host": "0.0.0.0", "port": 9000})
123
156
  t.daemon = True
124
157
  t.start()
125
158
 
126
159
 
127
160
  if __name__ == "__main__":
128
- app.run(host="localhost", port=9000)
161
+ app.run(host="0.0.0.0", port=9000)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wi1-bot
3
- Version: 1.4.0
3
+ Version: 1.4.2
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>
@@ -1,4 +1,3 @@
1
- .flake8
2
1
  .gitignore
3
2
  .pre-commit-config.yaml
4
3
  LICENSE
@@ -0,0 +1,13 @@
1
+ discord.py==2.3.2
2
+ Flask==3.0.2
3
+ mongoengine==0.28.0
4
+ pyarr==5.2.0
5
+ PyYAML==6.0.1
6
+ requests==2.31.0
7
+
8
+ [dev]
9
+ mongo-types==0.15.1
10
+ mypy==1.3.0
11
+ pre-commit==3.6.2
12
+ ruff==0.3.0
13
+ types-PyYAML==6.0.12.12
wi1-bot-1.4.0/.flake8 DELETED
@@ -1,4 +0,0 @@
1
- [flake8]
2
- max-line-length = 88
3
- extend-ignore = E203
4
- max-complexity = 12
@@ -1,29 +0,0 @@
1
- fail_fast: false
2
-
3
- repos:
4
- - repo: local
5
- hooks:
6
- - id: isort
7
- name: isort
8
- language: system
9
- entry: isort
10
- types: [python]
11
-
12
- - id: black
13
- name: black
14
- language: system
15
- entry: black
16
- types: [python]
17
-
18
- - id: flake8
19
- name: flake8
20
- language: system
21
- entry: flake8
22
- types: [python]
23
-
24
- - id: mypy
25
- name: mypy
26
- language: system
27
- entry: mypy
28
- pass_filenames: false
29
- types: [python]
@@ -1,15 +0,0 @@
1
- discord.py==2.3.1
2
- Flask==2.3.2
3
- mongoengine==0.27.0
4
- pyarr==5.2.0
5
- PyYAML==6.0.1
6
- requests==2.31.0
7
-
8
- [dev]
9
- black==23.3.0
10
- flake8==6.0.0
11
- isort==5.12.0
12
- mongo-types==0.15.1
13
- mypy==1.2.0
14
- pre-commit==3.2.2
15
- types-PyYAML==6.0.12.9
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