Skip to content

Commit

Permalink
Added ability to add volume cover (for volume formats) and chapter in…
Browse files Browse the repository at this point in the history
…fo (cover) and bunch other stuffs

- Changed every name {format.upper}FileExt to {format.upper}File (ex: CBZFileExt -> CBZFile)
- Fixed url repository is not displayed properly
- Now, getting cover url can be retrieved from "get_cover_art_url" function (from module "mangadex_downloader.utils"). Instead of "mangadex_downloader.manga.Manga.cover_art")
- "volume" property from "mangadex_downloader.cover.CoverArt" are now returning same type data value from "mangadex_downloader.chapter.Chapter.volume"
  • Loading branch information
mansuf committed Jan 31, 2023
1 parent 690b95a commit e3f6ac0
Show file tree
Hide file tree
Showing 17 changed files with 355 additions and 225 deletions.
1 change: 1 addition & 0 deletions mangadex_downloader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
__author_email__ = "danipart4@gmail.com"
__license__ = "MIT"
__repository__ = "mansuf/mangadex-downloader"
__url_repository__ = "https://github.com"

import logging

Expand Down
27 changes: 23 additions & 4 deletions mangadex_downloader/cli/args_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,11 @@ def get_args(argv):
'--no-chapter-info',
'-nci',
action='store_true',
help='Disable creation of chapter info for any `single` and `volume` formats. ' \
"NOTE: `epub-volume` and `epub-single` formats is not affected, " \
"because creation of chapter info is totally disabled for any `epub` formats",
default=config.no_chapter_info
help="[Deprecated] Use --use-chapter-cover to enable creation of chapter info. " \
"Previously, this option is used to disable creation of chapter info. " \
"Because it was automatically enabled when you downloading with any single or volume formats. " \
"Now, by default it was disabled. You must use --use-chapter-cover to enable " \
"creation of chapter info."
)
chap_group.add_argument(
'--range',
Expand All @@ -241,6 +242,24 @@ def get_args(argv):
'--sort-by',
help='Download sorting method, by default it\'s selected to "volume"',
default=config.sort_by
),
chap_group.add_argument(
"--use-chapter-cover",
"-ucc",
action="store_true",
help="Enable creation of chapter info (cover) for any single or volume formats. " \
"See https://mangadex-dl.mansuf.link/en/stable/cli_ref/chapter_info.html for more info. " \
"NOTE: chapter info creation are not enabled if you are using any chapter format (cbz, pdf, raw, etc)",
default=config.use_chapter_cover
)
chap_group.add_argument(
"--use-volume-cover",
"-uvc",
action="store_true",
help="Enable creation of volume cover for any volume formats. " \
"Volume cover will be placed in first page in each volume files. " \
"NOTE: Volume cover will be not created in chapter (cbz, pdf, raw, etc) and single formats)",
default=config.use_volume_cover
)

# Chapter page related
Expand Down
4 changes: 2 additions & 2 deletions mangadex_downloader/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import signal
import sys

from .. import __version__, __repository__
from .. import __version__, __repository__, __url_repository__
from ..update import architecture, executable
from ..network import Net
from ..downloader import _cleanup_jobs
Expand Down Expand Up @@ -203,7 +203,7 @@ def previous(self):
def print_version_info():
bundled_executable = 'yes' if executable else 'no'

