diff --git a/.github/workflows/package-gui.yaml b/.github/workflows/package-gui.yaml new file mode 100644 index 000000000..ad2e6f4fc --- /dev/null +++ b/.github/workflows/package-gui.yaml @@ -0,0 +1,276 @@ +name: ytld-sub Docker GUI Build + +on: + push: + # Publish `master` as Docker `latest` image. + branches: + - master + + # Publish `v1.2.3` tags as releases. + tags: + - v* + + # Run tests for any PRs. + pull_request: + +env: + IMAGE_NAME: ytdl-sub-gui + +jobs: + # Push image to GitHub Packages. + # See also https://docs.docker.com/docker-hub/builds/ + version: + name: version + runs-on: ubuntu-latest + outputs: + pypi_version: ${{ steps.set_outputs.outputs.pypi_version }} + local_version: ${{ steps.set_outputs.outputs.local_version }} + init_contents: ${{ steps.set_outputs.outputs.init_contents }} + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: master + + - name: Set date and commit hash variables + run: | + echo "DATE=$(date +'%Y.%m.%d')" >> $GITHUB_ENV + echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + + - name: Count number of commits on master on day, minus 1 to account for post-push + run: | + echo "DATE_COMMIT_COUNT=$(($(git rev-list --count master --since='${{ env.DATE }} 00:00:00')-1))" >> $GITHUB_ENV + - name: Set pypi and local version values + run: | + echo "LOCAL_VERSION=${{ env.DATE }}+${{ env.COMMIT_HASH }}" >> $GITHUB_ENV + if [ ${{ env.DATE_COMMIT_COUNT }} -le "0" ] + then + echo "PYPI_VERSION=${{ env.DATE }}" >> $GITHUB_ENV + else + echo "PYPI_VERSION=${{ env.DATE }}.post${{ env.DATE_COMMIT_COUNT }}" >> $GITHUB_ENV + fi + + - name: Test versions + run: | + echo "${{ env.PYPI_VERSION }}" + echo "${{ env.LOCAL_VERSION }}" + + - id: set_outputs + run: | + echo "pypi_version=${{ env.PYPI_VERSION }}" >> "$GITHUB_OUTPUT" + echo "local_version=${{ env.LOCAL_VERSION }}" >> "$GITHUB_OUTPUT" + echo 'init_contents=__pypi_version__ = "${{ env.PYPI_VERSION }}";__local_version__ = "${{ env.LOCAL_VERSION }}"' >> "$GITHUB_OUTPUT" + + build: + runs-on: ubuntu-22.04 + strategy: + matrix: + python-version: [ "3.10" ] + + permissions: + contents: read + + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + + - name: Build Wheel + run: | + make docker_stage + + - name: Save Python build cache + uses: actions/cache@v3 + with: + path: docker/root + key: ${{github.sha}} + + + # Build ARM64 container, only on master branch to save time testing + package-arm64: + runs-on: ubuntu-22.04 + needs: [ + build + ] + + permissions: + contents: read + + if: ${{ + github.ref == 'refs/heads/master' + && !contains(github.event.head_commit.message, '[DEV]') + && !contains(github.event.head_commit.message, '[DOCS]') + }} + steps: + - uses: actions/checkout@v3 + + - name: Restore Python build cache + uses: actions/cache@v3 + with: + path: docker/root + key: ${{github.sha}} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: linux/arm64 + + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v2.0.0 + + - name: Build Docker Image + run: | + docker buildx build \ + --platform=linux/arm64 \ + --cache-to=type=local,dest=/tmp/build-cache/arm64 \ + --tag $IMAGE_NAME \ + --label "runnumber=${GITHUB_RUN_ID}" \ + --file docker/Dockerfile.gui \ + docker/ + + - name: Save ARM64 build cache + uses: actions/cache@v3 + with: + path: /tmp/build-cache/arm64 + key: ${{github.sha}}-arm64 + + + # Build AMD64 container + package-amd64: + runs-on: ubuntu-22.04 + needs: [ + build + ] + + permissions: + contents: read + + steps: + - uses: actions/checkout@v3 + + - name: Restore Python build cache + uses: actions/cache@v3 + with: + path: docker/root + key: ${{github.sha}} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: linux/amd64 + + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v2.0.0 + + - name: Build Docker Image + run: | + docker buildx build \ + --platform=linux/amd64 \ + --cache-to=type=local,dest=/tmp/build-cache/amd64 \ + --tag $IMAGE_NAME \ + --label "runnumber=${GITHUB_RUN_ID}" \ + --file docker/Dockerfile.gui \ + docker/ + + - name: Save AMD64 build cache + uses: actions/cache@v3 + with: + path: /tmp/build-cache/amd64 + key: ${{github.sha}}-amd64 + + + # On master branch, build the docker manifest file from the cached + # docker builds and push to the registry + deploy: + runs-on: ubuntu-22.04 + needs: [ + version, + build, + package-arm64, + package-amd64 + ] + + permissions: + packages: write + contents: read + + if: ${{ + github.ref == 'refs/heads/master' + && !contains(github.event.head_commit.message, '[DEV]') + && !contains(github.event.head_commit.message, '[DOCS]') + }} + steps: + - uses: actions/checkout@v3 + + - name: Restore Python build cache + uses: actions/cache@v3 + with: + path: docker/root + key: ${{github.sha}} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: linux/amd64,linux/arm64 + + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v2.0.0 + + - name: login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Restore ARM64 build cache + uses: actions/cache@v3 + with: + path: /tmp/build-cache/arm64 + key: ${{github.sha}}-arm64 + + - name: Restore AMD64 build cache + uses: actions/cache@v3 + with: + path: /tmp/build-cache/amd64 + key: ${{github.sha}}-amd64 + + - name: Format image_id + id: formatted-image_id + run: | + IMAGE_ID=ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME} + + # Change all uppercase to lowercase + IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + echo IMAGE_ID=${IMAGE_ID} + + echo ::set-output name=IMAGE_ID::${IMAGE_ID} + + - name: Get the version + id: formatted_version + run: | + # Strip git ref prefix from version + VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') + # Strip "v" prefix from tag name + [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') + # Use Docker `latest` tag convention + [ "$VERSION" == "master" ] && VERSION=latest + echo VERSION=${VERSION} + + echo ::set-output name=VERSION::${VERSION} + + - name: Build Docker Image and push to registry + run: | + docker buildx build --push \ + --platform=linux/amd64,linux/arm64 \ + --cache-from=type=local,src=/tmp/build-cache/amd64 \ + --cache-from=type=local,src=/tmp/build-cache/arm64 \ + --tag ${{ steps.formatted-image_id.outputs.IMAGE_ID }}:${{ steps.formatted_version.outputs.VERSION }} \ + --tag ${{ steps.formatted-image_id.outputs.IMAGE_ID }}:${{ needs.version.outputs.pypi_version }} \ + --label "runnumber=${GITHUB_RUN_ID}" \ + --file docker/Dockerfile.gui \ + docker/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4d638c332..d467a2389 100644 --- a/.gitignore +++ b/.gitignore @@ -141,6 +141,7 @@ dmypy.json docker/*.whl docker/root/*.whl docker/root/defaults/examples +docker/testing/volumes .local/ diff --git a/Makefile b/Makefile index f61f8b342..30ca26b3c 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,9 @@ docker_stage: wheel docker: docker_stage sudo docker build --progress=plain --no-cache -t ytdl-sub:local docker/ docker_ubuntu: docker_stage - sudo docker build --progress=plain --no-cache -t ytdl-sub:local_ubuntu -f docker/Dockerfile.ubuntu docker/ + sudo docker build --progress=plain --no-cache -t ytdl-sub-ubuntu:local -f docker/Dockerfile.ubuntu docker/ +docker_gui: docker_stage + sudo docker build --progress=plain --no-cache -t ytdl-sub-gui:local -f docker/Dockerfile.gui docker/ executable: clean pyinstaller ytdl-sub.spec mv dist/ytdl-sub dist/ytdl-sub${EXEC_SUFFIX} diff --git a/docker/Dockerfile.gui b/docker/Dockerfile.gui new file mode 100644 index 000000000..1b99d8912 --- /dev/null +++ b/docker/Dockerfile.gui @@ -0,0 +1,87 @@ +FROM lscr.io/linuxserver/code-server:4.18.0 + +# Needed for phantomjs +ENV OPENSSL_CONF=/etc/ssl + +############################################################################### +# YTDL-SUB INSTALL + +SHELL ["/bin/bash", "-c"] +COPY root/ / +RUN mkdir -p /config && \ + apt-get -y update && \ + apt-get -y upgrade && \ + apt-get install --no-install-recommends -y \ + software-properties-common && \ + apt-get -y update && \ + apt-get -y upgrade && \ + apt-get install --no-install-recommends -y \ + vim \ + g++ \ + nano \ + make \ + python3.10-dev \ + python3-pip \ + fontconfig \ + xz-utils \ + bzip2 \ + aria2 \ + python3-venv && \ + if [[ $(uname -m) == "x86_64" ]]; then \ + curl -L -o ffmpeg.tar.gz https://github.com/yt-dlp/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz && \ + tar -xf ffmpeg.tar.gz && \ + chmod +x ffmpeg-master-latest-linux64-gpl/bin/ffmpeg && \ + chmod +x ffmpeg-master-latest-linux64-gpl/bin/ffprobe && \ + mv ffmpeg-master-latest-linux64-gpl/bin/ffmpeg /usr/bin/ffmpeg && \ + mv ffmpeg-master-latest-linux64-gpl/bin/ffprobe /usr/bin/ffprobe && \ + rm ffmpeg.tar.gz && \ + rm -rf ffmpeg-master-latest-linux64-gpl/ ; \ + else \ + curl -L -o ffmpeg.tar.gz https://github.com/yt-dlp/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linuxarm64-gpl.tar.xz && \ + tar -xf ffmpeg.tar.gz && \ + chmod +x ffmpeg-master-latest-linuxarm64-gpl/bin/ffmpeg && \ + chmod +x ffmpeg-master-latest-linuxarm64-gpl/bin/ffprobe && \ + mv ffmpeg-master-latest-linuxarm64-gpl/bin/ffmpeg /usr/bin/ffmpeg && \ + mv ffmpeg-master-latest-linuxarm64-gpl/bin/ffprobe /usr/bin/ffprobe && \ + rm ffmpeg.tar.gz && \ + rm -rf ffmpeg-master-latest-linuxarm64-gpl/ ; \ + fi && \ + # Ensure ffmpeg is installed + ffmpeg -version && \ + # Install phantomjs if using x86_64, ensure it is properly installed + if [[ $(uname -m) == "x86_64" ]]; then \ + curl -L -o phantomjs.tar.bz2 https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 && \ + tar -xvf phantomjs.tar.bz2 && \ + mv phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs && \ + rm -rf phantomjs-2.1.1-linux-x86_64/ && \ + rm phantomjs.tar.bz2 && \ + echo "Phantom JS version:" && \ + phantomjs --version ; \ + fi && \ + # Install ytdl-sub, ensure it is installed properly + pip install --no-cache-dir ytdl_sub-*.whl && \ + ytdl-sub -h && \ + # Delete unneeded packages after install + rm ytdl_sub-*.whl && \ + apt-get remove -y \ + g++ \ + make \ + xz-utils \ + bzip2 \ + python3.10-dev \ + python3-venv && \ + apt-get autoremove -y && \ + apt-get purge -y --auto-remove && \ + rm -rf /var/lib/apt/lists/* + +############################################################################### +# CONTAINER CONFIGS + + +ENV YTDL_SUB_TYPE="gui" \ +EDITOR="nano" \ +HOME="/config" \ +DOCKER_MODS=linuxserver/mods:universal-cron \ +DEFAULT_WORKSPACE=/config/ytdl-sub-configs + +VOLUME /config \ No newline at end of file diff --git a/docker/root/defaults/vs-code-data.tar.gz b/docker/root/defaults/vs-code-data.tar.gz new file mode 100644 index 000000000..194521cee Binary files /dev/null and b/docker/root/defaults/vs-code-data.tar.gz differ diff --git a/docker/root/etc/cont-init.d/defaults-gui b/docker/root/etc/cont-init.d/defaults-gui new file mode 100644 index 000000000..63bd61d2d --- /dev/null +++ b/docker/root/etc/cont-init.d/defaults-gui @@ -0,0 +1,30 @@ +#!/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 +[[ ! -e /config/data/ytdl-sub-applied ]] && \ + echo "First run, placing default vs-code data directory..." && \ + cp /defaults/vs-code-data.tar.gz /config && \ + cd /config && \ + tar -xzf vs-code-data.tar.gz && \ + rm vs-code-data.tar.gz && \ + touch /config/data/ytdl-sub-applied + +# permissions +chown -R ${PUID:-abc}:${PGID:-abc} \ + /config diff --git a/docker/root/etc/cont-init.d/30-config b/docker/root/etc/cont-init.d/defaults-headless similarity index 75% rename from docker/root/etc/cont-init.d/30-config rename to docker/root/etc/cont-init.d/defaults-headless index ed02409ac..8d5d632ba 100644 --- a/docker/root/etc/cont-init.d/30-config +++ b/docker/root/etc/cont-init.d/defaults-headless @@ -1,5 +1,12 @@ #!/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 @@ -10,4 +17,4 @@ # permissions chown -R ${PUID:-abc}:${PGID:-abc} \ - /config + /config \ No newline at end of file diff --git a/docker/testing/docker-compose.yml b/docker/testing/docker-compose.yml new file mode 100644 index 000000000..1a8797b95 --- /dev/null +++ b/docker/testing/docker-compose.yml @@ -0,0 +1,13 @@ +services: + ytdl-sub-gui: + image: ytdl-sub-gui:local + container_name: ytdl-sub-gui + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Los_Angeles + volumes: + - ./volumes/ytdl-sub-gui:/config + ports: + - 8443:8443 + restart: unless-stopped diff --git a/src/ytdl_sub/__init__.py b/src/ytdl_sub/__init__.py index 94aae3065..a1ae89f94 100644 --- a/src/ytdl_sub/__init__.py +++ b/src/ytdl_sub/__init__.py @@ -1,2 +1,2 @@ -__pypi_version__ = "2023.03.24.post7" -__local_version__ = "2023.03.24+14e4a4b" +__pypi_version__ = "2023.10.22.post3" +__local_version__ = "2023.10.22+bfba4f0"