pakt 0.1.0__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.
@@ -0,0 +1,83 @@
1
+ # Pakt - Plex-Trakt Sync Tool
2
+
3
+ Python CLI/web app that syncs watched status and ratings between Plex and Trakt using batch API operations.
4
+
5
+ ## Architecture
6
+
7
+ - **sync.py** - SyncEngine with 4-phase sync (fetch, index, compare, apply)
8
+ - **cli.py** - Click-based CLI
9
+ - **web/app.py** - FastAPI endpoints
10
+ - **web/templates/index.html** - Single-page web UI
11
+ - **trakt.py** - Async Trakt API client with VIP limit handling
12
+ - **plex.py** - PlexAPI wrapper with media metadata extraction
13
+ - **config.py** - Pydantic settings with env file support
14
+ - **scheduler.py** - APScheduler-based automatic sync
15
+ - **tray.py** - pystray system tray integration (Windows)
16
+
17
+ ## Implemented Features
18
+
19
+ - CLI commands: sync, login, logout, setup, status, libraries, serve, clear-cache
20
+ - Web UI with tabbed interface (Sync, Stats, Settings views)
21
+ - Batch API operations for Trakt (single calls for all watched/ratings)
22
+ - Batch episode fetch from Plex (searchEpisodes() instead of per-show calls)
23
+ - Bidirectional sync: movies watched, movie ratings, episode watched, episode ratings
24
+ - Library selection (CLI and web UI)
25
+ - File logging to ~/.config/pakt/sync.log
26
+ - OAuth device flow for Trakt auth
27
+ - Progress reporting to web UI console
28
+ - **Collection sync** (Plex → Trakt) with full media metadata:
29
+ - Resolution (4K, 1080p, 720p, etc.)
30
+ - HDR type (Dolby Vision, HDR10, HDR10+, HLG)
31
+ - Audio codec (Atmos, TrueHD, DTS-X, DTS-HD MA, etc.)
32
+ - Best quality version scoring when multiple versions exist
33
+ - **Watchlist sync** (bidirectional):
34
+ - Plex → Trakt watchlist
35
+ - Trakt → Plex watchlist (uses Plex Discover for items not in library)
36
+ - **Scheduled sync** via APScheduler:
37
+ - Configurable interval (hours)
38
+ - Enable/disable via web UI
39
+ - Automatic startup with server
40
+ - **System tray icon** (Windows, optional):
41
+ - Double-click to open web UI
42
+ - Right-click menu: Open Web UI, Sync Now, Exit
43
+ - `pakt serve --tray` or `--no-tray` flags
44
+ - **Trakt VIP/Free account handling**:
45
+ - Detects VIP status via `/users/settings` endpoint
46
+ - Free users limited to 100 items in collection/watchlist
47
+ - Warns and skips sync if at limit (prevents HTTP 420 errors)
48
+ - Catches `TraktAccountLimitError` gracefully with upgrade URL
49
+ - API endpoint `/api/trakt/account` returns VIP status and limits
50
+
51
+ ## Trakt Account Limits (Jan 2025)
52
+
53
+ Free users have 100 item limit on:
54
+ - Collection (movies + shows combined)
55
+ - Watchlist
56
+ - Personal lists (2 lists max, 100 items each)
57
+
58
+ VIP users have unlimited. Sync will:
59
+ 1. Check limits before attempting collection/watchlist sync
60
+ 2. Skip sync with warning if already at limit
61
+ 3. Catch HTTP 420 errors and log upgrade URL
62
+
63
+ ## Current State
64
+
65
+ All features implemented including VIP handling. Ready for testing.
66
+
67
+ ## Next Steps
68
+
69
+ 1. Test collection sync with real data (VIP and non-VIP)
70
+ 2. Test watchlist sync bidirectionally
71
+ 3. Test scheduler functionality
72
+ 4. Show ratings sync (currently only episode ratings, not show-level)
73
+ 5. Add VIP status indicator to web UI
74
+
75
+ ## Testing
76
+
77
+ ```bash
78
+ pip install -e . # Basic install
79
+ pip install -e ".[tray]" # With system tray support
80
+ pakt serve # Web UI at http://localhost:8080
81
+ pakt serve --tray # With system tray icon
82
+ pakt sync --dry-run
83
+ ```
pakt-0.1.0/.gitignore ADDED
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ htmlcov/
38
+
39
+ # Cache/config (user-specific)
40
+ .env
41
+ *.db
42
+ *.sqlite
43
+
44
+ # OS
45
+ .DS_Store
46
+ Thumbs.db
pakt-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: pakt
3
+ Version: 0.1.0
4
+ Summary: Fast, efficient Plex-Trakt sync using batch API operations
5
+ Project-URL: Repository, https://github.com/MikeSiLVO/pakt
6
+ Author: MikeSiLVO
7
+ License: MIT
8
+ Keywords: media,plex,scrobble,sync,trakt
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Multimedia :: Video
17
+ Requires-Python: >=3.11
18
+ Requires-Dist: aiosqlite>=0.19.0
19
+ Requires-Dist: apscheduler>=3.10.0
20
+ Requires-Dist: click>=8.1.0
21
+ Requires-Dist: fastapi>=0.110.0
22
+ Requires-Dist: httpx>=0.27.0
23
+ Requires-Dist: jinja2>=3.1.0
24
+ Requires-Dist: plexapi>=4.15.0
25
+ Requires-Dist: pydantic-settings>=2.0.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: uvicorn>=0.27.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.3.0; extra == 'dev'
33
+ Provides-Extra: tray
34
+ Requires-Dist: pillow>=10.0.0; extra == 'tray'
35
+ Requires-Dist: pystray>=0.19.0; extra == 'tray'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # <img src="src/pakt/assets/icon.png" width="32" alt=""> Pakt
39
+
40
+ Sync watched status, ratings, and collections between Plex and Trakt.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install pakt
46
+ ```
47
+
48
+ With system tray support (Windows):
49
+ ```bash
50
+ pip install pakt[tray]
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```bash
56
+ pakt setup # Interactive setup wizard
57
+ pakt sync # Run sync
58
+ ```
59
+
60
+ ## Commands
61
+
62
+ ```bash
63
+ pakt setup # Configure Plex and Trakt
64
+ pakt sync # Sync everything
65
+ pakt sync --dry-run # Preview without changes
66
+ pakt sync --verbose # Show detailed item list
67
+ pakt serve # Start web interface
68
+ pakt serve --tray # Web interface with system tray (Windows)
69
+ pakt status # Show configuration
70
+ pakt libraries # Manage library selection
71
+ pakt login # Authenticate with Trakt
72
+ pakt logout # Clear Trakt authentication
73
+ ```
74
+
75
+ ## Web Interface
76
+
77
+ Start the web UI:
78
+ ```bash
79
+ pakt serve
80
+ ```
81
+
82
+ Open http://localhost:8080 in your browser.
83
+
84
+ Features:
85
+ - Run syncs with progress display
86
+ - Configure sync options
87
+ - View Trakt account status
88
+ - Set up scheduled syncs
89
+ - Select which libraries to sync
90
+
91
+ ## Background Mode (Windows)
92
+
93
+ Run without a console window:
94
+ ```bash
95
+ pythonw -m pakt serve --tray
96
+ ```
97
+
98
+ ## What Gets Synced
99
+
100
+ | Data | Plex → Trakt | Trakt → Plex |
101
+ |------|:------------:|:------------:|
102
+ | Watched status | ✓ | ✓ |
103
+ | Ratings | ✓ | ✓ |
104
+ | Collection | ✓ | - |
105
+ | Watchlist | ✓ | ✓ |
106
+
107
+ Collection sync includes media info (resolution, HDR, audio codec).
108
+
109
+ ## Configuration
110
+
111
+ Config location:
112
+ - Windows: `%APPDATA%\pakt`
113
+ - Linux/macOS: `~/.config/pakt`
114
+
115
+ ## Trakt Account Limits
116
+
117
+ Free Trakt accounts have a 100-item limit on collections and watchlists. Pakt will warn you if you hit these limits. Upgrade to [Trakt VIP](https://trakt.tv/vip) for unlimited.
118
+
119
+ ## License
120
+
121
+ MIT
pakt-0.1.0/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # <img src="src/pakt/assets/icon.png" width="32" alt=""> Pakt
2
+
3
+ Sync watched status, ratings, and collections between Plex and Trakt.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install pakt
9
+ ```
10
+
11
+ With system tray support (Windows):
12
+ ```bash
13
+ pip install pakt[tray]
14
+ ```
15
+
16
+ ## Quick Start
17
+
18
+ ```bash
19
+ pakt setup # Interactive setup wizard
20
+ pakt sync # Run sync
21
+ ```
22
+
23
+ ## Commands
24
+
25
+ ```bash
26
+ pakt setup # Configure Plex and Trakt
27
+ pakt sync # Sync everything
28
+ pakt sync --dry-run # Preview without changes
29
+ pakt sync --verbose # Show detailed item list
30
+ pakt serve # Start web interface
31
+ pakt serve --tray # Web interface with system tray (Windows)
32
+ pakt status # Show configuration
33
+ pakt libraries # Manage library selection
34
+ pakt login # Authenticate with Trakt
35
+ pakt logout # Clear Trakt authentication
36
+ ```
37
+
38
+ ## Web Interface
39
+
40
+ Start the web UI:
41
+ ```bash
42
+ pakt serve
43
+ ```
44
+
45
+ Open http://localhost:8080 in your browser.
46
+
47
+ Features:
48
+ - Run syncs with progress display
49
+ - Configure sync options
50
+ - View Trakt account status
51
+ - Set up scheduled syncs
52
+ - Select which libraries to sync
53
+
54
+ ## Background Mode (Windows)
55
+
56
+ Run without a console window:
57
+ ```bash
58
+ pythonw -m pakt serve --tray
59
+ ```
60
+
61
+ ## What Gets Synced
62
+
63
+ | Data | Plex → Trakt | Trakt → Plex |
64
+ |------|:------------:|:------------:|
65
+ | Watched status | ✓ | ✓ |
66
+ | Ratings | ✓ | ✓ |
67
+ | Collection | ✓ | - |
68
+ | Watchlist | ✓ | ✓ |
69
+
70
+ Collection sync includes media info (resolution, HDR, audio codec).
71
+
72
+ ## Configuration
73
+
74
+ Config location:
75
+ - Windows: `%APPDATA%\pakt`
76
+ - Linux/macOS: `~/.config/pakt`
77
+
78
+ ## Trakt Account Limits
79
+
80
+ Free Trakt accounts have a 100-item limit on collections and watchlists. Pakt will warn you if you hit these limits. Upgrade to [Trakt VIP](https://trakt.tv/vip) for unlimited.
81
+
82
+ ## License
83
+
84
+ MIT
@@ -0,0 +1,69 @@
1
+ [project]
2
+ name = "pakt"
3
+ version = "0.1.0"
4
+ description = "Fast, efficient Plex-Trakt sync using batch API operations"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ license = {text = "MIT"}
8
+ authors = [
9
+ {name = "MikeSiLVO"}
10
+ ]
11
+ keywords = ["plex", "trakt", "sync", "media", "scrobble"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Environment :: Console",
15
+ "Intended Audience :: End Users/Desktop",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Topic :: Multimedia :: Video",
21
+ ]
22
+ dependencies = [
23
+ "httpx>=0.27.0",
24
+ "plexapi>=4.15.0",
25
+ "click>=8.1.0",
26
+ "rich>=13.0.0",
27
+ "pydantic>=2.0.0",
28
+ "pydantic-settings>=2.0.0",
29
+ "aiosqlite>=0.19.0",
30
+ "fastapi>=0.110.0",
31
+ "uvicorn>=0.27.0",
32
+ "jinja2>=3.1.0",
33
+ "apscheduler>=3.10.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ tray = [
38
+ "pystray>=0.19.0",
39
+ "Pillow>=10.0.0",
40
+ ]
41
+ dev = [
42
+ "pytest>=8.0.0",
43
+ "pytest-asyncio>=0.23.0",
44
+ "ruff>=0.3.0",
45
+ ]
46
+
47
+ [project.scripts]
48
+ pakt = "pakt.cli:main"
49
+
50
+ [project.urls]
51
+ Repository = "https://github.com/MikeSiLVO/pakt"
52
+
53
+ [build-system]
54
+ requires = ["hatchling"]
55
+ build-backend = "hatchling.build"
56
+
57
+ [tool.hatch.build.targets.wheel]
58
+ packages = ["src/pakt"]
59
+
60
+ [tool.ruff]
61
+ line-length = 120
62
+ target-version = "py311"
63
+
64
+ [tool.ruff.lint]
65
+ select = ["E", "F", "I", "W"]
66
+
67
+ [tool.pytest.ini_options]
68
+ asyncio_mode = "auto"
69
+ testpaths = ["tests"]
@@ -0,0 +1,3 @@
1
+ """Pakt - Fast, efficient Plex-Trakt sync."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Entry point for python -m pakt."""
2
+
3
+ from pakt.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
Binary file
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1"/>
5
+ <stop offset="100%" style="stop-color:#8b5cf6"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <circle cx="128" cy="128" r="120" fill="url(#bg)"/>
9
+ <text x="128" y="165" font-family="Inter, -apple-system, sans-serif" font-size="140" font-weight="600" fill="white" text-anchor="middle">P</text>
10
+ </svg>
Binary file