print(f"mangadex-downloader v{__version__} (https://github.com/{__repository__})")
print(f"mangadex-downloader v{__version__} ({__url_repository__}/{__repository__})")
print("Python: {0[0]}.{0[1]}.{0[2]}".format(sys.version_info))
print(f"arch: {architecture}")
print(f"bundled executable: {bundled_executable}")
Expand Down
12 changes: 8 additions & 4 deletions mangadex_downloader/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ class _Config:
None,
lambda x: validate_value_from_iterator(x, _doh_providers)
],
"no_chapter_info": [
False,
validate_bool
],
"no_group_name": [
False,
validate_bool
Expand All @@ -110,6 +106,14 @@ class _Config:
"download_mode": [
"default",
validate_download_mode
],
"use_chapter_cover": [
False,
validate_bool
],
"use_volume_cover": [
False,
validate_bool
]
}
default_conf = {
Expand Down
43 changes: 30 additions & 13 deletions mangadex_downloader/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,51 @@

from .fetcher import get_cover_art
from .language import get_language
from .utils import convert_int_or_float

valid_cover_types = [
'original',
'512px',
'256px',
'none'
"original",
"512px",
"256px",
"none"
]

default_cover_type = "original"

class CoverArt:
def __init__(self, cover_id=None, data=None):
if not data:
self.data = get_cover_art(cover_id)['data']
self.data = get_cover_art(cover_id)["data"]
else:
self.data = data

self.id = self.data['id']
attr = self.data['attributes']
self.id = self.data["id"]
attr = self.data["attributes"]

# Description
self.description = attr['description']

# Volume
self.volume = attr['volume']
self.description = attr["description"]

# File cover
self.file = attr['fileName']
self.file = attr["fileName"]

# Locale
self.locale = get_language(attr['locale'])
self.locale = get_language(attr["locale"])

@property
def volume(self):
vol = self.data["attributes"]["volume"]
if vol is not None:
# As far as i know
# Volume manga are integer numbers, not float
try:
return convert_int_or_float(vol)
except ValueError:
pass

# Weird af volume name
# Example: https://api.mangadex.org/manga/485a777b-e395-4ab1-b262-2a87f53e23c0/aggregate
# (Take a look volume "3Cxx")
return vol

# No volume
return vol
22 changes: 17 additions & 5 deletions mangadex_downloader/format/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ def __init__(
self.manga = manga
self.compress_img = config.use_compressed_image
self.replace = replace
self.no_chapter_info = config.no_chapter_info
self.kwargs_iter = kwargs_iter_chapter_img

self.chapter_read_marker = QueueWorkerReadMarker(manga.id)
Expand Down Expand Up @@ -172,10 +171,6 @@ def get_fmt_single_cache(self, manga):
kwargs_iter = self.kwargs_iter.copy()
kwargs_iter['log_cache'] = True
for chap_class, chap_images in manga.chapters.iter(**self.kwargs_iter):
# Fix #10
# Some programs wouldn't display images correctly
total += 1

total += chap_class.pages

item = [chap_class, chap_images]
Expand All @@ -184,10 +179,27 @@ def get_fmt_single_cache(self, manga):
if not cache:
return None

if self.config.use_chapter_cover:
total += len(cache)

name = "All chapters"

return cache, total, name

def get_total_pages_for_volume_fmt(self, chapters):
total = 0

if self.config.use_volume_cover:
total += 1

if self.config.use_chapter_cover:
total += len(chapters)

for chap_class, _ in chapters:
total += chap_class.pages

return total

def get_fmt_volume_cache(self, manga):
"""Get all cached volumes"""
# Sorting volumes
Expand Down
98 changes: 46 additions & 52 deletions mangadex_downloader/format/comic_book.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
from .utils import (
get_chapter_info,
NumberWithLeadingZeros,
verify_sha256
verify_sha256,
get_volume_cover
)
from ..utils import create_directory, delete_file

Expand Down Expand Up @@ -102,7 +103,7 @@ def generate_Comicinfo(manga, chapter):

return xml_root

class CBZFileExt:
class CBZFile:
file_ext = ".cbz"

def convert(self, zip_obj, images):
Expand Down Expand Up @@ -134,7 +135,41 @@ def make_zip(self, path):
compresslevel=env.zip_compression_level
)

class ComicBookArchive(ConvertedChaptersFormat, CBZFileExt):
def insert_ch_info_img(self, zip_obj, worker, chapter, count, path):
img_name = count.get() + '.png'
img_path = path / img_name

# Make sure we never duplicated it
write_ch_info_image = False
try:
zip_obj.getinfo(img_name)
except KeyError:
write_ch_info_image = self.config.use_chapter_cover

# Insert chapter info (cover) image
if write_ch_info_image:
get_chapter_info(chapter, img_path, self.replace)
worker.submit(lambda: zip_obj.write(img_path, img_name))
count.increase()

def insert_vol_cover_img(self, zip_obj, worker, volume, count, path):
# Insert volume cover
# Make sure we never duplicate it
img_name = count.get() + ".png"
img_path = path / img_name

write_vol_cover = False
try:
zip_obj.getinfo(img_name)
except KeyError:
write_vol_cover = self.config.use_volume_cover

if write_vol_cover:
get_volume_cover(self.manga, volume, img_path, self.replace)
worker.submit(lambda: zip_obj.write(img_path, img_name))
count.increase()

class ComicBookArchive(ConvertedChaptersFormat, CBZFile):
def download_chapters(self, worker, chapters):
manga = self.manga

Expand Down Expand Up @@ -182,21 +217,14 @@ def download_chapters(self, worker, chapters):

self.add_fi(chap_name, chap_class.id, chapter_zip_path)

class ComicBookArchiveVolume(ConvertedVolumesFormat, CBZFileExt):
class ComicBookArchiveVolume(ConvertedVolumesFormat, CBZFile):
def download_volumes(self, worker, volumes):
# Begin downloading
for volume, chapters in volumes.items():
num = 0
total = self.get_total_pages_for_volume_fmt(chapters)
images = []

for chap_class, _ in chapters:
# Each chapters has one page that has "Chapter n"
# This is called "start of the chapter" image
num += 1

num += chap_class.pages

count = NumberWithLeadingZeros(num)
count = NumberWithLeadingZeros(total)

volume_name = self.get_volume_name(volume)

Expand All @@ -219,26 +247,10 @@ def download_volumes(self, worker, volumes):

volume_zip = self.make_zip(volume_zip_path)

for chap_class, chap_images in chapters:
img_name = count.get() + '.png'
img_path = volume_path / img_name

# Make sure we never duplicated it
write_start_image = False
try:
volume_zip.getinfo(img_name)
except KeyError:
write_start_image = True
self.insert_vol_cover_img(volume_zip, worker, volume, count, volume_path)

if self.no_chapter_info:
write_start_image = False

# Insert "start of the chapter" image
if write_start_image:
get_chapter_info(chap_class, img_path, self.replace)
worker.submit(lambda: volume_zip.write(img_path, img_name))

count.increase()
for chap_class, chap_images in chapters:
self.insert_ch_info_img(volume_zip, worker, chap_class, count, volume_path)

images.extend(self.get_images(chap_class, chap_images, volume_path, count))

Expand All @@ -251,7 +263,7 @@ def download_volumes(self, worker, volumes):

self.add_fi(volume_name, None, volume_zip_path, chapters)

class ComicBookArchiveSingle(ConvertedSingleFormat, CBZFileExt):
class ComicBookArchiveSingle(ConvertedSingleFormat, CBZFile):
def download_single(self, worker, total, merged_name, chapters):
images = []
count = NumberWithLeadingZeros(total)
Expand All @@ -272,25 +284,7 @@ def download_single(self, worker, total, merged_name, chapters):
path = create_directory(merged_name, self.path)

for chap_class, chap_images in chapters:
img_name = count.get() + '.png'
img_path = path / img_name

# Make sure we never duplicated it
write_start_image = False
try:
manga_zip.getinfo(img_name)
except KeyError:
write_start_image = True

if self.no_chapter_info:
write_start_image = False

# Insert "start of the chapter" image
if write_start_image:
get_chapter_info(chap_class, img_path, self.replace)
worker.submit(lambda: manga_zip.write(img_path, img_name))

count.increase()
self.insert_ch_info_img(manga_zip, worker, chap_class, count, path)

# Begin downloading
images.extend(self.get_images(chap_class, chap_images, path, count))
Expand Down
Loading

0 comments on commit e3f6ac0

Please sign in to comment.