Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
99 changes: 61 additions & 38 deletions _Gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def validate(condition, entry, result):


class MainFrame(tk.Frame):
def __init__(self, _master, input_dir=None, file=None, name="", grayscale=False, max_width=None, max_height=None,
wrap_pages=True):
tk.Frame.__init__(self, master=_master, width=525, height=200)
def __init__(self, _master, input_dir=None, file=None, name="", author=None, publisher=None, language="en-US", grayscale=False, rotate_double_pages=True, max_width=None, max_height=None,
wrap_pages=True, manga_mode=False):
tk.Frame.__init__(self, master=_master, width=525, height=215)
self.master.protocol("WM_DELETE_WINDOW", self.close)
self.generic_queue = Queue()
self.progress_queue = Queue()
Expand All @@ -52,6 +52,7 @@ def __init__(self, _master, input_dir=None, file=None, name="", grayscale=False,
else:
self.input_dir = None
self.input_dir_var = tk.StringVar(value="No directory given")

self.file = file
self.working = False
self.thread: Optional[EPubMaker] = None
Expand All @@ -62,71 +63,85 @@ def __init__(self, _master, input_dir=None, file=None, name="", grayscale=False,
panel = tk.Frame()
panel.place(in_=self, anchor="c", relx=.5, rely=.5)

# directory

self.input_dir_entry = tk.Entry(panel, state='readonly', textvariable=self.input_dir_var)
# Directory
self.input_dir_entry = tk.Entry(panel, state='readonly', textvariable=self.input_dir_var, width=50)
self.input_dir_entry.grid(row=0, column=0, padx=5)
self.input_dir_entry.config(width=50)

self.button_dir = tk.Button(panel, text="Change directory", command=self.get_dir)
self.button_dir.config(width=15)
self.button_dir = tk.Button(panel, text="Change directory", command=self.get_dir, width=15)
self.button_dir.grid(row=0, column=1, padx=5, pady=3)

# file
# File
self.file_var = tk.StringVar(value=self.file)
self.file_entry = tk.Entry(panel, state='readonly', textvariable=self.file_var)
self.file_entry = tk.Entry(panel, state='readonly', textvariable=self.file_var, width=50)
self.file_entry.grid(row=1, column=0, padx=5)
self.file_entry.config(width=50)

self.button_file = tk.Button(panel, text="Change file", command=self.save_as)
self.button_file.config(width=15)
self.button_file = tk.Button(panel, text="Change file", command=self.save_as, width=15)
self.button_file.grid(row=1, column=1, padx=5, pady=3)

# name
# Name
name_frame = tk.Frame(panel)
name_frame.grid(row=2, column=0, columnspan=2, pady=3)
tk.Label(name_frame, text="Name:").grid(row=0, column=0)
self.name = tk.StringVar(value=name)
self.name_entry = tk.Entry(name_frame, textvariable=self.name, validate="key")
self.name_entry.config(width=40)
self.name_entry = tk.Entry(name_frame, textvariable=self.name, validate="key", width=60)
self.name_entry.grid(row=0, column=1, padx=5)

# image size
# Metadata
metadata_frame = tk.Frame(panel)
metadata_frame.grid(row=3, column=0, columnspan=2, pady=3)
tk.Label(metadata_frame, text="Author:").grid(row=0, column=0)
self.author = tk.StringVar(value=author)
self.author_entry = tk.Entry(metadata_frame, textvariable=self.author, validate="key", width=15)
self.author_entry.grid(row=0, column=1, padx=5)
tk.Label(metadata_frame, text="Publisher:").grid(row=0, column=2)
self.publisher = tk.StringVar(value=publisher)
self.publisher_entry = tk.Entry(metadata_frame, textvariable=self.publisher, validate="key", width=15)
self.publisher_entry.grid(row=0, column=3, padx=5)
tk.Label(metadata_frame, text="Language:").grid(row=0, column=4)
self.language = tk.StringVar(value=language)
languages_list = ["en-US", "pt-BR", "ja-JP"]
self.language_entry = tk.OptionMenu(metadata_frame, self.language, *languages_list)
self.language_entry.grid(row=0, column=5, padx=5)

# Image size
size_frame = tk.Frame(panel)
size_frame.grid(row=3, column=0, columnspan=2, pady=3)
size_frame.grid(row=4, column=0, columnspan=2, pady=3)
tk.Label(size_frame, text="Maximum width: ").grid(row=0, column=0)
self.max_width = tk.StringVar(value=max_width)
self.max_width_entry = tk.Entry(size_frame, textvariable=self.max_width)
self.max_width_entry.config(width=15)
self.max_width_entry = tk.Entry(size_frame, textvariable=self.max_width, width=15)
self.max_width_entry.grid(row=0, column=1, padx=5)
tk.Label(size_frame, text="Maximum height: ").grid(row=0, column=2)
self.max_height = tk.StringVar(value=max_height)
self.max_height_entry = tk.Entry(size_frame, textvariable=self.max_height)
self.max_height_entry.config(width=15)
self.max_height_entry = tk.Entry(size_frame, textvariable=self.max_height, width=15)
self.max_height_entry.grid(row=0, column=3, padx=5)

# options
# Options
options_frame = tk.Frame(panel)
options_frame.grid(row=4, column=0, columnspan=2, pady=3)
options_frame.grid(row=5, column=0, columnspan=2, pady=3)
self.grayscale = tk.BooleanVar(value=grayscale)
self.grayscale_entry = tk.Checkbutton(options_frame, text="Grayscale", variable=self.grayscale)
self.grayscale_entry.grid(row=0, column=0, padx=5)
self.rotate_double_pages = tk.BooleanVar(value=rotate_double_pages)
self.rotate_double_pages_entry = tk.Checkbutton(options_frame, text="Rotate double pages", variable=self.rotate_double_pages)
self.rotate_double_pages_entry.grid(row=0, column=1, padx=5)
self.wrap_pages = tk.BooleanVar(value=wrap_pages)
self.wrap_pages_entry = tk.Checkbutton(options_frame, text="Wrap pages", variable=self.wrap_pages)
self.wrap_pages_entry.grid(row=0, column=1, padx=5)
self.wrap_pages_entry.grid(row=0, column=2, padx=5)
self.manga_mode = tk.BooleanVar(value=manga_mode)
self.manga_mode_entry = tk.Checkbutton(options_frame, text="Manga mode", variable=self.manga_mode)
self.manga_mode_entry.grid(row=0, column=3, padx=5)


# progress
# Progress
progress = tk.Frame(panel)
progress.grid(row=5, column=0, columnspan=2, pady=3)
self.button_start = tk.Button(progress, text="Start", command=self.start)
self.button_start.config(width=10)
progress.grid(row=6, column=0, columnspan=2, pady=3)
self.button_start = tk.Button(progress, text="Start", command=self.start, width=10)
self.button_start.grid(row=0, column=0, padx=5, pady=3)

self.progress = ttk.Progressbar(progress, length=200, mode='determinate', name='progress of making the ePub')
self.progress.grid(row=0, column=1, padx=5, pady=3)

self.button_stop = tk.Button(progress, text="Stop", command=self.stop)
self.button_stop.config(width=10)
self.button_stop = tk.Button(progress, text="Stop", command=self.stop, width=10)
self.button_stop.grid(row=0, column=2, padx=5, pady=3)

self.set_state()
Expand All @@ -148,13 +163,19 @@ def save_as(self):
def get_invalid(self):
max_width = self.max_width.get()
max_height = self.max_height.get()
author = self.author.get()
publisher = self.publisher.get()
result = [
validate(self.input_dir and os.path.isdir(self.input_dir), self.input_dir_entry, "input directory"),
validate(self.file, self.file_entry, "ouput file"),
validate(self.name.get(), self.name_entry, "name"),
validate(not author or author, self.author_entry, "author"),
validate(not publisher or publisher, self.publisher_entry, "publisher"),
validate(self.language.get(), self.language_entry, "language"),
validate(not max_width or max_width.isnumeric(), self.max_width_entry, "maximum width"),
validate(not max_height or max_height.isnumeric(), self.max_height_entry, "maximum height"),
]

return list(filter(None, result))

def set_state(self):
Expand All @@ -163,9 +184,11 @@ def set_state(self):
self.button_file.config(state=state)
self.name_entry.config(state=state)
self.grayscale_entry.config(state=state)
self.rotate_double_pages_entry.config(state=state)
self.wrap_pages_entry.config(state=state)
self.max_width_entry.config(state=state)
self.max_height_entry.config(state=state)
self.manga_mode_entry.config(state=state)
self.button_stop.config(state=tk.NORMAL if self.working else tk.DISABLED)
self.button_start.config(state=tk.NORMAL if not self.working else tk.DISABLED)
return True
Expand All @@ -176,9 +199,9 @@ def start(self):
self.working = True
max_width, max_height = self.max_width.get(), self.max_height.get()
self.thread = EPubMaker(
master=self, input_dir=self.input_dir, file=self.file, name=self.name.get(),
wrap_pages=self.wrap_pages.get(), max_width=int(max_width) if max_width else None,
max_height=int(max_height) if max_height else None, grayscale=self.grayscale.get(),
master=self, input_dir=self.input_dir, file=self.file, name=self.name.get(), author=self.author.get(), publisher=self.publisher.get(), language=self.language.get(),
wrap_pages=self.wrap_pages.get(), rotate_double_pages=self.rotate_double_pages.get(), max_width=int(max_width) if max_width else None,
max_height=int(max_height) if max_height else None, grayscale=self.grayscale.get(), manga_mode=self.manga_mode.get(),
)
self.thread.start()
else:
Expand Down Expand Up @@ -230,11 +253,11 @@ def process_queue(self):
self.after(UPDATE_TIME, self.process_queue)


def start_gui(input_dir=None, file=None, name="", grayscale=False, max_width=None, max_height=None, wrap_pages=True):
def start_gui(input_dir=None, file=None, name="", author=None, publisher=None, language="en-US", grayscale=False, rotate_double_pages=True, max_width=None, max_height=None, wrap_pages=True, manga_mode=False):
root = tk.Tk()
MainFrame(
root, input_dir=input_dir, file=file, name=name, grayscale=grayscale, max_width=max_width,
max_height=max_height, wrap_pages=wrap_pages
root, input_dir=input_dir, file=file, name=name, author=author, publisher=publisher, language=language, grayscale=grayscale, rotate_double_pages=rotate_double_pages, max_width=max_width,
max_height=max_height, wrap_pages=wrap_pages, manga_mode=manga_mode
).mainloop()


Expand Down
25 changes: 17 additions & 8 deletions _ePubMaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def depth(self) -> int:


class EPubMaker(threading.Thread):
def __init__(self, master, input_dir, file, name, wrap_pages, grayscale, max_width, max_height, progress=None):
def __init__(self, master, input_dir, file, name, author=None, publisher=None, language="en-US", grayscale=False, rotate_double_pages=True, max_width=None, max_height=None, wrap_pages=True, manga_mode=False, progress=None):
threading.Thread.__init__(self)
self.master = master
self.progress = None
Expand All @@ -97,10 +97,15 @@ def __init__(self, master, input_dir, file, name, wrap_pages, grayscale, max_wid
self.chapter_tree: Optional[Chapter] = None
self.images = []
self.uuid = 'urn:uuid:' + str(uuid.uuid1())
self.author = author
self.publisher = publisher
self.language = language
self.grayscale = grayscale
self.rotate_double_pages = rotate_double_pages
self.max_width = max_width
self.max_height = max_height
self.wrap_pages = wrap_pages
self.manga_mode = manga_mode

def run(self):
try:
Expand Down Expand Up @@ -199,13 +204,16 @@ def write_images(self):
image_data: PIL.Image.Image = PIL.Image.open(image["source"])
image["width"], image["height"] = image_data.size
image["type"] = image_data.get_format_mimetype()
should_resize = (self.max_width and self.max_width < image["width"]) or (
self.max_height and self.max_height < image["height"])
should_rotate = self.rotate_double_pages and (image["width"] > image["height"])
should_resize = (self.max_width and self.max_width < image["width"]) or (self.max_height and self.max_height < image["height"])
should_grayscale = self.grayscale and image_data.mode != "L"
if not should_grayscale and not should_resize:
if should_rotate==should_resize==should_grayscale==False:
self.zip.write(image["source"], output)
else:
image_format = image_data.format
if should_rotate:
image_data = image_data.rotate(90, expand=1)
image["width"], image["height"] = image_data.size
if should_resize:
width_scale = image["width"] / self.max_width if self.max_width else 1.0
height_scale = image["height"] / self.max_height if self.max_height else 1.0
Expand All @@ -217,20 +225,21 @@ def write_images(self):
with self.zip.open(output, "w") as image_file:
image_data.save(image_file, format=image_format)

if self.wrap_pages:
if self.wrap_pages and not image["is_cover"]:
self.zip.writestr(os.path.join("pages", image["id"] + ".xhtml"), template.render(image))

if self.progress:
self.progress.progress_set_value(progress)
self.check_is_stopped()

if self.progress:
self.progress.progress_set_value(len(self.images))

def write_template(self, name, *, out=None, data=None):
out = out or name
data = data or {
"name": self.name, "uuid": self.uuid, "cover": self.cover, "chapter_tree": self.chapter_tree,
"images": self.images, "wrap_pages": self.wrap_pages,
"name": self.name, "author": self.author, "publisher": self.publisher, "language": self.language, "uuid": self.uuid, "cover": self.cover, "chapter_tree": self.chapter_tree,
"images": self.images, "wrap_pages": self.wrap_pages, "manga_mode": self.manga_mode,
}
self.zip.writestr(out, self.template_env.get_template(name + '.jinja2').render(data))

Expand Down Expand Up @@ -278,4 +287,4 @@ def progress_set_maximum(self, value):
self.maximum = value
if 0 <= value:
if self.nice:
print('\r│' + ' ' * self.width + '│ ', end="")
print('\r│' + ' ' * self.width + '│ ', end="")
16 changes: 9 additions & 7 deletions templates/package.opf.jinja2
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" prefix="rendition: http://www.idpf.org/vocab/rendition/#" unique-identifier="BookID">
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="en" prefix="rendition: httpcov://www.idpf.org/vocab/rendition/#" unique-identifier="BookID">
<metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title>{{ name }}</dc:title>
<dc:language>en-US</dc:language>
<dc:language>{{ language }}</dc:language>
<dc:rights>Public Domain</dc:rights>
<dc:creator>ePub Creator</dc:creator>
<dc:publisher>ePub Creator</dc:publisher>
<dc:creator>{{ author }}</dc:creator>
<dc:publisher>{{ publisher }}</dc:publisher>
<dc:identifier id="BookID" opf:scheme="UUID">{{ uuid }}</dc:identifier>
<meta property="dcterms:modified">2012-12-12T12:12:12Z</meta>
<meta property="rendition:layout">pre-paginated</meta>
Expand All @@ -18,17 +18,19 @@
<manifest>
<item id="style" href="stylesheet.css" media-type="text/css" />
{%- for image in images %}
<item id="{{ image.id }}" {% if image.is_cover %}properties="cover-image" {% endif %}href="images/{{ image.filename }}" media-type="{{ image.type }}"/>
{%- if wrap_pages %}
<item id="{{ image.id }}" {% if image.is_cover %}properties="cover-image" {% endif %} href="images/{{ image.filename }}" media-type="{{ image.type }}"/>
{%- if wrap_pages and not image.is_cover %}
<item id="{{ image.id }}_wrapper" href="pages/{{ image.id }}.xhtml" media-type="application/xhtml+xml"/>
{% endif %}
{%- endfor %}
<item id="toc" properties="nav" href="toc.xhtml" media-type="application/xhtml+xml"/>
<item id="ncxtoc" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
</manifest>
<spine toc="ncxtoc">
<spine toc="ncxtoc" {% if manga_mode %} page-progression-direction="rtl" {% endif %}>
{%- for image in images %}
{% if not image.is_cover %}
<itemref idref="{{- image.id -}} {%- if wrap_pages -%} _wrapper {%- endif -%}" />
{% endif %}
{%- endfor %}
</spine>
</package>
5 changes: 2 additions & 3 deletions templates/page.xhtml.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
padding: 0;
margin: 0;
}

body {
text-align: center;
padding: 0;
Expand All @@ -23,8 +22,8 @@
<body epub:type="bodymatter">
<div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%"
height="100%" viewBox="0 0 {{ width }} {{ height }}" preserveAspectRatio="none">
<image width="{{ width }}" height="{{ height }}" xlink:href="../images/{{ filename }}"/>
height="100%" viewBox="0 0 {{ width }} {{ height }}">
<image width="{{ width }}" height="{{ height }}" xlink:href="../images/{{ filename }}"/>
</svg>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion templates/toc.xhtml.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{%- endif %}
<li class="chapter" id="toc-{{ current_order }}">
<a href="{% if wrap_pages %}pages/{{ chapter.start.id }}.xhtml{% else %}images/{{ chapter.start.filename }}{% endif %}">
{{ current_order }} {{ chapter.title }}<br/>
{{ chapter.title }}<br/>
<img src="images/{{ chapter.start.filename }}" alt="Images not supported"/>
</a>
{{- chapter_to_string(chapter, current_order)|indent }}
Expand Down