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.
- pakt-0.1.0/.claude/CLAUDE.md +83 -0
- pakt-0.1.0/.gitignore +46 -0
- pakt-0.1.0/PKG-INFO +121 -0
- pakt-0.1.0/README.md +84 -0
- pakt-0.1.0/pyproject.toml +69 -0
- pakt-0.1.0/src/pakt/__init__.py +3 -0
- pakt-0.1.0/src/pakt/__main__.py +6 -0
- pakt-0.1.0/src/pakt/assets/icon.png +0 -0
- pakt-0.1.0/src/pakt/assets/icon.svg +10 -0
- pakt-0.1.0/src/pakt/assets/logo.png +0 -0
- pakt-0.1.0/src/pakt/cli.py +422 -0
- pakt-0.1.0/src/pakt/config.py +200 -0
- pakt-0.1.0/src/pakt/models.py +109 -0
- pakt-0.1.0/src/pakt/plex.py +519 -0
- pakt-0.1.0/src/pakt/scheduler.py +153 -0
- pakt-0.1.0/src/pakt/sync.py +1102 -0
- pakt-0.1.0/src/pakt/trakt.py +575 -0
- pakt-0.1.0/src/pakt/tray.py +132 -0
- pakt-0.1.0/src/pakt/web/__init__.py +5 -0
- pakt-0.1.0/src/pakt/web/app.py +524 -0
- pakt-0.1.0/src/pakt/web/templates/index.html +1705 -0
- pakt-0.1.0/tests/__init__.py +1 -0
|
@@ -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"]
|
|
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
|