Skip to content

Commit

Permalink
feat(New Site Supported): ✨ Manganato.com
Browse files Browse the repository at this point in the history
  • Loading branch information
thezak48 committed Feb 26, 2024
1 parent cb3bbf5 commit 7341d9a
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 3 deletions.
10 changes: 7 additions & 3 deletions manga_dl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Usage:
python manga_dl.py manga [options] save_location
"""

import argparse
import concurrent.futures
import os
Expand All @@ -23,6 +24,7 @@
from manga_dl.utilities.sites.madraOld import MadraOld
from manga_dl.utilities.sites.mangadex import Mangadex
from manga_dl.utilities.sites.mangakakalot import Mangakakalot
from manga_dl.utilities.sites.manganato import Manganato
from manga_dl.utilities.sites.webtoons import Webtoons


Expand Down Expand Up @@ -88,6 +90,8 @@ def get_website_class(url: str):
return Mangakakalot(log)
elif "mangadex.org" in url:
return Mangadex(log)
elif "manganato.com" in url or "chapmanganato.to" in url:
return Manganato(log)
else:
raise ValueError(f"Unsupported website: {url}")

Expand Down Expand Up @@ -234,9 +238,9 @@ def calc_next_run(schd, write_out=False):
f"{minutes} Minute{'s' if minutes > 1 else ''}" if minutes > 0 else ""
)
if write_out:
next_run[
"next_run_str"
] = f"Current Time: {current} | {time_until} until the next run at {time_to_run_str}"
next_run["next_run_str"] = (
f"Current Time: {current} | {time_until} until the next run at {time_to_run_str}"
)
else:
next_run["next_run"] = None
next_run["next_run_str"] = ""
Expand Down
177 changes: 177 additions & 0 deletions manga_dl/utilities/sites/manganato.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
"""
This module defines the Manganato class for interacting with the website manganato.com.
The Manganato class provides methods to fetch manga IDs, chapters, images,
and metadata from manganato.com, and to download manga images and save them as .cbz files.
Classes:
Manganato: A class to interact with the website manganato.com.
"""

import re

import requests
from bs4 import BeautifulSoup


class Manganato:
"""
A class to interact with the website manganato.com.
This class provides methods to fetch manga IDs, chapters, images,
and metadata from manganato.com, and to download manga images and save them as .cbz files.
Attributes:
logger: An instance of log.Logger for log.
"""

base_headers = {
"authority": "manganato.com",
"accept-language": "en-US,en;q=0.9,es-US;q=0.8,es;q=0.7,en-GB-oxendict;q=0.6",
"cache-control": "no-cache",
"pragma": "no-cache",
"sec-ch-ua": '"Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-site": "none",
"user-agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"
),
}

headers_image = base_headers.copy()
headers_image.update(
{
"accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
"referer": "https://manganato.com/",
"sec-fetch-dest": "image",
"sec-fetch-mode": "no-cors",
"sec-fetch-site": "same-site",
}
)

def __init__(self, logger):
self.logger = logger

def get_manga_title(self, manga_url):
"""
Get the manga ID for a given manga name.
"""
try:
self.logger.info(f"Fetching manga title for {manga_url}")
result = requests.get(manga_url, headers=self.base_headers, timeout=30)

if result.status_code == 200:
soup = BeautifulSoup(result.text, "html.parser")
node = soup.find("div", {"class": "story-info-right"})
title = node.h1

return title.text.lstrip().rstrip()

except Exception as e:
self.logger.error("unable to find the manga title needed")
self.logger.error(e)

return None

def get_manga_chapters(self, manga_id: str):
"""
Get the manga chapters for a given manga ID.
"""
try:
self.logger.info(f"Fetching manga chapters for {manga_id}")
title = self.get_manga_title(manga_id)
result = requests.get(
url=f"{manga_id}",
headers=self.base_headers,
timeout=30,
)

if result.status_code == 200:
soup = BeautifulSoup(result.text, "html.parser")
chapter_list = soup.find("ul", {"class": "row-content-chapter"})
if chapter_list is not None:
rows = chapter_list.find_all("li", {"class": "a-h"})
chapters = []
for row in rows:
try:
url = row.find("a")["href"]
chapter_number_raw = url.split("/chapter-")[-1]
number_parts = re.findall(
r"\d+\.\d+|\d+", chapter_number_raw
)
if "." in number_parts[0]:
chapter_number = float(number_parts[0])
else:
chapter_number = int(float(number_parts[0]))
chapters.append((chapter_number, url))

except TypeError:
continue

chapters.sort(key=lambda x: x[0])

return chapters, title

except Exception as e:
self.logger.error("unable to find the manga chapters needed")
self.logger.error(e)
return None

def get_chapter_images(self, chapter_url):
"""
Get the manga chapter images for a given chapter URL.
"""
try:
self.logger.info("Getting chapter images")
result = requests.get(
chapter_url,
headers=self.base_headers,
timeout=30,
)

if result.status_code == 200:
soup = BeautifulSoup(result.text, "html.parser")
node = soup.find("div", {"class": "container-chapter-reader"})
image_nodes = node.find_all("img")
images = []
for image_node in image_nodes:
images.append(image_node["src"].lstrip().rstrip())

return images

except Exception as e:
self.logger.error("unable to find the manga chapter images needed")
self.logger.error(e)

return None

def get_manga_metadata(self, manga_url):
"""
Get the manga metadata for a given manga name.
"""
try:
self.logger.info("Getting manga metadata")
result = requests.get(manga_url, headers=self.base_headers, timeout=30)

if result.status_code == 200:
soup = BeautifulSoup(result.text, "html.parser")

genres = []

summary_content = soup.find(
"div", {"class": "panel-story-info-description"}
)
summary = summary_content.text

return genres, summary

except Exception as e:
self.logger.error(f"Unable to find the manga metadata on {manga_url}")
self.logger.error(e)

genres = []
summary = []

return genres, summary

0 comments on commit 7341d9a

Please sign in to comment.