|
1 | 1 | # Watchly |
2 | | -[](https://ko-fi.com/I2I81OVJEH) |
3 | | -[](https://www.paypal.com/donate/?hosted_button_id=KRQMVS34FC5KC) |
4 | | - |
5 | 2 | **Watchly** is a Stremio catalog addon that provides personalized movie and series recommendations based on your Stremio library. It uses The Movie Database (TMDB) API to generate intelligent recommendations from the content you've watched and loved. |
6 | 3 |
|
7 | | -## What is Watchly? |
8 | | - |
9 | | -Watchly is a FastAPI-based Stremio addon that: |
10 | | - |
11 | | -- **Personalizes Recommendations**: Analyzes your Stremio library to understand your viewing preferences |
12 | | -- **Uses Your Loved Content**: Generates recommendations based on movies and series you've marked as "loved" in Stremio |
13 | | -- **Filters Watched Content**: Automatically excludes content you've already watched |
14 | | -- **Supports Movies & Series**: Provides recommendations for both movies and TV series |
15 | | -- **Genre-Based Discovery**: Offers genre-specific catalogs based on your viewing history |
16 | | -- **Similar Content**: Shows recommendations similar to specific titles when browsing |
17 | | - |
18 | | -## What Does It Do? |
19 | | - |
20 | | -1. **Connects to Your Stremio Library**: Securely authenticates with your Stremio account to access your library |
21 | | -2. **Analyzes Your Preferences**: Identifies your most loved movies and series as seed content |
22 | | -3. **Generates Recommendations**: Uses TMDB's recommendation engine to find similar content |
23 | | -4. **Filters & Scores**: Removes watched content and scores recommendations based on relevance |
24 | | -5. **Provides Stremio Catalogs**: Exposes catalogs that appear in your Stremio app for easy browsing |
25 | | - |
26 | 4 | ## Features |
27 | 5 |
|
28 | | -- ✅ **Personalized Recommendations** based on your Stremio library |
29 | | -- ✅ **Library-Based Filtering** - excludes content you've already watched |
30 | | -- ✅ **IMDB ID Support** - uses standard IMDB identifiers (Stremio standard) |
31 | | -- ✅ **Movies & Series Support** - recommendations for both content types |
32 | | -- ✅ **Genre-Based Catalogs** - dynamic genre catalogs based on your preferences |
33 | | -- ✅ **Similar Content Discovery** - find content similar to specific titles |
34 | | -- ✅ **Web Configuration Interface** - easy setup through a web UI |
35 | | -- ✅ **Caching** - optimized performance with intelligent caching |
36 | | -- ✅ **Secure Tokenized Access** - credentials/auth keys never travel in URLs |
37 | | -- ✅ **Docker Support** - easy deployment with Docker and Docker Compose |
38 | | -- ✅ **Background Catalog Refresh** - automatically keeps Stremio catalogs in sync |
39 | | -- ✅ **Credential Validation** - verifies access details and primes catalogs before issuing tokens |
| 6 | +- **Personalized Recommendations**: Analyzes your Stremio library to understand your viewing preferences. |
| 7 | +- **Smart Filtering**: Automatically excludes content you've already watched. |
| 8 | +- **Advanced Scoring**: Recommendations are intelligently weighted by recency and relevance. |
| 9 | +- **Genre-Based Discovery**: Offers genre-specific catalogs based on your viewing history. |
| 10 | +- **Similar Content**: Discover content similar to specific titles in your library. |
| 11 | +- **Web Configuration**: Easy-to-use web interface for secure setup. |
| 12 | +- **Secure Architecture**: Credentials are stored securely and never exposed in URLs. |
| 13 | +- **Background Sync**: Keeps your catalogs updated automatically in the background. |
| 14 | +- **Performance Optimized**: Intelligent caching for fast and reliable responses. |
40 | 15 |
|
41 | 16 | ## Installation |
42 | 17 |
|
43 | | -### Prerequisites |
44 | | - |
45 | | -- Python 3.10 or higher |
46 | | -- TMDB API key ([Get one here](https://www.themoviedb.org/settings/api)) |
47 | | -- Stremio account credentials (username/email and password) |
48 | | - |
49 | | -### Option 1: Docker Installation (Recommended) |
50 | | - |
51 | | -#### Using Docker Compose |
52 | | - |
53 | | -1. **Clone the repository:** |
54 | | - ```bash |
55 | | - git clone https://github.com/TimilsinaBimal/Watchly.git |
56 | | - cd Watchly |
57 | | - ``` |
58 | | - |
59 | | -2. **Create a `.env` file:** |
60 | | - ```bash |
61 | | - cp .env.example .env |
62 | | - # Edit .env and add your credentials |
63 | | - ``` |
64 | | - |
65 | | -3. **Edit `.env` file with your credentials:** |
66 | | - ``` |
67 | | - TMDB_API_KEY=your_tmdb_api_key_here |
68 | | - PORT=8000 |
69 | | - ... |
70 | | - ``` |
71 | | - |
72 | | -4. **Start the application:** |
73 | | - ```bash |
74 | | - docker-compose up -d |
75 | | - ``` |
76 | | - |
77 | | -5. **Access the application:** |
78 | | - - API: `http://localhost:8000` |
79 | | - - Configuration page: `http://localhost:8000/configure` |
80 | | - - API Documentation: `http://localhost:8000/docs` |
81 | | - |
82 | | - |
83 | | -### Option 2: Manual Installation |
84 | | - |
85 | | -1. **Clone the repository:** |
86 | | - ```bash |
87 | | - git clone https://github.com/TimilsinaBimal/Watchly.git |
88 | | - cd Watchly |
89 | | - ``` |
90 | | - |
91 | | -2. **Set environment variables:** |
92 | | - Create a `.env` file in the project root: |
93 | | - ``` |
94 | | - TMDB_API_KEY=your_tmdb_api_key_here |
95 | | - PORT=8000 |
96 | | - ... |
97 | | - ``` |
98 | | - |
99 | | -3. **Install UV and Run app (recommended):** |
100 | | -- [Installation Instructions](https://docs.astral.sh/uv/getting-started/installation/) |
101 | | - ```bash |
102 | | - uv run main.py |
103 | | - ``` |
104 | | - |
105 | | -4. **Access the application:** |
106 | | - - API: `http://localhost:8000` |
107 | | - - Configuration page: `http://localhost:8000/configure` |
108 | | - - API Documentation: `http://localhost:8000/docs` |
109 | | - |
110 | | - |
111 | | -*You Can also create virtual environment and install dependencies from requirements.txt and run the app* |
112 | | - |
113 | | -## Configuration |
114 | | - |
115 | | -### Environment Variables |
116 | | - |
117 | | -| Variable | Description | Required | Default | |
118 | | -|----------|-------------|----------|---------| |
119 | | -| `TMDB_API_KEY` | Your TMDB API key | Required for catalog features (optional for `/health`) | *(empty)* | |
120 | | -| `PORT` | Server port | No | 8000 | |
121 | | -| `ADDON_ID` | Stremio addon identifier | No | com.bimal.watchly | |
122 | | -| `ADDON_NAME` | Human-friendly addon name shown in the manifest/UI | No | Watchly | |
123 | | -| `REDIS_URL` | Redis connection string for credential tokens | No | `redis://localhost:6379/0` | |
124 | | -| `TOKEN_SALT` | Secret salt for hashing token IDs | Yes | - (must be set in production) | |
125 | | -| `TOKEN_TTL_SECONDS` | Token lifetime in seconds (`0` = no expiry) | No | 0 | |
126 | | -| `ANNOUNCEMENT_HTML` | Optional HTML snippet rendered in the configurator banner | No | *(empty)* | |
127 | | -| `TMDB_ADDON_URL` | Base URL for the TMDB addon metadata proxy | No | `https://94c8cb9f702d-tmdb-addon.baby-beamup.club/...` | |
128 | | -| `AUTO_UPDATE_CATALOGS` | Enable periodic background catalog refreshes | No | `true` | |
129 | | -| `CATALOG_REFRESH_INTERVAL_SECONDS` | Interval between automatic refreshes (seconds) | No | `21600` (6h) | |
130 | | - |
131 | | -### User Configuration |
132 | | - |
133 | | -Use the web interface at `/configure` to provision a secure access token: |
134 | | - |
135 | | -1. Provide either your **Stremio username/password** *or* an **existing `authKey`** (copy from `localStorage.authKey` in [https://web.stremio.com/](https://web.stremio.com/)). |
136 | | -2. Choose whether to base recommendations on loved items only or include everything you've watched. |
137 | | -3. Watchly verifies the credentials/auth key with Stremio, performs the first catalog refresh in the background, and only then stores the payload inside Redis. |
138 | | -4. Your manifest URL becomes `https://<host>/<token>/manifest.json`. Only this token ever appears in URLs. |
139 | | -5. Re-running the setup with the same credentials/configuration returns the exact same token. |
140 | | - |
141 | | -By default (`TOKEN_TTL_SECONDS=0`), tokens never expire. Set a positive TTL if you want automatic rotation. |
142 | | - |
143 | | -## How It Works |
144 | | - |
145 | | -1. **User Configuration**: User submits Stremio credentials or auth key via the web interface |
146 | | -2. **Secure Tokenization**: Credentials/auth keys are stored server-side in Redis; the user only receives a salted token |
147 | | -3. **Library Fetching**: When catalog is requested, service resolves the token, authenticates with Stremio, and fetches the library |
148 | | -4. **Seed Selection**: Uses most recent "loved" items (default: 10) as seed content |
149 | | -5. **Recommendation Generation**: For each seed, fetches recommendations from TMDB |
150 | | -6. **Filtering**: Removes items already in user's watched library |
151 | | -7. **Deduplication**: Combines recommendations from multiple seeds, scoring by relevance |
152 | | -8. **Metadata Fetching**: Fetches full metadata from TMDB addon |
153 | | -9. **Response**: Returns formatted catalog items compatible with Stremio |
154 | | - |
155 | | -## Project Structure |
156 | | - |
157 | | -``` |
158 | | -Watchly/ |
159 | | -├── app/ |
160 | | -│ ├── __init__.py # Package initialization |
161 | | -│ ├── core/ # Core application components |
162 | | -│ │ ├── __init__.py |
163 | | -│ │ ├── config.py # Application settings |
164 | | -│ │ └── app.py # FastAPI application initialization |
165 | | -│ ├── models/ # Pydantic models |
166 | | -│ │ ├── __init__.py |
167 | | -│ │ └── stremio.py # Stremio data models |
168 | | -│ ├── api/ # API routes |
169 | | -│ │ ├── main.py # API router |
170 | | -│ │ └── endpoints/ |
171 | | -│ │ ├── manifest.py # Stremio manifest endpoint |
172 | | -│ │ ├── catalogs.py # Catalog endpoints |
173 | | -│ │ ├── streams.py # Stream endpoints |
174 | | -│ │ └── caching.py # Cache management |
175 | | -│ ├── services/ # Business logic services |
176 | | -│ │ ├── tmdb_service.py # TMDB API integration |
177 | | -│ │ ├── stremio_service.py # Stremio API integration |
178 | | -│ │ ├── recommendation_service.py # Recommendation engine |
179 | | -│ │ └── catalog.py # Dynamic catalog service |
180 | | -│ └── utils.py # Utility functions |
181 | | -├── static/ # Static web files |
182 | | -│ ├── index.html # Configuration page |
183 | | -│ ├── style.css # Styling |
184 | | -│ ├── script.js # Configuration logic |
185 | | -│ └── logo.png # Addon logo |
186 | | -├── main.py # Application entry point (runs uvicorn) |
187 | | -├── requirements.txt # Python dependencies |
188 | | -├── Dockerfile # Docker image definition |
189 | | -├── docker-compose.yml # Docker Compose configuration |
190 | | -└── README.md # This file |
191 | | -``` |
| 18 | +### Using Docker (Recommended) |
| 19 | + |
| 20 | +You can pull the latest image from the GitHub Container Registry. |
| 21 | + |
| 22 | +1. **Create a `docker-compose.yml` file:** |
| 23 | + |
| 24 | + ```yaml |
| 25 | + services: |
| 26 | + redis: |
| 27 | + image: redis:7-alpine |
| 28 | + container_name: watchly-redis |
| 29 | + restart: unless-stopped |
| 30 | + volumes: |
| 31 | + - redis_data:/data |
| 32 | + |
| 33 | + watchly: |
| 34 | + image: ghcr.io/timilsinabimal/watchly:latest |
| 35 | + container_name: watchly |
| 36 | + restart: unless-stopped |
| 37 | + ports: |
| 38 | + - "8000:8000" |
| 39 | + env_file: |
| 40 | + - .env |
| 41 | + depends_on: |
| 42 | + - redis |
| 43 | + |
| 44 | + volumes: |
| 45 | + redis_data: |
| 46 | + ``` |
| 47 | +
|
| 48 | +2. **Create a `.env` file:** |
| 49 | + |
| 50 | + ```env |
| 51 | + # Required |
| 52 | + TMDB_API_KEY=your_tmdb_api_key_here |
| 53 | + TOKEN_SALT=generate_a_random_secure_string_here |
| 54 | +
|
| 55 | + # Optional |
| 56 | + PORT=8000 |
| 57 | + REDIS_URL=redis://redis:6379/0 |
| 58 | + ADDON_ID=com.bimal.watchly |
| 59 | + ADDON_NAME=Watchly |
| 60 | + TOKEN_TTL_SECONDS=0 |
| 61 | + AUTO_UPDATE_CATALOGS=true |
| 62 | + ``` |
| 63 | + |
| 64 | +3. **Start the application:** |
| 65 | + |
| 66 | + ```bash |
| 67 | + docker-compose up -d |
| 68 | + ``` |
| 69 | + |
| 70 | +4. **Configure the addon:** |
| 71 | + Open `http://localhost:8000/configure` in your browser to set up your Stremio credentials and install the addon. |
192 | 72 |
|
193 | 73 | ## Development |
194 | 74 |
|
195 | | -### Running in Development Mode |
| 75 | +To run the project locally: |
196 | 76 |
|
197 | | -```bash |
198 | | -uv run main.py --dev |
199 | | -``` |
| 77 | +1. **Clone the repository:** |
| 78 | + ```bash |
| 79 | + git clone https://github.com/TimilsinaBimal/Watchly.git |
| 80 | + cd Watchly |
| 81 | + ``` |
200 | 82 |
|
201 | | -Or using Python directly (with auto-reload based on APP_ENV): |
202 | | -```bash |
203 | | -python main.py |
204 | | -``` |
| 83 | +2. **Install dependencies:** |
| 84 | + We recommend using [uv](https://github.com/astral-sh/uv) for fast dependency management. |
| 85 | + ```bash |
| 86 | + uv sync |
| 87 | + ``` |
205 | 88 |
|
206 | | -### Health Check Endpoint |
| 89 | +3. **Run the application:** |
| 90 | + ```bash |
| 91 | + uv run main.py --dev |
| 92 | + ``` |
207 | 93 |
|
208 | | -The `/health` endpoint responds with `{ "status": "ok" }` without touching external services. This keeps container builds and probes green even when secrets like `TMDB_API_KEY` aren't supplied yet. |
209 | | - |
210 | | -### Background Catalog Updates |
211 | | - |
212 | | -Watchly now refreshes catalogs automatically using the credentials stored in Redis. By default the background worker runs every 6 hours and updates each token's catalogs directly via the Stremio API. To disable the behavior, set `AUTO_UPDATE_CATALOGS=false` (or choose a custom cadence with `CATALOG_REFRESH_INTERVAL_SECONDS`). Manual refreshes through `/{token}/catalog/update` continue to work and reuse the same logic. |
213 | | - |
214 | | -### Testing |
215 | | - |
216 | | -```bash |
217 | | -# Test manifest endpoint |
218 | | -curl http://localhost:8000/manifest.json |
219 | | - |
220 | | -# Test catalog endpoint (requires a credential token) |
221 | | -curl http://localhost:8000/{token}/catalog/movie/watchly.rec.json |
222 | | -``` |
223 | | - |
224 | | -## Security Notes |
| 94 | +## Contributing |
225 | 95 |
|
226 | | -- **Tokenized URLs**: Manifest/catalog URLs now contain only salted tokens. Credentials/auth keys never leave the server once submitted. |
227 | | -- **Rotate `TOKEN_SALT`**: Treat the salt like any other secret; rotate if you suspect compromise. Changing the salt invalidates all tokens. |
228 | | -- **Redis Security**: Ensure your Redis instance is not exposed publicly and enable authentication if hosted remotely. |
229 | | -- **HTTPS Recommended**: Always use HTTPS in production to protect tokens in transit. |
230 | | -- **Environment Variables**: Never commit `.env` files or expose API keys in code. |
| 96 | +We welcome contributions of all sizes! |
231 | 97 |
|
232 | | -## Troubleshooting |
| 98 | +- **Small Bug Fixes & Improvements**: Feel free to open a Pull Request directly. |
| 99 | +- **Major Features & Refactors**: Please **open an issue first** to discuss your proposed changes. This helps ensure your work aligns with the project's direction and saves you time. |
233 | 100 |
|
234 | | -### No recommendations appearing |
| 101 | +## Funding & Support |
235 | 102 |
|
236 | | -- Ensure user has "loved" items in their Stremio library |
237 | | -- Check that TMDB API key has proper permissions |
238 | | -- Review application logs for errors |
| 103 | +If you find Watchly useful, please consider supporting the project: |
| 104 | +- [Buy me Mo:Mo](https://buymemomo.com/timilsinabimal) |
| 105 | +- [Support on Ko-fi](https://ko-fi.com/I2I81OVJEH) |
| 106 | +- [Donate via PayPal](https://www.paypal.com/donate/?hosted_button_id=KRQMVS34FC5KC) |
239 | 107 |
|
240 | | -## License |
| 108 | +## Bug Reports |
241 | 109 |
|
242 | | -See [LICENSE](LICENSE) file for details. |
| 110 | +Found a bug or have a feature request? Please [open an issue](https://github.com/TimilsinaBimal/Watchly/issues) on GitHub. |
243 | 111 |
|
244 | | -## Contributing |
| 112 | +## Contributors |
245 | 113 |
|
246 | | -Contributions are welcome! Please feel free to submit a Pull Request. |
| 114 | +Thank you to everyone who has contributed to the project! |
247 | 115 |
|
248 | | -## Support |
| 116 | +## Acknowledgements |
249 | 117 |
|
250 | | -For issues and questions, please open an issue on GitHub. |
| 118 | +Special thanks to **[The Movie Database (TMDB)](https://www.themoviedb.org/)** for providing the rich metadata that powers Watchly's recommendations. |
0 commit comments