Add support for marvel unlimited

This commit is contained in:
Joakim Holm 2023-05-14 17:35:25 +02:00
parent f257898681
commit ada2005c2e
4 changed files with 32 additions and 4 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ MANIFEST
# Installer logs # Installer logs
pip-log.txt pip-log.txt
pip-delete-this-directory.txt pip-delete-this-directory.txt
cookies.txt

View File

@ -10,6 +10,7 @@ grawlix currently supports downloading from the following sources:
- [eReolen](https://ereolen.dk) - [eReolen](https://ereolen.dk)
- [Flipp](https://flipp.dk) - [Flipp](https://flipp.dk)
- [Manga Plus](https://mangaplus.shueisha.co.jp) - [Manga Plus](https://mangaplus.shueisha.co.jp)
- [Marvel Unlimited](https://marvel.com)
- [Royal Road](https://www.royalroad.com) - [Royal Road](https://www.royalroad.com)
- [Saxo](https://saxo.com) - [Saxo](https://saxo.com)
- [Webtoons](https://webtoons.com) - [Webtoons](https://webtoons.com)

View File

@ -4,6 +4,7 @@ from .source import Source
from .ereolen import Ereolen from .ereolen import Ereolen
from .flipp import Flipp from .flipp import Flipp
from .mangaplus import MangaPlus from .mangaplus import MangaPlus
from .marvel import Marvel
from .royal_road import RoyalRoad from .royal_road import RoyalRoad
from .saxo import Saxo from .saxo import Saxo
from .webtoons import Webtoons from .webtoons import Webtoons
@ -54,6 +55,7 @@ def get_source_classes() -> list[type[Source]]:
Ereolen, Ereolen,
Flipp, Flipp,
MangaPlus, MangaPlus,
Marvel,
RoyalRoad, RoyalRoad,
Saxo, Saxo,
Webtoons Webtoons

View File

@ -1,14 +1,18 @@
from grawlix.book import Book, Metadata, ImageList, OnlineFile, Series, Result from grawlix.book import Book, Metadata, ImageList, OnlineFile, Series, Result
from grawlix.exceptions import InvalidUrl from grawlix.exceptions import InvalidUrl, DataNotFound
from .source import Source from .source import Source
import re
# Personal marvel ip key # Personal marvel ip key
API_KEY = "83ac0da31d3f6801f2c73c7e07ad76e8" API_KEY = "83ac0da31d3f6801f2c73c7e07ad76e8"
class Marvel(Source[str]): class Marvel(Source[str]):
name: str = "Marvel" name: str = "Marvel"
match = [ match = [
r"https://www.marvel.com/comics/issue/\d+/.+",
r"https://read.marvel.com/#/book/\d+",
r"https://www.marvel.com/comics/series/\d+/.+" r"https://www.marvel.com/comics/series/\d+/.+"
] ]
_authentication_methods: list[str] = [ "cookies" ] _authentication_methods: list[str] = [ "cookies" ]
@ -17,6 +21,12 @@ class Marvel(Source[str]):
async def download(self, url: str) -> Result[str]: async def download(self, url: str) -> Result[str]:
match_index = self.get_match_index(url) match_index = self.get_match_index(url)
if match_index == 0: if match_index == 0:
issue_id = await self._get_issue_id(url)
return await self.download_book_from_id(issue_id)
if match_index == 1:
issue_id = url.split("/")[-1]
return await self.download_book_from_id(issue_id)
if match_index == 2:
return await self._download_series(url) return await self._download_series(url)
raise InvalidUrl raise InvalidUrl
@ -44,10 +54,10 @@ class Marvel(Source[str]):
:param series_id: Id of comic series on marvel.com :param series_id: Id of comic series on marvel.com
:returns: List of comic ids for marvel comics :returns: List of comic ids for marvel comics
""" """
response = self._client.get( response = await self._client.get(
f"https://api.marvel.com/browse/comics?byType=comic_series&isDigital=1&limit=10000&byId={series_id}", f"https://api.marvel.com/browse/comics?byType=comic_series&isDigital=1&limit=10000&byId={series_id}",
).json() )
issue_ids = [issue["digital_id"] for issue in response["data"]["results"]] issue_ids = [issue["digital_id"] for issue in response.json()["data"]["results"]]
return issue_ids return issue_ids
@ -66,6 +76,20 @@ class Marvel(Source[str]):
) )
return response.json() return response.json()
async def _get_issue_id(self, url: str) -> str:
"""
Download issue id from url
:param url: Url to issue info page
:return: Issue id
"""
response = await self._client.get(url)
search = re.search(r"digital_comic_id: \"(\d+)\"", response.text)
if not search:
raise DataNotFound
return search.group(1)
async def download_book_from_id(self, issue_id: str) -> Book: async def download_book_from_id(self, issue_id: str) -> Book:
return Book( return Book(