mangadex-sync 2.0.3__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.
- mangadex_sync-2.0.3/LICENSE +21 -0
- mangadex_sync-2.0.3/PKG-INFO +218 -0
- mangadex_sync-2.0.3/README.md +182 -0
- mangadex_sync-2.0.3/mangadex_sync/__init__.py +158 -0
- mangadex_sync-2.0.3/mangadex_sync/app.py +1948 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/PKG-INFO +218 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/SOURCES.txt +11 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/dependency_links.txt +1 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/entry_points.txt +2 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/requires.txt +12 -0
- mangadex_sync-2.0.3/mangadex_sync.egg-info/top_level.txt +1 -0
- mangadex_sync-2.0.3/pyproject.toml +52 -0
- mangadex_sync-2.0.3/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Your Name
|
|
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,218 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mangadex-sync
|
|
3
|
+
Version: 2.0.3
|
|
4
|
+
Summary: Export and import your MangaDex library to/from MyAnimeList and AniList — with scores, statuses, and chapter progress
|
|
5
|
+
Author-email: Spider2742 <mail@spidey.in>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/spider2742/mangadex-sync
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/spider2742/mangadex-sync/issues
|
|
9
|
+
Keywords: mangadex,myanimelist,anilist,manga,export,import,sync,mal
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Web Environment
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Internet
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: pywebview>=5.0.0
|
|
25
|
+
Requires-Dist: PyQt6>=6.4.0
|
|
26
|
+
Requires-Dist: PyQt6-WebEngine>=6.4.0
|
|
27
|
+
Requires-Dist: qtpy>=2.4.0
|
|
28
|
+
Requires-Dist: flask>=3.0.0
|
|
29
|
+
Requires-Dist: requests>=2.31.0
|
|
30
|
+
Requires-Dist: pandas>=2.0.0
|
|
31
|
+
Requires-Dist: openpyxl>=3.1.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: build; extra == "dev"
|
|
34
|
+
Requires-Dist: twine; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# MangaDex Sync
|
|
38
|
+
|
|
39
|
+
Export **and import** your MangaDex library to/from **MyAnimeList** and **AniList** — with scores, statuses, and optional chapter progress — all from a single clean app.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+

|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **Single app** — Export, Import, and Convert in one place, no switching between scripts
|
|
52
|
+
- **Import** — Restore your library from a MangaDex JSON backup or a MAL/AniList XML file
|
|
53
|
+
- **Fast mode** — Exports titles + status in minutes (recommended)
|
|
54
|
+
- **Deep mode** — Also fetches your last read chapter per manga (slower)
|
|
55
|
+
- **MAL XML** — Ready to import at `myanimelist.net/import.php` (includes `.gz`)
|
|
56
|
+
- **AniList XML** — Same format, ready to import at AniList
|
|
57
|
+
- **JSON backup** — Full local backup of your library data
|
|
58
|
+
- **Scores** — Fetches your MangaDex ratings and carries them over
|
|
59
|
+
- **Resume** — Saves a checkpoint so it can pick up if interrupted
|
|
60
|
+
- **Skipped list** — Shows exactly which manga had no MAL ID
|
|
61
|
+
- **Export history** — Logs every export with timestamp and file list
|
|
62
|
+
- **Dry run mode** — Simulate without writing any files
|
|
63
|
+
- **Native window** — Opens as a desktop app via pywebview (or falls back to browser)
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Requirements
|
|
68
|
+
|
|
69
|
+
- Python 3.10 or newer
|
|
70
|
+
- A MangaDex account
|
|
71
|
+
- A [MangaDex API Personal Client](https://mangadex.org/settings) (free to create)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install mangadex-sync
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Everything including the native desktop window is included — no extra steps needed.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Usage
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
mangadex-sync
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This opens a native desktop window. You can also open `http://localhost:7337` in any browser — useful for accessing it from another device on the same network.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Step-by-step Guide
|
|
96
|
+
|
|
97
|
+
### 1. Get your MangaDex API credentials
|
|
98
|
+
|
|
99
|
+
1. Go to [mangadex.org/settings](https://mangadex.org/settings)
|
|
100
|
+
2. Scroll to **API Clients** → click **Create**
|
|
101
|
+
3. Give it any name, set type to **Personal**
|
|
102
|
+
4. Copy your **Client ID** and **Client Secret**
|
|
103
|
+
|
|
104
|
+
### 2. Export your library
|
|
105
|
+
|
|
106
|
+
1. Open the app and go to the **Export** tab
|
|
107
|
+
2. Fill in:
|
|
108
|
+
- **Client ID** and **Client Secret** (from step 1)
|
|
109
|
+
- **Username** and **Password** (your MangaDex login)
|
|
110
|
+
- **Save folder** — where to save the output files
|
|
111
|
+
3. Choose **Fast** or **Deep** mode (Fast is recommended)
|
|
112
|
+
4. Click **⚡ Extract Entire Library**
|
|
113
|
+
|
|
114
|
+
> **MAL User ID and MAL Username are optional.** You do not need to fill them in to generate a working XML file. MAL identifies you by your login session when you upload — the ID and username fields in the XML header are just metadata and are ignored during import. Leave them blank if you don't know them.
|
|
115
|
+
|
|
116
|
+
### 3. Convert to XML
|
|
117
|
+
|
|
118
|
+
After export finishes, the **Convert** tab auto-fills with your exported files. Just:
|
|
119
|
+
|
|
120
|
+
1. Click **⚡ Generate XML Files**
|
|
121
|
+
2. Files are saved to your chosen folder
|
|
122
|
+
|
|
123
|
+
### 4. Import to MAL / AniList
|
|
124
|
+
|
|
125
|
+
- **MAL:** Go to [myanimelist.net/import.php](https://myanimelist.net/import.php) and upload the `mal_*.xml` file
|
|
126
|
+
- **AniList:** Go to [anilist.co/settings/import](https://anilist.co/settings/import) and upload the `anilist_*.xml` file
|
|
127
|
+
|
|
128
|
+
### 5. Import back to MangaDex
|
|
129
|
+
|
|
130
|
+
Use the **Import** tab to restore your library from:
|
|
131
|
+
- A `mdex_*.json` backup file (exported by this app)
|
|
132
|
+
- A MAL XML file (`mal_*.xml`)
|
|
133
|
+
- An AniList XML file (`anilist_*.xml`)
|
|
134
|
+
|
|
135
|
+
1. Browse or paste the path to your file
|
|
136
|
+
2. Optionally enable **Import Scores** to restore your ratings
|
|
137
|
+
3. Click **Start Import**
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Fast vs Deep Mode
|
|
142
|
+
|
|
143
|
+
| | Fast | Deep |
|
|
144
|
+
|---|---|---|
|
|
145
|
+
| Speed | ⚡ Minutes | 🐢 15–60+ min |
|
|
146
|
+
| Titles & status | ✓ | ✓ |
|
|
147
|
+
| Ratings/scores | ✓ | ✓ |
|
|
148
|
+
| Last read chapter | ✗ | ✓ |
|
|
149
|
+
| Recommended | ✓ | Only if you need progress |
|
|
150
|
+
|
|
151
|
+
Deep mode fetches every individual chapter you've ever read to find your last one per manga. This can mean 5,000–10,000+ API calls for a large library, which is why Fast mode exists.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Output Files
|
|
156
|
+
|
|
157
|
+
For each status group (reading, completed, etc.) the app creates:
|
|
158
|
+
|
|
159
|
+
| File | Description |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `mdex_{status}_{timestamp}.xlsx` | Raw export data — used by Convert tab |
|
|
162
|
+
| `mdex_{status}_{timestamp}.json` | Full JSON backup — used by Import tab |
|
|
163
|
+
| `mal_{status}_{timestamp}.xml` | MAL import file |
|
|
164
|
+
| `mal_{status}_{timestamp}.xml.gz` | Compressed version (also accepted by MAL) |
|
|
165
|
+
| `anilist_{status}_{timestamp}.xml` | AniList import file |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Resume
|
|
170
|
+
|
|
171
|
+
If the export is interrupted (crash, network error, you stopped it), the app saves a checkpoint after each completed status group. Click **▶ Resume** on the Export tab to continue from where it left off.
|
|
172
|
+
|
|
173
|
+
To start fresh, go to **Settings → Clear Checkpoint**.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Troubleshooting
|
|
178
|
+
|
|
179
|
+
**"Authentication failed"**
|
|
180
|
+
- Double-check your Client ID, Client Secret, username, and password
|
|
181
|
+
- Make sure your API client is set to **Personal** type and is **approved** on MangaDex
|
|
182
|
+
- Try the **✓ Test Credentials** button first
|
|
183
|
+
|
|
184
|
+
**"Failed to set status" during import**
|
|
185
|
+
- Make sure your API client exists and is approved at [mangadex.org/settings](https://mangadex.org/settings)
|
|
186
|
+
- Check that your credentials are correct
|
|
187
|
+
|
|
188
|
+
**Native window doesn't open**
|
|
189
|
+
- The app will fall back to your browser automatically with instructions on how to fix it
|
|
190
|
+
- On Linux you may need to install a GTK system package — the app will tell you the exact command for your distro
|
|
191
|
+
|
|
192
|
+
**Manga missing from MAL after import**
|
|
193
|
+
- Those titles are listed in the **Skipped Manga** section — they have no MAL ID on MangaDex
|
|
194
|
+
- Add them manually on MAL
|
|
195
|
+
|
|
196
|
+
**Slow export speed**
|
|
197
|
+
- The API enforces rate limits — the app already waits the minimum required between requests
|
|
198
|
+
- Deep mode is inherently slow for large libraries — use Fast mode if chapter progress isn't critical
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Dependencies
|
|
203
|
+
|
|
204
|
+
| Package | Purpose |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `flask` | Local web server |
|
|
207
|
+
| `requests` | MangaDex API calls |
|
|
208
|
+
| `pandas` | Excel file read/write |
|
|
209
|
+
| `openpyxl` | Excel engine for pandas |
|
|
210
|
+
| `pywebview` | Native desktop window |
|
|
211
|
+
| `PyQt6` + `PyQt6-WebEngine` | Qt backend for pywebview |
|
|
212
|
+
| `qtpy` | Qt abstraction layer |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Credits
|
|
217
|
+
|
|
218
|
+
Based on the original export scripts by [Seriousattempts](https://github.com/Seriousattempts/MangaDex). Rewritten and extended with a web UI, Fast/Deep mode, import support, resume, score export, and AniList output.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# MangaDex Sync
|
|
2
|
+
|
|
3
|
+
Export **and import** your MangaDex library to/from **MyAnimeList** and **AniList** — with scores, statuses, and optional chapter progress — all from a single clean app.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Single app** — Export, Import, and Convert in one place, no switching between scripts
|
|
16
|
+
- **Import** — Restore your library from a MangaDex JSON backup or a MAL/AniList XML file
|
|
17
|
+
- **Fast mode** — Exports titles + status in minutes (recommended)
|
|
18
|
+
- **Deep mode** — Also fetches your last read chapter per manga (slower)
|
|
19
|
+
- **MAL XML** — Ready to import at `myanimelist.net/import.php` (includes `.gz`)
|
|
20
|
+
- **AniList XML** — Same format, ready to import at AniList
|
|
21
|
+
- **JSON backup** — Full local backup of your library data
|
|
22
|
+
- **Scores** — Fetches your MangaDex ratings and carries them over
|
|
23
|
+
- **Resume** — Saves a checkpoint so it can pick up if interrupted
|
|
24
|
+
- **Skipped list** — Shows exactly which manga had no MAL ID
|
|
25
|
+
- **Export history** — Logs every export with timestamp and file list
|
|
26
|
+
- **Dry run mode** — Simulate without writing any files
|
|
27
|
+
- **Native window** — Opens as a desktop app via pywebview (or falls back to browser)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Requirements
|
|
32
|
+
|
|
33
|
+
- Python 3.10 or newer
|
|
34
|
+
- A MangaDex account
|
|
35
|
+
- A [MangaDex API Personal Client](https://mangadex.org/settings) (free to create)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install mangadex-sync
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Everything including the native desktop window is included — no extra steps needed.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
mangadex-sync
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This opens a native desktop window. You can also open `http://localhost:7337` in any browser — useful for accessing it from another device on the same network.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Step-by-step Guide
|
|
60
|
+
|
|
61
|
+
### 1. Get your MangaDex API credentials
|
|
62
|
+
|
|
63
|
+
1. Go to [mangadex.org/settings](https://mangadex.org/settings)
|
|
64
|
+
2. Scroll to **API Clients** → click **Create**
|
|
65
|
+
3. Give it any name, set type to **Personal**
|
|
66
|
+
4. Copy your **Client ID** and **Client Secret**
|
|
67
|
+
|
|
68
|
+
### 2. Export your library
|
|
69
|
+
|
|
70
|
+
1. Open the app and go to the **Export** tab
|
|
71
|
+
2. Fill in:
|
|
72
|
+
- **Client ID** and **Client Secret** (from step 1)
|
|
73
|
+
- **Username** and **Password** (your MangaDex login)
|
|
74
|
+
- **Save folder** — where to save the output files
|
|
75
|
+
3. Choose **Fast** or **Deep** mode (Fast is recommended)
|
|
76
|
+
4. Click **⚡ Extract Entire Library**
|
|
77
|
+
|
|
78
|
+
> **MAL User ID and MAL Username are optional.** You do not need to fill them in to generate a working XML file. MAL identifies you by your login session when you upload — the ID and username fields in the XML header are just metadata and are ignored during import. Leave them blank if you don't know them.
|
|
79
|
+
|
|
80
|
+
### 3. Convert to XML
|
|
81
|
+
|
|
82
|
+
After export finishes, the **Convert** tab auto-fills with your exported files. Just:
|
|
83
|
+
|
|
84
|
+
1. Click **⚡ Generate XML Files**
|
|
85
|
+
2. Files are saved to your chosen folder
|
|
86
|
+
|
|
87
|
+
### 4. Import to MAL / AniList
|
|
88
|
+
|
|
89
|
+
- **MAL:** Go to [myanimelist.net/import.php](https://myanimelist.net/import.php) and upload the `mal_*.xml` file
|
|
90
|
+
- **AniList:** Go to [anilist.co/settings/import](https://anilist.co/settings/import) and upload the `anilist_*.xml` file
|
|
91
|
+
|
|
92
|
+
### 5. Import back to MangaDex
|
|
93
|
+
|
|
94
|
+
Use the **Import** tab to restore your library from:
|
|
95
|
+
- A `mdex_*.json` backup file (exported by this app)
|
|
96
|
+
- A MAL XML file (`mal_*.xml`)
|
|
97
|
+
- An AniList XML file (`anilist_*.xml`)
|
|
98
|
+
|
|
99
|
+
1. Browse or paste the path to your file
|
|
100
|
+
2. Optionally enable **Import Scores** to restore your ratings
|
|
101
|
+
3. Click **Start Import**
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Fast vs Deep Mode
|
|
106
|
+
|
|
107
|
+
| | Fast | Deep |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| Speed | ⚡ Minutes | 🐢 15–60+ min |
|
|
110
|
+
| Titles & status | ✓ | ✓ |
|
|
111
|
+
| Ratings/scores | ✓ | ✓ |
|
|
112
|
+
| Last read chapter | ✗ | ✓ |
|
|
113
|
+
| Recommended | ✓ | Only if you need progress |
|
|
114
|
+
|
|
115
|
+
Deep mode fetches every individual chapter you've ever read to find your last one per manga. This can mean 5,000–10,000+ API calls for a large library, which is why Fast mode exists.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Output Files
|
|
120
|
+
|
|
121
|
+
For each status group (reading, completed, etc.) the app creates:
|
|
122
|
+
|
|
123
|
+
| File | Description |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `mdex_{status}_{timestamp}.xlsx` | Raw export data — used by Convert tab |
|
|
126
|
+
| `mdex_{status}_{timestamp}.json` | Full JSON backup — used by Import tab |
|
|
127
|
+
| `mal_{status}_{timestamp}.xml` | MAL import file |
|
|
128
|
+
| `mal_{status}_{timestamp}.xml.gz` | Compressed version (also accepted by MAL) |
|
|
129
|
+
| `anilist_{status}_{timestamp}.xml` | AniList import file |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Resume
|
|
134
|
+
|
|
135
|
+
If the export is interrupted (crash, network error, you stopped it), the app saves a checkpoint after each completed status group. Click **▶ Resume** on the Export tab to continue from where it left off.
|
|
136
|
+
|
|
137
|
+
To start fresh, go to **Settings → Clear Checkpoint**.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Troubleshooting
|
|
142
|
+
|
|
143
|
+
**"Authentication failed"**
|
|
144
|
+
- Double-check your Client ID, Client Secret, username, and password
|
|
145
|
+
- Make sure your API client is set to **Personal** type and is **approved** on MangaDex
|
|
146
|
+
- Try the **✓ Test Credentials** button first
|
|
147
|
+
|
|
148
|
+
**"Failed to set status" during import**
|
|
149
|
+
- Make sure your API client exists and is approved at [mangadex.org/settings](https://mangadex.org/settings)
|
|
150
|
+
- Check that your credentials are correct
|
|
151
|
+
|
|
152
|
+
**Native window doesn't open**
|
|
153
|
+
- The app will fall back to your browser automatically with instructions on how to fix it
|
|
154
|
+
- On Linux you may need to install a GTK system package — the app will tell you the exact command for your distro
|
|
155
|
+
|
|
156
|
+
**Manga missing from MAL after import**
|
|
157
|
+
- Those titles are listed in the **Skipped Manga** section — they have no MAL ID on MangaDex
|
|
158
|
+
- Add them manually on MAL
|
|
159
|
+
|
|
160
|
+
**Slow export speed**
|
|
161
|
+
- The API enforces rate limits — the app already waits the minimum required between requests
|
|
162
|
+
- Deep mode is inherently slow for large libraries — use Fast mode if chapter progress isn't critical
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Dependencies
|
|
167
|
+
|
|
168
|
+
| Package | Purpose |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `flask` | Local web server |
|
|
171
|
+
| `requests` | MangaDex API calls |
|
|
172
|
+
| `pandas` | Excel file read/write |
|
|
173
|
+
| `openpyxl` | Excel engine for pandas |
|
|
174
|
+
| `pywebview` | Native desktop window |
|
|
175
|
+
| `PyQt6` + `PyQt6-WebEngine` | Qt backend for pywebview |
|
|
176
|
+
| `qtpy` | Qt abstraction layer |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Credits
|
|
181
|
+
|
|
182
|
+
Based on the original export scripts by [Seriousattempts](https://github.com/Seriousattempts/MangaDex). Rewritten and extended with a web UI, Fast/Deep mode, import support, resume, score export, and AniList output.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MangaDex Sync
|
|
3
|
+
Export and import your MangaDex library to/from MyAnimeList and AniList.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "2.0.1"
|
|
7
|
+
__author__ = "Spider2742"
|
|
8
|
+
|
|
9
|
+
from .app import app # noqa: F401
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _webview_fix_hint():
|
|
13
|
+
"""Return a distro/OS-aware fix message for missing pywebview GUI backends."""
|
|
14
|
+
import platform
|
|
15
|
+
|
|
16
|
+
system = platform.system()
|
|
17
|
+
|
|
18
|
+
if system == "Windows":
|
|
19
|
+
return (
|
|
20
|
+
" On Windows, install Qt support:\n"
|
|
21
|
+
" pip install PyQt6 qtpy\n"
|
|
22
|
+
" Or reinstall pywebview:\n"
|
|
23
|
+
" pip install --upgrade pywebview"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if system == "Darwin":
|
|
27
|
+
return (
|
|
28
|
+
" On macOS, pywebview uses WebKit which should work out of the box.\n"
|
|
29
|
+
" Try upgrading pywebview:\n"
|
|
30
|
+
" pip install --upgrade pywebview\n"
|
|
31
|
+
" If that doesn't help, install Qt as a fallback:\n"
|
|
32
|
+
" brew install pyqt (requires Homebrew: brew.sh)\n"
|
|
33
|
+
" pip install PyQt6 qtpy"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
if system == "Linux":
|
|
37
|
+
distro_id = ""
|
|
38
|
+
distro_like = ""
|
|
39
|
+
try:
|
|
40
|
+
info = platform.freedesktop_os_release() # Python 3.10+
|
|
41
|
+
distro_id = info.get("ID", "").lower()
|
|
42
|
+
distro_like = info.get("ID_LIKE", "").lower()
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
combined = f"{distro_id} {distro_like}"
|
|
47
|
+
is_debian = any(x in combined for x in ("debian", "ubuntu", "mint", "pop", "elementary", "kali", "zorin", "raspbian"))
|
|
48
|
+
is_fedora = any(x in combined for x in ("fedora", "rhel", "centos", "rocky", "alma", "nobara"))
|
|
49
|
+
is_arch = any(x in combined for x in ("arch", "manjaro", "endeavour", "garuda", "artix"))
|
|
50
|
+
is_suse = any(x in combined for x in ("suse", "opensuse"))
|
|
51
|
+
is_void = "void" in combined
|
|
52
|
+
|
|
53
|
+
if is_debian:
|
|
54
|
+
gtk_hint = " sudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-webkit2-4.0"
|
|
55
|
+
elif is_fedora:
|
|
56
|
+
gtk_hint = " sudo dnf install python3-gobject python3-gobject-base webkit2gtk4.1"
|
|
57
|
+
elif is_arch:
|
|
58
|
+
gtk_hint = " sudo pacman -S python-gobject webkit2gtk-4.1"
|
|
59
|
+
elif is_suse:
|
|
60
|
+
gtk_hint = " sudo zypper install python3-gobject python3-gobject-Gdk typelib-1_0-WebKit2-4_1"
|
|
61
|
+
elif is_void:
|
|
62
|
+
gtk_hint = " sudo xbps-install python3-gobject webkit2gtk"
|
|
63
|
+
else:
|
|
64
|
+
gtk_hint = " Install python3-gobject and webkit2gtk via your package manager"
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
f" Fix with GTK (recommended):\n"
|
|
68
|
+
f"{gtk_hint}\n\n"
|
|
69
|
+
f" Or use Qt instead:\n"
|
|
70
|
+
f" pip install PyQt6 qtpy"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
" Try installing Qt support:\n"
|
|
75
|
+
" pip install PyQt6 qtpy\n"
|
|
76
|
+
" Or GTK via your system package manager (python3-gobject + webkit2gtk)"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def main():
|
|
81
|
+
"""CLI entry point: runs the Flask app with optional pywebview."""
|
|
82
|
+
import sys
|
|
83
|
+
import time
|
|
84
|
+
import webbrowser
|
|
85
|
+
import threading
|
|
86
|
+
import requests as req_lib
|
|
87
|
+
|
|
88
|
+
missing = []
|
|
89
|
+
for pkg in ["requests", "pandas", "openpyxl", "flask"]:
|
|
90
|
+
try:
|
|
91
|
+
__import__(pkg)
|
|
92
|
+
except ImportError:
|
|
93
|
+
missing.append(pkg)
|
|
94
|
+
if missing:
|
|
95
|
+
print(f"Missing packages. Run: pip install {' '.join(missing)}")
|
|
96
|
+
sys.exit(1)
|
|
97
|
+
|
|
98
|
+
PORT = 7337
|
|
99
|
+
|
|
100
|
+
flask_thread = threading.Thread(
|
|
101
|
+
target=lambda: app.run(host="127.0.0.1", port=PORT, debug=False, threaded=True),
|
|
102
|
+
daemon=True,
|
|
103
|
+
)
|
|
104
|
+
flask_thread.start()
|
|
105
|
+
|
|
106
|
+
for _ in range(20):
|
|
107
|
+
try:
|
|
108
|
+
req_lib.get(f"http://127.0.0.1:{PORT}/", timeout=1)
|
|
109
|
+
break
|
|
110
|
+
except Exception:
|
|
111
|
+
time.sleep(0.3)
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
import webview
|
|
115
|
+
|
|
116
|
+
print(f"\n MangaDex Sync v{__version__}")
|
|
117
|
+
print(f" Opening native window...")
|
|
118
|
+
print(f" (Also accessible at http://localhost:{PORT})\n")
|
|
119
|
+
webview.create_window(
|
|
120
|
+
title=f"MangaDex Sync v{__version__}",
|
|
121
|
+
url=f"http://127.0.0.1:{PORT}",
|
|
122
|
+
width=1200,
|
|
123
|
+
height=800,
|
|
124
|
+
min_size=(900, 600),
|
|
125
|
+
background_color="#0c0e14",
|
|
126
|
+
)
|
|
127
|
+
import os, sys
|
|
128
|
+
with open(os.devnull, 'w') as devnull:
|
|
129
|
+
old_stderr = sys.stderr
|
|
130
|
+
sys.stderr = devnull
|
|
131
|
+
try:
|
|
132
|
+
webview.start()
|
|
133
|
+
finally:
|
|
134
|
+
sys.stderr = old_stderr
|
|
135
|
+
|
|
136
|
+
except ImportError:
|
|
137
|
+
print(f"\n pywebview not installed - opening in browser instead.")
|
|
138
|
+
print(f" To get the native window: pip install 'mangadex-sync[desktop]'\n")
|
|
139
|
+
print(f" MangaDex Sync v{__version__}")
|
|
140
|
+
print(f" Open in browser: http://localhost:{PORT}\n")
|
|
141
|
+
webbrowser.open(f"http://localhost:{PORT}")
|
|
142
|
+
try:
|
|
143
|
+
while True:
|
|
144
|
+
time.sleep(1)
|
|
145
|
+
except KeyboardInterrupt:
|
|
146
|
+
print("\nShutting down.")
|
|
147
|
+
|
|
148
|
+
except Exception:
|
|
149
|
+
print(f"\n pywebview is installed but couldn't find a GUI backend.")
|
|
150
|
+
print(f"\n{_webview_fix_hint()}")
|
|
151
|
+
print(f"\n Falling back to browser...")
|
|
152
|
+
print(f" Open in browser: http://localhost:{PORT}\n")
|
|
153
|
+
webbrowser.open(f"http://localhost:{PORT}")
|
|
154
|
+
try:
|
|
155
|
+
while True:
|
|
156
|
+
time.sleep(1)
|
|
157
|
+
except KeyboardInterrupt:
|
|
158
|
+
print("\nShutting down.")
|