linkify-media 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.
- linkify_media-0.1.0/LICENSE +21 -0
- linkify_media-0.1.0/PKG-INFO +323 -0
- linkify_media-0.1.0/README.md +283 -0
- linkify_media-0.1.0/linkify_media/__init__.py +4 -0
- linkify_media-0.1.0/linkify_media/cli.py +25 -0
- linkify_media-0.1.0/linkify_media/core.py +85 -0
- linkify_media-0.1.0/linkify_media/utils.py +19 -0
- linkify_media-0.1.0/linkify_media.egg-info/PKG-INFO +323 -0
- linkify_media-0.1.0/linkify_media.egg-info/SOURCES.txt +13 -0
- linkify_media-0.1.0/linkify_media.egg-info/dependency_links.txt +1 -0
- linkify_media-0.1.0/linkify_media.egg-info/entry_points.txt +2 -0
- linkify_media-0.1.0/linkify_media.egg-info/requires.txt +2 -0
- linkify_media-0.1.0/linkify_media.egg-info/top_level.txt +3 -0
- linkify_media-0.1.0/pyproject.toml +34 -0
- linkify_media-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Code2Encoder aka Shadow Dev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: linkify-media
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async movie/TV metadata fetcher โ TMDB, IMDb, RT, Letterboxd
|
|
5
|
+
Author-email: Shadow Dev <your@email.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Code2Encoder aka Shadow Dev
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/Abdullahkhan000/Linkify-Media
|
|
29
|
+
Project-URL: Repository, https://github.com/Abdullahkhan000/Linkify-Media
|
|
30
|
+
Keywords: tmdb,movies,tv,metadata,async,cli
|
|
31
|
+
Classifier: Programming Language :: Python :: 3
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Operating System :: OS Independent
|
|
34
|
+
Requires-Python: >=3.10
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Requires-Dist: aiohttp>=3.9
|
|
38
|
+
Requires-Dist: python-decouple>=3.8
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# ๐ฌ Linkify-Media
|
|
42
|
+
|
|
43
|
+
[](https://www.python.org)
|
|
44
|
+
[](https://docs.aiohttp.org/)
|
|
45
|
+
[](https://hub.docker.com)
|
|
46
|
+
[](https://github.com/Abdullahkhan000/Linkify-Media/issues)
|
|
47
|
+
[](LICENSE)
|
|
48
|
+
|
|
49
|
+
<div align="center">
|
|
50
|
+
<img src="assets/banner.png" alt="Linkify Media Banner" width="100%" />
|
|
51
|
+
<p>
|
|
52
|
+
<b>Async TMDB ยท IMDb ยท Rotten Tomatoes ยท Metacritic ยท Letterboxd</b><br>
|
|
53
|
+
Fast CLI ยท Clean JSON ยท Docker Ready ยท API Ready ยท Zero 404 RT Links
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ๐ About
|
|
60
|
+
|
|
61
|
+
**Linkify Media** is a high-performance **Async CLI utility** that fetches complete metadata and verified platform links for **Movies & TV Series** using the **TMDB API**.
|
|
62
|
+
|
|
63
|
+
Built for:
|
|
64
|
+
- Backend APIs
|
|
65
|
+
- Media platforms
|
|
66
|
+
- Automation scripts
|
|
67
|
+
- Portfolio projects
|
|
68
|
+
- Data enrichment pipelines
|
|
69
|
+
|
|
70
|
+
Powered by:
|
|
71
|
+
- โก `aiohttp` (async requests)
|
|
72
|
+
- ๐ฏ Smart slug generation
|
|
73
|
+
- ๐ก๏ธ Rotten Tomatoes link validation
|
|
74
|
+
- ๐พ In-memory caching
|
|
75
|
+
- ๐ฅ๏ธ Proper CLI with `argparse`
|
|
76
|
+
- ๐ณ Docker support
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## โจ Key Features
|
|
81
|
+
|
|
82
|
+
| Feature | Status | Description |
|
|
83
|
+
| :--- | :---: | :--- |
|
|
84
|
+
| **Async Engine** | โก | Concurrent API calls using `asyncio` |
|
|
85
|
+
| **Full Metadata** | ๐ฌ | Title, Year, Genres, Runtime, Rating |
|
|
86
|
+
| **Top Cast Fetching** | ๐ฅ | First 5 credited actors |
|
|
87
|
+
| **Poster Support** | ๐ผ๏ธ | TMDB poster image URL |
|
|
88
|
+
| **Multi-Platform Links** | ๐ | TMDB, IMDb, RT, Metacritic, Letterboxd |
|
|
89
|
+
| **RT Validation** | ๐ก๏ธ | Prevents broken Rotten Tomatoes URLs |
|
|
90
|
+
| **CLI Arguments** | ๐ฅ๏ธ | `--media`, `--json` support |
|
|
91
|
+
| **Caching** | ๐พ | In-memory caching for performance |
|
|
92
|
+
| **Docker Support** | ๐ณ | Run anywhere without local setup |
|
|
93
|
+
| **Package Structure** | ๐ฆ | Clean, importable Python package |
|
|
94
|
+
| **API Ready** | ๐ | Easy to plug into Django / FastAPI |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## ๐ฆ Platforms Generated
|
|
99
|
+
|
|
100
|
+
- โ
TMDB
|
|
101
|
+
- โ
IMDb
|
|
102
|
+
- โ
Rotten Tomatoes (validated)
|
|
103
|
+
- โ
Metacritic
|
|
104
|
+
- โ
Letterboxd (movies only)
|
|
105
|
+
- โ
JustWatch (PK region)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## ๐๏ธ Project Structure
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
linkify-media/
|
|
113
|
+
โโโ linkify_media/
|
|
114
|
+
โ โโโ __init__.py # Package entry point
|
|
115
|
+
โ โโโ utils.py # slugify, fetch helpers
|
|
116
|
+
โ โโโ core.py # TMDB logic + link generation
|
|
117
|
+
โ โโโ cli.py # argparse CLI
|
|
118
|
+
โโโ assets/
|
|
119
|
+
โโโ .dockerignore
|
|
120
|
+
โโโ .env # TMDB_API_KEY (never commit this)
|
|
121
|
+
โโโ .gitignore
|
|
122
|
+
โโโ docker-compose.yml
|
|
123
|
+
โโโ Dockerfile
|
|
124
|
+
โโโ LICENSE
|
|
125
|
+
โโโ README.md
|
|
126
|
+
โโโ requirements.txt
|
|
127
|
+
โโโ pyproject.toml
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## ๐ Installation & Setup
|
|
133
|
+
|
|
134
|
+
### Option A โ Local (Python)
|
|
135
|
+
|
|
136
|
+
**1. Clone Repository**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
140
|
+
cd Linkify-Media
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**2. Create Virtual Environment**
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Windows
|
|
147
|
+
python -m venv .venv
|
|
148
|
+
.venv\Scripts\activate
|
|
149
|
+
|
|
150
|
+
# Mac / Linux
|
|
151
|
+
python3 -m venv .venv
|
|
152
|
+
source .venv/bin/activate
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**3. Install Dependencies**
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pip install -r requirements.txt
|
|
159
|
+
pip install .
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**4. Configure API Key**
|
|
163
|
+
|
|
164
|
+
Create `.env` in project root:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
TMDB_API_KEY=your_actual_api_key_here
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
> โ ๏ธ Never commit `.env` โ it's already in `.gitignore`
|
|
171
|
+
|
|
172
|
+
Get your free API key at [themoviedb.org/settings/api](https://www.themoviedb.org/settings/api)
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Option B โ Docker ๐ณ
|
|
177
|
+
|
|
178
|
+
No Python setup needed. Just Docker + your API key.
|
|
179
|
+
|
|
180
|
+
**1. Clone & create `.env`**
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
184
|
+
cd Linkify-Media
|
|
185
|
+
echo TMDB_API_KEY=your_key_here > .env
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**2. Build image**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
docker build -t linkify-media .
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**3. Run**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Movie
|
|
198
|
+
docker run --env-file .env linkify-media "Inception" --media movie
|
|
199
|
+
|
|
200
|
+
# TV Show
|
|
201
|
+
docker run --env-file .env linkify-media "The Bear" --media tv
|
|
202
|
+
|
|
203
|
+
# Save JSON output
|
|
204
|
+
docker run --env-file .env -v ${PWD}/output:/app/output linkify-media "Dune" --json
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> ๐ก **Windows PowerShell** users: use `${PWD}` not `$(pwd)` for volume mounts
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ๐ฅ๏ธ Usage (CLI)
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Movie (default)
|
|
215
|
+
linkify-media "Inception"
|
|
216
|
+
|
|
217
|
+
# TV Series
|
|
218
|
+
linkify-media "Breaking Bad" --media tv
|
|
219
|
+
|
|
220
|
+
# Save output as JSON file
|
|
221
|
+
linkify-media "Dune" --media movie --json
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## ๐ค Sample Output
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"Official Title": "Inception",
|
|
231
|
+
"Release Year": "2010",
|
|
232
|
+
"Genres": ["Action", "Science Fiction", "Adventure"],
|
|
233
|
+
"Runtime (mins)": 148,
|
|
234
|
+
"TMDB Rating": "8.369 (38000 votes)",
|
|
235
|
+
"Poster URL": "https://image.tmdb.org/t/p/w500/oYuLEt3zVCKq57qu2F8dT7NIa6f.jpg",
|
|
236
|
+
"Top Cast": ["Leonardo DiCaprio", "Joseph Gordon-Levitt", "Elliot Page", "Tom Hardy", "Ken Watanabe"],
|
|
237
|
+
"TMDB Link": "https://www.themoviedb.org/movie/27205",
|
|
238
|
+
"IMDb Link": "https://www.imdb.com/title/tt1375666/",
|
|
239
|
+
"Rotten Tomatoes": "https://www.rottentomatoes.com/m/inception",
|
|
240
|
+
"Metacritic": "https://www.metacritic.com/search/movie/inception/results",
|
|
241
|
+
"Letterboxd": "https://letterboxd.com/film/inception/",
|
|
242
|
+
"JustWatch (PK)": "https://www.justwatch.com/pk/search?q=Inception"
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## ๐ง Architecture
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
linkify_media/
|
|
252
|
+
โ
|
|
253
|
+
โโโ utils.py
|
|
254
|
+
โ โโโ slugify() # Clean URL-safe slugs
|
|
255
|
+
โ โโโ fetch_json() # Async GET requests
|
|
256
|
+
โ โโโ head_exists() # URL validation (RT check)
|
|
257
|
+
โ
|
|
258
|
+
โโโ core.py
|
|
259
|
+
โ โโโ fetch_tmdb_data() # Async TMDB search + details + credits
|
|
260
|
+
โ โโโ generate_links() # Platform links + RT validation + caching
|
|
261
|
+
โ โโโ CACHE # In-memory cache dict
|
|
262
|
+
โ
|
|
263
|
+
โโโ cli.py
|
|
264
|
+
โโโ main() # argparse CLI entrypoint
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## ๐งฉ Use Cases
|
|
270
|
+
|
|
271
|
+
- Backend Movie APIs
|
|
272
|
+
- Django REST integration
|
|
273
|
+
- FastAPI async endpoints
|
|
274
|
+
- Media dashboards
|
|
275
|
+
- Streaming aggregation tools
|
|
276
|
+
- Data scraping & enrichment pipelines
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## ๐ Roadmap
|
|
281
|
+
|
|
282
|
+
- [x] Async engine
|
|
283
|
+
- [x] Docker support
|
|
284
|
+
- [x] Python package structure
|
|
285
|
+
- [ ] PyPI release
|
|
286
|
+
- [ ] Redis caching
|
|
287
|
+
- [ ] Batch processing mode
|
|
288
|
+
- [ ] FastAPI version
|
|
289
|
+
- [ ] Trailer support (YouTube API)
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## ๐ค Contributing
|
|
294
|
+
|
|
295
|
+
1. Fork the repository
|
|
296
|
+
2. Create your branch (`git checkout -b feature/your-feature`)
|
|
297
|
+
3. Commit your changes (`git commit -m 'Add some feature'`)
|
|
298
|
+
4. Push to the branch (`git push origin feature/your-feature`)
|
|
299
|
+
5. Open a Pull Request
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## โค๏ธ Support the Project
|
|
304
|
+
|
|
305
|
+
If this project saves you time or helps your workflow, consider supporting its development.
|
|
306
|
+
|
|
307
|
+
[](https://www.patreon.com/c/code2encoder)
|
|
308
|
+
|
|
309
|
+
Your support helps add new features, improve performance, and maintain long-term updates.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## ๐ License
|
|
314
|
+
|
|
315
|
+
Licensed under the **MIT License** โ free to use, modify, and distribute.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
โญ Star the repo if you find it useful!
|
|
320
|
+
|
|
321
|
+
<div align="center">
|
|
322
|
+
<p>๐ Proudly made by <b>code2encoder aka Shadow Dev</b> ๐</p>
|
|
323
|
+
</div>
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# ๐ฌ Linkify-Media
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org)
|
|
4
|
+
[](https://docs.aiohttp.org/)
|
|
5
|
+
[](https://hub.docker.com)
|
|
6
|
+
[](https://github.com/Abdullahkhan000/Linkify-Media/issues)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
<div align="center">
|
|
10
|
+
<img src="assets/banner.png" alt="Linkify Media Banner" width="100%" />
|
|
11
|
+
<p>
|
|
12
|
+
<b>Async TMDB ยท IMDb ยท Rotten Tomatoes ยท Metacritic ยท Letterboxd</b><br>
|
|
13
|
+
Fast CLI ยท Clean JSON ยท Docker Ready ยท API Ready ยท Zero 404 RT Links
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## ๐ About
|
|
20
|
+
|
|
21
|
+
**Linkify Media** is a high-performance **Async CLI utility** that fetches complete metadata and verified platform links for **Movies & TV Series** using the **TMDB API**.
|
|
22
|
+
|
|
23
|
+
Built for:
|
|
24
|
+
- Backend APIs
|
|
25
|
+
- Media platforms
|
|
26
|
+
- Automation scripts
|
|
27
|
+
- Portfolio projects
|
|
28
|
+
- Data enrichment pipelines
|
|
29
|
+
|
|
30
|
+
Powered by:
|
|
31
|
+
- โก `aiohttp` (async requests)
|
|
32
|
+
- ๐ฏ Smart slug generation
|
|
33
|
+
- ๐ก๏ธ Rotten Tomatoes link validation
|
|
34
|
+
- ๐พ In-memory caching
|
|
35
|
+
- ๐ฅ๏ธ Proper CLI with `argparse`
|
|
36
|
+
- ๐ณ Docker support
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## โจ Key Features
|
|
41
|
+
|
|
42
|
+
| Feature | Status | Description |
|
|
43
|
+
| :--- | :---: | :--- |
|
|
44
|
+
| **Async Engine** | โก | Concurrent API calls using `asyncio` |
|
|
45
|
+
| **Full Metadata** | ๐ฌ | Title, Year, Genres, Runtime, Rating |
|
|
46
|
+
| **Top Cast Fetching** | ๐ฅ | First 5 credited actors |
|
|
47
|
+
| **Poster Support** | ๐ผ๏ธ | TMDB poster image URL |
|
|
48
|
+
| **Multi-Platform Links** | ๐ | TMDB, IMDb, RT, Metacritic, Letterboxd |
|
|
49
|
+
| **RT Validation** | ๐ก๏ธ | Prevents broken Rotten Tomatoes URLs |
|
|
50
|
+
| **CLI Arguments** | ๐ฅ๏ธ | `--media`, `--json` support |
|
|
51
|
+
| **Caching** | ๐พ | In-memory caching for performance |
|
|
52
|
+
| **Docker Support** | ๐ณ | Run anywhere without local setup |
|
|
53
|
+
| **Package Structure** | ๐ฆ | Clean, importable Python package |
|
|
54
|
+
| **API Ready** | ๐ | Easy to plug into Django / FastAPI |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## ๐ฆ Platforms Generated
|
|
59
|
+
|
|
60
|
+
- โ
TMDB
|
|
61
|
+
- โ
IMDb
|
|
62
|
+
- โ
Rotten Tomatoes (validated)
|
|
63
|
+
- โ
Metacritic
|
|
64
|
+
- โ
Letterboxd (movies only)
|
|
65
|
+
- โ
JustWatch (PK region)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## ๐๏ธ Project Structure
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
linkify-media/
|
|
73
|
+
โโโ linkify_media/
|
|
74
|
+
โ โโโ __init__.py # Package entry point
|
|
75
|
+
โ โโโ utils.py # slugify, fetch helpers
|
|
76
|
+
โ โโโ core.py # TMDB logic + link generation
|
|
77
|
+
โ โโโ cli.py # argparse CLI
|
|
78
|
+
โโโ assets/
|
|
79
|
+
โโโ .dockerignore
|
|
80
|
+
โโโ .env # TMDB_API_KEY (never commit this)
|
|
81
|
+
โโโ .gitignore
|
|
82
|
+
โโโ docker-compose.yml
|
|
83
|
+
โโโ Dockerfile
|
|
84
|
+
โโโ LICENSE
|
|
85
|
+
โโโ README.md
|
|
86
|
+
โโโ requirements.txt
|
|
87
|
+
โโโ pyproject.toml
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## ๐ Installation & Setup
|
|
93
|
+
|
|
94
|
+
### Option A โ Local (Python)
|
|
95
|
+
|
|
96
|
+
**1. Clone Repository**
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
100
|
+
cd Linkify-Media
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**2. Create Virtual Environment**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Windows
|
|
107
|
+
python -m venv .venv
|
|
108
|
+
.venv\Scripts\activate
|
|
109
|
+
|
|
110
|
+
# Mac / Linux
|
|
111
|
+
python3 -m venv .venv
|
|
112
|
+
source .venv/bin/activate
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**3. Install Dependencies**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pip install -r requirements.txt
|
|
119
|
+
pip install .
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**4. Configure API Key**
|
|
123
|
+
|
|
124
|
+
Create `.env` in project root:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
TMDB_API_KEY=your_actual_api_key_here
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> โ ๏ธ Never commit `.env` โ it's already in `.gitignore`
|
|
131
|
+
|
|
132
|
+
Get your free API key at [themoviedb.org/settings/api](https://www.themoviedb.org/settings/api)
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Option B โ Docker ๐ณ
|
|
137
|
+
|
|
138
|
+
No Python setup needed. Just Docker + your API key.
|
|
139
|
+
|
|
140
|
+
**1. Clone & create `.env`**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
144
|
+
cd Linkify-Media
|
|
145
|
+
echo TMDB_API_KEY=your_key_here > .env
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**2. Build image**
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
docker build -t linkify-media .
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**3. Run**
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Movie
|
|
158
|
+
docker run --env-file .env linkify-media "Inception" --media movie
|
|
159
|
+
|
|
160
|
+
# TV Show
|
|
161
|
+
docker run --env-file .env linkify-media "The Bear" --media tv
|
|
162
|
+
|
|
163
|
+
# Save JSON output
|
|
164
|
+
docker run --env-file .env -v ${PWD}/output:/app/output linkify-media "Dune" --json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
> ๐ก **Windows PowerShell** users: use `${PWD}` not `$(pwd)` for volume mounts
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## ๐ฅ๏ธ Usage (CLI)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Movie (default)
|
|
175
|
+
linkify-media "Inception"
|
|
176
|
+
|
|
177
|
+
# TV Series
|
|
178
|
+
linkify-media "Breaking Bad" --media tv
|
|
179
|
+
|
|
180
|
+
# Save output as JSON file
|
|
181
|
+
linkify-media "Dune" --media movie --json
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## ๐ค Sample Output
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"Official Title": "Inception",
|
|
191
|
+
"Release Year": "2010",
|
|
192
|
+
"Genres": ["Action", "Science Fiction", "Adventure"],
|
|
193
|
+
"Runtime (mins)": 148,
|
|
194
|
+
"TMDB Rating": "8.369 (38000 votes)",
|
|
195
|
+
"Poster URL": "https://image.tmdb.org/t/p/w500/oYuLEt3zVCKq57qu2F8dT7NIa6f.jpg",
|
|
196
|
+
"Top Cast": ["Leonardo DiCaprio", "Joseph Gordon-Levitt", "Elliot Page", "Tom Hardy", "Ken Watanabe"],
|
|
197
|
+
"TMDB Link": "https://www.themoviedb.org/movie/27205",
|
|
198
|
+
"IMDb Link": "https://www.imdb.com/title/tt1375666/",
|
|
199
|
+
"Rotten Tomatoes": "https://www.rottentomatoes.com/m/inception",
|
|
200
|
+
"Metacritic": "https://www.metacritic.com/search/movie/inception/results",
|
|
201
|
+
"Letterboxd": "https://letterboxd.com/film/inception/",
|
|
202
|
+
"JustWatch (PK)": "https://www.justwatch.com/pk/search?q=Inception"
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## ๐ง Architecture
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
linkify_media/
|
|
212
|
+
โ
|
|
213
|
+
โโโ utils.py
|
|
214
|
+
โ โโโ slugify() # Clean URL-safe slugs
|
|
215
|
+
โ โโโ fetch_json() # Async GET requests
|
|
216
|
+
โ โโโ head_exists() # URL validation (RT check)
|
|
217
|
+
โ
|
|
218
|
+
โโโ core.py
|
|
219
|
+
โ โโโ fetch_tmdb_data() # Async TMDB search + details + credits
|
|
220
|
+
โ โโโ generate_links() # Platform links + RT validation + caching
|
|
221
|
+
โ โโโ CACHE # In-memory cache dict
|
|
222
|
+
โ
|
|
223
|
+
โโโ cli.py
|
|
224
|
+
โโโ main() # argparse CLI entrypoint
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## ๐งฉ Use Cases
|
|
230
|
+
|
|
231
|
+
- Backend Movie APIs
|
|
232
|
+
- Django REST integration
|
|
233
|
+
- FastAPI async endpoints
|
|
234
|
+
- Media dashboards
|
|
235
|
+
- Streaming aggregation tools
|
|
236
|
+
- Data scraping & enrichment pipelines
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## ๐ Roadmap
|
|
241
|
+
|
|
242
|
+
- [x] Async engine
|
|
243
|
+
- [x] Docker support
|
|
244
|
+
- [x] Python package structure
|
|
245
|
+
- [ ] PyPI release
|
|
246
|
+
- [ ] Redis caching
|
|
247
|
+
- [ ] Batch processing mode
|
|
248
|
+
- [ ] FastAPI version
|
|
249
|
+
- [ ] Trailer support (YouTube API)
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## ๐ค Contributing
|
|
254
|
+
|
|
255
|
+
1. Fork the repository
|
|
256
|
+
2. Create your branch (`git checkout -b feature/your-feature`)
|
|
257
|
+
3. Commit your changes (`git commit -m 'Add some feature'`)
|
|
258
|
+
4. Push to the branch (`git push origin feature/your-feature`)
|
|
259
|
+
5. Open a Pull Request
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## โค๏ธ Support the Project
|
|
264
|
+
|
|
265
|
+
If this project saves you time or helps your workflow, consider supporting its development.
|
|
266
|
+
|
|
267
|
+
[](https://www.patreon.com/c/code2encoder)
|
|
268
|
+
|
|
269
|
+
Your support helps add new features, improve performance, and maintain long-term updates.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## ๐ License
|
|
274
|
+
|
|
275
|
+
Licensed under the **MIT License** โ free to use, modify, and distribute.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
โญ Star the repo if you find it useful!
|
|
280
|
+
|
|
281
|
+
<div align="center">
|
|
282
|
+
<p>๐ Proudly made by <b>code2encoder aka Shadow Dev</b> ๐</p>
|
|
283
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
from .core import generate_links
|
|
5
|
+
from .utils import slugify
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
parser = argparse.ArgumentParser(description="Async Movie / TV metadata fetcher")
|
|
9
|
+
parser.add_argument("title", help="Movie or TV show name")
|
|
10
|
+
parser.add_argument("--media", choices=["movie", "tv"], default="movie")
|
|
11
|
+
parser.add_argument("--json", action="store_true", help="Save output as JSON")
|
|
12
|
+
|
|
13
|
+
args = parser.parse_args()
|
|
14
|
+
|
|
15
|
+
result = asyncio.run(generate_links(args.title, args.media))
|
|
16
|
+
print(json.dumps(result, indent=4, ensure_ascii=False))
|
|
17
|
+
|
|
18
|
+
if args.json:
|
|
19
|
+
filename = f"{slugify(args.title)}.json"
|
|
20
|
+
with open(filename, "w", encoding="utf-8") as f:
|
|
21
|
+
json.dump(result, f, indent=4, ensure_ascii=False)
|
|
22
|
+
print(f"\nSaved โ {filename}")
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import aiohttp
|
|
3
|
+
from decouple import config
|
|
4
|
+
from .utils import slugify, fetch_json, head_exists
|
|
5
|
+
|
|
6
|
+
TMDB_API_KEY = config("TMDB_API_KEY")
|
|
7
|
+
TMDB_BASE_URL = "https://api.themoviedb.org/3"
|
|
8
|
+
IMAGE_BASE = "https://image.tmdb.org/t/p/w500"
|
|
9
|
+
|
|
10
|
+
CACHE = {}
|
|
11
|
+
|
|
12
|
+
async def fetch_tmdb_data(title: str, media: str, session):
|
|
13
|
+
search_url = f"{TMDB_BASE_URL}/search/{media}"
|
|
14
|
+
search = await fetch_json(
|
|
15
|
+
session,
|
|
16
|
+
search_url,
|
|
17
|
+
{"api_key": TMDB_API_KEY, "query": title}
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if not search.get("results"):
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
item = search["results"][0]
|
|
24
|
+
tmdb_id = item["id"]
|
|
25
|
+
|
|
26
|
+
details_url = f"{TMDB_BASE_URL}/{media}/{tmdb_id}"
|
|
27
|
+
credits_url = f"{details_url}/credits"
|
|
28
|
+
|
|
29
|
+
details, credits = await asyncio.gather(
|
|
30
|
+
fetch_json(session, details_url, {"api_key": TMDB_API_KEY}),
|
|
31
|
+
fetch_json(session, credits_url, {"api_key": TMDB_API_KEY})
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
official_title = details.get("title") or details.get("name")
|
|
35
|
+
release_date = details.get("release_date") or details.get("first_air_date")
|
|
36
|
+
release_year = release_date[:4] if release_date else None
|
|
37
|
+
runtime = details.get("runtime")
|
|
38
|
+
if not runtime:
|
|
39
|
+
ep = details.get("episode_run_time")
|
|
40
|
+
runtime = ep[0] if ep else None
|
|
41
|
+
|
|
42
|
+
poster = details.get("poster_path")
|
|
43
|
+
poster_url = f"{IMAGE_BASE}{poster}" if poster else None
|
|
44
|
+
genres = [g["name"] for g in details.get("genres", [])]
|
|
45
|
+
cast = [c["name"] for c in credits.get("cast", [])[:5]]
|
|
46
|
+
imdb_id = details.get("imdb_id")
|
|
47
|
+
imdb_link = f"https://www.imdb.com/title/{imdb_id}/" if imdb_id else None
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
"Official Title": official_title,
|
|
51
|
+
"Release Year": release_year,
|
|
52
|
+
"Genres": genres,
|
|
53
|
+
"Runtime (mins)": runtime,
|
|
54
|
+
"TMDB Rating": f'{details.get("vote_average")} ({details.get("vote_count")} votes)',
|
|
55
|
+
"Poster URL": poster_url,
|
|
56
|
+
"Top Cast": cast,
|
|
57
|
+
"TMDB Link": f"https://www.themoviedb.org/{media}/{tmdb_id}",
|
|
58
|
+
"IMDb Link": imdb_link,
|
|
59
|
+
"slug": slugify(official_title)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async def generate_links(title: str, media: str):
|
|
63
|
+
cache_key = f"{title}_{media}"
|
|
64
|
+
if cache_key in CACHE:
|
|
65
|
+
return CACHE[cache_key]
|
|
66
|
+
|
|
67
|
+
async with aiohttp.ClientSession() as session:
|
|
68
|
+
data = await fetch_tmdb_data(title, media, session)
|
|
69
|
+
if not data:
|
|
70
|
+
return {"Error": "Movie / TV show not found"}
|
|
71
|
+
|
|
72
|
+
rt_type = "m" if media == "movie" else "tv"
|
|
73
|
+
rt_url = f"https://www.rottentomatoes.com/{rt_type}/{data['slug']}"
|
|
74
|
+
rt_final = rt_url if await head_exists(session, rt_url) else "RT page not found"
|
|
75
|
+
|
|
76
|
+
result = {
|
|
77
|
+
**{k: v for k, v in data.items() if k != "slug"},
|
|
78
|
+
"Rotten Tomatoes": rt_final,
|
|
79
|
+
"Metacritic": f"https://www.metacritic.com/search/{media}/{data['slug']}/results",
|
|
80
|
+
"Letterboxd": f"https://letterboxd.com/film/{data['slug']}/" if media == "movie" else None,
|
|
81
|
+
"JustWatch (PK)": f"https://www.justwatch.com/pk/search?q={title}"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
CACHE[cache_key] = result
|
|
85
|
+
return result
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import aiohttp
|
|
3
|
+
|
|
4
|
+
def slugify(text: str) -> str:
|
|
5
|
+
text = text.lower()
|
|
6
|
+
text = re.sub(r"[^\w\s]", "", text)
|
|
7
|
+
text = re.sub(r"\s+", "_", text)
|
|
8
|
+
return text
|
|
9
|
+
|
|
10
|
+
async def fetch_json(session, url, params=None):
|
|
11
|
+
async with session.get(url, params=params, timeout=10) as resp:
|
|
12
|
+
return await resp.json()
|
|
13
|
+
|
|
14
|
+
async def head_exists(session, url):
|
|
15
|
+
try:
|
|
16
|
+
async with session.head(url, allow_redirects=True, timeout=5) as r:
|
|
17
|
+
return r.status == 200
|
|
18
|
+
except:
|
|
19
|
+
return False
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: linkify-media
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async movie/TV metadata fetcher โ TMDB, IMDb, RT, Letterboxd
|
|
5
|
+
Author-email: Shadow Dev <your@email.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Code2Encoder aka Shadow Dev
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/Abdullahkhan000/Linkify-Media
|
|
29
|
+
Project-URL: Repository, https://github.com/Abdullahkhan000/Linkify-Media
|
|
30
|
+
Keywords: tmdb,movies,tv,metadata,async,cli
|
|
31
|
+
Classifier: Programming Language :: Python :: 3
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Operating System :: OS Independent
|
|
34
|
+
Requires-Python: >=3.10
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Requires-Dist: aiohttp>=3.9
|
|
38
|
+
Requires-Dist: python-decouple>=3.8
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# ๐ฌ Linkify-Media
|
|
42
|
+
|
|
43
|
+
[](https://www.python.org)
|
|
44
|
+
[](https://docs.aiohttp.org/)
|
|
45
|
+
[](https://hub.docker.com)
|
|
46
|
+
[](https://github.com/Abdullahkhan000/Linkify-Media/issues)
|
|
47
|
+
[](LICENSE)
|
|
48
|
+
|
|
49
|
+
<div align="center">
|
|
50
|
+
<img src="assets/banner.png" alt="Linkify Media Banner" width="100%" />
|
|
51
|
+
<p>
|
|
52
|
+
<b>Async TMDB ยท IMDb ยท Rotten Tomatoes ยท Metacritic ยท Letterboxd</b><br>
|
|
53
|
+
Fast CLI ยท Clean JSON ยท Docker Ready ยท API Ready ยท Zero 404 RT Links
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ๐ About
|
|
60
|
+
|
|
61
|
+
**Linkify Media** is a high-performance **Async CLI utility** that fetches complete metadata and verified platform links for **Movies & TV Series** using the **TMDB API**.
|
|
62
|
+
|
|
63
|
+
Built for:
|
|
64
|
+
- Backend APIs
|
|
65
|
+
- Media platforms
|
|
66
|
+
- Automation scripts
|
|
67
|
+
- Portfolio projects
|
|
68
|
+
- Data enrichment pipelines
|
|
69
|
+
|
|
70
|
+
Powered by:
|
|
71
|
+
- โก `aiohttp` (async requests)
|
|
72
|
+
- ๐ฏ Smart slug generation
|
|
73
|
+
- ๐ก๏ธ Rotten Tomatoes link validation
|
|
74
|
+
- ๐พ In-memory caching
|
|
75
|
+
- ๐ฅ๏ธ Proper CLI with `argparse`
|
|
76
|
+
- ๐ณ Docker support
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## โจ Key Features
|
|
81
|
+
|
|
82
|
+
| Feature | Status | Description |
|
|
83
|
+
| :--- | :---: | :--- |
|
|
84
|
+
| **Async Engine** | โก | Concurrent API calls using `asyncio` |
|
|
85
|
+
| **Full Metadata** | ๐ฌ | Title, Year, Genres, Runtime, Rating |
|
|
86
|
+
| **Top Cast Fetching** | ๐ฅ | First 5 credited actors |
|
|
87
|
+
| **Poster Support** | ๐ผ๏ธ | TMDB poster image URL |
|
|
88
|
+
| **Multi-Platform Links** | ๐ | TMDB, IMDb, RT, Metacritic, Letterboxd |
|
|
89
|
+
| **RT Validation** | ๐ก๏ธ | Prevents broken Rotten Tomatoes URLs |
|
|
90
|
+
| **CLI Arguments** | ๐ฅ๏ธ | `--media`, `--json` support |
|
|
91
|
+
| **Caching** | ๐พ | In-memory caching for performance |
|
|
92
|
+
| **Docker Support** | ๐ณ | Run anywhere without local setup |
|
|
93
|
+
| **Package Structure** | ๐ฆ | Clean, importable Python package |
|
|
94
|
+
| **API Ready** | ๐ | Easy to plug into Django / FastAPI |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## ๐ฆ Platforms Generated
|
|
99
|
+
|
|
100
|
+
- โ
TMDB
|
|
101
|
+
- โ
IMDb
|
|
102
|
+
- โ
Rotten Tomatoes (validated)
|
|
103
|
+
- โ
Metacritic
|
|
104
|
+
- โ
Letterboxd (movies only)
|
|
105
|
+
- โ
JustWatch (PK region)
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## ๐๏ธ Project Structure
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
linkify-media/
|
|
113
|
+
โโโ linkify_media/
|
|
114
|
+
โ โโโ __init__.py # Package entry point
|
|
115
|
+
โ โโโ utils.py # slugify, fetch helpers
|
|
116
|
+
โ โโโ core.py # TMDB logic + link generation
|
|
117
|
+
โ โโโ cli.py # argparse CLI
|
|
118
|
+
โโโ assets/
|
|
119
|
+
โโโ .dockerignore
|
|
120
|
+
โโโ .env # TMDB_API_KEY (never commit this)
|
|
121
|
+
โโโ .gitignore
|
|
122
|
+
โโโ docker-compose.yml
|
|
123
|
+
โโโ Dockerfile
|
|
124
|
+
โโโ LICENSE
|
|
125
|
+
โโโ README.md
|
|
126
|
+
โโโ requirements.txt
|
|
127
|
+
โโโ pyproject.toml
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## ๐ Installation & Setup
|
|
133
|
+
|
|
134
|
+
### Option A โ Local (Python)
|
|
135
|
+
|
|
136
|
+
**1. Clone Repository**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
140
|
+
cd Linkify-Media
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**2. Create Virtual Environment**
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Windows
|
|
147
|
+
python -m venv .venv
|
|
148
|
+
.venv\Scripts\activate
|
|
149
|
+
|
|
150
|
+
# Mac / Linux
|
|
151
|
+
python3 -m venv .venv
|
|
152
|
+
source .venv/bin/activate
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**3. Install Dependencies**
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pip install -r requirements.txt
|
|
159
|
+
pip install .
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**4. Configure API Key**
|
|
163
|
+
|
|
164
|
+
Create `.env` in project root:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
TMDB_API_KEY=your_actual_api_key_here
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
> โ ๏ธ Never commit `.env` โ it's already in `.gitignore`
|
|
171
|
+
|
|
172
|
+
Get your free API key at [themoviedb.org/settings/api](https://www.themoviedb.org/settings/api)
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Option B โ Docker ๐ณ
|
|
177
|
+
|
|
178
|
+
No Python setup needed. Just Docker + your API key.
|
|
179
|
+
|
|
180
|
+
**1. Clone & create `.env`**
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
git clone https://github.com/Abdullahkhan000/Linkify-Media
|
|
184
|
+
cd Linkify-Media
|
|
185
|
+
echo TMDB_API_KEY=your_key_here > .env
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**2. Build image**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
docker build -t linkify-media .
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**3. Run**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Movie
|
|
198
|
+
docker run --env-file .env linkify-media "Inception" --media movie
|
|
199
|
+
|
|
200
|
+
# TV Show
|
|
201
|
+
docker run --env-file .env linkify-media "The Bear" --media tv
|
|
202
|
+
|
|
203
|
+
# Save JSON output
|
|
204
|
+
docker run --env-file .env -v ${PWD}/output:/app/output linkify-media "Dune" --json
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
> ๐ก **Windows PowerShell** users: use `${PWD}` not `$(pwd)` for volume mounts
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ๐ฅ๏ธ Usage (CLI)
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Movie (default)
|
|
215
|
+
linkify-media "Inception"
|
|
216
|
+
|
|
217
|
+
# TV Series
|
|
218
|
+
linkify-media "Breaking Bad" --media tv
|
|
219
|
+
|
|
220
|
+
# Save output as JSON file
|
|
221
|
+
linkify-media "Dune" --media movie --json
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## ๐ค Sample Output
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"Official Title": "Inception",
|
|
231
|
+
"Release Year": "2010",
|
|
232
|
+
"Genres": ["Action", "Science Fiction", "Adventure"],
|
|
233
|
+
"Runtime (mins)": 148,
|
|
234
|
+
"TMDB Rating": "8.369 (38000 votes)",
|
|
235
|
+
"Poster URL": "https://image.tmdb.org/t/p/w500/oYuLEt3zVCKq57qu2F8dT7NIa6f.jpg",
|
|
236
|
+
"Top Cast": ["Leonardo DiCaprio", "Joseph Gordon-Levitt", "Elliot Page", "Tom Hardy", "Ken Watanabe"],
|
|
237
|
+
"TMDB Link": "https://www.themoviedb.org/movie/27205",
|
|
238
|
+
"IMDb Link": "https://www.imdb.com/title/tt1375666/",
|
|
239
|
+
"Rotten Tomatoes": "https://www.rottentomatoes.com/m/inception",
|
|
240
|
+
"Metacritic": "https://www.metacritic.com/search/movie/inception/results",
|
|
241
|
+
"Letterboxd": "https://letterboxd.com/film/inception/",
|
|
242
|
+
"JustWatch (PK)": "https://www.justwatch.com/pk/search?q=Inception"
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## ๐ง Architecture
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
linkify_media/
|
|
252
|
+
โ
|
|
253
|
+
โโโ utils.py
|
|
254
|
+
โ โโโ slugify() # Clean URL-safe slugs
|
|
255
|
+
โ โโโ fetch_json() # Async GET requests
|
|
256
|
+
โ โโโ head_exists() # URL validation (RT check)
|
|
257
|
+
โ
|
|
258
|
+
โโโ core.py
|
|
259
|
+
โ โโโ fetch_tmdb_data() # Async TMDB search + details + credits
|
|
260
|
+
โ โโโ generate_links() # Platform links + RT validation + caching
|
|
261
|
+
โ โโโ CACHE # In-memory cache dict
|
|
262
|
+
โ
|
|
263
|
+
โโโ cli.py
|
|
264
|
+
โโโ main() # argparse CLI entrypoint
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## ๐งฉ Use Cases
|
|
270
|
+
|
|
271
|
+
- Backend Movie APIs
|
|
272
|
+
- Django REST integration
|
|
273
|
+
- FastAPI async endpoints
|
|
274
|
+
- Media dashboards
|
|
275
|
+
- Streaming aggregation tools
|
|
276
|
+
- Data scraping & enrichment pipelines
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## ๐ Roadmap
|
|
281
|
+
|
|
282
|
+
- [x] Async engine
|
|
283
|
+
- [x] Docker support
|
|
284
|
+
- [x] Python package structure
|
|
285
|
+
- [ ] PyPI release
|
|
286
|
+
- [ ] Redis caching
|
|
287
|
+
- [ ] Batch processing mode
|
|
288
|
+
- [ ] FastAPI version
|
|
289
|
+
- [ ] Trailer support (YouTube API)
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## ๐ค Contributing
|
|
294
|
+
|
|
295
|
+
1. Fork the repository
|
|
296
|
+
2. Create your branch (`git checkout -b feature/your-feature`)
|
|
297
|
+
3. Commit your changes (`git commit -m 'Add some feature'`)
|
|
298
|
+
4. Push to the branch (`git push origin feature/your-feature`)
|
|
299
|
+
5. Open a Pull Request
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## โค๏ธ Support the Project
|
|
304
|
+
|
|
305
|
+
If this project saves you time or helps your workflow, consider supporting its development.
|
|
306
|
+
|
|
307
|
+
[](https://www.patreon.com/c/code2encoder)
|
|
308
|
+
|
|
309
|
+
Your support helps add new features, improve performance, and maintain long-term updates.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## ๐ License
|
|
314
|
+
|
|
315
|
+
Licensed under the **MIT License** โ free to use, modify, and distribute.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
โญ Star the repo if you find it useful!
|
|
320
|
+
|
|
321
|
+
<div align="center">
|
|
322
|
+
<p>๐ Proudly made by <b>code2encoder aka Shadow Dev</b> ๐</p>
|
|
323
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
linkify_media/__init__.py
|
|
5
|
+
linkify_media/cli.py
|
|
6
|
+
linkify_media/core.py
|
|
7
|
+
linkify_media/utils.py
|
|
8
|
+
linkify_media.egg-info/PKG-INFO
|
|
9
|
+
linkify_media.egg-info/SOURCES.txt
|
|
10
|
+
linkify_media.egg-info/dependency_links.txt
|
|
11
|
+
linkify_media.egg-info/entry_points.txt
|
|
12
|
+
linkify_media.egg-info/requires.txt
|
|
13
|
+
linkify_media.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "linkify-media"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Async movie/TV metadata fetcher โ TMDB, IMDb, RT, Letterboxd"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {file = "LICENSE"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Shadow Dev", email = "your@email.com"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["tmdb", "movies", "tv", "metadata", "async", "cli"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"aiohttp>=3.9",
|
|
23
|
+
"python-decouple>=3.8",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/Abdullahkhan000/Linkify-Media"
|
|
28
|
+
Repository = "https://github.com/Abdullahkhan000/Linkify-Media"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
linkify-media = "linkify_media.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
where = ["."]
|