Merge branch 'master' into emby
This commit is contained in:
commit
9f54aeda69
199 changed files with 5270 additions and 710 deletions
8
.github/workflows/ci-windows.yaml
vendored
8
.github/workflows/ci-windows.yaml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run unit tests with coverage
|
||||
run: |
|
||||
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run integration tests with coverage
|
||||
run: |
|
||||
|
|
@ -66,7 +66,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run prebuilt preset integration tests with coverage
|
||||
run: |
|
||||
|
|
@ -89,7 +89,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run e2e tests with coverage
|
||||
run: |
|
||||
|
|
|
|||
22
.github/workflows/ci.yaml
vendored
22
.github/workflows/ci.yaml
vendored
|
|
@ -9,7 +9,7 @@ on:
|
|||
- master
|
||||
jobs:
|
||||
test-lint:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run linters
|
||||
run: |
|
||||
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
make check_lint
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run unit tests with coverage
|
||||
run: |
|
||||
|
|
@ -53,7 +53,7 @@ jobs:
|
|||
key: ${{github.sha}}-coverage-unit
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run integration tests with coverage
|
||||
run: |
|
||||
|
|
@ -79,7 +79,7 @@ jobs:
|
|||
key: ${{github.sha}}-coverage-integration
|
||||
|
||||
test-integration-prebuilt-presets:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run prebuilt preset integration tests with coverage
|
||||
run: |
|
||||
|
|
@ -105,7 +105,7 @@ jobs:
|
|||
key: ${{github.sha}}-coverage-integration-prebuilt-presets
|
||||
|
||||
test-e2e:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run e2e tests with coverage
|
||||
run: |
|
||||
|
|
@ -125,7 +125,7 @@ jobs:
|
|||
coverage run -m pytest tests/e2e && coverage xml -o /opt/coverage/e2e/coverage.xml
|
||||
|
||||
codecov-upload:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
test-unit,
|
||||
test-integration,
|
||||
|
|
|
|||
10
.github/workflows/package-gui.yaml
vendored
10
.github/workflows/package-gui.yaml
vendored
|
|
@ -63,10 +63,10 @@ jobs:
|
|||
echo 'init_contents=__pypi_version__ = "${{ env.PYPI_VERSION }}";__local_version__ = "${{ env.LOCAL_VERSION }}"' >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ "3.10" ]
|
||||
python-version: [ "3.12" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
@ -92,7 +92,7 @@ jobs:
|
|||
|
||||
# Build ARM64 container, only on master branch to save time testing
|
||||
package-arm64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -141,7 +141,7 @@ jobs:
|
|||
|
||||
# Build AMD64 container
|
||||
package-amd64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -186,7 +186,7 @@ jobs:
|
|||
# On master branch, build the docker manifest file from the cached
|
||||
# docker builds and push to the registry
|
||||
deploy:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
version,
|
||||
build,
|
||||
|
|
|
|||
10
.github/workflows/package-ubuntu.yaml
vendored
10
.github/workflows/package-ubuntu.yaml
vendored
|
|
@ -63,10 +63,10 @@ jobs:
|
|||
echo 'init_contents=__pypi_version__ = "${{ env.PYPI_VERSION }}";__local_version__ = "${{ env.LOCAL_VERSION }}"' >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ "3.10" ]
|
||||
python-version: [ "3.12" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
@ -92,7 +92,7 @@ jobs:
|
|||
|
||||
# Build ARM64 container, only on master branch to save time testing
|
||||
package-arm64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -141,7 +141,7 @@ jobs:
|
|||
|
||||
# Build AMD64 container
|
||||
package-amd64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -186,7 +186,7 @@ jobs:
|
|||
# On master branch, build the docker manifest file from the cached
|
||||
# docker builds and push to the registry
|
||||
deploy:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
version,
|
||||
build,
|
||||
|
|
|
|||
10
.github/workflows/package.yaml
vendored
10
.github/workflows/package.yaml
vendored
|
|
@ -63,10 +63,10 @@ jobs:
|
|||
echo 'init_contents=__pypi_version__ = "${{ env.PYPI_VERSION }}";__local_version__ = "${{ env.LOCAL_VERSION }}"' >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ "3.10" ]
|
||||
python-version: [ "3.12" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
@ -92,7 +92,7 @@ jobs:
|
|||
|
||||
# Build ARM64 container, only on master branch to save time testing
|
||||
package-arm64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -136,7 +136,7 @@ jobs:
|
|||
|
||||
# Build AMD64 container
|
||||
package-amd64:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
build
|
||||
]
|
||||
|
|
@ -180,7 +180,7 @@ jobs:
|
|||
# On master branch, build the docker manifest file from the cached
|
||||
# docker builds and push to the registry
|
||||
deploy:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
needs: [
|
||||
version,
|
||||
build,
|
||||
|
|
|
|||
41
.github/workflows/release.yaml
vendored
41
.github/workflows/release.yaml
vendored
|
|
@ -61,9 +61,16 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
arch: [ "aarch64", "x86_64" ]
|
||||
runs-on: ubuntu-latest
|
||||
include:
|
||||
- arch: "aarch64"
|
||||
runner: "ubuntu-24.04-arm"
|
||||
container: "quay.io/pypa/manylinux_2_28_aarch64"
|
||||
- arch: "x86_64"
|
||||
runner: "ubuntu-latest"
|
||||
container: "quay.io/pypa/manylinux_2_28_x86_64"
|
||||
runs-on: ${{ matrix.runner }}
|
||||
container:
|
||||
image: quay.io/pypa/manylinux_2_28_x86_64
|
||||
image: ${{ matrix.container }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Write version to init file
|
||||
|
|
@ -76,17 +83,17 @@ jobs:
|
|||
dnf install -y epel-release tar wget make gcc openssl-devel bzip2-devel libffi-devel zlib-devel
|
||||
- name: Install Python
|
||||
run: |
|
||||
wget https://www.python.org/ftp/python/3.10.10/Python-3.10.10.tar.xz
|
||||
tar -xf Python-3.10.10.tar.xz
|
||||
cd Python-3.10.10 && ./configure --with-ensurepip=install --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
|
||||
wget https://www.python.org/ftp/python/3.12.9/Python-3.12.9.tar.xz
|
||||
tar -xf Python-3.12.9.tar.xz
|
||||
cd Python-3.12.9 && ./configure --with-ensurepip=install --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
|
||||
make -j 8
|
||||
make altinstall
|
||||
python3.10 --version
|
||||
python3.10 -m ensurepip --upgrade
|
||||
python3.12 --version
|
||||
python3.12 -m ensurepip --upgrade
|
||||
- name: Build Package
|
||||
run: |
|
||||
python3.10 -m pip install -e .
|
||||
python3.10 -m pip install pyinstaller
|
||||
python3.12 -m pip install -e .
|
||||
python3.12 -m pip install pyinstaller
|
||||
# Build executable
|
||||
pyinstaller ytdl-sub.spec
|
||||
mkdir -p /opt/builds
|
||||
|
|
@ -95,7 +102,7 @@ jobs:
|
|||
mv dist/ytdl-sub /opt/builds/ytdl-sub_${{ matrix.arch }}
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ytdl-sub_${{ matrix.arch }}
|
||||
path: /opt/builds/ytdl-sub_${{ matrix.arch }}
|
||||
|
|
@ -112,7 +119,7 @@ jobs:
|
|||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version: "3.12"
|
||||
- name: Write version to init file
|
||||
run: |
|
||||
echo '${{ needs.version.outputs.init_contents }}'> src/ytdl_sub/__init__.py
|
||||
|
|
@ -124,7 +131,7 @@ jobs:
|
|||
.\dist\ytdl-sub.exe -h
|
||||
|
||||
- name: Upload build
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ytdl-sub_exe
|
||||
path: .\dist\ytdl-sub.exe
|
||||
|
|
@ -145,19 +152,19 @@ jobs:
|
|||
echo '${{ needs.version.outputs.init_contents }}' > src/ytdl_sub/__init__.py
|
||||
|
||||
- name: Restore exe build
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ytdl-sub_exe
|
||||
path: /opt/builds
|
||||
|
||||
- name: Restore aarch64 build
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ytdl-sub_aarch64
|
||||
path: /opt/builds
|
||||
|
||||
- name: Restore x86_64 build
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ytdl-sub_x86_64
|
||||
path: /opt/builds
|
||||
|
|
@ -193,13 +200,13 @@ jobs:
|
|||
name: pypi-publish
|
||||
needs:
|
||||
- version
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.12'
|
||||
- name: Write version to init file
|
||||
run: |
|
||||
echo '${{ needs.version.outputs.init_contents }}' > src/ytdl_sub/__init__.py
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -14,9 +14,9 @@ else
|
|||
endif
|
||||
|
||||
lint:
|
||||
@-isort .
|
||||
@-black .
|
||||
@-pylint src/
|
||||
python3 -m isort .
|
||||
python3 -m black .
|
||||
python3 -m pylint src
|
||||
check_lint:
|
||||
isort . --check-only --diff \
|
||||
&& black . --check \
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ FROM ghcr.io/linuxserver/baseimage-alpine:edge
|
|||
###############################################################################
|
||||
# YTDL-SUB INSTALL
|
||||
|
||||
# Needed for phantomjs
|
||||
# For phantomjs
|
||||
ENV OPENSSL_CONF="/etc/ssl"
|
||||
# For downloading thumbnails
|
||||
ENV SSL_CERT_DIR="/etc/ssl/certs/"
|
||||
|
||||
COPY root/ /
|
||||
RUN mkdir -p /config && \
|
||||
|
|
@ -55,6 +57,12 @@ RUN mkdir -p /config && \
|
|||
# CONTAINER CONFIGS
|
||||
|
||||
ENV EDITOR="nano" \
|
||||
HOME="/config"
|
||||
HOME="/config" \
|
||||
DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \
|
||||
DEFAULT_WORKSPACE=/config \
|
||||
CRON_SCRIPT="/config/cron" \
|
||||
CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \
|
||||
LOGS_TO_STDOUT=/config/.cron.log \
|
||||
LSIO_FIRST_PARTY=false
|
||||
|
||||
VOLUME /config
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
FROM lscr.io/linuxserver/code-server:4.18.0-ls181
|
||||
FROM lscr.io/linuxserver/code-server:4.98.2
|
||||
|
||||
# Needed for phantomjs
|
||||
ENV OPENSSL_CONF=/etc/ssl
|
||||
# For phantomjs
|
||||
ENV OPENSSL_CONF="/etc/ssl"
|
||||
# For downloading thumbnails
|
||||
ENV SSL_CERT_DIR="/etc/ssl/certs/"
|
||||
|
||||
###############################################################################
|
||||
# YTDL-SUB INSTALL
|
||||
|
|
@ -20,7 +22,6 @@ RUN mkdir -p /config && \
|
|||
g++ \
|
||||
nano \
|
||||
make \
|
||||
python3.10-dev \
|
||||
python3-pip \
|
||||
fontconfig \
|
||||
xz-utils \
|
||||
|
|
@ -59,7 +60,7 @@ RUN mkdir -p /config && \
|
|||
phantomjs --version ; \
|
||||
fi && \
|
||||
# Install ytdl-sub, ensure it is installed properly
|
||||
pip install --no-cache-dir ytdl_sub-*.whl && \
|
||||
pip install --no-cache-dir --break-system-packages ytdl_sub-*.whl && \
|
||||
ytdl-sub -h && \
|
||||
# Delete unneeded packages after install
|
||||
rm ytdl_sub-*.whl && \
|
||||
|
|
@ -68,7 +69,6 @@ RUN mkdir -p /config && \
|
|||
make \
|
||||
xz-utils \
|
||||
bzip2 \
|
||||
python3.10-dev \
|
||||
python3-venv && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get purge -y --auto-remove && \
|
||||
|
|
@ -77,11 +77,13 @@ RUN mkdir -p /config && \
|
|||
###############################################################################
|
||||
# CONTAINER CONFIGS
|
||||
|
||||
|
||||
ENV YTDL_SUB_TYPE="gui" \
|
||||
EDITOR="nano" \
|
||||
ENV EDITOR="nano" \
|
||||
HOME="/config" \
|
||||
DOCKER_MODS=linuxserver/mods:universal-cron \
|
||||
DEFAULT_WORKSPACE=/config/ytdl-sub-configs
|
||||
DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \
|
||||
DEFAULT_WORKSPACE=/config/ytdl-sub-configs \
|
||||
CRON_SCRIPT="/config/ytdl-sub-configs/cron" \
|
||||
CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \
|
||||
LOGS_TO_STDOUT=/config/.cron.log \
|
||||
LSIO_FIRST_PARTY=false
|
||||
|
||||
VOLUME /config
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
FROM ghcr.io/linuxserver/baseimage-ubuntu:jammy
|
||||
FROM ghcr.io/linuxserver/baseimage-ubuntu:noble
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Needed for phantomjs
|
||||
ENV OPENSSL_CONF=/etc/ssl
|
||||
# For phantomjs
|
||||
ENV OPENSSL_CONF="/etc/ssl"
|
||||
# For downloading thumbnails
|
||||
ENV SSL_CERT_DIR="/etc/ssl/certs/"
|
||||
|
||||
###############################################################################
|
||||
# YTDL-SUB INSTALL
|
||||
|
|
@ -23,7 +25,6 @@ RUN mkdir -p /config && \
|
|||
g++ \
|
||||
nano \
|
||||
make \
|
||||
python3.10-dev \
|
||||
python3-pip \
|
||||
fontconfig \
|
||||
xz-utils \
|
||||
|
|
@ -62,7 +63,7 @@ RUN mkdir -p /config && \
|
|||
phantomjs --version ; \
|
||||
fi && \
|
||||
# Install ytdl-sub, ensure it is installed properly
|
||||
pip install --no-cache-dir ytdl_sub-*.whl && \
|
||||
pip install --no-cache-dir --break-system-packages ytdl_sub-*.whl && \
|
||||
ytdl-sub -h && \
|
||||
# Delete unneeded packages after install
|
||||
rm ytdl_sub-*.whl && \
|
||||
|
|
@ -71,7 +72,6 @@ RUN mkdir -p /config && \
|
|||
make \
|
||||
xz-utils \
|
||||
bzip2 \
|
||||
python3.10-dev \
|
||||
python3-venv && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get purge -y --auto-remove && \
|
||||
|
|
@ -81,6 +81,12 @@ RUN mkdir -p /config && \
|
|||
# CONTAINER CONFIGS
|
||||
|
||||
ENV EDITOR="nano" \
|
||||
HOME="/config"
|
||||
HOME="/config" \
|
||||
DOCKER_MODS=linuxserver/mods:universal-stdout-logs|linuxserver/mods:universal-cron \
|
||||
DEFAULT_WORKSPACE=/config \
|
||||
CRON_SCRIPT="/config/cron" \
|
||||
CRON_WRAPPER_SCRIPT="/config/.cron_wrapper" \
|
||||
LOGS_TO_STDOUT=/config/.cron.log \
|
||||
LSIO_FIRST_PARTY=false
|
||||
|
||||
VOLUME /config
|
||||
68
docker/root/custom-cont-init.d/defaults
Normal file
68
docker/root/custom-cont-init.d/defaults
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#!/usr/bin/with-contenv bash
|
||||
|
||||
echo "Starting ytdl-sub..."
|
||||
|
||||
# copy config
|
||||
[[ ! -e "$DEFAULT_WORKSPACE/config.yaml" ]] && \
|
||||
mkdir -p "$DEFAULT_WORKSPACE" && \
|
||||
cp /defaults/config.yaml "$DEFAULT_WORKSPACE/config.yaml"
|
||||
[[ ! -e "$DEFAULT_WORKSPACE/subscriptions.yaml" ]] && \
|
||||
mkdir -p "$DEFAULT_WORKSPACE" && \
|
||||
cp /defaults/subscriptions.yaml "$DEFAULT_WORKSPACE/subscriptions.yaml"
|
||||
[[ ! -d "$DEFAULT_WORKSPACE/examples" ]] && \
|
||||
mkdir -p "$DEFAULT_WORKSPACE/examples" && \
|
||||
cp -r /defaults/examples/* "$DEFAULT_WORKSPACE/examples"
|
||||
|
||||
[[ ! -e "/config/.bashrc" ]] && \
|
||||
echo "alias ls='ls --color=auto'" > /config/.bashrc && \
|
||||
echo "cd ." >> /config/.bashrc
|
||||
|
||||
# permissions
|
||||
chown -R ${PUID:-abc}:${PGID:-abc} \
|
||||
/config
|
||||
|
||||
# always create empty cron log file on start
|
||||
echo "" > "$LOGS_TO_STDOUT"
|
||||
|
||||
# set up cron
|
||||
if [ "$CRON_SCHEDULE" != "" ] ; then
|
||||
[[ ! -e "$CRON_SCRIPT" ]] && \
|
||||
cp /defaults/cron "$CRON_SCRIPT"
|
||||
|
||||
# create cron script wrapper
|
||||
echo '#!/bin/bash' > "$CRON_WRAPPER_SCRIPT"
|
||||
echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> "$CRON_WRAPPER_SCRIPT"
|
||||
echo "cd \"$DEFAULT_WORKSPACE\"" >> "$CRON_WRAPPER_SCRIPT"
|
||||
echo ". \"$CRON_SCRIPT\" | tee -a \"$LOGS_TO_STDOUT\"" >> "$CRON_WRAPPER_SCRIPT"
|
||||
chmod +x "$CRON_WRAPPER_SCRIPT"
|
||||
chown abc:abc "$CRON_WRAPPER_SCRIPT"
|
||||
|
||||
# Set the crontab file to the schedule, cleanly
|
||||
CRON_SCHEDULE_CLEAN="${CRON_SCHEDULE//\"/}"
|
||||
CRON_SCHEDULE_CLEAN="${CRON_SCHEDULE_CLEAN//\'/}"
|
||||
|
||||
echo "# min hour day month weekday command" > /config/crontabs/abc
|
||||
echo "$CRON_SCHEDULE_CLEAN $CRON_WRAPPER_SCRIPT" >> /config/crontabs/abc
|
||||
|
||||
chmod +x "$CRON_SCRIPT"
|
||||
chown abc:abc "$CRON_SCRIPT"
|
||||
|
||||
crontab -u abc /config/crontabs/abc
|
||||
|
||||
CRON_SUCCESS=$?
|
||||
if [ $CRON_SUCCESS -eq 0 ] ; then
|
||||
echo "Cron enabled with schedule $CRON_SCHEDULE_CLEAN"
|
||||
|
||||
if [ "$CRON_RUN_ON_START" = true ] ; then
|
||||
echo "Running cron script on start in the background"
|
||||
# ensure it runs as abc to respect puid/guid with delay for tail to start
|
||||
su -s "/bin/bash" -c "sleep 5 && . '$CRON_WRAPPER_SCRIPT'" abc > /dev/null 2>&1 &
|
||||
fi
|
||||
else
|
||||
echo "Error in CRON_SCHEDULE definition, disabling cron."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "CRON_SCHEDULE not specified, leaving crontabs as-is. Current configuration in /config/crontabs/abc"
|
||||
cat /config/crontabs/abc
|
||||
fi
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Exit if not gui
|
||||
if [ "$YTDL_SUB_TYPE" != "gui" ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Checking ytdl-sub-gui defaults..."
|
||||
|
||||
# copy config
|
||||
[[ ! -e /config/ytdl-sub-configs/config.yaml ]] && \
|
||||
mkdir -p /config/ytdl-sub-configs && \
|
||||
cp /defaults/config.yaml /config/ytdl-sub-configs/config.yaml
|
||||
[[ ! -e /config/ytdl-sub-configs/subscriptions.yaml ]] && \
|
||||
mkdir -p /config/ytdl-sub-configs && \
|
||||
cp /defaults/subscriptions.yaml /config/ytdl-sub-configs/subscriptions.yaml
|
||||
[[ ! -d /config/ytdl-sub-configs/examples ]] && \
|
||||
mkdir -p /config/ytdl-sub-configs/examples && \
|
||||
cp /defaults/examples/* /config/ytdl-sub-configs/examples
|
||||
|
||||
# permissions
|
||||
chown -R ${PUID:-abc}:${PGID:-abc} \
|
||||
/config
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Exit if gui
|
||||
if [ "$YTDL_SUB_TYPE" == "gui" ] ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Checking ytdl-sub defaults..."
|
||||
|
||||
# copy config
|
||||
[[ ! -e /config/config.yaml ]] && \
|
||||
cp /defaults/config.yaml /config/config.yaml
|
||||
[[ ! -e /config/subscriptions.yaml ]] && \
|
||||
cp /defaults/subscriptions.yaml /config/subscriptions.yaml
|
||||
[[ ! -d /config/examples ]] && \
|
||||
cp -R /defaults/examples /config/
|
||||
|
||||
# permissions
|
||||
chown -R ${PUID:-abc}:${PGID:-abc} \
|
||||
/config
|
||||
4
docker/root/defaults/cron
Normal file
4
docker/root/defaults/cron
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
echo "Beginning cron job..."
|
||||
|
||||
# Place your ytdl-sub command(s) here.
|
||||
# This script is executed in the same relative path as this file.
|
||||
15
docker/root/etc/s6-overlay/s6-rc.d/init-adduser/branding
Normal file
15
docker/root/etc/s6-overlay/s6-rc.d/init-adduser/branding
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
――――――――――――――――――――――――――――――――――――
|
||||
██╗ ██╗████████╗██████╗ ██╗
|
||||
╚██╗ ██╔╝╚══██╔══╝██╔══██╗██║
|
||||
╚████╔╝ ██║ ██║ ██║██║
|
||||
╚██╔╝ ██║ ██║ ██║██║
|
||||
██║ ██║ ██████╔╝███████╗
|
||||
╚═╝ ╚═╝ ╚═════╝ ╚══════╝
|
||||
|
||||
███████╗██╗ ██╗██████╗
|
||||
██╔════╝██║ ██║██╔══██╗
|
||||
███████╗██║ ██║██████╔╝
|
||||
╚════██║██║ ██║██╔══██╗
|
||||
███████║╚██████╔╝██████╔╝
|
||||
╚══════╝ ╚═════╝ ╚═════╝
|
||||
――――――――――――――――――――――――――――――――――――
|
||||
|
|
@ -6,8 +6,34 @@ services:
|
|||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- CRON_SCHEDULE="*/1 * * * *"
|
||||
- CRON_RUN_ON_START=true
|
||||
volumes:
|
||||
- ./volumes/ytdl-sub-gui:/config
|
||||
ports:
|
||||
- 8443:8443
|
||||
restart: unless-stopped
|
||||
ytdl-sub:
|
||||
image: ytdl-sub:local
|
||||
container_name: ytdl-sub
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- CRON_SCHEDULE="*/1 * * * *"
|
||||
- CRON_RUN_ON_START=true
|
||||
volumes:
|
||||
- ./volumes/ytdl-sub:/config
|
||||
restart: unless-stopped
|
||||
ytdl-sub-ubuntu:
|
||||
image: ytdl-sub-ubuntu:local
|
||||
container_name: ytdl-sub-ubuntu
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- CRON_SCHEDULE="*/1 * * * *"
|
||||
- CRON_RUN_ON_START=true
|
||||
volumes:
|
||||
- ./volumes/ytdl-sub:/config
|
||||
restart: unless-stopped
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ with a ``.nfo`` extension. You can add any values into the NFO.
|
|||
|
||||
``kodi_safe``
|
||||
|
||||
:expected type: Optional[Boolean]
|
||||
:expected type: OverridesBooleanFormatterValidator
|
||||
:description:
|
||||
Defaults to False. Kodi does not support > 3-byte unicode characters, which include
|
||||
emojis and some foreign language characters. Setting this to True will replace those
|
||||
|
|
@ -554,7 +554,7 @@ Usage:
|
|||
|
||||
``kodi_safe``
|
||||
|
||||
:expected type: Optional[Boolean]
|
||||
:expected type: OverridesBooleanFormatterValidator
|
||||
:description:
|
||||
Defaults to False. Kodi does not support > 3-byte unicode characters, which include
|
||||
emojis and some foreign language characters. Setting this to True will replace those
|
||||
|
|
@ -640,6 +640,8 @@ Defines where to output files and thumbnails after all post-processing has compl
|
|||
maintain_download_archive: True
|
||||
keep_files_before: now
|
||||
keep_files_after: 19000101
|
||||
keep_max_files: 1000
|
||||
keep_files_date_eval: "{upload_date_standardized}"
|
||||
|
||||
``download_archive_name``
|
||||
|
||||
|
|
@ -690,6 +692,16 @@ Defines where to output files and thumbnails after all post-processing has compl
|
|||
``keep_max_files``.
|
||||
|
||||
|
||||
``keep_files_date_eval``
|
||||
|
||||
:expected type: str
|
||||
:description:
|
||||
Uses this standardized date in the form of YYYY-MM-DD to record in the
|
||||
download archive for a given entry. Subsequently, uses this value to
|
||||
perform evaluation for keep_files_before/after and keep_max_files. Defaults
|
||||
to the entry's upload_date_standardized variable.
|
||||
|
||||
|
||||
``keep_max_files``
|
||||
|
||||
:expected type: Optional[OverridesFormatter]
|
||||
|
|
@ -966,6 +978,9 @@ scripted.
|
|||
presets:
|
||||
my_example_preset:
|
||||
throttle_protection:
|
||||
sleep_per_request_s:
|
||||
min: 5.5
|
||||
max: 10.4
|
||||
sleep_per_download_s:
|
||||
min: 2.2
|
||||
max: 10.8
|
||||
|
|
@ -1001,6 +1016,16 @@ scripted.
|
|||
ytdl-sub to perform post-processing.
|
||||
|
||||
|
||||
``sleep_per_request_s``
|
||||
|
||||
:expected type: Optional[Range]
|
||||
:description:
|
||||
Number in seconds to sleep between each request during metadata download. Note that
|
||||
metadata download refers to the initial info.json download, not the actual audio/video
|
||||
download for the entry. Also, yt-dlp only supports a single value at this time for this,
|
||||
so will always use the max value.
|
||||
|
||||
|
||||
``sleep_per_subscription_s``
|
||||
|
||||
:expected type: Optional[Range]
|
||||
|
|
|
|||
|
|
@ -659,3 +659,9 @@ ytdl_sub_input_url_index
|
|||
:type: ``Integer``
|
||||
:description:
|
||||
The index of the input URL as defined in the subscription, top-most being the 0th index.
|
||||
|
||||
ytdl_sub_keep_files_date_eval
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
:type: ``String``
|
||||
:description:
|
||||
The standardized date variable supplied in ``output_options.keep_files_date_eval``.
|
||||
|
|
|
|||
|
|
@ -523,6 +523,38 @@ sub
|
|||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
|
||||
Print Functions
|
||||
---------------
|
||||
|
||||
print
|
||||
~~~~~
|
||||
:spec: ``print(message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer]) -> ReturnableArgument``
|
||||
|
||||
:description:
|
||||
Print the ``message`` and return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
|
||||
print_if_false
|
||||
~~~~~~~~~~~~~~
|
||||
:spec: ``print_if_false(message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer]) -> ReturnableArgument``
|
||||
|
||||
:description:
|
||||
Print the ``message`` if ``passthrough`` evaluates to ``false``. Return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
|
||||
print_if_true
|
||||
~~~~~~~~~~~~~
|
||||
:spec: ``print_if_true(message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer]) -> ReturnableArgument``
|
||||
|
||||
:description:
|
||||
Print the ``message`` if ``passthrough`` evaluates to ``true``. Return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
|
||||
Regex Functions
|
||||
---------------
|
||||
|
||||
|
|
@ -634,7 +666,7 @@ capitalize
|
|||
|
||||
concat
|
||||
~~~~~~
|
||||
:spec: ``concat(values: String, ...) -> String``
|
||||
:spec: ``concat(values: AnyArgument, ...) -> String``
|
||||
|
||||
:description:
|
||||
Concatenate multiple Strings into a single String.
|
||||
|
|
@ -660,6 +692,24 @@ contains_any
|
|||
:description:
|
||||
Returns true if any element in ``contains_array`` is in ``string``. False otherwise.
|
||||
|
||||
join
|
||||
~~~~
|
||||
:spec: ``join(separator: String, array: Array) -> String``
|
||||
|
||||
:description:
|
||||
Join all elements in the array together as a string, and insert the
|
||||
separator between them.
|
||||
|
||||
:usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
%join( ", ", ["item1", "item2"] )
|
||||
}
|
||||
|
||||
# "item1, item2"
|
||||
|
||||
lower
|
||||
~~~~~
|
||||
:spec: ``lower(string: String) -> String``
|
||||
|
|
@ -710,6 +760,23 @@ string
|
|||
:description:
|
||||
Cast to String.
|
||||
|
||||
strip
|
||||
~~~~~
|
||||
:spec: ``strip(string: String) -> String``
|
||||
|
||||
:description:
|
||||
Strip a string of all its whitespace at the beginning and end.
|
||||
|
||||
:usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
%trim(" delete the outer! ")
|
||||
}
|
||||
|
||||
# "delete the outer!"
|
||||
|
||||
titlecase
|
||||
~~~~~~~~~
|
||||
:spec: ``titlecase(string: String) -> String``
|
||||
|
|
|
|||
|
|
@ -62,6 +62,29 @@ See the prebuilt preset :doc:`chunk_initial_download </prebuilt_presets/helpers>
|
|||
|
||||
See the prebuilt preset :doc:`Filter Keywords </prebuilt_presets/helpers>`.
|
||||
|
||||
...prevent creation of NFO file
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Creation of NFO files is done by the NFO tags plugin. It, as any other plugin, can be disabled:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
nfo_tags:
|
||||
enabled: False
|
||||
|
||||
...prevent download of images
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The :ref:`config_reference/prebuilt_presets/tv_show:TV Show` presets by default downloads images corresponding to show and each episode.
|
||||
This can be prevented by overriding following variables:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
overrides:
|
||||
tv_show_fanart_file_name: "" # to stop creation of fanart.jpg in subscription
|
||||
tv_show_poster_file_name: "" # to stop creation of poster.jpg in subscription
|
||||
thumbnail_name: "" # to stop creation of episode thumbnails
|
||||
|
||||
There is a bug where...
|
||||
-----------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,127 +1,43 @@
|
|||
Automating Downloads
|
||||
====================
|
||||
|
||||
One of the key capabilities of ``ytdl-sub`` automating new downloads.
|
||||
To take advantage of this, you must set up scheduling to execute the commands at some interval.
|
||||
How you set up this scheduling depends on which version of ``ytdl-sub`` you downloaded.
|
||||
|
||||
|
||||
:ref:`Guide for Docker and Unraid Containers <guides/getting_started/automating_downloads:docker and unraid>`
|
||||
|
||||
:ref:`Guide for Linux <guides/getting_started/automating_downloads:linux>`
|
||||
|
||||
:ref:`Guide for Windows <guides/getting_started/automating_downloads:windows>`
|
||||
|
||||
.. _cron tab manpage: https://man7.org/linux/man-pages/man5/crontab.5.html#EXAMPLE_CRON_FILE
|
||||
.. _cron scheduling syntax: https://crontab.guru/#0_*/6_*_*_*
|
||||
|
||||
.. _docker-unraid-setup:
|
||||
|
||||
Docker and Unraid
|
||||
-----------------
|
||||
|
||||
.. tab-set::
|
||||
|
||||
.. tab-item:: GUI Image
|
||||
|
||||
The script that will execute automatically is located at ``/config/ytdl-sub-configs/run_cron``.
|
||||
Cron is preconfigured in every ytdl-sub docker container. Enable by adding the following
|
||||
ENV variables to your docker setup.
|
||||
|
||||
Access your container at http://localhost:8443/, then in the GUI terminal run these commands:
|
||||
.. code-block:: yaml
|
||||
|
||||
.. code-block:: shell
|
||||
services:
|
||||
ytdl-sub:
|
||||
environment:
|
||||
- CRON_SCHEDULE="0 */6 * * *"
|
||||
- CRON_RUN_ON_START=false
|
||||
|
||||
echo '#!/bin/bash' > /config/ytdl-sub-configs/run_cron
|
||||
echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /config/ytdl-sub-configs/run_cron
|
||||
echo "echo 'Cron started, running ytdl-sub...'" >> /config/ytdl-sub-configs/run_cron
|
||||
echo "cd /config/ytdl-sub-configs" >> /config/ytdl-sub-configs/run_cron
|
||||
echo "ytdl-sub --config=config.yaml sub subscriptions.yaml" >> /config/ytdl-sub-configs/run_cron
|
||||
chmod +x /config/ytdl-sub-configs/run_cron
|
||||
chown abc:abc /config/ytdl-sub-configs/run_cron
|
||||
|
||||
You can test the newly created script by running:
|
||||
- ``CRON_SCHEDULE`` follows the standard `cron scheduling syntax`_. The above value will run the script once every 6 hours.
|
||||
- ``CRON_RUN_ON_START`` toggles whether to run your cron script on container start in addition to the cron schedule.
|
||||
|
||||
.. code-block:: shell
|
||||
The cron script will reside in the main directory with the file name ``cron``.
|
||||
Cron logs should show when viewing the Docker logs.
|
||||
|
||||
/config/ytdl-sub-configs/run_cron
|
||||
|
||||
To create the cron definition, run the following command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo "# min hour day month weekday command" > /config/crontabs/abc
|
||||
echo " 0 */6 * * * /config/ytdl-sub-configs/run_cron" >> /config/crontabs/abc
|
||||
|
||||
This will run the script every 6 hours. To run every hour, change ``*/6`` to ``*/1``, or to run once a day, change the same value to the hour (in 24hr format) that you want it to run at. See the `cron tab manpage`_ for more options.
|
||||
|
||||
.. tab-item:: Headless Image
|
||||
|
||||
.. _LinuxServer's Universal Cron mod: https://github.com/linuxserver/docker-mods/tree/universal-cron
|
||||
|
||||
The first step is to ensure you have `LinuxServer's Universal Cron mod`_ enabled via the environment variable. For the GUI image, this is already included (no need to add it).
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
services:
|
||||
ytdl-sub:
|
||||
image: ghcr.io/jmbannon/ytdl-sub:latest
|
||||
container_name: ytdl-sub
|
||||
environment:
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- DOCKER_MODS=linuxserver/mods:universal-cron # <-- Make sure you have this!
|
||||
volumes:
|
||||
# ensure directories have user permissions
|
||||
- </path/to/ytdl-sub/config>:/config
|
||||
- </path/to/ytdl-sub/tv_shows>:/tv_shows
|
||||
restart: unless-stopped
|
||||
|
||||
This line will tell your container to install and enable cron on start.
|
||||
|
||||
If you had to add this line, you will need to restart your container.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
docker compose restart
|
||||
|
||||
The script that will execute automatically is located at ``/config/run_cron``.
|
||||
|
||||
Access your container from the terminal by running:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
docker exec -itu abc ytdl-sub /bin/bash
|
||||
|
||||
then in the terminal run these commands:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo '#!/bin/bash' > /config/run_cron
|
||||
echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /config/run_cron
|
||||
echo "echo 'Cron started, running ytdl-sub...'" >> /config/run_cron
|
||||
echo "cd /config" >> /config/run_cron
|
||||
echo "ytdl-sub --config=config.yaml sub subscriptions.yaml" >> /config/run_cron
|
||||
chmod +x /config/run_cron
|
||||
chown abc:abc /config/run_cron
|
||||
|
||||
You can test the newly created script by running:
|
||||
|
||||
.. code-block::
|
||||
|
||||
/config/run_cron
|
||||
|
||||
To create the cron definition, run the following command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
echo "# min hour day month weekday command" > /config/crontabs/abc
|
||||
echo " 0 */6 * * * /config/run_cron" >> /config/crontabs/abc
|
||||
|
||||
This will run the script every 6 hours. To run every hour, change ``*/6`` to ``*/1``, or to run once a day, change the same value to the hour (in 24hr format) that you want it to run at. See the `cron tab manpage`_ for more options.
|
||||
|
||||
.. _linux-setup:
|
||||
|
||||
Linux
|
||||
-----
|
||||
Must configure crontab manually, like so:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ Docker Compose is an easy "set it and forget it" install method. Follow the inst
|
|||
- PUID=1000
|
||||
- PGID=1000
|
||||
- TZ=America/Los_Angeles
|
||||
- DOCKER_MODS=linuxserver/mods:universal-cron
|
||||
volumes:
|
||||
- <path/to/ytdl-sub/config>:/config
|
||||
- <path/to/tv_shows>:/tv_shows # optional
|
||||
|
|
|
|||
|
|
@ -28,23 +28,18 @@ Plex
|
|||
|
||||
----------------------------------------------
|
||||
|
||||
Generic Presets
|
||||
===============
|
||||
|
||||
There are two main methods for downloading and formatting videos as a TV show.
|
||||
|
||||
TV Show by Date
|
||||
---------------
|
||||
===============
|
||||
|
||||
TV Show by Date will organize something like a YouTube channel or playlist into a tv show, where seasons and episodes are organized using upload date.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
-------
|
||||
Must define ``tv_show_directory``. Available presets:
|
||||
|
||||
* ``"Kodi TV Show by Date"``
|
||||
* ``"Jellyfin TV Show by Date"``
|
||||
* ``"Plex TV Show by Date"``
|
||||
* ``Kodi TV Show by Date``
|
||||
* ``Jellyfin TV Show by Date``
|
||||
* ``Plex TV Show by Date``
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
|
@ -72,30 +67,68 @@ Must define ``tv_show_directory``. Available presets:
|
|||
- "https://www.youtube.com/@rickbeato240"
|
||||
|
||||
Advanced Usage
|
||||
~~~~~~~~~~~~~~
|
||||
--------------
|
||||
|
||||
If you prefer a different organization method, you can instead apply multiple presets to your subscriptions.
|
||||
If you prefer a different season/episode organization method, you can set the following override variables.
|
||||
|
||||
You will need a base of one of the below:
|
||||
.. code-block:: yaml
|
||||
|
||||
* ``kodi_tv_show_by_date``
|
||||
* ``jellyfin_tv_show_by_date``
|
||||
* ``plex_tv_show_by_date``
|
||||
__preset__:
|
||||
overrides:
|
||||
tv_show_directory: "/tv_shows"
|
||||
tv_show_by_date_season_ordering: "upload-year-month"
|
||||
tv_show_by_date_episode_ordering: "upload-day"
|
||||
|
||||
And then add one of these:
|
||||
Or for a specific preset
|
||||
|
||||
* ``season_by_year__episode_by_month_day``
|
||||
* ``season_by_year_month__episode_by_day``
|
||||
* ``season_by_year__episode_by_month_day_reversed``
|
||||
|
||||
* Episode numbers are reversed, meaning more recent episodes appear at the top of a season by having a lower value.
|
||||
* ``season_by_year__episode_by_download_index``
|
||||
|
||||
* Episodes are numbered by the download order. NOTE that this is fetched using the length of the download archive. Do not use if you intend to remove old videos.
|
||||
.. code-block:: yaml
|
||||
|
||||
"~Kids Toys Play":
|
||||
url: "https://www.youtube.com/@KidsToysPlayChannel"
|
||||
tv_show_by_date_season_ordering: "upload-year-month"
|
||||
tv_show_by_date_episode_ordering: "upload-day"
|
||||
|
||||
The following are supported. Be sure the combined season + episode ordering
|
||||
include the year, month, day, i.e. upload-year + upload-month-day.
|
||||
|
||||
|
||||
Season Ordering
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
``tv_show_by_date_season_ordering`` supports one of the following:
|
||||
|
||||
* ``upload-year`` (default)
|
||||
* ``upload-year-month``
|
||||
* ``release-year``
|
||||
* ``release-year-month``
|
||||
|
||||
|
||||
Episode Ordering
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``tv_show_by_date_episode_ordering`` supports one of the following:
|
||||
|
||||
* ``upload-month-day`` (default)
|
||||
* ``upload-month-day-reversed``
|
||||
|
||||
* Reversed means more recent episodes appear at the top of a season by having a lower value.
|
||||
* ``upload-day``
|
||||
* ``release-day``
|
||||
* ``release-month-day``
|
||||
* ``release-month-day-reversed``
|
||||
* ``download-index``
|
||||
|
||||
* Episodes are numbered by the download order. **NOTE**: this is fetched using the length of the download archive. Do not use if you intend to remove old videos.
|
||||
|
||||
TV Show by Date presets use the following for defaults:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
tv_show_by_date_season_ordering: "upload-year"
|
||||
tv_show_by_date_episode_ordering: "upload-month-day"
|
||||
|
||||
TV Show Collection
|
||||
------------------
|
||||
==================
|
||||
|
||||
TV Show Collections set each URL as its own season. If a video belongs to multiple URLs
|
||||
(i.e. a channel and a channel's playlist), the video will only download once and reside in
|
||||
|
|
@ -109,12 +142,12 @@ Two main use cases of a collection are:
|
|||
represents a separate channel/playlist.
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
-------
|
||||
Must define ``tv_show_directory``. Available presets:
|
||||
|
||||
* ``"Kodi TV Show Collection"``
|
||||
* ``"Jellyfin TV Show Collection"``
|
||||
* ``"Plex TV Show Collection"``
|
||||
* ``Kodi TV Show Collection``
|
||||
* ``Jellyfin TV Show Collection``
|
||||
* ``Plex TV Show Collection``
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
|
@ -132,21 +165,44 @@ Must define ``tv_show_directory``. Available presets:
|
|||
s02_url: "https://www.youtube.com/playlist?list=PLE62gWlWZk5NWVAVuf0Lm9jdv_-_KXs0W"
|
||||
|
||||
Advanced Usage
|
||||
~~~~~~~~~~~~~~
|
||||
--------------
|
||||
|
||||
If you prefer a different organization method, you can instead apply multiple presets to your subscriptions.
|
||||
If you prefer a different episode organization method, you can set the following override variables.
|
||||
|
||||
You will need a base of one of the below:
|
||||
.. code-block:: yaml
|
||||
|
||||
* ``kodi_tv_show_collection``
|
||||
* ``jellyfin_tv_show_collection``
|
||||
* ``plex_tv_show_collection``
|
||||
__preset__:
|
||||
overrides:
|
||||
tv_show_directory: "/tv_shows"
|
||||
tv_show_collection_episode_ordering: "release-year-month-day"
|
||||
|
||||
And then add one of these:
|
||||
Or for a specific preset
|
||||
|
||||
* ``season_by_collection__episode_by_year_month_day``
|
||||
* ``season_by_collection__episode_by_year_month_day_reversed``
|
||||
* ``season_by_collection__episode_by_playlist_index``
|
||||
|
||||
* Only use playlist_index episode formatting for playlists that will be fully downloaded once and never again. Otherwise, indices can change.
|
||||
* ``season_by_collection__episode_by_playlist_index_reversed``
|
||||
.. code-block:: yaml
|
||||
|
||||
"~Beyond the Guitar":
|
||||
tv_show_collection_episode_ordering: "release-year-month-day"
|
||||
s01_name: "Videos"
|
||||
s01_url: "https://www.youtube.com/c/BeyondTheGuitar"
|
||||
s02_name: "Covers"
|
||||
s02_url: "https://www.youtube.com/playlist?list=PLE62gWlWZk5NWVAVuf0Lm9jdv_-_KXs0W"
|
||||
|
||||
|
||||
The following are supported.
|
||||
|
||||
|
||||
Episode Ordering
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``tv_show_collection_episode_ordering`` supports one of the following:
|
||||
|
||||
* ``upload-year-month-day`` (default)
|
||||
* ``upload-year-month-day-reversed``
|
||||
* ``release-year-month-day``
|
||||
* ``release-year-month-day-reversed``
|
||||
* ``playlist-index``
|
||||
|
||||
* Only use ``playlist-index`` episode formatting for playlists that will be fully downloaded once and never again. Otherwise, indices can change.
|
||||
* ``playlist-index-reversed``
|
||||
|
||||
TV Show Collection presets use upload-year-month-day as the default.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ classifiers = [
|
|||
"Programming Language :: Python :: 3.11",
|
||||
]
|
||||
dependencies = [
|
||||
"yt-dlp[default]==2024.12.23",
|
||||
"yt-dlp[default]==2025.5.22",
|
||||
"colorama~=0.4",
|
||||
"mergedeep~=1.3",
|
||||
"mediafile~=0.12",
|
||||
|
|
@ -48,8 +48,8 @@ test = [
|
|||
]
|
||||
lint = [
|
||||
"black==24.10.0",
|
||||
"isort==5.13.2",
|
||||
"pylint==3.3.3",
|
||||
"isort==6.0.1",
|
||||
"pylint==3.3.7",
|
||||
]
|
||||
docs = [
|
||||
"sphinx>=7,<9",
|
||||
|
|
|
|||
|
|
@ -271,6 +271,6 @@ def main() -> List[Subscription]:
|
|||
transaction_log_file_path=args.transaction_log,
|
||||
)
|
||||
|
||||
output_summary(subscriptions)
|
||||
output_summary(subscriptions, suppress_colors=args.suppress_colors)
|
||||
|
||||
return subscriptions
|
||||
|
|
|
|||
|
|
@ -8,16 +8,16 @@ from ytdl_sub.utils.logger import Logger
|
|||
logger = Logger.get()
|
||||
|
||||
|
||||
def _green(value: str) -> str:
|
||||
return Fore.GREEN + value + Fore.RESET
|
||||
def _green(value: str, suppress_colors: bool = False) -> str:
|
||||
return value if suppress_colors else Fore.GREEN + value + Fore.RESET
|
||||
|
||||
|
||||
def _red(value: str) -> str:
|
||||
return Fore.RED + value + Fore.RESET
|
||||
def _red(value: str, suppress_colors: bool = False) -> str:
|
||||
return value if suppress_colors else Fore.RED + value + Fore.RESET
|
||||
|
||||
|
||||
def _no_color(value: str) -> str:
|
||||
return Fore.RESET + value + Fore.RESET
|
||||
def _no_color(value: str, suppress_colors: bool = False) -> str:
|
||||
return value if suppress_colors else Fore.RESET + value + Fore.RESET
|
||||
|
||||
|
||||
def _str_int(value: int) -> str:
|
||||
|
|
@ -26,21 +26,23 @@ def _str_int(value: int) -> str:
|
|||
return str(value)
|
||||
|
||||
|
||||
def _color_int(value: int) -> str:
|
||||
def _color_int(value: int, suppress_colors: bool = False) -> str:
|
||||
str_int = _str_int(value)
|
||||
if value > 0:
|
||||
return _green(str_int)
|
||||
return _green(str_int, suppress_colors)
|
||||
if value < 0:
|
||||
return _red(str_int)
|
||||
return _no_color(str_int)
|
||||
return _red(str_int, suppress_colors)
|
||||
return _no_color(str_int, suppress_colors)
|
||||
|
||||
|
||||
def output_summary(subscriptions: List[Subscription]) -> None:
|
||||
def output_summary(subscriptions: List[Subscription], suppress_colors: bool) -> None:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
subscriptions
|
||||
Processed subscriptions
|
||||
suppress_colors
|
||||
Whether to have color or not
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -65,21 +67,21 @@ def output_summary(subscriptions: List[Subscription]) -> None:
|
|||
|
||||
# Initialize widths to 0
|
||||
width_sub_name: int = max(len(sub.name) for sub in subscriptions) + 4 # aesthetics
|
||||
width_num_entries_added: int = len(_color_int(total_added))
|
||||
width_num_entries_modified: int = len(_color_int(total_modified))
|
||||
width_num_entries_removed: int = len(_color_int(total_removed))
|
||||
width_num_entries_added: int = len(_color_int(total_added, suppress_colors))
|
||||
width_num_entries_modified: int = len(_color_int(total_modified, suppress_colors))
|
||||
width_num_entries_removed: int = len(_color_int(total_removed, suppress_colors))
|
||||
width_num_entries: int = len(str(total_entries)) + 4 # aesthetics
|
||||
|
||||
# Build the summary
|
||||
for subscription in subscriptions:
|
||||
num_entries_added = _color_int(subscription.num_entries_added)
|
||||
num_entries_modified = _color_int(subscription.num_entries_modified)
|
||||
num_entries_removed = _color_int(subscription.num_entries_removed * -1)
|
||||
num_entries_added = _color_int(subscription.num_entries_added, suppress_colors)
|
||||
num_entries_modified = _color_int(subscription.num_entries_modified, suppress_colors)
|
||||
num_entries_removed = _color_int(subscription.num_entries_removed * -1, suppress_colors)
|
||||
num_entries = str(subscription.num_entries)
|
||||
status = (
|
||||
_red(subscription.exception.__class__.__name__)
|
||||
_red(subscription.exception.__class__.__name__, suppress_colors)
|
||||
if subscription.exception
|
||||
else _green("✔")
|
||||
else _green("✔", suppress_colors)
|
||||
)
|
||||
|
||||
summary.append(
|
||||
|
|
@ -92,14 +94,16 @@ def output_summary(subscriptions: List[Subscription]) -> None:
|
|||
)
|
||||
|
||||
total_errors_str = (
|
||||
_green("Success") if total_errors == 0 else _red(f"Error{'s' if total_errors > 1 else ''}")
|
||||
_green("Success", suppress_colors)
|
||||
if total_errors == 0
|
||||
else _red(f"Error{'s' if total_errors > 1 else ''}", suppress_colors)
|
||||
)
|
||||
|
||||
summary.append(
|
||||
f"{total_subs_str:<{width_sub_name}} "
|
||||
f"{_color_int(total_added):>{width_num_entries_added}} "
|
||||
f"{_color_int(total_modified):>{width_num_entries_modified}} "
|
||||
f"{_color_int(total_removed):>{width_num_entries_removed}} "
|
||||
f"{_color_int(total_added, suppress_colors):>{width_num_entries_added}} "
|
||||
f"{_color_int(total_modified, suppress_colors):>{width_num_entries_modified}} "
|
||||
f"{_color_int(total_removed * -1, suppress_colors):>{width_num_entries_removed}} "
|
||||
f"{total_entries:>{width_num_entries}} "
|
||||
f"{total_errors_str}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ class MainArguments:
|
|||
short="-m",
|
||||
long="--match",
|
||||
)
|
||||
SUPPRESS_COLORS = CLIArgument(short="-nc", long="--suppress-colors")
|
||||
|
||||
@classmethod
|
||||
def all(cls) -> List[CLIArgument]:
|
||||
|
|
@ -59,6 +60,7 @@ class MainArguments:
|
|||
cls.TRANSACTION_LOG,
|
||||
cls.SUPPRESS_TRANSACTION_LOG,
|
||||
cls.MATCH,
|
||||
cls.SUPPRESS_COLORS,
|
||||
]
|
||||
|
||||
@classmethod
|
||||
|
|
@ -129,6 +131,13 @@ def _add_shared_arguments(arg_parser: argparse.ArgumentParser, suppress_defaults
|
|||
help="do not output transaction logs to console or file",
|
||||
default=argparse.SUPPRESS if suppress_defaults else False,
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
MainArguments.SUPPRESS_COLORS.short,
|
||||
MainArguments.SUPPRESS_COLORS.long,
|
||||
action="store_true",
|
||||
help="do not use colors in ytdl-sub output",
|
||||
default=argparse.SUPPRESS if suppress_defaults else False,
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
MainArguments.MATCH.short,
|
||||
MainArguments.MATCH.long,
|
||||
|
|
|
|||
|
|
@ -221,3 +221,12 @@ class Overrides(UnstructuredDictFormatterValidator, Scriptable):
|
|||
return self._apply_to_resolvable(
|
||||
formatter=formatter, entry=None, function_overrides=None
|
||||
).native
|
||||
|
||||
def evaluate_boolean(
|
||||
self, formatter: StringFormatterValidator, entry: Optional[Entry] = None
|
||||
) -> bool:
|
||||
"""
|
||||
Apply a formatter, and evaluate it to a boolean
|
||||
"""
|
||||
output = self.apply_formatter(formatter=formatter, entry=entry)
|
||||
return ScriptUtils.bool_formatter_output(output)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ from ytdl_sub.config.validators.options import OptionsValidatorT
|
|||
from ytdl_sub.config.validators.options import ToggleableOptionsDictValidator
|
||||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.utils.file_handler import FileMetadata
|
||||
from ytdl_sub.utils.script import ScriptUtils
|
||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import DownloadArchiver
|
||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||
|
||||
|
|
@ -49,9 +48,7 @@ class Plugin(BasePlugin[OptionsValidatorT], Generic[OptionsValidatorT], ABC):
|
|||
Returns True if enabled, False if disabled.
|
||||
"""
|
||||
if isinstance(self.plugin_options, ToggleableOptionsDictValidator):
|
||||
return ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(self.plugin_options.enable)
|
||||
)
|
||||
return self.overrides.evaluate_boolean(self.plugin_options.enable)
|
||||
return True
|
||||
|
||||
def ytdl_options_match_filters(self) -> Tuple[List[str], List[str]]:
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
|
||||
from ytdl_sub.config.defaults import DEFAULT_DOWNLOAD_ARCHIVE_NAME
|
||||
from ytdl_sub.config.overrides import Overrides
|
||||
from ytdl_sub.config.plugin.plugin_operation import PluginOperation
|
||||
from ytdl_sub.config.validators.options import OptionsDictValidator
|
||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES as v
|
||||
from ytdl_sub.validators.file_path_validators import OverridesStringFormatterFilePathValidator
|
||||
from ytdl_sub.validators.file_path_validators import StringFormatterFileNameValidator
|
||||
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
||||
from ytdl_sub.validators.string_datetime import StringDatetimeValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import OverridesIntegerFormatterValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import StandardizedDateValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import (
|
||||
UnstructuredOverridesDictFormatterValidator,
|
||||
|
|
@ -65,7 +69,7 @@ class YTDLOptions(UnstructuredOverridesDictFormatterValidator):
|
|||
# pylint: disable=line-too-long
|
||||
|
||||
|
||||
class OutputOptions(StrictDictValidator):
|
||||
class OutputOptions(OptionsDictValidator):
|
||||
"""
|
||||
Defines where to output files and thumbnails after all post-processing has completed.
|
||||
|
||||
|
|
@ -87,6 +91,8 @@ class OutputOptions(StrictDictValidator):
|
|||
maintain_download_archive: True
|
||||
keep_files_before: now
|
||||
keep_files_after: 19000101
|
||||
keep_max_files: 1000
|
||||
keep_files_date_eval: "{upload_date_standardized}"
|
||||
"""
|
||||
|
||||
_required_keys = {"output_directory", "file_name"}
|
||||
|
|
@ -99,6 +105,8 @@ class OutputOptions(StrictDictValidator):
|
|||
"keep_files_before",
|
||||
"keep_files_after",
|
||||
"keep_max_files",
|
||||
"download_archive_standardized_date",
|
||||
"keep_files_date_eval",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
|
@ -156,6 +164,11 @@ class OutputOptions(StrictDictValidator):
|
|||
self._keep_max_files = self._validate_key_if_present(
|
||||
"keep_max_files", OverridesIntegerFormatterValidator
|
||||
)
|
||||
self._keep_files_date_eval = self._validate_key(
|
||||
"keep_files_date_eval",
|
||||
StandardizedDateValidator,
|
||||
default=f"{{{v.upload_date_standardized.variable_name}}}",
|
||||
)
|
||||
|
||||
if (
|
||||
self._keep_files_before or self._keep_files_after or self._keep_max_files
|
||||
|
|
@ -272,6 +285,18 @@ class OutputOptions(StrictDictValidator):
|
|||
"""
|
||||
return self._keep_files_after
|
||||
|
||||
@property
|
||||
def keep_files_date_eval(self) -> StandardizedDateValidator:
|
||||
"""
|
||||
:expected type: str
|
||||
:description:
|
||||
Uses this standardized date in the form of YYYY-MM-DD to record in the
|
||||
download archive for a given entry. Subsequently, uses this value to
|
||||
perform evaluation for keep_files_before/after and keep_max_files. Defaults
|
||||
to the entry's upload_date_standardized variable.
|
||||
"""
|
||||
return self._keep_files_date_eval
|
||||
|
||||
@property
|
||||
def keep_max_files(self) -> Optional[OverridesIntegerFormatterValidator]:
|
||||
"""
|
||||
|
|
@ -283,3 +308,10 @@ class OutputOptions(StrictDictValidator):
|
|||
applied. Can be used in conjunction with ``keep_files_before`` and ``keep_files_after``.
|
||||
"""
|
||||
return self._keep_max_files
|
||||
|
||||
def added_variables(self, unresolved_variables: Set[str]) -> Dict[PluginOperation, Set[str]]:
|
||||
return {
|
||||
# PluginOperation.MODIFY_ENTRY_METADATA: {
|
||||
# VARIABLES.ytdl_sub_entry_date_eval.variable_name
|
||||
# }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,13 +57,14 @@ def _add_dummy_overrides(overrides: Overrides) -> Dict[str, str]:
|
|||
|
||||
|
||||
def _get_added_and_modified_variables(
|
||||
plugins: PresetPlugins, downloader_options: MultiUrlValidator
|
||||
plugins: PresetPlugins, downloader_options: MultiUrlValidator, output_options: OutputOptions
|
||||
) -> Iterable[Tuple[OptionsValidator, Set[str], Set[str]]]:
|
||||
"""
|
||||
Iterates and returns the plugin options, added variables, modified variables
|
||||
"""
|
||||
options: List[OptionsValidator] = plugins.plugin_options
|
||||
options.append(downloader_options)
|
||||
options.append(output_options)
|
||||
|
||||
for plugin_options in options:
|
||||
added_variables: Set[str] = set()
|
||||
|
|
@ -117,6 +118,7 @@ class VariableValidation:
|
|||
) in _get_added_and_modified_variables(
|
||||
plugins=self.plugins,
|
||||
downloader_options=self.downloader_options,
|
||||
output_options=self.output_options,
|
||||
):
|
||||
|
||||
for added_variable in added_variables:
|
||||
|
|
@ -183,6 +185,9 @@ class VariableValidation:
|
|||
self._add_variables(PluginOperation.DOWNLOADER, options=self.downloader_options)
|
||||
self._add_subscription_override_variables()
|
||||
|
||||
# Always add output options first
|
||||
self._add_variables(PluginOperation.MODIFY_ENTRY_METADATA, options=self.output_options)
|
||||
|
||||
# Metadata variables to be added
|
||||
for plugin_options in PluginMapping.order_options_by(
|
||||
self.plugins.zipped(), PluginOperation.MODIFY_ENTRY_METADATA
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
|||
from ytdl_sub.entries.script.variable_definitions import VariableDefinitions
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
from ytdl_sub.utils.script import ScriptUtils
|
||||
from ytdl_sub.utils.thumbnail import ThumbnailTypes
|
||||
from ytdl_sub.utils.thumbnail import download_and_convert_url_thumbnail
|
||||
from ytdl_sub.utils.thumbnail import try_convert_download_thumbnail
|
||||
|
|
@ -459,11 +458,9 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
|||
metadata_ytdl_options = self.metadata_ytdl_options(
|
||||
ytdl_option_overrides=validator.ytdl_options.to_native_dict(self.overrides)
|
||||
)
|
||||
download_reversed = ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(validator.download_reverse)
|
||||
)
|
||||
include_sibling_metadata = ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(validator.include_sibling_metadata)
|
||||
download_reversed = self.overrides.evaluate_boolean(validator.download_reverse)
|
||||
include_sibling_metadata = self.overrides.evaluate_boolean(
|
||||
validator.include_sibling_metadata
|
||||
)
|
||||
|
||||
parents, orphan_entries = self._download_url_metadata(
|
||||
|
|
@ -534,8 +531,8 @@ class MultiUrlDownloader(SourcePlugin[MultiUrlValidator]):
|
|||
download_logger.info("Entry rejected by download match-filter, skipping ..")
|
||||
return None
|
||||
|
||||
upload_date_idx = self._enhanced_download_archive.mapping.get_num_entries_with_upload_date(
|
||||
upload_date_standardized=entry.get(v.upload_date_standardized, str)
|
||||
upload_date_idx = self._enhanced_download_archive.mapping.get_num_entries_with_date(
|
||||
standardized_date=entry.get(v.ytdl_sub_keep_files_date_eval, str)
|
||||
)
|
||||
download_idx = self._enhanced_download_archive.num_entries
|
||||
|
||||
|
|
|
|||
|
|
@ -823,6 +823,17 @@ class YtdlSubVariableDefinitions(ABC):
|
|||
variable_name="upload_date_index_reversed_padded", pad=2
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def ytdl_sub_keep_files_date_eval(self: "VariableDefinitions") -> StringVariable:
|
||||
"""
|
||||
:description:
|
||||
The standardized date variable supplied in ``output_options.keep_files_date_eval``.
|
||||
"""
|
||||
return StringVariable(
|
||||
variable_name="ytdl_sub_entry_date_eval",
|
||||
definition=f"{{%string({self.upload_date_standardized.variable_name})}}",
|
||||
)
|
||||
|
||||
|
||||
class EntryVariableDefinitions(ABC):
|
||||
@cached_property
|
||||
|
|
@ -1121,6 +1132,7 @@ class VariableDefinitions(
|
|||
self.ytdl_sub_input_url,
|
||||
self.ytdl_sub_input_url_index,
|
||||
self.ytdl_sub_input_url_count,
|
||||
self.ytdl_sub_keep_files_date_eval,
|
||||
}
|
||||
|
||||
@cache
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ from typing import Tuple
|
|||
from ytdl_sub.config.plugin.plugin import Plugin
|
||||
from ytdl_sub.config.validators.options import ToggleableOptionsDictValidator
|
||||
from ytdl_sub.utils.datetime import to_date_str
|
||||
from ytdl_sub.utils.script import ScriptUtils
|
||||
from ytdl_sub.validators.string_datetime import StringDatetimeValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import OverridesBooleanFormatterValidator
|
||||
|
||||
|
|
@ -95,9 +94,7 @@ class DateRangePlugin(Plugin[DateRangeOptions]):
|
|||
date_validator=self.plugin_options.after, overrides=self.overrides
|
||||
)
|
||||
after_filter = f"upload_date >= {after_str}"
|
||||
if ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(self.plugin_options.breaks)
|
||||
):
|
||||
if self.overrides.evaluate_boolean(self.plugin_options.breaks):
|
||||
breaking_match_filters.append(after_filter)
|
||||
else:
|
||||
match_filters.append(after_filter)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ from ytdl_sub.config.validators.options import OptionsValidator
|
|||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.utils.exceptions import StringFormattingException
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
from ytdl_sub.utils.script import ScriptUtils
|
||||
from ytdl_sub.validators.string_formatter_validators import ListFormatterValidator
|
||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||
|
||||
|
|
@ -53,10 +52,9 @@ class FilterExcludePlugin(Plugin[FilterExcludeOptions]):
|
|||
return entry
|
||||
|
||||
for formatter in self.plugin_options.list:
|
||||
out = ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(formatter=formatter, entry=entry)
|
||||
)
|
||||
if bool(out):
|
||||
should_exclude = self.overrides.evaluate_boolean(formatter=formatter, entry=entry)
|
||||
|
||||
if should_exclude:
|
||||
logger.info(
|
||||
"Filtering '%s' from the filter %s evaluating to True",
|
||||
entry.title,
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ class FilterIncludePlugin(Plugin[FilterIncludeOptions]):
|
|||
return entry
|
||||
|
||||
for formatter in self.plugin_options.list:
|
||||
out = ScriptUtils.bool_formatter_output(
|
||||
should_exclude = ScriptUtils.bool_formatter_output(
|
||||
self.overrides.apply_formatter(formatter=formatter, entry=entry)
|
||||
)
|
||||
if not bool(out):
|
||||
if not should_exclude:
|
||||
logger.info(
|
||||
"Filtering '%s' from the filter %s evaluating to False",
|
||||
entry.title,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ from pathlib import Path
|
|||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from ytdl_sub.config.plugin.plugin import Plugin
|
||||
from ytdl_sub.config.validators.options import ToggleableOptionsDictValidator
|
||||
|
|
@ -19,8 +18,8 @@ from ytdl_sub.utils.xml import to_xml
|
|||
from ytdl_sub.validators.file_path_validators import StringFormatterFileNameValidator
|
||||
from ytdl_sub.validators.nfo_validators import NfoTagsValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import OverridesBooleanFormatterValidator
|
||||
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||
from ytdl_sub.validators.validators import BoolValidator
|
||||
|
||||
|
||||
class SharedNfoTagsOptions(ToggleableOptionsDictValidator):
|
||||
|
|
@ -54,8 +53,8 @@ class SharedNfoTagsOptions(ToggleableOptionsDictValidator):
|
|||
)
|
||||
self._tags = self._validate_key_if_present(key="tags", validator=NfoTagsValidator)
|
||||
self._kodi_safe = self._validate_key_if_present(
|
||||
key="kodi_safe", validator=BoolValidator, default=False
|
||||
).value
|
||||
key="kodi_safe", validator=OverridesBooleanFormatterValidator, default="False"
|
||||
)
|
||||
|
||||
@property
|
||||
def nfo_name(self) -> StringFormatterFileNameValidator:
|
||||
|
|
@ -81,9 +80,9 @@ class SharedNfoTagsOptions(ToggleableOptionsDictValidator):
|
|||
return self._tags
|
||||
|
||||
@property
|
||||
def kodi_safe(self) -> Optional[bool]:
|
||||
def kodi_safe(self) -> OverridesBooleanFormatterValidator:
|
||||
"""
|
||||
:expected type: Optional[Boolean]
|
||||
:expected type: OverridesBooleanFormatterValidator
|
||||
:description:
|
||||
Defaults to False. Kodi does not support > 3-byte unicode characters, which include
|
||||
emojis and some foreign language characters. Setting this to True will replace those
|
||||
|
|
@ -141,7 +140,7 @@ class SharedNfoTagsPlugin(Plugin[SharedNfoTagsOptions], ABC):
|
|||
if not nfo_tags:
|
||||
return
|
||||
|
||||
if self.plugin_options.kodi_safe:
|
||||
if self.overrides.evaluate_boolean(self.plugin_options.kodi_safe):
|
||||
nfo_root = to_max_3_byte_utf8_string(nfo_root)
|
||||
nfo_tags = {
|
||||
to_max_3_byte_utf8_string(key): [
|
||||
|
|
|
|||
|
|
@ -146,7 +146,12 @@ class SubtitlesPlugin(Plugin[SubtitleOptions]):
|
|||
plugin_options_type = SubtitleOptions
|
||||
|
||||
def ytdl_options(self) -> Optional[Dict]:
|
||||
builder = YTDLOptionsBuilder().add({"writesubtitles": True})
|
||||
builder = YTDLOptionsBuilder().add(
|
||||
{
|
||||
"writesubtitles": True,
|
||||
"sleep_interval_subtitles": 5.367, # for safe measure
|
||||
}
|
||||
)
|
||||
|
||||
if self.plugin_options.embed_subtitles:
|
||||
builder.add(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import random
|
||||
import time
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
from ytdl_sub.config.overrides import Overrides
|
||||
|
|
@ -40,6 +41,22 @@ class RandomizedRangeValidator(StrictDictValidator):
|
|||
f"max ({self._max}) must be greater than or equal to min ({self._min})"
|
||||
)
|
||||
|
||||
def min_value(self) -> float:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Minimum value
|
||||
"""
|
||||
return self._min
|
||||
|
||||
def max_value(self) -> float:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Maximum value
|
||||
"""
|
||||
return self._max
|
||||
|
||||
def randomized_float(self) -> float:
|
||||
"""
|
||||
Returns
|
||||
|
|
@ -70,6 +87,9 @@ class ThrottleProtectionOptions(ToggleableOptionsDictValidator):
|
|||
presets:
|
||||
my_example_preset:
|
||||
throttle_protection:
|
||||
sleep_per_request_s:
|
||||
min: 5.5
|
||||
max: 10.4
|
||||
sleep_per_download_s:
|
||||
min: 2.2
|
||||
max: 10.8
|
||||
|
|
@ -84,6 +104,7 @@ class ThrottleProtectionOptions(ToggleableOptionsDictValidator):
|
|||
|
||||
_optional_keys = {
|
||||
"enable",
|
||||
"sleep_per_request_s",
|
||||
"sleep_per_download_s",
|
||||
"sleep_per_subscription_s",
|
||||
"max_downloads_per_subscription",
|
||||
|
|
@ -93,6 +114,9 @@ class ThrottleProtectionOptions(ToggleableOptionsDictValidator):
|
|||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
||||
self._sleep_per_request_s = self._validate_key_if_present(
|
||||
key="sleep_per_request_s", validator=RandomizedRangeValidator
|
||||
)
|
||||
self._sleep_per_download_s = self._validate_key_if_present(
|
||||
key="sleep_per_download_s", validator=RandomizedRangeValidator
|
||||
)
|
||||
|
|
@ -106,6 +130,18 @@ class ThrottleProtectionOptions(ToggleableOptionsDictValidator):
|
|||
key="subscription_download_probability", validator=ProbabilityValidator
|
||||
)
|
||||
|
||||
@property
|
||||
def sleep_per_request_s(self) -> Optional[RandomizedRangeValidator]:
|
||||
"""
|
||||
:expected type: Optional[Range]
|
||||
:description:
|
||||
Number in seconds to sleep between each request during metadata download. Note that
|
||||
metadata download refers to the initial info.json download, not the actual audio/video
|
||||
download for the entry. Also, yt-dlp only supports a single value at this time for this,
|
||||
so will always use the max value.
|
||||
"""
|
||||
return self._sleep_per_request_s
|
||||
|
||||
@property
|
||||
def sleep_per_download_s(self) -> Optional[RandomizedRangeValidator]:
|
||||
"""
|
||||
|
|
@ -165,6 +201,11 @@ class ThrottleProtectionPlugin(Plugin[ThrottleProtectionOptions]):
|
|||
self.plugin_options.max_downloads_per_subscription.randomized_int()
|
||||
)
|
||||
|
||||
def ytdl_options(self) -> Optional[Dict]:
|
||||
if self.plugin_options.sleep_per_request_s is not None:
|
||||
return {"sleep_interval_requests": self.plugin_options.sleep_per_request_s.max_value()}
|
||||
return {}
|
||||
|
||||
def initialize_subscription(self) -> bool:
|
||||
if self.plugin_options.subscription_download_probability:
|
||||
proba = self.plugin_options.subscription_download_probability.value
|
||||
|
|
|
|||
|
|
@ -12,28 +12,6 @@ class TvShowByDatePresets(PrebuiltPresets):
|
|||
}
|
||||
|
||||
|
||||
class TvShowByDateOldPresets(PrebuiltPresets):
|
||||
"""
|
||||
TV Show by Date presets create a TV show from a single URL using upload dates as season/episode
|
||||
numbers.
|
||||
"""
|
||||
|
||||
preset_names = {
|
||||
"kodi_tv_show_by_date",
|
||||
"jellyfin_tv_show_by_date",
|
||||
"plex_tv_show_by_date",
|
||||
}
|
||||
|
||||
|
||||
class TvShowByDateEpisodeFormattingPresets(PrebuiltPresets):
|
||||
preset_names = {
|
||||
"season_by_year__episode_by_month_day",
|
||||
"season_by_year__episode_by_month_day_reversed",
|
||||
"season_by_year_month__episode_by_day",
|
||||
"season_by_year__episode_by_download_index",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionPresets(PrebuiltPresets):
|
||||
preset_names = {
|
||||
"Kodi TV Show Collection",
|
||||
|
|
@ -48,24 +26,3 @@ class TvShowCollectionOldPresets(PrebuiltPresets):
|
|||
"jellyfin_tv_show_collection",
|
||||
"plex_tv_show_collection",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionEpisodeFormattingPresets(PrebuiltPresets):
|
||||
preset_names = {
|
||||
"season_by_collection__episode_by_year_month_day",
|
||||
"season_by_collection__episode_by_year_month_day_reversed",
|
||||
"season_by_collection__episode_by_playlist_index",
|
||||
"season_by_collection__episode_by_playlist_index_reversed",
|
||||
}
|
||||
|
||||
|
||||
class TvShowCollectionSeasonPresets(PrebuiltPresets):
|
||||
"""Now Deprecated"""
|
||||
|
||||
preset_names = {
|
||||
"collection_season_1",
|
||||
"collection_season_2",
|
||||
"collection_season_3",
|
||||
"collection_season_4",
|
||||
"collection_season_5",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ presets:
|
|||
thumbnail_name: "{thumbnail_file_name}"
|
||||
info_json_name: "{episode_file_path}.{info_json_ext}"
|
||||
maintain_download_archive: True
|
||||
keep_files_date_eval: "{episode_date_standardized}"
|
||||
|
||||
ytdl_options:
|
||||
break_on_existing: True
|
||||
|
|
@ -36,14 +37,11 @@ presets:
|
|||
tv_show_genre: "{subscription_indent_1}"
|
||||
tv_show_content_rating: "{subscription_indent_2}"
|
||||
season_directory_name: "Season {season_number_padded}"
|
||||
episode_title: "{upload_date_standardized} - {title}"
|
||||
episode_title: "{episode_date_standardized} - {title}"
|
||||
episode_plot: "{webpage_url}\n\n{description}"
|
||||
episode_year: "{upload_year}"
|
||||
episode_content_rating: "{tv_show_content_rating}"
|
||||
episode_date_standardized: "{upload_date_standardized}"
|
||||
episode_file_name: "s{season_number_padded}.e{episode_number_padded} - {file_title}"
|
||||
episode_file_path: "{season_directory_name_sanitized}/{episode_file_name_sanitized}"
|
||||
thumbnail_file_name: "{episode_file_path}-thumb.jpg"
|
||||
|
||||
|
||||
|
||||
episode_year: "{%slice(episode_date_standardized, 0, 4)}"
|
||||
|
|
|
|||
|
|
@ -35,22 +35,125 @@ presets:
|
|||
|
||||
# TV show from one or more sources. Uses {url}'s avatar and banner as poster and fanart
|
||||
_tv_show_by_date:
|
||||
preset: "_multi_url_bilateral"
|
||||
preset:
|
||||
- "_multi_url_bilateral"
|
||||
- "_tv_show_by_date_asserts"
|
||||
overrides:
|
||||
avatar_uncropped_thumbnail_file_name: "{tv_show_poster_file_name}"
|
||||
banner_uncropped_thumbnail_file_name: "{tv_show_fanart_file_name}"
|
||||
|
||||
_tv_show_by_date_asserts:
|
||||
overrides:
|
||||
s01_url: ""
|
||||
s01_name: ""
|
||||
assert_not_collection: >-
|
||||
{
|
||||
%assert(
|
||||
%and(
|
||||
%not( %bool(s01_url) ),
|
||||
%not( %bool(s01_name) )
|
||||
),
|
||||
"Provided `s01_url` or `s01_name` variable to TV Show by Date preset when it expects `url`. Perhaps you meant to use the `TV Show Collection` preset?"
|
||||
)
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
_tv_show_by_date_season_episode_ordering:
|
||||
overrides:
|
||||
tv_show_by_date_season_ordering: >-
|
||||
{ %throw("Must specify tv_show_by_date_season_ordering") }
|
||||
|
||||
"%season_ordering_": >-
|
||||
{ %eq( %lower(tv_show_by_date_season_ordering), $0 ) }
|
||||
|
||||
season_number: >-
|
||||
{
|
||||
%elif(
|
||||
%season_ordering_( "upload-year" ), upload_year,
|
||||
%season_ordering_( "upload-year-month" ), %concat(upload_year, upload_month_padded),
|
||||
%season_ordering_( "release-year" ), release_year,
|
||||
%season_ordering_( "release-year-month" ), %concat(release_year, release_month_padded),
|
||||
%throw(
|
||||
'tv_show_by_date_season_ordering must be one of the following: "upload-year", "upload-year-month", "release-year", "release-year-month"'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
# both year and year-month are fixed width, until the year 10000 :)
|
||||
season_number_padded: "{season_number}"
|
||||
|
||||
##################################### episode overrides
|
||||
|
||||
tv_show_by_date_episode_ordering: >-
|
||||
{ %throw("Must specify tv_show_by_date_episode_ordering") }
|
||||
|
||||
"%episode_ordering_": >-
|
||||
{ %eq( %lower(tv_show_by_date_episode_ordering), $0 ) }
|
||||
|
||||
episode_number_and_padded_: >-
|
||||
{
|
||||
%elif(
|
||||
%episode_ordering_( "upload-day" ), [ %concat(upload_day, upload_date_index_padded), 4 ],
|
||||
%episode_ordering_( "upload-month-day" ), [ %concat(upload_month, upload_day_padded, upload_date_index_padded), 6],
|
||||
%episode_ordering_( "upload-month-day-reversed" ), [ %concat(upload_day_of_year_reversed, upload_date_index_reversed_padded), 5],
|
||||
%episode_ordering_( "release-day" ), [ %concat(release_day, upload_date_index_padded), 4 ],
|
||||
%episode_ordering_( "release-month-day" ), [ %concat(release_month, release_day_padded, upload_date_index_padded), 6],
|
||||
%episode_ordering_( "release-month-day-reversed" ), [ %concat(release_day_of_year_reversed, upload_date_index_reversed_padded), 5],
|
||||
%episode_ordering_( "download-index" ), [ download_index, 6 ],
|
||||
%throw(
|
||||
'tv_show_by_date_episode_ordering must be one of the following: "upload-day", "upload-month-day", "upload-month-day-reversed", "release-day", "release-month-day", "release-month-day-reversed", "download-index"'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
episode_number: "{ %array_at(episode_number_and_padded_, 0) }"
|
||||
episode_number_padded: "{ %pad_zero( %int(episode_number), %int(%array_at(episode_number_and_padded_, 1))) }"
|
||||
episode_date_standardized: >-
|
||||
{
|
||||
%if(
|
||||
%contains(tv_show_by_date_season_ordering, "release"),
|
||||
release_date_standardized,
|
||||
upload_date_standardized
|
||||
)
|
||||
}
|
||||
|
||||
##################################### season/episode pairing validation
|
||||
|
||||
"%ordering_pair_eq": >-
|
||||
{
|
||||
%eq([tv_show_by_date_season_ordering, tv_show_by_date_episode_ordering], [$0, $1])
|
||||
}
|
||||
tv_show_by_date_ordering_pair_validation_: >-
|
||||
{
|
||||
%assert_then(
|
||||
%or(
|
||||
%ordering_pair_eq("upload-year", "upload-month-day"),
|
||||
%ordering_pair_eq("upload-year", "upload-month-day-reversed"),
|
||||
%ordering_pair_eq("upload-year", "download-index"),
|
||||
%ordering_pair_eq("upload-year-month", "upload-day"),
|
||||
%ordering_pair_eq("release-year", "release-month-day"),
|
||||
%ordering_pair_eq("release-year", "release-month-day-reversed"),
|
||||
%ordering_pair_eq("release-year", "download-index"),
|
||||
%ordering_pair_eq("release-year-month", "release-day")
|
||||
),
|
||||
episode_number_and_padded_,
|
||||
"Detected incompatibility between tv_show_by_date_season_ordering and tv_show_by_date_episode_ordering. Ensure you are not using both upload and release date, and that the year/month/day are included in the combined season and episode."
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# LEGACY PRESETS
|
||||
|
||||
_season_by_year:
|
||||
preset: "_tv_show_by_date_season_episode_ordering"
|
||||
overrides:
|
||||
season_number: "{upload_year}"
|
||||
season_number_padded: "{season_number}"
|
||||
tv_show_by_date_season_ordering: "upload-year"
|
||||
|
||||
_season_by_year_month:
|
||||
preset: "_tv_show_by_date_season_episode_ordering"
|
||||
overrides:
|
||||
season_number: "{upload_year}{upload_month_padded}"
|
||||
season_number_padded: "{season_number}"
|
||||
tv_show_by_date_season_ordering: "upload-year-month"
|
||||
|
||||
####################################################################################################
|
||||
|
||||
|
|
@ -58,26 +161,22 @@ presets:
|
|||
preset:
|
||||
- "_season_by_year_month"
|
||||
overrides:
|
||||
episode_number: "{upload_day}{upload_date_index_padded}"
|
||||
episode_number_padded: "{upload_day_padded}{upload_date_index_padded}"
|
||||
tv_show_by_date_episode_ordering: "upload-day"
|
||||
|
||||
season_by_year__episode_by_month_day:
|
||||
preset:
|
||||
- "_season_by_year"
|
||||
overrides:
|
||||
episode_number: "{upload_month}{upload_day_padded}{upload_date_index_padded}"
|
||||
episode_number_padded: "{upload_month_padded}{upload_day_padded}{upload_date_index_padded}"
|
||||
tv_show_by_date_episode_ordering: "upload-month-day"
|
||||
|
||||
season_by_year__episode_by_month_day_reversed:
|
||||
preset:
|
||||
- "_season_by_year"
|
||||
overrides:
|
||||
episode_number: "{upload_day_of_year_reversed}{upload_date_index_reversed_padded}"
|
||||
episode_number_padded: "{upload_day_of_year_reversed_padded}{upload_date_index_reversed_padded}"
|
||||
tv_show_by_date_episode_ordering: "upload-month-day-reversed"
|
||||
|
||||
season_by_year__episode_by_download_index:
|
||||
preset:
|
||||
- "_season_by_year"
|
||||
overrides:
|
||||
episode_number: "{download_index}"
|
||||
episode_number_padded: "{download_index_padded6}"
|
||||
tv_show_by_date_episode_ordering: "download-index"
|
||||
|
|
|
|||
|
|
@ -39,31 +39,68 @@ presets:
|
|||
|
||||
###############################
|
||||
|
||||
season_by_collection__episode_by_year_month_day:
|
||||
_tv_show_collection_episode_ordering:
|
||||
overrides:
|
||||
episode_number: "{upload_year_truncated}{upload_month_padded}{upload_day_padded}{upload_date_index_padded}"
|
||||
episode_number_padded: "{episode_number}"
|
||||
tv_show_collection_episode_ordering: >-
|
||||
{ %throw("Must specify tv_show_collection_episode_ordering") }
|
||||
|
||||
"%episode_ordering_": >-
|
||||
{ %eq( %lower(tv_show_collection_episode_ordering), $0 ) }
|
||||
|
||||
episode_number_and_padded_: >-
|
||||
{
|
||||
%elif(
|
||||
%episode_ordering_( "upload-year-month-day" ), [ %concat(upload_year_truncated, upload_month_padded, upload_day_padded, upload_date_index_padded), 8 ],
|
||||
%episode_ordering_( "upload-year-month-day-reversed" ), [ %concat(upload_year_truncated_reversed, upload_month_reversed_padded, upload_day_reversed_padded, upload_date_index_reversed_padded), 8],
|
||||
%episode_ordering_( "release-year-month-day" ), [ %concat(release_year_truncated, release_month_padded, release_day_padded, upload_date_index_padded), 8 ],
|
||||
%episode_ordering_( "release-year-month-day-reversed" ), [ %concat(release_year_truncated_reversed, release_month_reversed_padded, release_day_reversed_padded, upload_date_index_reversed_padded), 8],
|
||||
%episode_ordering_( "playlist-index" ), [ %concat(playlist_index), 6],
|
||||
%episode_ordering_( "playlist-index-reversed" ), [ %concat(playlist_index_reversed), 6],
|
||||
%throw(
|
||||
'tv_show_collection_episode_ordering must be one of the following: "upload-year-month-day", "upload-year-month-day-reversed", "release-year-month-day", "release-year-month-day-reversed", "playlist-index", "playlist-index-reversed"'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
episode_number: "{ %array_at(episode_number_and_padded_, 0) }"
|
||||
episode_number_padded: "{ %pad_zero( %int(episode_number), %int(%array_at(episode_number_and_padded_, 1))) }"
|
||||
episode_date_standardized: >-
|
||||
{
|
||||
%if(
|
||||
%contains(tv_show_collection_episode_ordering, "release"),
|
||||
release_date_standardized,
|
||||
upload_date_standardized
|
||||
)
|
||||
}
|
||||
|
||||
### LEGACY PRESETS
|
||||
|
||||
season_by_collection__episode_by_year_month_day:
|
||||
preset: "_tv_show_collection_episode_ordering"
|
||||
overrides:
|
||||
tv_show_collection_episode_ordering: "upload-year-month-day"
|
||||
|
||||
season_by_collection__episode_by_year_month_day_reversed:
|
||||
preset: "_tv_show_collection_episode_ordering"
|
||||
overrides:
|
||||
episode_number: "{upload_year_truncated_reversed}{upload_month_reversed_padded}{upload_day_reversed_padded}{upload_date_index_reversed_padded}"
|
||||
episode_number_padded: "{episode_number}"
|
||||
tv_show_collection_episode_ordering: "upload-year-month-day-reversed"
|
||||
|
||||
season_by_collection__episode_by_playlist_index:
|
||||
preset: "_tv_show_collection_episode_ordering"
|
||||
overrides:
|
||||
episode_number: "{playlist_index}"
|
||||
episode_number_padded: "{playlist_index_padded6}"
|
||||
tv_show_collection_episode_ordering: "playlist-index"
|
||||
|
||||
season_by_collection__episode_by_playlist_index_reversed:
|
||||
preset: "_tv_show_collection_episode_ordering"
|
||||
overrides:
|
||||
episode_number: "{playlist_index_reversed}"
|
||||
episode_number_padded: "{playlist_index_reversed_padded6}"
|
||||
tv_show_collection_episode_ordering: "playlist-index-reversed"
|
||||
|
||||
##############
|
||||
|
||||
_tv_show_collection:
|
||||
preset:
|
||||
- "_tv_show_collection_bilateral"
|
||||
- "_tv_show_collection_asserts"
|
||||
|
||||
download:
|
||||
- url: "{collection_season_1_url}"
|
||||
|
|
@ -1017,6 +1054,16 @@ presets:
|
|||
ytdl_options:
|
||||
playlist_items: "-1:0:-1"
|
||||
|
||||
_tv_show_collection_asserts:
|
||||
overrides:
|
||||
url: ""
|
||||
assert_not_by_date: >-
|
||||
{
|
||||
%assert(
|
||||
%not( %bool(url) ),
|
||||
"Provided `url` to TV Show Collection preset when it expects `s01_url`. Perhaps you meant to use the `TV Show by Date` preset?"
|
||||
)
|
||||
}
|
||||
|
||||
####################################################################################################
|
||||
# DEPRECATED SEASON PRESETS
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from ytdl_sub.script.functions.error_functions import ErrorFunctions
|
|||
from ytdl_sub.script.functions.json_functions import JsonFunctions
|
||||
from ytdl_sub.script.functions.map_functions import MapFunctions
|
||||
from ytdl_sub.script.functions.numeric_functions import NumericFunctions
|
||||
from ytdl_sub.script.functions.print_functions import PrintFunctions
|
||||
from ytdl_sub.script.functions.regex_functions import RegexFunctions
|
||||
from ytdl_sub.script.functions.string_functions import StringFunctions
|
||||
from ytdl_sub.script.types.resolvable import Resolvable
|
||||
|
|
@ -26,6 +27,7 @@ class Functions(
|
|||
RegexFunctions,
|
||||
DateFunctions,
|
||||
JsonFunctions,
|
||||
PrintFunctions,
|
||||
):
|
||||
_custom_functions: Dict[str, Callable[..., Resolvable]] = {}
|
||||
|
||||
|
|
|
|||
67
src/ytdl_sub/script/functions/print_functions.py
Normal file
67
src/ytdl_sub/script/functions/print_functions.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
from typing import Optional
|
||||
|
||||
from ytdl_sub.script.types.resolvable import AnyArgument
|
||||
from ytdl_sub.script.types.resolvable import Integer
|
||||
from ytdl_sub.script.types.resolvable import ReturnableArgument
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
|
||||
logger = Logger.get(name="preset")
|
||||
|
||||
|
||||
def _log(message: AnyArgument, level: Optional[Integer]) -> None:
|
||||
if level is None:
|
||||
logger.info(str(message))
|
||||
return
|
||||
|
||||
level_value: int = level.native
|
||||
if level_value < 0:
|
||||
logger.debug(str(message))
|
||||
elif level_value == 0:
|
||||
logger.info(str(message))
|
||||
elif level_value == 1:
|
||||
logger.warning(str(message))
|
||||
else: # > 1
|
||||
logger.error(str(message))
|
||||
|
||||
|
||||
class PrintFunctions:
|
||||
@staticmethod
|
||||
def print(
|
||||
message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer] = None
|
||||
) -> ReturnableArgument:
|
||||
"""
|
||||
:description:
|
||||
Print the ``message`` and return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
"""
|
||||
_log(message=message, level=level)
|
||||
return passthrough
|
||||
|
||||
@staticmethod
|
||||
def print_if_true(
|
||||
message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer] = None
|
||||
) -> ReturnableArgument:
|
||||
"""
|
||||
:description:
|
||||
Print the ``message`` if ``passthrough`` evaluates to ``true``. Return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
"""
|
||||
if passthrough.value:
|
||||
_log(message=message, level=level)
|
||||
return passthrough
|
||||
|
||||
@staticmethod
|
||||
def print_if_false(
|
||||
message: AnyArgument, passthrough: ReturnableArgument, level: Optional[Integer] = None
|
||||
) -> ReturnableArgument:
|
||||
"""
|
||||
:description:
|
||||
Print the ``message`` if ``passthrough`` evaluates to ``false``. Return ``passthrough``.
|
||||
Optionally can pass level, where < 0 is debug, 0 is info, 1 is warning, > 1 is error.
|
||||
Defaults to info.
|
||||
"""
|
||||
if not passthrough.value:
|
||||
_log(message=message, level=level)
|
||||
return passthrough
|
||||
|
|
@ -127,12 +127,12 @@ class StringFunctions:
|
|||
return Array([String(split_val) for split_val in string.value.split(sep=sep.value)])
|
||||
|
||||
@staticmethod
|
||||
def concat(*values: String) -> String:
|
||||
def concat(*values: AnyArgument) -> String:
|
||||
"""
|
||||
:description:
|
||||
Concatenate multiple Strings into a single String.
|
||||
"""
|
||||
return String("".join(val.value for val in values))
|
||||
return String("".join(str(val.value) for val in values))
|
||||
|
||||
@staticmethod
|
||||
def pad(string: String, length: Integer, char: String) -> String:
|
||||
|
|
@ -176,3 +176,41 @@ class StringFunctions:
|
|||
# World
|
||||
"""
|
||||
return String(string.value.encode("utf-8").decode("unicode_escape"))
|
||||
|
||||
@staticmethod
|
||||
def join(separator: String, array: Array) -> String:
|
||||
"""
|
||||
:description:
|
||||
Join all elements in the array together as a string, and insert the
|
||||
separator between them.
|
||||
|
||||
:usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
%join( ", ", ["item1", "item2"] )
|
||||
}
|
||||
|
||||
# "item1, item2"
|
||||
"""
|
||||
|
||||
return String(separator.value.join(str(val) for val in array.value))
|
||||
|
||||
@staticmethod
|
||||
def strip(string: String) -> String:
|
||||
"""
|
||||
:description:
|
||||
Strip a string of all its whitespace at the beginning and end.
|
||||
|
||||
:usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
%trim(" delete the outer! ")
|
||||
}
|
||||
|
||||
# "delete the outer!"
|
||||
"""
|
||||
return String(string.value.strip())
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from ytdl_sub.downloaders.source_plugin import SourcePlugin
|
|||
from ytdl_sub.downloaders.url.downloader import MultiUrlDownloader
|
||||
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
|
||||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.entries.script.variable_definitions import VARIABLES
|
||||
from ytdl_sub.subscriptions.base_subscription import BaseSubscription
|
||||
from ytdl_sub.subscriptions.subscription_ytdl_options import SubscriptionYTDLOptions
|
||||
from ytdl_sub.utils.datetime import to_date_range
|
||||
|
|
@ -215,9 +216,23 @@ class SubscriptionDownload(BaseSubscription, ABC):
|
|||
FileHandler.delete(entry.get_download_thumbnail_path())
|
||||
FileHandler.delete(entry.get_download_info_json_path())
|
||||
|
||||
@classmethod
|
||||
def _preprocess_entry(cls, plugins: List[Plugin], entry: Entry) -> Optional[Entry]:
|
||||
def _preprocess_entry(self, plugins: List[Plugin], entry: Entry) -> Optional[Entry]:
|
||||
maybe_entry: Optional[Entry] = entry
|
||||
|
||||
# Inject OutputOption variables here
|
||||
entry.add(
|
||||
{
|
||||
VARIABLES.ytdl_sub_keep_files_date_eval: (
|
||||
self.output_options.keep_files_date_eval.format_string
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
# Run it to make sure it's actually a standardized date
|
||||
_ = self.overrides.apply_formatter(
|
||||
formatter=self.output_options.keep_files_date_eval, entry=entry
|
||||
)
|
||||
|
||||
for plugin in PluginMapping.order_plugins_by(
|
||||
plugins, PluginOperation.MODIFY_ENTRY_METADATA
|
||||
):
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from ytdl_sub.plugins.match_filters import MatchFiltersPlugin
|
|||
from ytdl_sub.plugins.match_filters import combine_filters
|
||||
from ytdl_sub.plugins.match_filters import default_filters
|
||||
from ytdl_sub.plugins.subtitles import SubtitlesPlugin
|
||||
from ytdl_sub.plugins.throttle_protection import ThrottleProtectionPlugin
|
||||
from ytdl_sub.utils.ffmpeg import FFMPEG
|
||||
from ytdl_sub.utils.logger import Logger
|
||||
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
|
||||
|
|
@ -175,6 +176,7 @@ class SubscriptionYTDLOptions:
|
|||
self._global_options,
|
||||
self._output_options,
|
||||
self._plugin_match_filters,
|
||||
self._plugin_ytdl_options(ThrottleProtectionPlugin),
|
||||
self._plugin_ytdl_options(FormatPlugin),
|
||||
self._plugin_ytdl_options(AudioExtractPlugin), # will override format
|
||||
self._user_ytdl_options, # user ytdl options...
|
||||
|
|
|
|||
|
|
@ -220,10 +220,17 @@ class Chapters:
|
|||
# Timestamp captured, store it
|
||||
if match := Timestamp.TIMESTAMP_REGEX.search(line):
|
||||
timestamp_str = match.group(1)
|
||||
timestamps.append(Timestamp.from_str(timestamp_str))
|
||||
|
||||
# Remove timestamp and surrounding whitespace from it
|
||||
title_str = re.sub(f"\\s*{re.escape(timestamp_str)}\\s*", " ", line).strip()
|
||||
|
||||
timestamp = Timestamp.from_str(timestamp_str)
|
||||
if timestamps and (timestamps[-1].timestamp_sec == timestamp.timestamp_sec):
|
||||
# duplicate timestamp... combine into one chapter
|
||||
titles[-1] += " // " + title_str
|
||||
continue
|
||||
timestamps.append(timestamp)
|
||||
|
||||
titles.append(title_str)
|
||||
|
||||
# If more than 3 timestamps were parsed, return it
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from datetime import datetime
|
||||
from typing import Dict
|
||||
from typing import Set
|
||||
from typing import Union
|
||||
|
|
@ -73,6 +74,20 @@ class StringFormatterValidator(StringValidator):
|
|||
return resolved
|
||||
|
||||
|
||||
class StandardizedDateValidator(StringFormatterValidator):
|
||||
_expected_value_type_name = "standardized_date"
|
||||
|
||||
def post_process(self, resolved: str) -> str:
|
||||
try:
|
||||
datetime.strptime(resolved, "%Y-%m-%d")
|
||||
except ValueError as exc:
|
||||
raise self._validation_exception(
|
||||
f"Expected a standardized date in the form of YYYY-MM-DD, but received '{resolved}'"
|
||||
) from exc
|
||||
|
||||
return resolved
|
||||
|
||||
|
||||
# pylint: disable=line-too-long
|
||||
class OverridesStringFormatterValidator(StringFormatterValidator):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class DownloadMapping:
|
|||
DownloadMapping for the entry
|
||||
"""
|
||||
return DownloadMapping(
|
||||
upload_date=entry.get(v.upload_date_standardized, str),
|
||||
upload_date=entry.get(v.ytdl_sub_keep_files_date_eval, str),
|
||||
extractor=entry.download_archive_extractor,
|
||||
file_names=set(),
|
||||
)
|
||||
|
|
@ -248,20 +248,18 @@ class DownloadMappings:
|
|||
del self._entry_mappings[entry_id]
|
||||
return self
|
||||
|
||||
def get_num_entries_with_upload_date(self, upload_date_standardized: str) -> int:
|
||||
def get_num_entries_with_date(self, standardized_date: str) -> int:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
upload_date_standardized
|
||||
standardized_date
|
||||
A standardized upload date
|
||||
|
||||
Returns
|
||||
-------
|
||||
Number of entries in the mapping with this upload date
|
||||
"""
|
||||
return len(
|
||||
[_ for _ in self._entry_mappings.values() if _.upload_date == upload_date_standardized]
|
||||
)
|
||||
return len([_ for _ in self._entry_mappings.values() if _.upload_date == standardized_date])
|
||||
|
||||
def get_num_entries(self) -> int:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from typing import List
|
||||
|
||||
import pytest
|
||||
from conftest import assert_logs
|
||||
from expected_download import assert_expected_downloads
|
||||
|
|
@ -17,6 +19,7 @@ def subscription_dict(output_directory):
|
|||
"subscription_indent_1": "Acoustic",
|
||||
"music_directory": output_directory,
|
||||
},
|
||||
"throttle_protection": {"sleep_per_request_s": {"min": 0.1, "max": 0.5}},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -34,6 +37,21 @@ class TestSoundcloudDiscography:
|
|||
output_directory,
|
||||
dry_run,
|
||||
):
|
||||
ignored_mp3s: List[str] = [
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3",
|
||||
]
|
||||
discography_subscription = Subscription.from_dict(
|
||||
preset_dict=subscription_dict,
|
||||
preset_name="j_b",
|
||||
|
|
@ -49,6 +67,7 @@ class TestSoundcloudDiscography:
|
|||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="soundcloud/test_soundcloud_discography.json",
|
||||
ignore_md5_hashes_for=ignored_mp3s,
|
||||
)
|
||||
|
||||
# Ensure another invocation will hit ExistingVideoReached
|
||||
|
|
@ -65,4 +84,5 @@ class TestSoundcloudDiscography:
|
|||
output_directory=output_directory,
|
||||
dry_run=dry_run,
|
||||
expected_download_summary_file_name="soundcloud/test_soundcloud_discography.json",
|
||||
ignore_md5_hashes_for=ignored_mp3s,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from pathlib import Path
|
|||
from typing import Callable
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -53,6 +54,7 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
|||
is_youtube_channel: bool = False,
|
||||
mock_download_to_working_dir: bool = True,
|
||||
is_extracted_audio: bool = False,
|
||||
release_date: Optional[str] = None,
|
||||
) -> Dict:
|
||||
entry_dict = {
|
||||
v.uid.metadata_key: uid,
|
||||
|
|
@ -71,6 +73,10 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
|||
v.description.metadata_key: "The Description",
|
||||
}
|
||||
|
||||
# TODO: Make this required eventually
|
||||
if release_date is not None:
|
||||
entry_dict[v.release_date.metadata_key] = release_date
|
||||
|
||||
if is_youtube_channel:
|
||||
entry_dict[v.playlist_metadata.metadata_key]["thumbnails"] = [
|
||||
{
|
||||
|
|
@ -153,6 +159,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="21-1",
|
||||
upload_date="20210808",
|
||||
release_date="20010808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=1,
|
||||
playlist_count=4,
|
||||
|
|
@ -163,6 +170,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-1",
|
||||
upload_date="20200808",
|
||||
release_date="20000808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=2,
|
||||
playlist_count=4,
|
||||
|
|
@ -173,6 +181,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-2",
|
||||
upload_date="20200808",
|
||||
release_date="20000808",
|
||||
playlist_title="Download First",
|
||||
playlist_index=3,
|
||||
playlist_count=4,
|
||||
|
|
@ -183,6 +192,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-3",
|
||||
upload_date="20200807",
|
||||
release_date="20000807",
|
||||
playlist_title="Download First",
|
||||
playlist_index=4,
|
||||
playlist_count=4,
|
||||
|
|
@ -196,6 +206,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-3",
|
||||
upload_date="20200807",
|
||||
release_date="20000807",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=1,
|
||||
playlist_count=5,
|
||||
|
|
@ -206,6 +217,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-4",
|
||||
upload_date="20200806",
|
||||
release_date="20000806",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=2,
|
||||
playlist_count=5,
|
||||
|
|
@ -216,6 +228,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-5",
|
||||
upload_date="20200706",
|
||||
release_date="20000706",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=3,
|
||||
playlist_count=5,
|
||||
|
|
@ -226,6 +239,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-6",
|
||||
upload_date="20200706",
|
||||
release_date="20000706",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=4,
|
||||
playlist_count=5,
|
||||
|
|
@ -236,6 +250,7 @@ def mock_download_collection_entries(
|
|||
mock_entry_dict_factory(
|
||||
uid="20-7",
|
||||
upload_date="20200606",
|
||||
release_date="20000606",
|
||||
playlist_title="Download Second",
|
||||
playlist_index=5,
|
||||
playlist_count=5,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import re
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
from unittest.mock import patch
|
||||
|
|
@ -11,6 +12,7 @@ from ytdl_sub.config.config_file import ConfigFile
|
|||
from ytdl_sub.downloaders.ytdlp import YTDLP
|
||||
from ytdl_sub.entries.entry import Entry
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.exceptions import ValidationException
|
||||
from ytdl_sub.utils.file_handler import FileHandler
|
||||
from ytdl_sub.utils.thumbnail import try_convert_download_thumbnail
|
||||
|
||||
|
|
@ -223,3 +225,35 @@ class TestOutputOptions:
|
|||
dry_run=False,
|
||||
expected_download_summary_file_name="plugins/output_options/test_missing_thumb.json",
|
||||
)
|
||||
|
||||
def test_invalid_keep_files_date_eval(
|
||||
self,
|
||||
config: ConfigFile,
|
||||
subscription_name: str,
|
||||
output_options_subscription_dict: Dict,
|
||||
output_directory: str,
|
||||
mock_download_collection_entries,
|
||||
):
|
||||
output_options_subscription_dict["output_options"]["keep_files_date_eval"] = "nope"
|
||||
|
||||
subscription = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=output_options_subscription_dict,
|
||||
)
|
||||
|
||||
expected_error_msg = (
|
||||
"Validation error in subscription_test.output_options.keep_files_date_eval: "
|
||||
"Expected a standardized date in the form of YYYY-MM-DD, but received 'nope'"
|
||||
)
|
||||
|
||||
with (
|
||||
mock_download_collection_entries(
|
||||
is_youtube_channel=False,
|
||||
num_urls=1,
|
||||
is_extracted_audio=False,
|
||||
is_dry_run=True,
|
||||
),
|
||||
pytest.raises(ValidationException, match=re.escape(expected_error_msg)),
|
||||
):
|
||||
subscription.download(dry_run=True)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,30 @@
|
|||
import re
|
||||
from typing import Set
|
||||
|
||||
import pytest
|
||||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDateEpisodeFormattingPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowByDatePresets
|
||||
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS = {
|
||||
"Kodi TV Show by Date": "kodi_tv_show_by_date",
|
||||
"Jellyfin TV Show by Date": "jellyfin_tv_show_by_date",
|
||||
"Plex TV Show by Date": "plex_tv_show_by_date",
|
||||
}
|
||||
DEFAULT_SEASON_ORDERING = "upload-year"
|
||||
DEFAULT_EPISODE_ORDERING = "upload-month-day"
|
||||
|
||||
DEFAULT_EPISODE_ORDERING_PRESET = "season_by_year__episode_by_month_day"
|
||||
VALID_ORDERING_COMBOS = [
|
||||
# upload
|
||||
("upload-year", "upload-month-day"),
|
||||
("upload-year", "upload-month-day-reversed"),
|
||||
("upload-year", "download-index"),
|
||||
("upload-year-month", "upload-day"),
|
||||
# release
|
||||
("release-year", "release-month-day"),
|
||||
("release-year", "release-month-day-reversed"),
|
||||
("release-year", "download-index"),
|
||||
("release-year-month", "release-day"),
|
||||
]
|
||||
|
||||
|
||||
class TestPrebuiltTVShowPresets:
|
||||
|
|
@ -24,24 +35,28 @@ class TestPrebuiltTVShowPresets:
|
|||
subscription_name: str,
|
||||
output_directory: str,
|
||||
tv_show_preset: str,
|
||||
episode_ordering_preset: str,
|
||||
season_ordering: str,
|
||||
episode_ordering: str,
|
||||
is_youtube_channel: bool = True,
|
||||
is_many_urls: bool = False,
|
||||
):
|
||||
|
||||
expected_summary_name = "unit/{}/{}/is_yt_{}{}".format(
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS[tv_show_preset],
|
||||
episode_ordering_preset,
|
||||
expected_summary_name = "integration/by-date/{}/{}/{}/is_yt_{}{}".format(
|
||||
tv_show_preset.split(" ")[0],
|
||||
season_ordering,
|
||||
episode_ordering,
|
||||
int(is_youtube_channel),
|
||||
"_many_urls" if is_many_urls else "",
|
||||
)
|
||||
|
||||
preset_dict = {
|
||||
"preset": [tv_show_preset, episode_ordering_preset],
|
||||
"preset": tv_show_preset,
|
||||
"overrides": {
|
||||
"url": "https://your.name.here",
|
||||
"tv_show_name": "Best Prebuilt TV Show by Date",
|
||||
"tv_show_directory": output_directory,
|
||||
"tv_show_by_date_season_ordering": season_ordering,
|
||||
"tv_show_by_date_episode_ordering": episode_ordering,
|
||||
},
|
||||
}
|
||||
if is_many_urls:
|
||||
|
|
@ -67,16 +82,19 @@ class TestPrebuiltTVShowPresets:
|
|||
)
|
||||
|
||||
###################################### Perform reformat
|
||||
reformatted_tv_show_structure_preset = "season_by_year__episode_by_download_index"
|
||||
reformatted_expected_summary_name = "unit/{}/{}/is_yt_{}{}".format(
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS[tv_show_preset],
|
||||
reformatted_tv_show_structure_preset,
|
||||
reformatted_season_ordering = "upload-year"
|
||||
reformatted_episode_ordering = "download-index"
|
||||
|
||||
reformatted_expected_summary_name = "integration/by-date/{}/{}/{}/is_yt_{}{}".format(
|
||||
tv_show_preset.split(" ")[0],
|
||||
reformatted_season_ordering,
|
||||
reformatted_episode_ordering,
|
||||
int(is_youtube_channel),
|
||||
"_many_urls" if is_many_urls else "",
|
||||
)
|
||||
|
||||
reformatted_preset_dict = {
|
||||
"preset": [tv_show_preset, reformatted_tv_show_structure_preset],
|
||||
"preset": tv_show_preset,
|
||||
"output_options": {
|
||||
"migrated_download_archive_name": ".ytdl-sub-{tv_show_name_sanitized}-download-archive.json"
|
||||
},
|
||||
|
|
@ -84,6 +102,8 @@ class TestPrebuiltTVShowPresets:
|
|||
"url": "https://your.name.here",
|
||||
"tv_show_name": "Best Prebuilt TV Show by Date",
|
||||
"tv_show_directory": output_directory,
|
||||
"tv_show_by_date_season_ordering": reformatted_season_ordering,
|
||||
"tv_show_by_date_episode_ordering": reformatted_episode_ordering,
|
||||
},
|
||||
}
|
||||
if is_many_urls:
|
||||
|
|
@ -98,7 +118,7 @@ class TestPrebuiltTVShowPresets:
|
|||
output_directory=output_directory,
|
||||
transaction_log=reformatted_transaction_log,
|
||||
transaction_log_summary_file_name=(
|
||||
f"{expected_summary_name}_reformatted_to_{reformatted_tv_show_structure_preset}.txt"
|
||||
f"{expected_summary_name}_reformatted_to_{reformatted_season_ordering}.txt"
|
||||
),
|
||||
)
|
||||
assert_expected_downloads(
|
||||
|
|
@ -123,11 +143,13 @@ class TestPrebuiltTVShowPresets:
|
|||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
tv_show_preset=tv_show_preset,
|
||||
episode_ordering_preset=DEFAULT_EPISODE_ORDERING_PRESET,
|
||||
season_ordering=DEFAULT_SEASON_ORDERING,
|
||||
episode_ordering=DEFAULT_EPISODE_ORDERING,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"episode_ordering_preset", TvShowByDateEpisodeFormattingPresets.preset_names
|
||||
"season_ordering, episode_ordering",
|
||||
VALID_ORDERING_COMBOS,
|
||||
)
|
||||
def test_episode_ordering_presets(
|
||||
self,
|
||||
|
|
@ -135,7 +157,8 @@ class TestPrebuiltTVShowPresets:
|
|||
subscription_name,
|
||||
output_directory,
|
||||
mock_download_collection_entries,
|
||||
episode_ordering_preset: str,
|
||||
season_ordering: str,
|
||||
episode_ordering: str,
|
||||
):
|
||||
|
||||
with mock_download_collection_entries(
|
||||
|
|
@ -146,5 +169,91 @@ class TestPrebuiltTVShowPresets:
|
|||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
tv_show_preset="Kodi TV Show by Date",
|
||||
episode_ordering_preset=episode_ordering_preset,
|
||||
season_ordering=season_ordering,
|
||||
episode_ordering=episode_ordering,
|
||||
)
|
||||
|
||||
def test_invalid_season_ordering(
|
||||
self, config, subscription_name, output_directory, mock_download_collection_entries
|
||||
):
|
||||
expected_message = (
|
||||
"tv_show_by_date_season_ordering must be one of the following: "
|
||||
'"upload-year", '
|
||||
'"upload-year-month", '
|
||||
'"release-year", '
|
||||
'"release-year-month"'
|
||||
)
|
||||
|
||||
with (
|
||||
mock_download_collection_entries(is_youtube_channel=True, num_urls=1),
|
||||
pytest.raises(UserThrownRuntimeError, match=re.escape(expected_message)),
|
||||
):
|
||||
self.run(
|
||||
config=config,
|
||||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
tv_show_preset="Kodi TV Show by Date",
|
||||
season_ordering="nope",
|
||||
episode_ordering=DEFAULT_EPISODE_ORDERING,
|
||||
)
|
||||
|
||||
def test_invalid_episode_ordering(
|
||||
self, config, subscription_name, output_directory, mock_download_collection_entries
|
||||
):
|
||||
expected_message = (
|
||||
"tv_show_by_date_episode_ordering must be one of the following: "
|
||||
'"upload-day", '
|
||||
'"upload-month-day", '
|
||||
'"upload-month-day-reversed", '
|
||||
'"release-day", '
|
||||
'"release-month-day", '
|
||||
'"release-month-day-reversed", '
|
||||
'"download-index"'
|
||||
)
|
||||
|
||||
with (
|
||||
mock_download_collection_entries(is_youtube_channel=True, num_urls=1),
|
||||
pytest.raises(UserThrownRuntimeError, match=re.escape(expected_message)),
|
||||
):
|
||||
self.run(
|
||||
config=config,
|
||||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
tv_show_preset="Kodi TV Show by Date",
|
||||
season_ordering=DEFAULT_SEASON_ORDERING,
|
||||
episode_ordering="not-a-valid",
|
||||
)
|
||||
|
||||
def test_invalid_season_episode_ordering_combo(
|
||||
self, config, subscription_name, output_directory, mock_download_collection_entries
|
||||
):
|
||||
expected_message = (
|
||||
"Detected incompatibility between tv_show_by_date_season_ordering "
|
||||
"and tv_show_by_date_episode_ordering. Ensure you are not using both "
|
||||
"upload and release date, and that the year/month/day are included in "
|
||||
"the combined season and episode."
|
||||
)
|
||||
|
||||
possible_seasons: Set[str] = set()
|
||||
possible_episodes: Set[str] = set()
|
||||
for season_ordering, episode_ordering in VALID_ORDERING_COMBOS:
|
||||
possible_seasons.add(season_ordering)
|
||||
possible_episodes.add(episode_ordering)
|
||||
|
||||
for season_ordering in possible_seasons:
|
||||
for episode_ordering in possible_episodes:
|
||||
if (season_ordering, episode_ordering) in VALID_ORDERING_COMBOS:
|
||||
continue
|
||||
|
||||
with (
|
||||
mock_download_collection_entries(is_youtube_channel=True, num_urls=1),
|
||||
pytest.raises(UserThrownRuntimeError, match=re.escape(expected_message)),
|
||||
):
|
||||
self.run(
|
||||
config=config,
|
||||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
tv_show_preset="Kodi TV Show by Date",
|
||||
season_ordering=season_ordering,
|
||||
episode_ordering=episode_ordering,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import re
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
|
||||
|
|
@ -6,17 +7,11 @@ from expected_download import assert_expected_downloads
|
|||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionEpisodeFormattingPresets
|
||||
from ytdl_sub.prebuilt_presets.tv_show import TvShowCollectionPresets
|
||||
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS = {
|
||||
"Kodi TV Show Collection": "kodi_tv_show_collection",
|
||||
"Jellyfin TV Show Collection": "jellyfin_tv_show_collection",
|
||||
"Plex TV Show Collection": "plex_tv_show_collection",
|
||||
}
|
||||
|
||||
DEFAULT_EPISODE_ORDERING_PRESET = "season_by_collection__episode_by_year_month_day"
|
||||
DEFAULT_EPISODE_ORDERING = "upload-year-month-day"
|
||||
|
||||
|
||||
class TestPrebuiltTvShowCollectionPresets:
|
||||
|
|
@ -27,22 +22,19 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
subscription_name: str,
|
||||
output_directory: str,
|
||||
media_player_preset: str,
|
||||
tv_show_structure_preset: str,
|
||||
episode_ordering: str,
|
||||
season_indices: List[int],
|
||||
is_youtube_channel: bool = True,
|
||||
):
|
||||
expected_summary_name = "unit/{}/{}/s_{}/is_yt_{}".format(
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS[media_player_preset],
|
||||
tv_show_structure_preset,
|
||||
expected_summary_name = "integration/collection/{}/{}/s_{}/is_yt_{}".format(
|
||||
media_player_preset.split(" ")[0],
|
||||
episode_ordering,
|
||||
len(season_indices),
|
||||
int(is_youtube_channel),
|
||||
)
|
||||
parent_presets: List[str] = [media_player_preset, tv_show_structure_preset]
|
||||
|
||||
overrides: Dict[str, str] = {}
|
||||
for season_index in season_indices:
|
||||
parent_presets.append(f"collection_season_{season_index}")
|
||||
|
||||
overrides = dict(
|
||||
overrides,
|
||||
**{
|
||||
|
|
@ -55,12 +47,13 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict={
|
||||
"preset": parent_presets,
|
||||
"preset": media_player_preset,
|
||||
"overrides": dict(
|
||||
overrides,
|
||||
**{
|
||||
"tv_show_name": "Best Prebuilt TV Show Collection",
|
||||
"tv_show_directory": output_directory,
|
||||
"tv_show_collection_episode_ordering": episode_ordering,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
|
@ -79,12 +72,10 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
)
|
||||
|
||||
###################################### Perform reformat
|
||||
reformatted_tv_show_structure_preset = (
|
||||
"season_by_collection__episode_by_playlist_index_reversed"
|
||||
)
|
||||
reformatted_expected_summary_name = "unit/{}/{}/s_{}/is_yt_{}".format(
|
||||
DEPRECATED_TV_SHOW_PRESET_EQUIVALENTS[media_player_preset],
|
||||
reformatted_tv_show_structure_preset,
|
||||
reformatted_tv_show_collection_episode_ordering = "playlist-index-reversed"
|
||||
reformatted_expected_summary_name = "integration/collection/{}/{}/s_{}/is_yt_{}".format(
|
||||
media_player_preset.split(" ")[0],
|
||||
reformatted_tv_show_collection_episode_ordering,
|
||||
len(season_indices),
|
||||
int(is_youtube_channel),
|
||||
)
|
||||
|
|
@ -93,7 +84,7 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict={
|
||||
"preset": parent_presets + [reformatted_tv_show_structure_preset],
|
||||
"preset": media_player_preset,
|
||||
"output_options": {
|
||||
"migrated_download_archive_name": ".ytdl-sub-{tv_show_name_sanitized}-download-archive.json"
|
||||
},
|
||||
|
|
@ -102,6 +93,7 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
**{
|
||||
"tv_show_name": "Best Prebuilt TV Show Collection",
|
||||
"tv_show_directory": output_directory,
|
||||
"tv_show_collection_episode_ordering": reformatted_tv_show_collection_episode_ordering,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
|
@ -112,7 +104,7 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
output_directory=output_directory,
|
||||
transaction_log=reformatted_transaction_log,
|
||||
transaction_log_summary_file_name=(
|
||||
f"{expected_summary_name}_reformatted_to_{reformatted_tv_show_structure_preset}.txt"
|
||||
f"{expected_summary_name}_reformatted_to_{reformatted_tv_show_collection_episode_ordering}.txt"
|
||||
),
|
||||
)
|
||||
assert_expected_downloads(
|
||||
|
|
@ -141,12 +133,20 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
media_player_preset=media_player_preset,
|
||||
tv_show_structure_preset=DEFAULT_EPISODE_ORDERING_PRESET,
|
||||
episode_ordering=DEFAULT_EPISODE_ORDERING,
|
||||
season_indices=season_indices,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"episode_ordering_preset", TvShowCollectionEpisodeFormattingPresets.preset_names
|
||||
"episode_ordering",
|
||||
[
|
||||
"upload-year-month-day",
|
||||
"upload-year-month-day-reversed",
|
||||
"release-year-month-day",
|
||||
"release-year-month-day-reversed",
|
||||
"playlist-index",
|
||||
"playlist-index-reversed",
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("season_indices", [[1], [1, 2]])
|
||||
def test_episode_ordering_presets(
|
||||
|
|
@ -155,7 +155,7 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
subscription_name,
|
||||
output_directory,
|
||||
mock_download_collection_entries,
|
||||
episode_ordering_preset: str,
|
||||
episode_ordering: str,
|
||||
season_indices: List[int],
|
||||
):
|
||||
|
||||
|
|
@ -167,6 +167,32 @@ class TestPrebuiltTvShowCollectionPresets:
|
|||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
media_player_preset="Kodi TV Show Collection",
|
||||
tv_show_structure_preset=episode_ordering_preset,
|
||||
episode_ordering=episode_ordering,
|
||||
season_indices=season_indices,
|
||||
)
|
||||
|
||||
def test_invalid_episode_ordering(
|
||||
self, config, subscription_name, output_directory, mock_download_collection_entries
|
||||
):
|
||||
expected_message = (
|
||||
"tv_show_collection_episode_ordering must be one of the following: "
|
||||
'"upload-year-month-day", '
|
||||
'"upload-year-month-day-reversed", '
|
||||
'"release-year-month-day", '
|
||||
'"release-year-month-day-reversed", '
|
||||
'"playlist-index", '
|
||||
'"playlist-index-reversed"'
|
||||
)
|
||||
|
||||
with (
|
||||
mock_download_collection_entries(is_youtube_channel=True, num_urls=1),
|
||||
pytest.raises(UserThrownRuntimeError, match=re.escape(expected_message)),
|
||||
):
|
||||
self.run(
|
||||
config=config,
|
||||
subscription_name=subscription_name,
|
||||
output_directory=output_directory,
|
||||
media_player_preset="Kodi TV Show Collection",
|
||||
episode_ordering="does-not-exist",
|
||||
season_indices=[1],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@
|
|||
".ytdl-sub-subscription_test-download-archive.json": "76e202bd03ceef93daaffffee2cfa193",
|
||||
"JMC/Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-1.mp4": "dbaeb2a3bfd1de1c7e9615e8bdacb910",
|
||||
"JMC/Mock Entry 20-1.mp4": "d8dc9918d1646c92b4a4bd246291d849",
|
||||
"JMC/Mock Entry 20-1.nfo": "5d001a105d2380844db181911d5df5c6",
|
||||
"JMC/Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-2.mp4": "76c2c70572489c684923a51cb1b50687",
|
||||
"JMC/Mock Entry 20-2.mp4": "6f925179a5b6bf7ffcaf2f70ad585296",
|
||||
"JMC/Mock Entry 20-2.nfo": "dccdded1ca7ebb38d2c9a0e5130bea33",
|
||||
"JMC/Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-3.mp4": "7bb4f21d59a6fb91836537b27a24e776",
|
||||
"JMC/Mock Entry 20-3.mp4": "b48f1803f14be665677e9ac9da787593",
|
||||
"JMC/Mock Entry 20-3.nfo": "7b1eab48693161e83c21203b1308b64e",
|
||||
"JMC/Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 21-1.mp4": "7b008531ca5660b51fb8adc83c799084",
|
||||
"JMC/Mock Entry 21-1.mp4": "5fb865f27ee1cac381597d1e182dfa48",
|
||||
"JMC/Mock Entry 21-1.nfo": "3b4b0e6820f80370d6738ce828f14a89"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-Best Prebuilt TV Show by Date-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "1d0714fb3ca4d31a0f88492a06a6142d",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "a8f3f8580989f3927606bf6060a64e30",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "265b1104b382fd157a123842e49fcdfd",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "09fa4599fd48836c6c0da0760c306006",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "e30d83126c2c6981c936ed894a6f159b",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.mp4": "c712d7fd5dfdb9bb6c2be99f7c796c6f",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.nfo": "7c0f2a9d38bf617377e474fcb9bf2bc2",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.mp4": "7ec7ac1923053c4b5653bbfb8924fdc6",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.nfo": "1f4dec756555ee345cd9d6489b63e070",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.mp4": "414c243016f406451c790757949173aa",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.nfo": "f6f704ae3ae0c4055590a147eb425609",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.mp4": "e2f858efd08ac82749fd01db65d8341e",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.nfo": "c6e0d368bfe9d70134e5a2ff2d3dccc6",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "95d3790190cece6e49d2f4d5f68868b1",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0701 - Mock Entry 20-3.mp4": "6dd6860e8075e5e99c85e14729c41bdb",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0701 - Mock Entry 20-3.nfo": "92d978e6f64d97e7e71e7045c9d2fb1f",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0801 - Mock Entry 20-2.mp4": "6b3537db708f88a877d3c5273df02eb0",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0801 - Mock Entry 20-2.nfo": "b1a3768f43d0f7f4dde1207a8670f9b1",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0802 - Mock Entry 20-1.mp4": "7e40cf2da8eedd93b3df9a017c78cd2e",
|
||||
"Best Prebuilt TV Show by Date/Season 200008/s200008.e0802 - Mock Entry 20-1.nfo": "ea37e0d89713f971a87ddf67f8933be1",
|
||||
"Best Prebuilt TV Show by Date/Season 200108/s200108.e0801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 200108/s200108.e0801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 200108/s200108.e0801 - Mock Entry 21-1.mp4": "c14c0b1901c456e87e1070539d32917e",
|
||||
"Best Prebuilt TV Show by Date/Season 200108/s200108.e0801 - Mock Entry 21-1.nfo": "4e18e9e0454bc948cf8daa0151a0b137",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "d2888d629be62badedce415f8296a995",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000001 - Mock Entry 20-3.mp4": "f94c693da1964bd8e916459253ede6d4",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000001 - Mock Entry 20-3.nfo": "57b7ef31d0b9948bd67ba6a7c83dd22b",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000002 - Mock Entry 20-2.mp4": "68a76930c4456ab58f30ad1a3eb109aa",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000002 - Mock Entry 20-2.nfo": "1cc84f0bbe25315268dc453db8941c7f",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000003 - Mock Entry 20-1.mp4": "b24b301ec95f359ba28ca503e678522f",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e000003 - Mock Entry 20-1.nfo": "e77cc16953d13241f83fbd01792c15ba",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e000004 - Mock Entry 21-1.mp4": "cf36da70822036f06e5c834dac291dd3",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e000004 - Mock Entry 21-1.nfo": "cbd1abadd656f6d047775969604e9af4",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "1e8b4072d6d6aace4cac0c94ac0e711e",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14698 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14698 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14698 - Mock Entry 20-1.mp4": "f4846a3b9ee6a16df3348916077d6476",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14698 - Mock Entry 20-1.nfo": "ad715f955b255f356b6263f06941bf05",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14699 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14699 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14699 - Mock Entry 20-2.mp4": "82a1f043b879412d6219e16993b8b188",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14699 - Mock Entry 20-2.nfo": "2fa884c057a44122a245efe3c33921cd",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14799 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14799 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14799 - Mock Entry 20-3.mp4": "6626433c9c3399c6403ba5753e3b31c2",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e14799 - Mock Entry 20-3.nfo": "63f4405964a11f99ff1595cc18266489",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e14699 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e14699 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e14699 - Mock Entry 21-1.mp4": "bac622134b8f65eaeccce6f3b822be64",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e14699 - Mock Entry 21-1.nfo": "6b9659879d7a1b9f5e2dccee70d7fe66",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "f13a43a83e725981df8417ab1d36705a",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080701 - Mock Entry 20-3.mp4": "219480c0ee2075ed86ccba740cca3d70",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080701 - Mock Entry 20-3.nfo": "6085b15cd1a32e8b45b97cee69ca4741",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080801 - Mock Entry 20-2.mp4": "7ed6abcf342149769ea2de23a0fee0a1",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080801 - Mock Entry 20-2.nfo": "599b687960602264db2f7f44dbd2f849",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080802 - Mock Entry 20-1.mp4": "1431320eb3acc337b1c70a895362397a",
|
||||
"Best Prebuilt TV Show by Date/Season 2000/s2000.e080802 - Mock Entry 20-1.nfo": "6da492b1897671a3309df38e6fa33279",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e080801 - Mock Entry 21-1.mp4": "5c7f600b9a40039ea77729deda8d103f",
|
||||
"Best Prebuilt TV Show by Date/Season 2001/s2001.e080801 - Mock Entry 21-1.nfo": "294fb0959c2cf640312f112c0a7aae27",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "5269b5e9e4fad7b63b6fdb3fef477b1e",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0701 - Mock Entry 20-3.mp4": "b095358d6b335a25f3be3ae44a6d10ac",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0701 - Mock Entry 20-3.nfo": "4ba0e01c1e7295952c3f5e6b9b251d7d",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0801 - Mock Entry 20-2.mp4": "43f73b6f99439e4873bf8d4ba1802452",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0801 - Mock Entry 20-2.nfo": "db9196b729c7b2cd26e3f0fc649b39f0",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0802 - Mock Entry 20-1.mp4": "632af351287dde4d1a096460f6bd93b1",
|
||||
"Best Prebuilt TV Show by Date/Season 202008/s202008.e0802 - Mock Entry 20-1.nfo": "ba4a387d9462f416ba176c31c1c55316",
|
||||
"Best Prebuilt TV Show by Date/Season 202108/s202108.e0801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 202108/s202108.e0801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 202108/s202108.e0801 - Mock Entry 21-1.mp4": "bf0104b783e168b150ea165faa898915",
|
||||
"Best Prebuilt TV Show by Date/Season 202108/s202108.e0801 - Mock Entry 21-1.nfo": "93dd5c4c493422f9a60e61a6b965b39a",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "1d0714fb3ca4d31a0f88492a06a6142d",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "a8f3f8580989f3927606bf6060a64e30",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "265b1104b382fd157a123842e49fcdfd",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "09fa4599fd48836c6c0da0760c306006",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-Best Prebuilt TV Show by Date-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "1d0714fb3ca4d31a0f88492a06a6142d",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "a8f3f8580989f3927606bf6060a64e30",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "265b1104b382fd157a123842e49fcdfd",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "09fa4599fd48836c6c0da0760c306006",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "05539b932348da7e949a63eb71f77efc",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14698 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14698 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14698 - Mock Entry 20-1.mp4": "c27d1898d39763a265e4fe4451777688",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14698 - Mock Entry 20-1.nfo": "88fee5353ad7eecd96865b34654bbde6",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14699 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14699 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14699 - Mock Entry 20-2.mp4": "80c087803d5ac9c0efe02361fdaaa5bd",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14699 - Mock Entry 20-2.nfo": "d781b80ef24916acbf3bf181ab32ddea",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14799 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14799 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14799 - Mock Entry 20-3.mp4": "1b5084c06b33f7e0d6daf7cff03adc73",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e14799 - Mock Entry 20-3.nfo": "252b3639b4d1686f8c79476943f89439",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e14699 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e14699 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e14699 - Mock Entry 21-1.mp4": "a83870aaca55947b7a91ac90109163af",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e14699 - Mock Entry 21-1.nfo": "e7374b766d9ec0599ecf209a0f78c0ba",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "e30d83126c2c6981c936ed894a6f159b",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.mp4": "c712d7fd5dfdb9bb6c2be99f7c796c6f",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.nfo": "7c0f2a9d38bf617377e474fcb9bf2bc2",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.mp4": "7ec7ac1923053c4b5653bbfb8924fdc6",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.nfo": "1f4dec756555ee345cd9d6489b63e070",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.mp4": "414c243016f406451c790757949173aa",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.nfo": "f6f704ae3ae0c4055590a147eb425609",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.mp4": "e2f858efd08ac82749fd01db65d8341e",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.nfo": "c6e0d368bfe9d70134e5a2ff2d3dccc6",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show by Date/tvshow.nfo": "2439ebc18e46a67064956cb940c992e9"
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-Best Prebuilt TV Show by Date-download-archive.json": "0011c85c3339ac1301d80be2f3330e67",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "1d0714fb3ca4d31a0f88492a06a6142d",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "a8f3f8580989f3927606bf6060a64e30",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "265b1104b382fd157a123842e49fcdfd",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "09fa4599fd48836c6c0da0760c306006",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"Best Prebuilt TV Show by Date/.ytdl-sub-subscription_test-download-archive.json": "6cd67e6b935bc5b2521f6ed0fa2ea2ed",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080701 - Mock Entry 20-3.mp4": "c712d7fd5dfdb9bb6c2be99f7c796c6f",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080801 - Mock Entry 20-2.mp4": "7ec7ac1923053c4b5653bbfb8924fdc6",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2020/s2020.e080802 - Mock Entry 20-1.mp4": "414c243016f406451c790757949173aa",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show by Date/Season 2021/s2021.e080801 - Mock Entry 21-1.mp4": "e2f858efd08ac82749fd01db65d8341e",
|
||||
"Best Prebuilt TV Show by Date/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show by Date/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "809885e6c29bba06215b840516628090",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.nfo": "ddf2763f976aaa79199bddbfd3b66501",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.nfo": "cda58b9d5b7ee05d5e4d5144ebfe0f94",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.nfo": "4d5775492f2731cb5dc04a84ebcb029d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.nfo": "2980b224863465a8b8a465c9d381d1f4",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "7331c3a7cc0b43cd547b82af4ec35a3f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.mp4": "6390603e1f9642ea573f25179b42f6af",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.nfo": "42ad110e3f608de3edb94735631d39a7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.mp4": "179e310bd4de1638d84b6da787ff9fa8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.nfo": "ea4dee97b5bb9e49cb72f0942f851feb",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.mp4": "3c412f47cb87e820138fb8909c672216",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.nfo": "7f71bd60012d850ece38fa644eeddc5e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.mp4": "8409a144e67c50573bae29bf76431d76",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.nfo": "c487f013b8d5adc399a793bc803b898f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.nfo": "4eedc1c0e99858530e6228001d024766",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.nfo": "cc1541a65508fcbfd9f024042cb6b6ce",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.nfo": "d5fa573faf1d29c367117917417df62c",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.nfo": "6c40cd5d13c8d088e57906e809a591f8",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "ede1deeba072bae50f7f7039deca0543",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.nfo": "043c6de15ab09f32e64414d1f4a8a89c",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.nfo": "4fb018858502fe2c7a0d3dcb89145a8d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.nfo": "6ac2ee3bd87b453d56bd90b42bbf52a0",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.nfo": "d54ba1888f0083f8de6f401e399ad379",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "9b9e26ff3d036f450501bf5adb979aeb",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.mp4": "fab0f2d0a74558a86b3935c6b962ebe3",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.nfo": "9ceac835c0166bf4f7354106379e6d17",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.mp4": "9c2569c62ff81f067fe3d91324942c11",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.nfo": "35f15e5437cae813095fe2ca3bd2ca18",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.mp4": "921e686edbf2a2e11f8d3eba9ef32592",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.nfo": "9aa69e4c86bb282ac57b2024ec2fbd34",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.mp4": "a9fae3eca046637910a6e79aae4a8354",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.nfo": "709533b6b8f501196db0d98dfe2b2b16",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.nfo": "05f34cd0e6be4b09ea96134faec892f6",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.nfo": "54b4f84daf25626703f7b3a36b0dea49",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.nfo": "3d2644161e57b94cfac5e95732864cc3",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.nfo": "fd91adb2089d0fcdbb2e568a10ac880e",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "809885e6c29bba06215b840516628090",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.nfo": "ddf2763f976aaa79199bddbfd3b66501",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.nfo": "cda58b9d5b7ee05d5e4d5144ebfe0f94",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.nfo": "4d5775492f2731cb5dc04a84ebcb029d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.nfo": "2980b224863465a8b8a465c9d381d1f4",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "809885e6c29bba06215b840516628090",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.nfo": "ddf2763f976aaa79199bddbfd3b66501",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.nfo": "cda58b9d5b7ee05d5e4d5144ebfe0f94",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.nfo": "4d5775492f2731cb5dc04a84ebcb029d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.nfo": "2980b224863465a8b8a465c9d381d1f4",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "7331c3a7cc0b43cd547b82af4ec35a3f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.mp4": "6390603e1f9642ea573f25179b42f6af",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.nfo": "42ad110e3f608de3edb94735631d39a7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.mp4": "179e310bd4de1638d84b6da787ff9fa8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.nfo": "ea4dee97b5bb9e49cb72f0942f851feb",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.mp4": "3c412f47cb87e820138fb8909c672216",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.nfo": "7f71bd60012d850ece38fa644eeddc5e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.mp4": "8409a144e67c50573bae29bf76431d76",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.nfo": "c487f013b8d5adc399a793bc803b898f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.nfo": "4eedc1c0e99858530e6228001d024766",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.nfo": "cc1541a65508fcbfd9f024042cb6b6ce",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.nfo": "d5fa573faf1d29c367117917417df62c",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.nfo": "6c40cd5d13c8d088e57906e809a591f8",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "7331c3a7cc0b43cd547b82af4ec35a3f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.mp4": "6390603e1f9642ea573f25179b42f6af",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.nfo": "42ad110e3f608de3edb94735631d39a7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.mp4": "179e310bd4de1638d84b6da787ff9fa8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.nfo": "ea4dee97b5bb9e49cb72f0942f851feb",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.mp4": "3c412f47cb87e820138fb8909c672216",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.nfo": "7f71bd60012d850ece38fa644eeddc5e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.mp4": "8409a144e67c50573bae29bf76431d76",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.nfo": "c487f013b8d5adc399a793bc803b898f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.nfo": "4eedc1c0e99858530e6228001d024766",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.nfo": "cc1541a65508fcbfd9f024042cb6b6ce",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.nfo": "d5fa573faf1d29c367117917417df62c",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.nfo": "6c40cd5d13c8d088e57906e809a591f8",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "4e5ef7394c029e7fe230f82dfe134e4c",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 21-1.mp4": "79cac07b1964b53ff128ef041e3ed10b",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 21-1.nfo": "2a3d9b51221a541fefc29eebffe47cd4",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-1.mp4": "ebd20e58d50951bfcd2316bcf660ba11",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-1.nfo": "ec57b2c78058e18cdc015813e8a14b9d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-2.mp4": "331068e0bf01c2baaa131c7760a46c02",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-2.nfo": "cd919caf88b0eed99fd2a595c1afa6b1",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-3.mp4": "c646ebe3838f553abb5e9cb1dd96b85f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-3.nfo": "7c4b28456fe5d398b7dad966eb194421",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "c7c2427315924db344d4659a60c59bc9",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-4.mp4": "a37dba001208063f0c04b2a681973c1c",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-4.nfo": "7d8f03bdcd8ee66fd1578a86f20365cc",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.mp4": "3c412f47cb87e820138fb8909c672216",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.nfo": "7f71bd60012d850ece38fa644eeddc5e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-6.mp4": "0bee8e6eb39dbfa8aab81fb78c74ffa0",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-6.nfo": "39996f43e9761247dce614247f99c808",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000005 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000005 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000005 - Mock Entry 20-7.mp4": "db88af54bfd315035ce187c2da47f95a",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000005 - Mock Entry 20-7.nfo": "cae377877c966dad492eaa3f224b86ba",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 21-1.mp4": "79cac07b1964b53ff128ef041e3ed10b",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 21-1.nfo": "974bb83bd43b9579ab1716f66589ccc1",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-1.mp4": "ebd20e58d50951bfcd2316bcf660ba11",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-1.nfo": "b12dcb09ffad7f23f21d350e1f60f128",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-2.mp4": "331068e0bf01c2baaa131c7760a46c02",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-2.nfo": "e6fd0fc3e95b77c595d1a77c2060fd98",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 20-3.mp4": "c646ebe3838f553abb5e9cb1dd96b85f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 20-3.nfo": "23386ea27c1e64afcecdb235acb81b79",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "df87dea55d4f4076ab4c075a3bceaa3d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052498 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052498 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052498 - Mock Entry 20-1.mp4": "170f6eaaa831b92e80ba798b5ae50b60",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052498 - Mock Entry 20-1.nfo": "93e75d3231077883d37c5baac435e182",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052499 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052499 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052499 - Mock Entry 20-2.mp4": "0e1805471b84d94f605f645d9ea94c9e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052499 - Mock Entry 20-2.nfo": "6d022da37f3545d9ab8608f11b8059cd",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052599 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052599 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052599 - Mock Entry 20-3.mp4": "2b59eab2673eb7f2a0ec91033737634a",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052599 - Mock Entry 20-3.nfo": "f47403746915586d1bd87436210311c5",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e99052499 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e99052499 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e99052499 - Mock Entry 21-1.mp4": "450737dd9b8307f498eddb2ac7f4e567",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e99052499 - Mock Entry 21-1.nfo": "5c095683a8c1ae4ff950d4302dc5f06e",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "e89ac9f59f9f9ef22e01c9055708b81c",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052699 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052699 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052699 - Mock Entry 20-4.mp4": "1ea0b0274a45288449dddcb1c91a0ac7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100052699 - Mock Entry 20-4.nfo": "f670533b516a47b833cd0ae04bec5877",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062698 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062698 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062698 - Mock Entry 20-5.mp4": "9b03d1c2e2be9cd75920821accae7774",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062698 - Mock Entry 20-5.nfo": "a223cdfe24fb5d285704351f38db7b46",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062699 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062699 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062699 - Mock Entry 20-6.mp4": "2240a972bc91ef589b3b0a25f1e41725",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100062699 - Mock Entry 20-6.nfo": "bb1cc5d794aa28d43e405179622f2095",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100072599 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100072599 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100072599 - Mock Entry 20-7.mp4": "5944f9af51010e2783576fdbd2ad5436",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e100072599 - Mock Entry 20-7.nfo": "dbd5b09d734a10795a11344a5b536b8f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052498 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052498 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052498 - Mock Entry 20-1.mp4": "170f6eaaa831b92e80ba798b5ae50b60",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052498 - Mock Entry 20-1.nfo": "bb5c4debab0a9f5bbd0a4e303c9bed2d",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052499 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052499 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052499 - Mock Entry 20-2.mp4": "0e1805471b84d94f605f645d9ea94c9e",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052499 - Mock Entry 20-2.nfo": "de6eab4d23acac23213ee25adb8095ac",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052599 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052599 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052599 - Mock Entry 20-3.mp4": "2b59eab2673eb7f2a0ec91033737634a",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e100052599 - Mock Entry 20-3.nfo": "23e88cb7a059946b12c0702a1f987bc7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e99052499 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e99052499 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e99052499 - Mock Entry 21-1.mp4": "450737dd9b8307f498eddb2ac7f4e567",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e99052499 - Mock Entry 21-1.nfo": "ee3a0c5681e7bf7923f72c323e7a9795",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "8f0390db6223f1c48072c28aabdc4162",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080701 - Mock Entry 20-3.mp4": "680b08a1e5032d89188def2784e62146",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080701 - Mock Entry 20-3.nfo": "2ecfb16f4216df21e9485b90b14e355f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080801 - Mock Entry 20-2.mp4": "3c0dcdd38605f032c98aac9068732329",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080801 - Mock Entry 20-2.nfo": "090cfb9795b2ddd210afb93873cb60ce",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080802 - Mock Entry 20-1.mp4": "29d7648807690a4af93541ae340dd7bc",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080802 - Mock Entry 20-1.nfo": "e4aa8129a961c47e3151062b95f39b73",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e01080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e01080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e01080801 - Mock Entry 21-1.mp4": "9abd6ecaf194553e9486e1bf02f552cf",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e01080801 - Mock Entry 21-1.nfo": "34704ea06cbdfaa1c9939e061fd1633a",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "b6ee943d41ca8b0f9b54bb9cb04da7de",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00060601 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00060601 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00060601 - Mock Entry 20-7.mp4": "a75f9d2b28d82b78ae30da3962f57f61",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00060601 - Mock Entry 20-7.nfo": "29b6f491d1d7cb5e62f6a3dd290ba74a",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070601 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070601 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070601 - Mock Entry 20-6.mp4": "18226f783f8c3fac3089d61307bee3ba",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070601 - Mock Entry 20-6.nfo": "8ce2b32b9371cc45908acb73a5c5d5e6",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070602 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070602 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070602 - Mock Entry 20-5.mp4": "180e86031e6af3ea1a54714460a6bf1f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00070602 - Mock Entry 20-5.nfo": "4567dfd30fc7287eea63f28e465d9c54",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080601 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080601 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080601 - Mock Entry 20-4.mp4": "09fba17ad8bf9deb8157ff83880185c3",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e00080601 - Mock Entry 20-4.nfo": "0fc29c2520ae80c4390a5b68d02e6794",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080701 - Mock Entry 20-3.mp4": "680b08a1e5032d89188def2784e62146",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080701 - Mock Entry 20-3.nfo": "7276a8c14720f76cf4e5e624eb1dea2d",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080801 - Mock Entry 20-2.mp4": "3c0dcdd38605f032c98aac9068732329",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080801 - Mock Entry 20-2.nfo": "028a4161b6bccda2cf8d2a0a3ff13f4f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080802 - Mock Entry 20-1.mp4": "29d7648807690a4af93541ae340dd7bc",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e00080802 - Mock Entry 20-1.nfo": "7303574842c9409a6521486ddeb7cde9",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e01080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e01080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e01080801 - Mock Entry 21-1.mp4": "9abd6ecaf194553e9486e1bf02f552cf",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e01080801 - Mock Entry 21-1.nfo": "5b9d248c2fd2460030aa590d8660d957",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "e26598ffd47b150e6bf09e5490546e94",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e79052499 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e79052499 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e79052499 - Mock Entry 21-1.mp4": "cda96931a134eeb6e05e0b5aec03ddfe",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e79052499 - Mock Entry 21-1.nfo": "a7e21040a3fcb264f287e4eba1853f94",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052498 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052498 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052498 - Mock Entry 20-1.mp4": "a7f2ca37b817da0512af297b5652e5e8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052498 - Mock Entry 20-1.nfo": "78c08ad76d004a74cdba012f0b746c22",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052499 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052499 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052499 - Mock Entry 20-2.mp4": "35ebd30923d8f321e023281ec6ef4e6f",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052499 - Mock Entry 20-2.nfo": "d9031d8608d12742c40a3279138c8371",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052599 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052599 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052599 - Mock Entry 20-3.mp4": "204ce9c28ab7b69c659f0f76b6c75bfa",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052599 - Mock Entry 20-3.nfo": "74bd8dc59c5b76ae112d90638977c464",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "2990d95213df5a6c87825a28daa970f4",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052699 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052699 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052699 - Mock Entry 20-4.mp4": "611d34cf77a2123181a7c4096623f6b9",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80052699 - Mock Entry 20-4.nfo": "0242d92e5e0d26745948b42c25eecfba",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062698 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062698 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062698 - Mock Entry 20-5.mp4": "f09ce6574a040cea52b7177f74b9ccea",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062698 - Mock Entry 20-5.nfo": "52b17bcad30adb6eaef4c3b21c1af76b",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062699 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062699 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062699 - Mock Entry 20-6.mp4": "435692c75994d929807b5f09726728ad",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80062699 - Mock Entry 20-6.nfo": "31fb72d089fd680fea1340f3d3c41d64",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80072599 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80072599 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80072599 - Mock Entry 20-7.mp4": "613c386e00bf1c87e4f1d1acbbd98281",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e80072599 - Mock Entry 20-7.nfo": "df65227ee260219883ff618c9fbdf1d4",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e79052499 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e79052499 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e79052499 - Mock Entry 21-1.mp4": "cda96931a134eeb6e05e0b5aec03ddfe",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e79052499 - Mock Entry 21-1.nfo": "0e4ea058d6a1e8760c80d3a02d25aafc",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052498 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052498 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052498 - Mock Entry 20-1.mp4": "a7f2ca37b817da0512af297b5652e5e8",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052498 - Mock Entry 20-1.nfo": "1095322364e512dff963a44b2beffe30",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052499 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052499 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052499 - Mock Entry 20-2.mp4": "35ebd30923d8f321e023281ec6ef4e6f",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052499 - Mock Entry 20-2.nfo": "5130c71d99f1c0726fee8cb8c9d82ba7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052599 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052599 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052599 - Mock Entry 20-3.mp4": "204ce9c28ab7b69c659f0f76b6c75bfa",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e80052599 - Mock Entry 20-3.nfo": "bde2a5401c49b58de0eacea4145d91ae",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "ede1deeba072bae50f7f7039deca0543",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.nfo": "043c6de15ab09f32e64414d1f4a8a89c",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.nfo": "4fb018858502fe2c7a0d3dcb89145a8d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.nfo": "6ac2ee3bd87b453d56bd90b42bbf52a0",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.nfo": "d54ba1888f0083f8de6f401e399ad379",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "a3f1061135b7aa0c25e5176a271d32f0"
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "9b9e26ff3d036f450501bf5adb979aeb",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.mp4": "fab0f2d0a74558a86b3935c6b962ebe3",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.nfo": "9ceac835c0166bf4f7354106379e6d17",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.mp4": "9c2569c62ff81f067fe3d91324942c11",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.nfo": "35f15e5437cae813095fe2ca3bd2ca18",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.mp4": "921e686edbf2a2e11f8d3eba9ef32592",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.nfo": "9aa69e4c86bb282ac57b2024ec2fbd34",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.mp4": "a9fae3eca046637910a6e79aae4a8354",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.nfo": "709533b6b8f501196db0d98dfe2b2b16",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.nfo": "05f34cd0e6be4b09ea96134faec892f6",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.nfo": "54b4f84daf25626703f7b3a36b0dea49",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.nfo": "3d2644161e57b94cfac5e95732864cc3",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.nfo": "fd91adb2089d0fcdbb2e568a10ac880e",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a",
|
||||
"Best Prebuilt TV Show Collection/season01-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/season02-poster.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/tvshow.nfo": "61943a17325c5188475651ca7c68446d"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "ba324b2c6532fe9d8fbe03e0dd6d0410",
|
||||
"Best Prebuilt TV Show Collection/Season 01/Season01.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-Best Prebuilt TV Show Collection-download-archive.json": "6ec6913047c175cedcbd41cb3ef402fc",
|
||||
"Best Prebuilt TV Show Collection/Season 01/Season01.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000001 - Mock Entry 20-7.mp4": "6390603e1f9642ea573f25179b42f6af",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000002 - Mock Entry 20-6.mp4": "179e310bd4de1638d84b6da787ff9fa8",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000003 - Mock Entry 20-5.mp4": "3c412f47cb87e820138fb8909c672216",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e000004 - Mock Entry 20-4.mp4": "8409a144e67c50573bae29bf76431d76",
|
||||
"Best Prebuilt TV Show Collection/Season 02/Season02.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000001 - Mock Entry 20-3.mp4": "e107a93fa177c5f8594ccc3e023db8e8",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000002 - Mock Entry 20-2.mp4": "2788e6b165908e6d52d7d771859b085e",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000003 - Mock Entry 20-1.mp4": "6f0fd7cb3b3c49a8cf7baa6657cb5148",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e000004 - Mock Entry 21-1.mp4": "6a983aa1b5dff65c54bd5f0b78003e07",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "87f96a1e055447383bfea0a12680438d",
|
||||
"Best Prebuilt TV Show Collection/Season 01/Season01.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"Best Prebuilt TV Show Collection/.ytdl-sub-subscription_test-download-archive.json": "04d06f293fcb5164266bedf66b4d4264",
|
||||
"Best Prebuilt TV Show Collection/Season 01/Season01.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20060601 - Mock Entry 20-7.mp4": "fab0f2d0a74558a86b3935c6b962ebe3",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070601 - Mock Entry 20-6.mp4": "9c2569c62ff81f067fe3d91324942c11",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20070602 - Mock Entry 20-5.mp4": "921e686edbf2a2e11f8d3eba9ef32592",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 01/s01.e20080601 - Mock Entry 20-4.mp4": "a9fae3eca046637910a6e79aae4a8354",
|
||||
"Best Prebuilt TV Show Collection/Season 02/Season02.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080701 - Mock Entry 20-3.mp4": "a874866ad7096eb3bf31c72ea3315354",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080801 - Mock Entry 20-2.mp4": "fe6fcf8bfc13c0913ad1509703b447f1",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e20080802 - Mock Entry 20-1.mp4": "1d0f1081b402ebea9aeedf75f891c811",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Best Prebuilt TV Show Collection/Season 02/s02.e21080801 - Mock Entry 21-1.mp4": "e5a844cc2c8fe19037afdf0692731414",
|
||||
"Best Prebuilt TV Show Collection/fanart.jpg": "15c9a67b554f415a662fdf7a3340cd61",
|
||||
"Best Prebuilt TV Show Collection/poster.jpg": "0b0fdbe56bab3e3fdda18730588d742a"
|
||||
}
|
||||
|
|
@ -2,18 +2,18 @@
|
|||
".ytdl-sub-subscription_test-download-archive.json": "76e202bd03ceef93daaffffee2cfa193",
|
||||
"JMC/Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-1.mp4": "40efe3f597c40c11d0d3f2f87cc7650b",
|
||||
"JMC/Mock Entry 20-1.mp4": "f9f1542629edf78fb9d80f2517e6530e",
|
||||
"JMC/Mock Entry 20-1.nfo": "fefcf0b3e4f4ff80ad636584d50dadec",
|
||||
"JMC/Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-2.mp4": "0747f56d03e720128b1fa5ef25bcf3c8",
|
||||
"JMC/Mock Entry 20-2.mp4": "48a46efb360b908a5c9653ef266f6574",
|
||||
"JMC/Mock Entry 20-2.nfo": "025c0b631da5ff5470382b38fce78d2d",
|
||||
"JMC/Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-3.mp4": "eb776b8e6da77a848666d88623600fd6",
|
||||
"JMC/Mock Entry 20-3.mp4": "69b89a35ca5554d047d7ea375635e557",
|
||||
"JMC/Mock Entry 20-3.nfo": "618b0ff948d9de2e10cf1da8c0dd6615",
|
||||
"JMC/Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 21-1.mp4": "5d56530dc8a4cfe55efb791d82bae0f0",
|
||||
"JMC/Mock Entry 21-1.mp4": "a3a18a3acf6e28ab921b8458d1526886",
|
||||
"JMC/Mock Entry 21-1.nfo": "e5c715749efc1603a6e2f59244d87aba"
|
||||
}
|
||||
|
|
@ -2,18 +2,18 @@
|
|||
".ytdl-sub-subscription_test-download-archive.json": "19cf39d57914ba9cbd1e57ba6f1e0683",
|
||||
"JMC/Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-1.mkv": "1514f89a141f7b5ee3fdde9a70e63f57",
|
||||
"JMC/Mock Entry 20-1.mkv": "eb9a8ff61701ab673c2f06147fe29a4e",
|
||||
"JMC/Mock Entry 20-1.nfo": "fefcf0b3e4f4ff80ad636584d50dadec",
|
||||
"JMC/Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-2.mkv": "da089645cc944fdb411ecc46facfe9f6",
|
||||
"JMC/Mock Entry 20-2.mkv": "65d047562c61a068e8a92bd8df8801fa",
|
||||
"JMC/Mock Entry 20-2.nfo": "025c0b631da5ff5470382b38fce78d2d",
|
||||
"JMC/Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 20-3.mkv": "5dbae183aa57c4062af9d5a2e0e0f8fe",
|
||||
"JMC/Mock Entry 20-3.mkv": "98582526fcb3bea10ab7b3df7a5bc65d",
|
||||
"JMC/Mock Entry 20-3.nfo": "618b0ff948d9de2e10cf1da8c0dd6615",
|
||||
"JMC/Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"JMC/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"JMC/Mock Entry 21-1.mkv": "61910bf74a0175fbdf595095109d1a1c",
|
||||
"JMC/Mock Entry 21-1.mkv": "3fe368f6d4bd9662a24abca9215b4d26",
|
||||
"JMC/Mock Entry 21-1.nfo": "e5c715749efc1603a6e2f59244d87aba"
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "7c6fbd0631d7d02025f3da457ba203e3",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "06e7e5beab0b68e4ee3535c801448b4c",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "dfe89d82ae778bae164e161f10ac9adc",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "273785dcc28969f4de4a6e3e5ff1e61e",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "2170bfbc2b85057ba0ec403e7e5ea66d",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
".ytdl-sub-JMC-migrated-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "06e7e5beab0b68e4ee3535c801448b4c",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "dfe89d82ae778bae164e161f10ac9adc",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "273785dcc28969f4de4a6e3e5ff1e61e",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "2170bfbc2b85057ba0ec403e7e5ea66d",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
".ytdl-sub-subscription_test-download-archive.json": "456d8882fc5e35d74f19b386d1d9a059",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "06e7e5beab0b68e4ee3535c801448b4c",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "dfe89d82ae778bae164e161f10ac9adc",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "273785dcc28969f4de4a6e3e5ff1e61e",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1-thumb.jpg": "e80c508c4818454300133fe1dc1a9cd7",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "2170bfbc2b85057ba0ec403e7e5ea66d",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
".ytdl-sub-subscription_test-download-archive.json": "e049068ba7f5bdc27c474b18f4c6b402",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "7d2ee7fe8003ea63ece37dd2a441c123",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.mp4": "06e7e5beab0b68e4ee3535c801448b4c",
|
||||
"Season 2020/s2020.e000001 - Mock Entry 20-3.nfo": "dbe61f2c8ae41041773f713ba5376726",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "699017cd1b67ae216eda769bef413415",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.mp4": "dfe89d82ae778bae164e161f10ac9adc",
|
||||
"Season 2020/s2020.e000002 - Mock Entry 20-2.nfo": "0f071078c9fa2569bbcb998664d40681",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.info.json": "INFO_JSON",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "a16741d4fbf657d1de4c50493db14062",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.mp4": "273785dcc28969f4de4a6e3e5ff1e61e",
|
||||
"Season 2020/s2020.e000003 - Mock Entry 20-1.nfo": "837a61dca11bbe1874ea07cb8ef8a7c9",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.info.json": "INFO_JSON",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "7433153952b069a5674e2a3ed529b49b",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.mp4": "2170bfbc2b85057ba0ec403e7e5ea66d",
|
||||
"Season 2021/s2021.e000004 - Mock Entry 21-1.nfo": "8ee3845c514a411425b7e9198666b61c",
|
||||
"tvshow.nfo": "cccca1086b41af04d8ea004b1aa250e8"
|
||||
}
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
{
|
||||
".ytdl-sub-j_b-download-archive.json": "1a99156e9ece62539fb2608416a07200",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "b35d01351e5dd1195e90a41b2edeb5b7",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "0aecc0e9832768002f41e09a7e70b305",
|
||||
"j_b/[2021] Baby Santana's Dorian Groove/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "5c107c122048389aa40936c4fba0436e",
|
||||
"j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "2d4154dfa596c905d71cfd970f5dc9d3",
|
||||
"j_b/[2021] Purple Clouds/folder.jpg": "967892be44b8c47e1be73f055a7c6f08",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "e737c2ba118920643cec9eac09a283ea",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "d5def3e4329b9b95c5354c838dd3bc91",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "1694c4a2889aa7dacafc5f2fdb4fe1d7",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "9c8ddee6aaf88b38706ce6bbdf907878",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "4bf9e700137cb1b58e730dd312e00bb4",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "c1920254046eda0d84b36dd34f9bafdb",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "26f2eb8395b23cecc4000e2fd58304bf",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "e3ceb5ae25c115d037a298b4620bce9f",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "f3dcfe7c8569853a02eb12ad21b0e248",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "4fb9a18b3fdd788ce9d9f4c8a07b6028",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "ad186ee1d0029f8de02357e8b8712a4b",
|
||||
"j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "10c925fc97629ca788c44ae8082ee889",
|
||||
"j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "da0e8a7db660adbfef255ba1763c384c",
|
||||
"j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "42284493f75a55bd1b1d3f1ac8d1ffe1",
|
||||
"j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "d660abefa257a10cbeae434c770bf3e5",
|
||||
"j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "565d4dcf92e40e1485ed77fa79b52c17",
|
||||
"j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "7c5903693230ca9ac8b44b76ed004eb4",
|
||||
"j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "dfec9909cb8156ec8d5c28cfce858f36",
|
||||
"j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "2c8769a9de3d1033d0e152c642512e40",
|
||||
"j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "b3920d39deb847be938e03e3d74d4ac9",
|
||||
"j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "759394ebe3db9ccef564fa9d7c0dfd09",
|
||||
"j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "477af6c479263539f244db8d9de04201",
|
||||
"j_b/[2022] Acoustic Treats/folder.jpg": "967892be44b8c47e1be73f055a7c6f08"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue