Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update 1.1.0 #200

Merged
merged 33 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0ce6db8
Fix drag and drop in build
ThePromidius Sep 16, 2023
8d8032c
Fixed extensions not loading
ThePromidius Nov 13, 2023
4489535
Keep files if user did not select new files. Closes #197
ThePromidius Jan 8, 2024
f62468d
Added button on CoverManager to process. This toggles a refresh on mo…
ThePromidius Jan 8, 2024
549c88b
Added buttons to toggle all covers or backcovers. Closes #192
ThePromidius Jan 8, 2024
3dfc8d6
Added darkmode (early stages might have stuff not properly displaying…
ThePromidius Jan 8, 2024
d7dcd87
Updated some widgets not migrated to ttk.
ThePromidius Jan 8, 2024
c797994
Updated develop version
ThePromidius Jan 8, 2024
5403cd0
Fixed some windows crashing app due to tkinter moved to ttk
ThePromidius Jan 8, 2024
0d18177
Remove old docker stuff
ThePromidius Jan 8, 2024
01bee01
Swapped algorith to find similar images to pytorch and openclip
ThePromidius Jan 9, 2024
9c2404a
docker fixes?
ThePromidius Jan 9, 2024
3a80583
docker fixes?
ThePromidius Jan 9, 2024
c16d449
docker fixes?
ThePromidius Jan 9, 2024
73b447f
docker fixes?
ThePromidius Jan 9, 2024
9b38295
Disable torchlib
ThePromidius Jan 9, 2024
a83f2f9
Updated version
ThePromidius Jan 9, 2024
c64e576
Optimizations for CoverManager
ThePromidius Jan 9, 2024
cb50fc2
Option to not load torch
ThePromidius Jan 9, 2024
4289345
bump nightly version
ThePromidius Jan 9, 2024
e7445e3
- Show messagebox in cover manager once it's finished processing.
ThePromidius Jan 10, 2024
29248b0
bump nightly
ThePromidius Jan 10, 2024
dccbbdd
Cover downloader First implementation (#201)
ThePromidius Jan 13, 2024
5729647
Bump version hash
ThePromidius Jan 13, 2024
08021ce
added hidden import
ThePromidius Jan 13, 2024
5d78fe4
Ui improvements
ThePromidius Jan 13, 2024
6b0992b
Bump version hash
ThePromidius Jan 13, 2024
511d8bc
Changed requirement for ComicInfo
ThePromidius Jan 18, 2024
a7bcc77
Changed requirement for ComicInfo
ThePromidius Jan 18, 2024
e7a5e90
webp multiprocessing improvements
ThePromidius Jan 27, 2024
50ffdd4
reverted ComicInfo.xds as its used for tests
ThePromidius Jan 27, 2024
51ad0d3
Bump version hash
ThePromidius Jan 27, 2024
ca0c058
Bump version hash
ThePromidius Jan 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/MangaManagerV2.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 3 additions & 13 deletions .idea/runConfigurations/Build.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/runConfigurations/MangaManager.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .idea/runConfigurations/MangaManager_DEBUG.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions .idea/runConfigurations/MangaManager_TRACE.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion DEVELOPMENT.MD
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,16 @@ After that you can now create the build with the command below
If you can not run the build make sure all requirements are installed.
Pyinstaller does not use the virtual env requirements. So make sure the base python has them installed
Some of the requirements that gave me issues are:
- `chardet`
- `chardet`

# QuickGuides
## Adding a setting

### Is this a main app/default setting?

If so go into src.Settings.SettingsDefault and add it there.

Say i want to add a toggle to enable darkmode

I add the key i'll use under Main section. `{"darkmode_enabled":False}` I want it opt-in so i set it to False
Lets add the setting in the settings menu. Head to src.MetadataManager.GUI.windows.SettingsWindow. Add your key in the corresponding section using the SettingControl of your choosing. In my case its a boolean. So SettingControlType.Bool
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ENV GUIAUTOSTART=true

WORKDIR /tmp
COPY requirements.txt /tmp/
COPY requirements.txt /app/

# Copy App
COPY --chown=$UID:$GID [ "/MangaManager", "/app" ]
Expand All @@ -22,6 +23,7 @@ RUN apt-get update && \
xubuntu-default-settings \
xubuntu-icon-theme \
unrar\
# git\
# Python \
idle-python3.11 \
python3-tk \
Expand Down
39 changes: 39 additions & 0 deletions MangaManager/Extensions/CoverDownloader/CoverData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import dataclasses
from pathlib import Path
from os.path import splitext
@dataclasses.dataclass
class SeriesCoverData:
normalized_name:str

class CoverData:
# filename:str
# extension:str
#
# volume:str
# locale:str
@property
def dest_filename(self):
"""
The final filename
:return:
"""
return f"Cover{'_Vol.'+str(self.volume).zfill(2) if self.volume else ''}{'_' + self.locale if self.locale else ''}{self.extension}"


def __init__(self,source_filename=None,volume=None,locale=None):

self.source_filename=source_filename
if source_filename:
self.filename, self.extension = splitext(self.source_filename)
else:
self.filename, self.extension = None, None
self.volume=volume
self.locale=locale


def from_cover_data(self,cover_data):
self.source_filename = cover_data.get("attributes").get("fileName")
self.filename, self.extension = splitext(self.source_filename)
self.volume = cover_data.get("attributes").get("volume")
self.locale = cover_data.get("attributes").get("locale")
return self
151 changes: 140 additions & 11 deletions MangaManager/Extensions/CoverDownloader/CoverDownloader.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,156 @@
from tkinter import Label, Frame, Entry

# import tkinter
# from idlelib.tooltip import Hovertip
# from idlelib.tooltip import Hovertip
import asyncio
import logging
import urllib.request
import os
import platform
import subprocess
from enum import StrEnum
from pathlib import Path
from tkinter import Frame, Label, StringVar
from tkinter.ttk import Entry, Button, Frame
import slugify
import requests

from Extensions.CoverDownloader.CoverData import CoverData
from Extensions.CoverDownloader.MangaDex import parse_mangadex_id
from Extensions.CoverDownloader.exceptions import UrlNotFound
from Extensions.IExtensionApp import IExtensionApp
from src.MetadataManager.GUI.widgets import ProgressBarWidget
# from src.MetadataManager.GUI.tooltip import ToolTip
from src.Settings import Settings, SettingHeading, SettingSection, SettingControl, SettingControlType

logger = logging.getLogger()
def get_cover_from_source_dummy() -> list:
...


class CoverDownloader():#IExtensionApp):
class CoverDownloaderSetting(StrEnum):
ForceOverwrite = "force_overwrite" # If existing covers should be re-downloaded and overwritten
class CoverDownloader(IExtensionApp):
name = "Cover Downloader"
embedded_ui = True

def init_settings(self):

self.settings = [
SettingSection(self.name,self.name,[
SettingControl(
key=CoverDownloaderSetting.ForceOverwrite,
name="Force Overwrite",
control_type=SettingControlType.Bool,
value=False,
tooltip="Enable if existing covers should be re-downloaded and overwritten"
)
])
]
super().init_settings()

@property
def output_folder(self):
return Settings().get(SettingHeading.Main, 'covers_folder_path')

def serve_gui(self):
if not self.master:
return Exception("Tried to initialize ui with no master window")
self.url_var = StringVar(name="mdex_cover_url")
self.url_var.trace("w",self.get_series_data)

self.dest_path_var = StringVar(name="dest_path",value=str(Path((self.output_folder or Path(Path.home(),"Pictures","Manga Covers")),
'<Manga Name Folder>')))
Label(self.master,text="MangaManager will download all availabe images from").pack()
# self.frame_3 = Frame(frame1)
Label(self.master, text='MANGADEX MANGA ID / URL').pack(side='top')
Entry(master=self.master,textvariable=self.url_var).pack(side='top')

Label(self.master, text="to the folder:").pack()
label_path = Label(self.master,textvariable=self.dest_path_var)
label_path.pack(pady="10 30", side='top')

self.button_1 = Button(self.master, text='Correct! Start!', state="disabled", command=self.process_download)
self.button_1.pack(side='top')
self.button_explorer = Button(self.master, text='Open explorer', command=self.open_explorer)
self.pb = ProgressBarWidget(self.master)

def process_download(self):
try:
self.download()
except Exception as e:
logger.exception("Error downloading")
finally:
self.button_1.configure(text="DONE", state="disabled")
self.show_open_explorer_btn()

def show_open_explorer_btn(self):
self.button_explorer.pack(side='top')
def hide_open_explorer_btn(self):
self.button_explorer.pack_forget()

def open_explorer(self):

path = self.dest_path_var.get()
if platform.system() == "Windows":
os.startfile(path)
elif platform.system() == "Darwin":
subprocess.Popen(["open", path])
else:
subprocess.Popen(["xdg-open", path])
...





frame = Frame(self.master)
frame.pack()
def get_series_data(self,*_):
mdex_id = parse_mangadex_id(self.url_var.get())
if mdex_id is None:
return
self.hide_open_explorer_btn()
self.button_1.configure(text="Correct! Start", state="normal")
# self.show_open_explorer_btn()

Label(frame, text="Manga identifier").pack()
Entry(frame).pack()
# Combobox(frame, state="readonly",values=sources_factory["CoverSources"]).pack()
logger.debug(f"Parsed mdex id: '{mdex_id}'")
data = {"manga[]": [mdex_id], "includes[]": ["manga"], "limit": 50}
# Request the list of covers in the prrovided manga
r = requests.get(f"https://api.mangadex.org/cover", params=data)

covers = get_cover_from_source_dummy()
if r.status_code != 200:
logger.warning(f"Page responded with {r.status_code}",extra={"url":r.url})
return
# raise UrlNotFound(r.url)
data = r.json().get("data")
cover_attributes = data[0].get("relationships")[0].get("attributes")

# Get title
ja_title = list(filter(lambda p: p.get("ja-ro"),
cover_attributes.get("altTitles")))
if ja_title:
ja_title = ja_title[0].get("ja-ro")
full_name = (ja_title or cover_attributes.get("title").get("en"))
normalized_manga_name = slugify.slugify(full_name[:50])

# Get final path where images will be saved
self.destination_dirpath = Path((self.output_folder or Path(Path.home(), "Pictures", "Manga Covers")),normalized_manga_name)

# Update ui path
self.dest_path_var.set(str(self.destination_dirpath))
self.update()
self.cur_id = mdex_id
self.cur_data = data
def download(self):
self.pb.start(len(self.cur_data))
self.destination_dirpath.mkdir(parents=True, exist_ok=True)
for i,cover_data in enumerate(self.cur_data):
cover = CoverData().from_cover_data(cover_data)
image_path = Path(self.destination_dirpath, cover.dest_filename)
if not image_path.exists() or Settings().get(self.name,CoverDownloaderSetting.ForceOverwrite):
image_url = f"https://mangadex.org/covers/{self.cur_id}/{cover.source_filename}"

urllib.request.urlretrieve(image_url, image_path)
logger.debug(f"Downloaded '{image_path}'")
else:
logger.info(f"Skipped https://mangadex.org/covers/{self.cur_id}/{cover.source_filename} -> Already exists")
self.pb.increase_failed()
self.pb.increase_processed()
self.pb.stop()
self.update()
Loading
Loading