Compare commits

...

3 Commits

Author SHA1 Message Date
f3661cba45
update base 2024-04-20 01:47:41 +02:00
crocs
7f4feed2f2
Update README.md (#35)
* Update README.md

* fix spelling

---------

Co-authored-by: Simon <simobilleter@gmail.com>
2024-04-20 06:10:54 +07:00
Florian Wetzel
e3e9c5fc68
Add ability to have a different name for folder (#20)
* Add ability to have a different name for folder

---------

Co-authored-by: Simon <simobilleter@gmail.com>
2024-04-20 06:08:32 +07:00
8 changed files with 41 additions and 10 deletions

View File

@ -1,4 +1,4 @@
FROM python:3.11.3-slim-bullseye FROM python:3.11.8-slim-bookworm
ARG INSTALL_DEBUG ARG INSTALL_DEBUG
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED 1
ENV PATH=/root/.local/bin:$PATH ENV PATH=/root/.local/bin:$PATH

View File

@ -1,3 +1,17 @@
## 📢 Important Announcement: Repository Deprecation and Migration
We want to inform you that we are deprecating this repository,
[tubearchivist-jf ](https://github.com/tubearchivist/tubearchivist-jf), and moving to an updated repo, [tubearchivist-jf-plugin](https://github.com/tubearchivist/tubearchivist-jf-plugin).
This decision comes as part of our efforts to streamline our development process and provide a better experience for our users.
The new plugin offers better features, as well as a more futureproof codebase.
***Key Dates:***
- [tubearchivist-jf ](https://github.com/tubearchivist/tubearchivist-jf) will be set to read-only on **July 20th, 2024**.
***What Does This Mean for You?***
- We strongly suggest *not* installing this repo as it will stop receiving updates.
- Transition to the new repo at your earliest convenience.
## Tube Archivist Jellyfin Integration ## Tube Archivist Jellyfin Integration
Import your Tube Archivist media folder into Jellyfin Import your Tube Archivist media folder into Jellyfin
@ -53,6 +67,7 @@ An example configuration is provided in the docker-compose.yml file. Configure t
- `TA_TOKEN`: Tube Archivist API token, accessible from the settings page - `TA_TOKEN`: Tube Archivist API token, accessible from the settings page
- `JF_URL`: Full URL where Jellyfin is reachable - `JF_URL`: Full URL where Jellyfin is reachable
- `JF_TOKEN`: Jellyfin API token - `JF_TOKEN`: Jellyfin API token
- `JF_FOLDER`: Folder override if your folder is not named "YouTube" on your Filesystem.
- `LISTEN_PORT`: Optionally change the port where the integration is listening for messages. Defaults to `8001`. If you change this, make sure to also change the json link for auto trigger as described below. - `LISTEN_PORT`: Optionally change the port where the integration is listening for messages. Defaults to `8001`. If you change this, make sure to also change the json link for auto trigger as described below.
Mount the `/youtube` folder from Tube Archivist also in this container at `/youtube` to give this integration access to the media archive. Mount the `/youtube` folder from Tube Archivist also in this container at `/youtube` to give this integration access to the media archive.
@ -83,6 +98,7 @@ pip install requests
- `ta_token`: Tube Archivist API token, accessible from the settings page - `ta_token`: Tube Archivist API token, accessible from the settings page
- `jf_url`: Full URL where Jellyfin is reachable - `jf_url`: Full URL where Jellyfin is reachable
- `jf_token`: Jellyfin API token - `jf_token`: Jellyfin API token
- `jf_folder`: Name of the folder where TubeArchivist puts the files into
Then run the script from the main folder with python, e.g. Then run the script from the main folder with python, e.g.
```python ```python

View File

@ -38,6 +38,7 @@ def get_config_env() -> ConfigType | Literal[False]:
"ta_token": os.environ["TA_TOKEN"], "ta_token": os.environ["TA_TOKEN"],
"jf_url": os.environ["JF_URL"], "jf_url": os.environ["JF_URL"],
"jf_token": os.environ["JF_TOKEN"], "jf_token": os.environ["JF_TOKEN"],
"jf_folder": os.environ.get("JF_FOLDER", "youtube"),
} }
return config_content return config_content

View File

@ -9,7 +9,14 @@ from src.static_types import ConfigType, TAChannel, TAVideo
CONFIG: ConfigType = get_config() CONFIG: ConfigType = get_config()
TIMEOUT = 60 TIMEOUT = 60
EXPECTED_ENV = {"ta_url", "ta_token", "jf_url", "jf_token", "ta_video_path"} EXPECTED_ENV = {
"ta_url",
"ta_token",
"jf_url",
"jf_token",
"ta_video_path",
"jf_folder",
}
class Jellyfin: class Jellyfin:

View File

@ -22,8 +22,10 @@ class Library:
"""get collection id for youtube folder""" """get collection id for youtube folder"""
path: str = "Items?Recursive=true&includeItemTypes=Folder" path: str = "Items?Recursive=true&includeItemTypes=Folder"
folders: dict = Jellyfin().get(path) folders: dict = Jellyfin().get(path)
folder_name: str = get_config()["jf_folder"]
for folder in folders["Items"]: for folder in folders["Items"]:
if folder.get("Name").lower() == "youtube": if folder.get("Name").lower() == folder_name.lower():
return folder.get("Id") return folder.get("Id")
raise ValueError("youtube folder not found") raise ValueError("youtube folder not found")
@ -76,7 +78,7 @@ class Library:
) )
Jellyfin().post(path, False) Jellyfin().post(path, False)
for _ in range(12): while True:
response = Jellyfin().get("Library/VirtualFolders") response = Jellyfin().get("Library/VirtualFolders")
for folder in response: for folder in response:
if not folder["ItemId"] == collection_id: if not folder["ItemId"] == collection_id:
@ -86,7 +88,7 @@ class Library:
return return
print("waiting for library refresh") print("waiting for library refresh")
sleep(5) sleep(10)
class Show: class Show:
@ -213,10 +215,13 @@ class Show:
path: str = ( path: str = (
f"Items/{jf_id}/Refresh?Recursive=true&ImageRefreshMode=Default&MetadataRefreshMode=Default" # noqa: E501 f"Items/{jf_id}/Refresh?Recursive=true&ImageRefreshMode=Default&MetadataRefreshMode=Default" # noqa: E501
) )
print(f"[setup] {path=}")
Jellyfin().post(path, False) Jellyfin().post(path, False)
for _ in range(12): for _ in range(24):
all_existing: set[str] = set(self._get_existing_seasons()) all_existing: set[str] = set(self._get_existing_seasons())
print(f"[setup] seasons: {all_existing} {expected_season=}")
if expected_season in all_existing: if expected_season in all_existing:
return return

