pynetv 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pynetv-0.4.1/.dockerignore +39 -0
- pynetv-0.4.1/.github/actionlint.yaml +5 -0
- pynetv-0.4.1/.github/workflows/ai-upscale.yml +155 -0
- pynetv-0.4.1/.github/workflows/ci.yml +109 -0
- pynetv-0.4.1/.github/workflows/ffmpeg-base.yml +155 -0
- pynetv-0.4.1/.github/workflows/publish-pypi.yml +50 -0
- pynetv-0.4.1/.github/workflows/release.yml +75 -0
- pynetv-0.4.1/.gitignore +39 -0
- pynetv-0.4.1/.pre-commit-config.yaml +421 -0
- pynetv-0.4.1/.python-version +1 -0
- pynetv-0.4.1/Dockerfile +81 -0
- pynetv-0.4.1/Dockerfile.ai_upscale +112 -0
- pynetv-0.4.1/Dockerfile.ffmpeg +301 -0
- pynetv-0.4.1/Dockerfile.gateway +33 -0
- pynetv-0.4.1/LICENSE +190 -0
- pynetv-0.4.1/PKG-INFO +916 -0
- pynetv-0.4.1/README.md +883 -0
- pynetv-0.4.1/__init__.py +0 -0
- pynetv-0.4.1/apple/.env.example +2 -0
- pynetv-0.4.1/apple/.gitignore +5 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/AppleTV/01-live-guide.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/AppleTV/02-channel-browsing.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/AppleTV/03-full-screen.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/Attribution.txt +48 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/Mac/01-live-guide.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/Mac/02-channel-browsing.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/Mac/03-full-screen.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/contact-sheet.jpg +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPad/01-live-guide.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPad/02-channel-browsing.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPad/03-full-screen.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone/01-live-guide.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone/02-channel-browsing.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone/03-full-screen.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone-6.5-inch/01-live-guide.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone-6.5-inch/02-channel-browsing.png +0 -0
- pynetv-0.4.1/apple/AppStoreScreenshots/iPhone-6.5-inch/03-full-screen.png +0 -0
- pynetv-0.4.1/apple/Config.xcconfig +3 -0
- pynetv-0.4.1/apple/PrivacyInfo.xcprivacy +74 -0
- pynetv-0.4.1/apple/README.md +284 -0
- pynetv-0.4.1/apple/Resources/PrivacyPolicy.txt +88 -0
- pynetv-0.4.1/apple/Resources/Support.txt +44 -0
- pynetv-0.4.1/apple/Shared/APIClient.swift +492 -0
- pynetv-0.4.1/apple/Shared/AppInformationView.swift +103 -0
- pynetv-0.4.1/apple/Shared/AppModel.swift +512 -0
- pynetv-0.4.1/apple/Shared/GuideView.swift +926 -0
- pynetv-0.4.1/apple/Shared/LoginView.swift +73 -0
- pynetv-0.4.1/apple/Shared/MainView.swift +191 -0
- pynetv-0.4.1/apple/Shared/Models.swift +447 -0
- pynetv-0.4.1/apple/Shared/PlayerView.swift +1859 -0
- pynetv-0.4.1/apple/Shared/RootView.swift +50 -0
- pynetv-0.4.1/apple/Shared/SettingsView.swift +35 -0
- pynetv-0.4.1/apple/Shared/Theme.swift +65 -0
- pynetv-0.4.1/apple/Shared/WatchView.swift +594 -0
- pynetv-0.4.1/apple/Shared/neTVApp.swift +26 -0
- pynetv-0.4.1/apple/Tests/ArchiveAPIChecks.swift +204 -0
- pynetv-0.4.1/apple/Tests/GuideDataChecks.swift +173 -0
- pynetv-0.4.1/apple/Tests/PlaybackStartChecks.swift +469 -0
- pynetv-0.4.1/apple/archive-testflight.sh +48 -0
- pynetv-0.4.1/apple/iOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png +0 -0
- pynetv-0.4.1/apple/iOS/Info.plist +57 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-128@1x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-16@1x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-256@1x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-32@1x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-512@1x.png +0 -0
- pynetv-0.4.1/apple/macOS/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png +0 -0
- pynetv-0.4.1/apple/macOS/Info.plist +44 -0
- pynetv-0.4.1/apple/macOS/neTV.entitlements +10 -0
- pynetv-0.4.1/apple/neTV.xcodeproj/project.pbxproj +675 -0
- pynetv-0.4.1/apple/neTV.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- pynetv-0.4.1/apple/neTV.xcodeproj/xcshareddata/xcschemes/neTV-iOS.xcscheme +87 -0
- pynetv-0.4.1/apple/neTV.xcodeproj/xcshareddata/xcschemes/neTV-macOS.xcscheme +87 -0
- pynetv-0.4.1/apple/neTV.xcodeproj/xcshareddata/xcschemes/neTV-tvOS.xcscheme +87 -0
- pynetv-0.4.1/apple/project.yml +117 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Background.imagestacklayer/Content.imageset/icon@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Background.imagestacklayer/Content.imageset/icon@2x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Foreground.imagestacklayer/Content.imageset/icon@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Foreground.imagestacklayer/Content.imageset/icon@2x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Store Icon.imagestack/Background.imagestacklayer/Content.imageset/icon@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Store Icon.imagestack/Foreground.imagestacklayer/Content.imageset/icon@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Wide.imageset/image@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Wide.imageset/image@2x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf.imageset/image@1x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf.imageset/image@2x.png +0 -0
- pynetv-0.4.1/apple/tvOS/Info.plist +31 -0
- pynetv-0.4.1/auth.py +370 -0
- pynetv-0.4.1/auth_test.py +331 -0
- pynetv-0.4.1/cache.py +963 -0
- pynetv-0.4.1/cache_test.py +1093 -0
- pynetv-0.4.1/catchup.py +149 -0
- pynetv-0.4.1/catchup_test.py +144 -0
- pynetv-0.4.1/chromecast.py +389 -0
- pynetv-0.4.1/chromecast_test.py +423 -0
- pynetv-0.4.1/collector_tests/cast.test.cjs +299 -0
- pynetv-0.4.1/collector_tests/live-playback.test.cjs +324 -0
- pynetv-0.4.1/collector_tests/player-live-integration.test.cjs +883 -0
- pynetv-0.4.1/collector_tests/player-quality.test.cjs +89 -0
- pynetv-0.4.1/collector_tests/virtual-guide.test.cjs +52 -0
- pynetv-0.4.1/dataclasses_test.py +105 -0
- pynetv-0.4.1/docker-compose.cast.yml +14 -0
- pynetv-0.4.1/docker-compose.yml +125 -0
- pynetv-0.4.1/entrypoint-ai_upscale.sh +98 -0
- pynetv-0.4.1/entrypoint.sh +68 -0
- pynetv-0.4.1/epg.py +582 -0
- pynetv-0.4.1/epg_test.py +729 -0
- pynetv-0.4.1/fast_start.py +354 -0
- pynetv-0.4.1/fast_start_test.py +861 -0
- pynetv-0.4.1/ffmpeg_command.py +1782 -0
- pynetv-0.4.1/ffmpeg_command_test.py +2102 -0
- pynetv-0.4.1/ffmpeg_session.py +2646 -0
- pynetv-0.4.1/ffmpeg_session_coverage_test.py +2120 -0
- pynetv-0.4.1/ffmpeg_session_lifecycle_test.py +205 -0
- pynetv-0.4.1/ffmpeg_session_test.py +1358 -0
- pynetv-0.4.1/gateway.py +703 -0
- pynetv-0.4.1/gateway_catalog.py +354 -0
- pynetv-0.4.1/gateway_catalog_test.py +475 -0
- pynetv-0.4.1/gateway_epg.py +189 -0
- pynetv-0.4.1/gateway_epg_test.py +428 -0
- pynetv-0.4.1/gateway_test.py +1360 -0
- pynetv-0.4.1/handoff.py +489 -0
- pynetv-0.4.1/handoff_test.py +391 -0
- pynetv-0.4.1/live_recovery_test.py +375 -0
- pynetv-0.4.1/m3u.py +567 -0
- pynetv-0.4.1/m3u_test.py +692 -0
- pynetv-0.4.1/main.py +4580 -0
- pynetv-0.4.1/main_core_test.py +1031 -0
- pynetv-0.4.1/main_test.py +2655 -0
- pynetv-0.4.1/main_views_test.py +1529 -0
- pynetv-0.4.1/playback_policy.py +181 -0
- pynetv-0.4.1/playback_policy_test.py +232 -0
- pynetv-0.4.1/playback_session_test.py +237 -0
- pynetv-0.4.1/playlists.py +533 -0
- pynetv-0.4.1/playlists_test.py +318 -0
- pynetv-0.4.1/pyproject.toml +402 -0
- pynetv-0.4.1/screenshots/ai-upscale_batman_disabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_batman_enabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_cleopatra_disabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_cleopatra_enabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_macgyver_disabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_macgyver_enabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_price-is-right_disabled.png +0 -0
- pynetv-0.4.1/screenshots/ai-upscale_price-is-right_enabled.png +0 -0
- pynetv-0.4.1/screenshots/epg.png +0 -0
- pynetv-0.4.1/screenshots/player.png +0 -0
- pynetv-0.4.1/screenshots/series.png +0 -0
- pynetv-0.4.1/screenshots/settings.png +0 -0
- pynetv-0.4.1/screenshots/vod.png +0 -0
- pynetv-0.4.1/static/icons/android-chrome-192x192.png +0 -0
- pynetv-0.4.1/static/icons/android-chrome-512x512.png +0 -0
- pynetv-0.4.1/static/icons/apple-touch-icon.png +0 -0
- pynetv-0.4.1/static/icons/favicon-16x16.png +0 -0
- pynetv-0.4.1/static/icons/favicon-32x32.png +0 -0
- pynetv-0.4.1/static/icons/mstile-150x150.png +0 -0
- pynetv-0.4.1/static/icons/site.webmanifest +20 -0
- pynetv-0.4.1/static/js/app.js +245 -0
- pynetv-0.4.1/static/js/cast.js +325 -0
- pynetv-0.4.1/static/js/favorites-grid.js +225 -0
- pynetv-0.4.1/static/js/handoff-card.js +54 -0
- pynetv-0.4.1/static/js/live-playback.js +227 -0
- pynetv-0.4.1/static/js/player-quality.js +41 -0
- pynetv-0.4.1/static/js/player.js +1925 -0
- pynetv-0.4.1/static/js/settings.js +944 -0
- pynetv-0.4.1/static/js/virtual-guide.js +711 -0
- pynetv-0.4.1/templates/base.html +87 -0
- pynetv-0.4.1/templates/error.html +14 -0
- pynetv-0.4.1/templates/guide.html +592 -0
- pynetv-0.4.1/templates/icons.html +5 -0
- pynetv-0.4.1/templates/login.html +35 -0
- pynetv-0.4.1/templates/movie_detail.html +101 -0
- pynetv-0.4.1/templates/player.html +286 -0
- pynetv-0.4.1/templates/playlists.html +452 -0
- pynetv-0.4.1/templates/search.html +207 -0
- pynetv-0.4.1/templates/series.html +110 -0
- pynetv-0.4.1/templates/series_detail.html +111 -0
- pynetv-0.4.1/templates/settings.html +1007 -0
- pynetv-0.4.1/templates/setup.html +46 -0
- pynetv-0.4.1/templates/vod.html +111 -0
- pynetv-0.4.1/testing.py +31 -0
- pynetv-0.4.1/testing_test.py +42 -0
- pynetv-0.4.1/tools/alignm3u.py +310 -0
- pynetv-0.4.1/tools/alignm3u_test.py +195 -0
- pynetv-0.4.1/tools/benchmark-nomos.py +270 -0
- pynetv-0.4.1/tools/benchmark-nomos_test.py +310 -0
- pynetv-0.4.1/tools/build-nomos-benchmark.sh +18 -0
- pynetv-0.4.1/tools/debug_remap.py +79 -0
- pynetv-0.4.1/tools/debug_remap_test.py +117 -0
- pynetv-0.4.1/tools/export-tensorrt.py +579 -0
- pynetv-0.4.1/tools/export-tensorrt_test.py +757 -0
- pynetv-0.4.1/tools/install-ai_upscale.sh +152 -0
- pynetv-0.4.1/tools/install-ffmpeg.sh +1801 -0
- pynetv-0.4.1/tools/install-letsencrypt.sh +46 -0
- pynetv-0.4.1/tools/install-netv.sh +143 -0
- pynetv-0.4.1/tools/install-prereqs.sh +30 -0
- pynetv-0.4.1/tools/manual_remap.py +121 -0
- pynetv-0.4.1/tools/manual_remap_test.py +131 -0
- pynetv-0.4.1/tools/patches/dnn_backend_tensorrt.cpp +1844 -0
- pynetv-0.4.1/tools/patches/dnn_backend_torch.cpp +1006 -0
- pynetv-0.4.1/tools/patches/dnn_cuda_kernels.cu +424 -0
- pynetv-0.4.1/tools/patches/dnn_cuda_kernels.h +49 -0
- pynetv-0.4.1/tools/patches/vf_dnn_processing.c +491 -0
- pynetv-0.4.1/tools/remap_epg.py +915 -0
- pynetv-0.4.1/tools/remap_epg_test.py +348 -0
- pynetv-0.4.1/tools/uninstall-netv.sh +40 -0
- pynetv-0.4.1/tools/xtream2m3u.py +671 -0
- pynetv-0.4.1/tools/xtream2m3u_test.py +495 -0
- pynetv-0.4.1/tools/zap2xml.py +733 -0
- pynetv-0.4.1/tools/zap2xml_test.py +419 -0
- pynetv-0.4.1/util.py +232 -0
- pynetv-0.4.1/util_test.py +253 -0
- pynetv-0.4.1/uv.lock +3449 -0
- pynetv-0.4.1/xtream.py +161 -0
- pynetv-0.4.1/xtream_test.py +410 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Git
|
|
2
|
+
.git/
|
|
3
|
+
.gitignore
|
|
4
|
+
|
|
5
|
+
# Python
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
.venv/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
uv.lock
|
|
12
|
+
|
|
13
|
+
# App data (user-specific)
|
|
14
|
+
cache/
|
|
15
|
+
.cache/
|
|
16
|
+
settings.json
|
|
17
|
+
*.pem
|
|
18
|
+
|
|
19
|
+
# Tools (not needed in container, except specific scripts)
|
|
20
|
+
tools/
|
|
21
|
+
!tools/install-ffmpeg.sh
|
|
22
|
+
!tools/patches/
|
|
23
|
+
!tools/install-ai_upscale.sh
|
|
24
|
+
!tools/export-tensorrt.py
|
|
25
|
+
|
|
26
|
+
# Tests
|
|
27
|
+
*_test.py
|
|
28
|
+
conftest.py
|
|
29
|
+
|
|
30
|
+
# Docs
|
|
31
|
+
*.md
|
|
32
|
+
!README.md
|
|
33
|
+
screenshots/
|
|
34
|
+
LICENSE
|
|
35
|
+
|
|
36
|
+
# Docker
|
|
37
|
+
Dockerfile
|
|
38
|
+
docker-compose.yml
|
|
39
|
+
.dockerignore
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
name: AI Upscale Image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# Run manually when an FFmpeg base-image update should be published immediately.
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
paths:
|
|
9
|
+
- "Dockerfile.ai_upscale"
|
|
10
|
+
- "entrypoint-ai_upscale.sh"
|
|
11
|
+
- "*.py"
|
|
12
|
+
- "pyproject.toml"
|
|
13
|
+
- "templates/**"
|
|
14
|
+
- "static/**"
|
|
15
|
+
- "tools/**"
|
|
16
|
+
- ".github/workflows/ai-upscale.yml"
|
|
17
|
+
|
|
18
|
+
env:
|
|
19
|
+
REGISTRY: ghcr.io
|
|
20
|
+
IMAGE_NAME: ${{ github.repository }}-ai-upscale
|
|
21
|
+
DEFAULT_BASE: ubuntu:26.04
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
runs-on: ubuntu-26.04
|
|
26
|
+
permissions:
|
|
27
|
+
contents: read
|
|
28
|
+
packages: write
|
|
29
|
+
strategy:
|
|
30
|
+
# One failing combination must not cancel the others.
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
# Mirrors ffmpeg-base.yml: each image builds on the ffmpeg image of the same CUDA and OS.
|
|
34
|
+
nvidia: ['cuda:12.4', 'cuda:12.6', 'cuda:12.8', 'cuda:13.0']
|
|
35
|
+
base_image: ['ubuntu:22.04', 'ubuntu:24.04', 'ubuntu:26.04']
|
|
36
|
+
|
|
37
|
+
steps:
|
|
38
|
+
- name: Free disk space
|
|
39
|
+
run: |
|
|
40
|
+
# Remove large unnecessary packages to free up space for torch/tensorrt
|
|
41
|
+
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache
|
|
42
|
+
sudo apt-get clean
|
|
43
|
+
df -h
|
|
44
|
+
|
|
45
|
+
- uses: actions/checkout@v7
|
|
46
|
+
|
|
47
|
+
- name: Set up Docker Buildx
|
|
48
|
+
uses: docker/setup-buildx-action@v4
|
|
49
|
+
|
|
50
|
+
- name: Log in to Container Registry
|
|
51
|
+
uses: docker/login-action@v4
|
|
52
|
+
with:
|
|
53
|
+
registry: ${{ env.REGISTRY }}
|
|
54
|
+
username: ${{ github.actor }}
|
|
55
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
56
|
+
|
|
57
|
+
- name: Parse CUDA version
|
|
58
|
+
id: cuda
|
|
59
|
+
run: |
|
|
60
|
+
# Extract "12.4" from "cuda:12.4"
|
|
61
|
+
CUDA_VER="${{ matrix.nvidia }}"
|
|
62
|
+
CUDA_VER="${CUDA_VER#cuda:}"
|
|
63
|
+
echo "version=$CUDA_VER" >> $GITHUB_OUTPUT
|
|
64
|
+
# "ubuntu:26.04" -> "ubuntu26.04"
|
|
65
|
+
OS="${{ matrix.base_image }}"
|
|
66
|
+
echo "os=${OS/:/}" >> $GITHUB_OUTPUT
|
|
67
|
+
|
|
68
|
+
- name: Extract metadata
|
|
69
|
+
id: meta
|
|
70
|
+
uses: docker/metadata-action@v6
|
|
71
|
+
with:
|
|
72
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
73
|
+
tags: |
|
|
74
|
+
type=raw,value=cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }}
|
|
75
|
+
type=raw,value=cuda${{ steps.cuda.outputs.version }},enable=${{ matrix.base_image == env.DEFAULT_BASE }}
|
|
76
|
+
type=raw,value=latest,enable=${{ matrix.base_image == env.DEFAULT_BASE && steps.cuda.outputs.version == '13.0' }}
|
|
77
|
+
|
|
78
|
+
- name: Build and push
|
|
79
|
+
uses: docker/build-push-action@v7
|
|
80
|
+
with:
|
|
81
|
+
context: .
|
|
82
|
+
file: Dockerfile.ai_upscale
|
|
83
|
+
push: true
|
|
84
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
85
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
86
|
+
build-args: |
|
|
87
|
+
FFMPEG_IMAGE=ghcr.io/${{ github.repository }}-ffmpeg:cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }}
|
|
88
|
+
NVIDIA=${{ matrix.nvidia }}
|
|
89
|
+
BASE_IMAGE=${{ matrix.base_image }}
|
|
90
|
+
no-cache: true
|
|
91
|
+
|
|
92
|
+
- name: Verify image
|
|
93
|
+
run: |
|
|
94
|
+
# Free space: BuildKit uses separate storage, prune it before pulling
|
|
95
|
+
docker buildx prune -af || true
|
|
96
|
+
docker system prune -af || true
|
|
97
|
+
df -h
|
|
98
|
+
IMG=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }}
|
|
99
|
+
docker pull $IMG
|
|
100
|
+
# Verify everything that should be enabled is actually linked
|
|
101
|
+
# Note: --entrypoint bypasses the default entrypoint which tries to build TensorRT engines (requires GPU)
|
|
102
|
+
docker run --rm --entrypoint sh "$IMG" -c "
|
|
103
|
+
echo '=== Verifying AI Upscale build ==='
|
|
104
|
+
LDD_OUTPUT=\$(ldd /usr/local/bin/ffmpeg)
|
|
105
|
+
|
|
106
|
+
# Verify ffmpeg binaries exist
|
|
107
|
+
for bin in ffmpeg ffprobe ffplay; do
|
|
108
|
+
test -x /usr/local/bin/\$bin || { echo \"ERROR: \$bin not found\"; exit 1; }
|
|
109
|
+
echo \"OK: \$bin exists\"
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
# Verify non-NVIDIA dependencies are satisfied
|
|
113
|
+
# Note: All NVIDIA libraries (libnvinfer, libcuda, libcudart) are loaded via dlopen,
|
|
114
|
+
# so ffmpeg works even without NVIDIA GPU/drivers installed
|
|
115
|
+
MISSING=\$(echo \"\$LDD_OUTPUT\" | grep 'not found' | grep -v -E 'libnvinfer|libnvonnxparser|libcudart|libcuda' || true)
|
|
116
|
+
if [ -n \"\$MISSING\" ]; then
|
|
117
|
+
echo 'ERROR: Missing non-NVIDIA libraries:'
|
|
118
|
+
echo \"\$MISSING\"
|
|
119
|
+
exit 1
|
|
120
|
+
fi
|
|
121
|
+
echo 'OK: All non-NVIDIA dependencies satisfied'
|
|
122
|
+
|
|
123
|
+
# Verify ffmpeg has NO hard CUDA dependency (all CUDA/TensorRT loaded via dlopen)
|
|
124
|
+
if echo \"\$LDD_OUTPUT\" | grep -q 'libcudart'; then
|
|
125
|
+
echo 'ERROR: libcudart linked at compile time (should use dlopen)'
|
|
126
|
+
exit 1
|
|
127
|
+
fi
|
|
128
|
+
echo 'OK: No libcudart dependency (CUDA Driver API via dlopen)'
|
|
129
|
+
echo 'OK: libnvinfer loaded via dlopen (not in ldd output)'
|
|
130
|
+
|
|
131
|
+
# Verify Python AI packages installed (use pip show, not import - import needs CUDA runtime)
|
|
132
|
+
echo '=== Verifying Python packages ==='
|
|
133
|
+
pip3 show torch >/dev/null 2>&1 || { echo 'ERROR: torch not installed'; exit 1; }
|
|
134
|
+
echo 'OK: torch installed'
|
|
135
|
+
pip3 show onnx >/dev/null 2>&1 || { echo 'ERROR: onnx not installed'; exit 1; }
|
|
136
|
+
echo 'OK: onnx installed'
|
|
137
|
+
pip3 show tensorrt >/dev/null 2>&1 || { echo 'ERROR: tensorrt not installed'; exit 1; }
|
|
138
|
+
echo 'OK: tensorrt installed'
|
|
139
|
+
|
|
140
|
+
# Verify AI upscale scripts exist
|
|
141
|
+
echo '=== Verifying AI upscale scripts ==='
|
|
142
|
+
test -x /app/tools/install-ai_upscale.sh || { echo 'ERROR: install-ai_upscale.sh not found'; exit 1; }
|
|
143
|
+
echo 'OK: install-ai_upscale.sh exists'
|
|
144
|
+
test -f /app/tools/export-tensorrt.py || { echo 'ERROR: export-tensorrt.py not found'; exit 1; }
|
|
145
|
+
echo 'OK: export-tensorrt.py exists'
|
|
146
|
+
python3 /app/tools/export-tensorrt.py --list | grep -q '2x-nomosuni-compact' || { echo 'ERROR: Nomos model unavailable'; exit 1; }
|
|
147
|
+
if python3 /app/tools/export-tensorrt.py --help | grep -q -- '--model'; then
|
|
148
|
+
echo 'ERROR: Legacy model selection is still available'
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
echo 'OK: Nomos is the sole supported model'
|
|
152
|
+
|
|
153
|
+
echo ''
|
|
154
|
+
echo '=== All verifications passed ==='
|
|
155
|
+
"
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# Run manually when an FFmpeg base-image update should be published immediately.
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
paths:
|
|
9
|
+
# Only trigger on files used by main Dockerfile
|
|
10
|
+
- "Dockerfile"
|
|
11
|
+
- "*.py"
|
|
12
|
+
- "pyproject.toml"
|
|
13
|
+
- "uv.lock"
|
|
14
|
+
- "templates/**"
|
|
15
|
+
- "static/**"
|
|
16
|
+
- "entrypoint.sh"
|
|
17
|
+
- ".github/workflows/ci.yml"
|
|
18
|
+
pull_request:
|
|
19
|
+
branches: [main]
|
|
20
|
+
|
|
21
|
+
env:
|
|
22
|
+
REGISTRY: ghcr.io
|
|
23
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
24
|
+
FFMPEG_IMAGE: ghcr.io/${{ github.repository }}-ffmpeg:latest
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
test:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v7
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v7
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.14.10"
|
|
36
|
+
|
|
37
|
+
- name: Install uv
|
|
38
|
+
uses: astral-sh/setup-uv@v7
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.14.10"
|
|
41
|
+
|
|
42
|
+
- name: Install FFmpeg
|
|
43
|
+
run: |
|
|
44
|
+
sudo apt-get update
|
|
45
|
+
sudo apt-get install --yes --no-install-recommends ffmpeg
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: uv sync --frozen --group pre-commit
|
|
49
|
+
|
|
50
|
+
- name: Lint with ruff
|
|
51
|
+
run: uv --quiet run --frozen --group pre-commit ruff check .
|
|
52
|
+
|
|
53
|
+
- name: Type check with basedpyright
|
|
54
|
+
run: uv --quiet run --frozen --group pre-commit basedpyright
|
|
55
|
+
|
|
56
|
+
- name: Run tests
|
|
57
|
+
run: uv --quiet run --frozen --group pre-commit pytest
|
|
58
|
+
|
|
59
|
+
build:
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
needs: test
|
|
62
|
+
permissions:
|
|
63
|
+
contents: read
|
|
64
|
+
packages: write
|
|
65
|
+
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v7
|
|
68
|
+
|
|
69
|
+
- name: Set up Docker Buildx
|
|
70
|
+
uses: docker/setup-buildx-action@v4
|
|
71
|
+
|
|
72
|
+
- name: Log in to Container Registry
|
|
73
|
+
if: github.event_name != 'pull_request'
|
|
74
|
+
uses: docker/login-action@v4
|
|
75
|
+
with:
|
|
76
|
+
registry: ${{ env.REGISTRY }}
|
|
77
|
+
username: ${{ github.actor }}
|
|
78
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
79
|
+
|
|
80
|
+
- name: Verify base image exists
|
|
81
|
+
run: |
|
|
82
|
+
if ! docker manifest inspect ${{ env.FFMPEG_IMAGE }} > /dev/null 2>&1; then
|
|
83
|
+
echo "ERROR: Base image ${{ env.FFMPEG_IMAGE }} not found"
|
|
84
|
+
echo "Run the 'FFmpeg Base Image' workflow first"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
echo "Base image verified: ${{ env.FFMPEG_IMAGE }}"
|
|
88
|
+
|
|
89
|
+
- name: Extract metadata
|
|
90
|
+
id: meta
|
|
91
|
+
uses: docker/metadata-action@v6
|
|
92
|
+
with:
|
|
93
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
94
|
+
tags: |
|
|
95
|
+
type=raw,value=latest,enable={{is_default_branch}}
|
|
96
|
+
type=ref,event=branch
|
|
97
|
+
type=sha,prefix=
|
|
98
|
+
|
|
99
|
+
- name: Build and push
|
|
100
|
+
uses: docker/build-push-action@v7
|
|
101
|
+
with:
|
|
102
|
+
context: .
|
|
103
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
104
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
105
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
106
|
+
build-args: |
|
|
107
|
+
FFMPEG_IMAGE=${{ env.FFMPEG_IMAGE }}
|
|
108
|
+
cache-from: type=gha
|
|
109
|
+
cache-to: type=gha,mode=max
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
name: FFmpeg Base Image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
# Build daily at 3 AM UTC
|
|
6
|
+
# Application images are rebuilt separately on code changes or manual dispatch.
|
|
7
|
+
- cron: "0 3 * * *"
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
paths:
|
|
11
|
+
- "Dockerfile.ffmpeg"
|
|
12
|
+
- "tools/install-ffmpeg.sh"
|
|
13
|
+
- ".github/workflows/ffmpeg-base.yml"
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
inputs:
|
|
16
|
+
ffmpeg_version:
|
|
17
|
+
description: "FFmpeg version (e.g., 7.1 or snapshot)"
|
|
18
|
+
required: false
|
|
19
|
+
default: "snapshot"
|
|
20
|
+
|
|
21
|
+
env:
|
|
22
|
+
REGISTRY: ghcr.io
|
|
23
|
+
IMAGE_NAME: ${{ github.repository }}-ffmpeg
|
|
24
|
+
DEFAULT_BASE: ubuntu:26.04
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
build:
|
|
28
|
+
runs-on: ubuntu-26.04
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
packages: write
|
|
32
|
+
strategy:
|
|
33
|
+
# One failing combination must not cancel the others.
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
# Every CUDA on every supported LTS; older CUDA serves older drivers/GPUs.
|
|
37
|
+
# The newest LTS owns the unsuffixed cudaX.Y and latest tags (see DEFAULT_BASE).
|
|
38
|
+
nvidia: ['cuda:12.4', 'cuda:12.6', 'cuda:12.8', 'cuda:13.0']
|
|
39
|
+
base_image: ['ubuntu:22.04', 'ubuntu:24.04', 'ubuntu:26.04']
|
|
40
|
+
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v7
|
|
43
|
+
|
|
44
|
+
- name: Set up Docker Buildx
|
|
45
|
+
uses: docker/setup-buildx-action@v4
|
|
46
|
+
|
|
47
|
+
- name: Log in to Container Registry
|
|
48
|
+
uses: docker/login-action@v4
|
|
49
|
+
with:
|
|
50
|
+
registry: ${{ env.REGISTRY }}
|
|
51
|
+
username: ${{ github.actor }}
|
|
52
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
53
|
+
|
|
54
|
+
- name: Parse CUDA version
|
|
55
|
+
id: cuda
|
|
56
|
+
run: |
|
|
57
|
+
# Extract "12.4" from "cuda:12.4"
|
|
58
|
+
CUDA_VER="${{ matrix.nvidia }}"
|
|
59
|
+
CUDA_VER="${CUDA_VER#cuda:}"
|
|
60
|
+
echo "version=$CUDA_VER" >> $GITHUB_OUTPUT
|
|
61
|
+
# "ubuntu:26.04" -> "ubuntu26.04"
|
|
62
|
+
OS="${{ matrix.base_image }}"
|
|
63
|
+
echo "os=${OS/:/}" >> $GITHUB_OUTPUT
|
|
64
|
+
|
|
65
|
+
- name: Generate build date
|
|
66
|
+
id: date
|
|
67
|
+
run: |
|
|
68
|
+
echo "date=$(date -u +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
|
69
|
+
echo "datetime=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
|
70
|
+
|
|
71
|
+
- name: Determine FFmpeg version
|
|
72
|
+
id: version
|
|
73
|
+
run: |
|
|
74
|
+
VERSION="${{ github.event.inputs.ffmpeg_version || 'snapshot' }}"
|
|
75
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
76
|
+
if [ "$VERSION" = "snapshot" ]; then
|
|
77
|
+
echo "tag=${{ steps.date.outputs.date }}" >> $GITHUB_OUTPUT
|
|
78
|
+
else
|
|
79
|
+
echo "tag=$VERSION" >> $GITHUB_OUTPUT
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
- name: Extract metadata
|
|
83
|
+
id: meta
|
|
84
|
+
uses: docker/metadata-action@v6
|
|
85
|
+
with:
|
|
86
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
87
|
+
tags: |
|
|
88
|
+
type=raw,value=cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }}
|
|
89
|
+
type=raw,value=cuda${{ steps.cuda.outputs.version }},enable=${{ matrix.base_image == env.DEFAULT_BASE }}
|
|
90
|
+
type=raw,value=latest,enable=${{ matrix.base_image == env.DEFAULT_BASE && steps.cuda.outputs.version == '13.0' }}
|
|
91
|
+
type=raw,value=${{ steps.date.outputs.date }}-cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }},enable=${{ steps.version.outputs.version == 'snapshot' }}
|
|
92
|
+
|
|
93
|
+
- name: Build and push
|
|
94
|
+
uses: docker/build-push-action@v7
|
|
95
|
+
with:
|
|
96
|
+
context: .
|
|
97
|
+
file: Dockerfile.ffmpeg
|
|
98
|
+
push: true
|
|
99
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
100
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
101
|
+
build-args: |
|
|
102
|
+
BUILD_DATE=${{ steps.date.outputs.datetime }}
|
|
103
|
+
FFMPEG_VERSION=${{ steps.version.outputs.version }}
|
|
104
|
+
NVIDIA=${{ matrix.nvidia }}
|
|
105
|
+
FFMPEG_BASE_IMAGE=${{ matrix.base_image }}
|
|
106
|
+
no-cache: true
|
|
107
|
+
|
|
108
|
+
- name: Verify image
|
|
109
|
+
run: |
|
|
110
|
+
IMG=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:cuda${{ steps.cuda.outputs.version }}-${{ steps.cuda.outputs.os }}
|
|
111
|
+
docker pull $IMG
|
|
112
|
+
# Verify ffmpeg build - check binaries and shared library dependencies
|
|
113
|
+
# Note: Static libraries (libx264, libx265, etc.) are compiled into the binary
|
|
114
|
+
# and won't appear in ldd output. If they were missing, the build would have failed.
|
|
115
|
+
docker run --rm $IMG sh -c "
|
|
116
|
+
echo '=== Verifying ffmpeg build ==='
|
|
117
|
+
|
|
118
|
+
# Verify all binaries exist
|
|
119
|
+
for bin in ffmpeg ffprobe ffplay; do
|
|
120
|
+
test -x /usr/local/bin/\$bin || { echo \"ERROR: \$bin not found\"; exit 1; }
|
|
121
|
+
echo \"OK: \$bin exists\"
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
# Get ldd output for shared library checks
|
|
125
|
+
LDD_OUTPUT=\$(ldd /usr/local/bin/ffmpeg)
|
|
126
|
+
|
|
127
|
+
# Verify non-NVIDIA shared dependencies are satisfied
|
|
128
|
+
MISSING=\$(echo \"\$LDD_OUTPUT\" | grep 'not found' | grep -v -E 'libnvinfer|libnvonnxparser|libcudart|libcuda' || true)
|
|
129
|
+
if [ -n \"\$MISSING\" ]; then
|
|
130
|
+
echo 'ERROR: Missing non-NVIDIA libraries:'
|
|
131
|
+
echo \"\$MISSING\"
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
echo 'OK: All non-NVIDIA shared dependencies satisfied'
|
|
135
|
+
|
|
136
|
+
# Verify NVIDIA libraries (all loaded via dlopen - no hard dependencies)
|
|
137
|
+
# - CUDA Driver API (libcuda): loaded via dlopen when TensorRT backend used
|
|
138
|
+
# - TensorRT (libnvinfer): loaded via dlopen when TensorRT backend used
|
|
139
|
+
echo '=== Verifying NVIDIA libraries ==='
|
|
140
|
+
# Verify ffmpeg has NO hard CUDA dependency
|
|
141
|
+
if echo \"\$LDD_OUTPUT\" | grep -q 'libcudart'; then
|
|
142
|
+
echo 'ERROR: libcudart linked at compile time (should use dlopen)'
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
echo 'OK: No libcudart dependency (uses CUDA Driver API via dlopen)'
|
|
146
|
+
ls /usr/lib/x86_64-linux-gnu/libnvinfer.so* >/dev/null 2>&1 || { echo 'ERROR: TensorRT (libnvinfer) not installed'; exit 1; }
|
|
147
|
+
echo 'OK: libnvinfer installed (loaded via dlopen)'
|
|
148
|
+
|
|
149
|
+
# Verify libva is linked (we build it as shared for runtime)
|
|
150
|
+
echo \"\$LDD_OUTPUT\" | grep -q libva || { echo 'ERROR: libva not linked'; exit 1; }
|
|
151
|
+
echo 'OK: libva linked'
|
|
152
|
+
|
|
153
|
+
echo ''
|
|
154
|
+
echo '=== All verifications passed ==='
|
|
155
|
+
"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
|
+
- uses: astral-sh/setup-uv@v7
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- name: Build distributions
|
|
21
|
+
run: uv build
|
|
22
|
+
- name: Check package metadata
|
|
23
|
+
run: uvx --from twine twine check --strict dist/*
|
|
24
|
+
- name: Smoke test installed commands
|
|
25
|
+
env:
|
|
26
|
+
NETV_DATA_DIR: ${{ runner.temp }}/netv-data
|
|
27
|
+
run: |
|
|
28
|
+
uvx --isolated --from "$PWD"/dist/*.whl netv --help
|
|
29
|
+
uvx --isolated --from "$PWD"/dist/*.whl netv-gateway --help
|
|
30
|
+
- uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: distributions
|
|
33
|
+
path: dist/*
|
|
34
|
+
if-no-files-found: error
|
|
35
|
+
|
|
36
|
+
publish:
|
|
37
|
+
needs: build
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
environment:
|
|
40
|
+
name: pypi
|
|
41
|
+
url: https://pypi.org/p/pynetv
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/download-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: distributions
|
|
48
|
+
path: dist/
|
|
49
|
+
- name: Publish to PyPI
|
|
50
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
REGISTRY: ghcr.io
|
|
10
|
+
IMAGE_NAME: ${{ github.repository }}
|
|
11
|
+
FFMPEG_IMAGE: ghcr.io/${{ github.repository }}-ffmpeg:latest
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
release:
|
|
15
|
+
runs-on: ubuntu-26.04
|
|
16
|
+
permissions:
|
|
17
|
+
contents: write
|
|
18
|
+
packages: write
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
with:
|
|
23
|
+
fetch-depth: 0 # full history and tags for the changelog
|
|
24
|
+
|
|
25
|
+
- name: Set up Docker Buildx
|
|
26
|
+
uses: docker/setup-buildx-action@v4
|
|
27
|
+
|
|
28
|
+
- name: Log in to Container Registry
|
|
29
|
+
uses: docker/login-action@v4
|
|
30
|
+
with:
|
|
31
|
+
registry: ${{ env.REGISTRY }}
|
|
32
|
+
username: ${{ github.actor }}
|
|
33
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
34
|
+
|
|
35
|
+
- name: Extract metadata
|
|
36
|
+
id: meta
|
|
37
|
+
uses: docker/metadata-action@v6
|
|
38
|
+
with:
|
|
39
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
40
|
+
tags: |
|
|
41
|
+
type=semver,pattern={{version}}
|
|
42
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
43
|
+
type=semver,pattern={{major}}
|
|
44
|
+
type=raw,value=latest
|
|
45
|
+
|
|
46
|
+
- name: Build and push
|
|
47
|
+
uses: docker/build-push-action@v7
|
|
48
|
+
with:
|
|
49
|
+
context: .
|
|
50
|
+
push: true
|
|
51
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
52
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
53
|
+
build-args: |
|
|
54
|
+
FFMPEG_IMAGE=${{ env.FFMPEG_IMAGE }}
|
|
55
|
+
cache-from: type=gha
|
|
56
|
+
cache-to: type=gha,mode=max
|
|
57
|
+
|
|
58
|
+
- name: Generate release notes
|
|
59
|
+
id: notes
|
|
60
|
+
run: |
|
|
61
|
+
echo "## Docker Image" >> notes.md
|
|
62
|
+
echo "" >> notes.md
|
|
63
|
+
echo "Pull the image:" >> notes.md
|
|
64
|
+
echo "\`\`\`bash" >> notes.md
|
|
65
|
+
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}" >> notes.md
|
|
66
|
+
echo "\`\`\`" >> notes.md
|
|
67
|
+
echo "" >> notes.md
|
|
68
|
+
echo "## What's Changed" >> notes.md
|
|
69
|
+
git log $(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-list --max-parents=0 HEAD)..HEAD --pretty=format:"- %s" | grep -v '^- Release v' >> notes.md || true
|
|
70
|
+
|
|
71
|
+
- name: Create GitHub Release
|
|
72
|
+
uses: softprops/action-gh-release@v3
|
|
73
|
+
with:
|
|
74
|
+
body_path: notes.md
|
|
75
|
+
generate_release_notes: true
|
pynetv-0.4.1/.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
.ruff_cache/
|
|
6
|
+
.pytest_cache/
|
|
7
|
+
|
|
8
|
+
# Debugging
|
|
9
|
+
**/*.out
|
|
10
|
+
**/*.log
|
|
11
|
+
|
|
12
|
+
# App data
|
|
13
|
+
.cache/
|
|
14
|
+
cache/
|
|
15
|
+
|
|
16
|
+
# Certificates
|
|
17
|
+
*.pem
|
|
18
|
+
/apple/.env
|
|
19
|
+
|
|
20
|
+
# Tools - user data and generated files
|
|
21
|
+
**/*.gz
|
|
22
|
+
**/*.json
|
|
23
|
+
**/*.m3u
|
|
24
|
+
**/*.xml
|
|
25
|
+
tools/.zap2xml/
|
|
26
|
+
|
|
27
|
+
# macOS
|
|
28
|
+
.DS_Store
|
|
29
|
+
|
|
30
|
+
# Local App Store source material
|
|
31
|
+
/apple/AppStoreScreenshots/**/*.pdf
|
|
32
|
+
|
|
33
|
+
.testmondata
|
|
34
|
+
.codegraph
|
|
35
|
+
.coverage
|
|
36
|
+
.testmondata*
|
|
37
|
+
.codegraph/
|
|
38
|
+
.coverage.*
|
|
39
|
+
.coverage-*
|