Files
my-webtoon/converter/converter.py

178 lines
7.4 KiB
Python

import json
from pathlib import Path
import shutil
from PIL import Image
from data.path_constant import ANDROID_ASSETS, DOWNLOAD_DIR, NETWORK_DIR
class WebtoonConverter:
def __init__(self, webtoon_path: Path):
self.webtoon_path = webtoon_path
self.webtoon_path_network = NETWORK_DIR / webtoon_path.name
self.img_extensions = {'.png', '.jpg', '.jpeg', '.webp'}
def do_convert(self):
if self.webtoon_path.is_dir() and self.has_new_episode():
print(self.webtoon_path)
self.copy_information()
for item_path in self.webtoon_path.iterdir():
if item_path.is_dir():
episode_path = item_path
if self.is_new_episode(episode_path):
print(f"new episode: {episode_path}")
self.delete_over_width_image(episode_path)
self.concat_images(episode_path)
elif item_path.suffix.lower() in self.img_extensions:
thumbnail_path = item_path
self.copy_thumbnail(thumbnail_path)
def has_new_episode(self) -> bool:
self.webtoon_path_network.mkdir(parents=True, exist_ok=True)
return self._count_episodes(self.webtoon_path) > self._count_episodes(self.webtoon_path_network)
def _count_episodes(self, path: Path):
episodes = [d for d in path.iterdir() if d.is_dir()]
return len(episodes)
def copy_information(self):
info_path_local = self.webtoon_path / 'information.json'
info_path_network = self.webtoon_path_network / 'information.json'
self.updateTag(info_path_local)
copy_necessary = True
if info_path_network.exists():
with open(info_path_local, "r", encoding='utf-8') as json_file:
local_information = json.load(json_file)
with open(info_path_network, "r", encoding='utf-8') as json_file:
network_information = json.load(json_file)
if (
local_information["title"] == network_information["title"] and
local_information["author"] == network_information["author"] and
local_information["tag"] == network_information["tag"] and
local_information["description"] == network_information["description"] and
local_information["thumbnail_name"] == network_information["thumbnail_name"]
):
copy_necessary = False
if (copy_necessary):
try:
shutil.copyfile(info_path_local, info_path_network)
print(f"File '{info_path_local}' copied to '{info_path_network}'.")
except FileNotFoundError:
print(f"Source file '{info_path_local}' not found.")
def updateTag(self, path: Path):
update_necessary = False
if path.exists():
with open(path, "r", encoding='utf-8') as json_file:
existing_information = json.load(json_file)
tag = existing_information["tag"]
print(tag)
if '冒險' in tag and tag != '冒險':
tag = '冒險'
update_necessary = True
elif '愛情' in tag and tag != '愛情':
tag = '愛情'
update_necessary = True
elif 'BL' in tag and tag != 'BL':
tag = 'BL'
update_necessary = True
elif '武俠' in tag:
tag = '冒險'
update_necessary = True
elif '大人系' in tag:
tag = '愛情'
update_necessary = True
elif '驚悚' in tag:
tag = '劇情'
update_necessary = True
elif '奇幻' in tag:
tag = '劇情'
update_necessary = True
elif '宮廷' in tag:
tag = '劇情'
update_necessary = True
elif '懸疑' in tag:
tag = '劇情'
update_necessary = True
if update_necessary:
information = {
"title": existing_information["title"],
"author": existing_information["author"],
"tag": tag,
"description": existing_information["description"],
"thumbnail_name": existing_information["thumbnail_name"]
}
with open(path, 'w', encoding='utf-8') as json_file:
json.dump(information, json_file, ensure_ascii=False, indent=2)
print(f"{path} is saved.")
def copy_thumbnail(self, thumbnail_path: Path):
assets_path = ANDROID_ASSETS / thumbnail_path.name
if (not assets_path.exists()):
try:
shutil.copyfile(thumbnail_path, assets_path)
print(f"File '{thumbnail_path}' copied to '{assets_path}'.")
except FileNotFoundError:
print(f"Source file '{thumbnail_path}' not found.")
def delete_over_width_image(self, episode_path: Path):
for img_path in episode_path.iterdir():
if self._is_image_800(img_path):
img_path.unlink()
print(f"delete {img_path}")
def _is_image_800(self, image_path: Path) -> bool:
try:
with Image.open(image_path) as img:
return img.width >= 800
except Exception as e:
print(f"Error opening image {image_path}: {e}")
return False
def is_new_episode(self, episode_path: Path) -> bool:
episode_path_network = self.webtoon_path_network / episode_path.name
return not episode_path_network.exists()
def concat_images(self, episode_path: Path):
episode_path_network = self.webtoon_path_network / episode_path.name
episode_path_network.mkdir(parents=True, exist_ok=True)
result_images = []
total_height = 0
result_index = 1
for img_path in episode_path.iterdir():
if img_path.suffix.lower() in self.img_extensions:
with open(img_path, 'rb') as img_file:
img = Image.open(img_file)
img.load()
if total_height + img.height > 28800:
self.save_concatenated_image(result_images, episode_path_network, result_index)
result_index += 1
result_images = []
total_height = 0
result_images.append(img)
total_height += img.height
if result_images:
self.save_concatenated_image(result_images, episode_path_network, result_index)
def save_concatenated_image(self, images: list, output_episode_path: Path, index: int):
img_width = images[0].width # Assuming all images have the same width
total_height = sum(img.height for img in images)
result_image = Image.new('RGB', (img_width, total_height))
y_offset = 0
for img in images:
result_image.paste(img, (0, y_offset))
y_offset += img.height
output_file = output_episode_path / f"{index}.jpg"
print(f"saving '{output_file}'")
result_image.save(output_file)