View File

@ -11,6 +11,7 @@ class ConfigType(TypedDict):
ta_token: str ta_token: str
jf_url: str jf_url: str
jf_token: str jf_token: str
jf_folder: str
class TAChannel(TypedDict): class TAChannel(TypedDict):

View File

@ -3,5 +3,6 @@
"ta_url": "http://tubearchivist.local", "ta_url": "http://tubearchivist.local",
"ta_token": "xxxxxxxxxxxxxxxx", "ta_token": "xxxxxxxxxxxxxxxx",
"jf_url": "http://jellyfin.local:8096", "jf_url": "http://jellyfin.local:8096",
"jf_token": "yyyyyyyyyyyyyyyy" "jf_token": "yyyyyyyyyyyyyyyy",
"jf_folder": "YouTube"
} }

View File

@ -17,12 +17,12 @@ function validate {
echo "running black" echo "running black"
black --force-exclude "migrations/*" --diff --color --check -l 79 "$check_path" black --force-exclude "migrations/*" --diff --color --check -l 79 "$check_path"
echo "running codespell" echo "running codespell"
codespell --skip="./.git,./.venv,./.mypy_cache" "$check_path" codespell --skip="./.git,./.venv,venv,./.mypy_cache" "$check_path"
echo "running flake8" echo "running flake8"
flake8 "$check_path" --exclude "migrations,.venv" --count --max-complexity=10 \ flake8 "$check_path" --exclude "migrations,.venv,venv" --count --max-complexity=10 \
--max-line-length=79 --show-source --statistics --max-line-length=79 --show-source --statistics
echo "running isort" echo "running isort"
isort --skip "migrations" --skip ".venv" --check-only --diff --profile black -l 79 "$check_path" isort --skip "migrations" --skip ".venv" --skip "venv" --check-only --diff --profile black -l 79 "$check_path"
printf " \n> all validations passed\n" printf " \n> all validations passed\n"
} }