Compare commits

..
9 Commits
Author SHA1 Message Date
hyugogirubato 0947e1904b New Contributors 2024-07-15 19:54:41 +02:00
hyugogirubato 7f1060fc30 Release v3.3.1 2024-07-15 19:51:54 +02:00
hyugogirubato df54489eef Add from_pdf method 2024-07-15 19:45:38 +02:00
hyugogirubato 68e843af63 Change quit keyboard shortcut to allow clipboard 2024-07-15 19:19:36 +02:00
hyugogirubato 4b2c47b4b8 Fix minimum player dimensions 2024-07-15 19:18:26 +02:00
hyugogirubato 74a6a0e9b6 Fix player border margin 2024-07-15 19:12:22 +02:00
hyugogirubato 82e1764c2e Fix windows taskbar player icon 2024-07-15 19:05:13 +02:00
hyugogirubato f62a508d9a Merge pull request #9 from flolep2607/fix-linux-player
fix: cbzplayer icon  for linux
2024-07-15 18:55:00 +02:00
flolep2607 90abd137c5 fix: cbzplayer icon for linux 2024-07-14 20:26:05 +02:00
8 changed files with 175 additions and 15 deletions
+2 -1
View File
@@ -171,4 +171,5 @@ poetry.toml
pyrightconfig.json pyrightconfig.json
### CBZ ### ### CBZ ###
.cbz *.cbz
*.pdf
+23
View File
@@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.3.1] - 2024-07-15
### Added
- Added `from_pdf` method to convert `.pdf` files to `.cbz`.
### Changed
- Set a default standard size.
- Changed a keyboard shortcut that prevented copying information.
### Fixed
- Fixed the icon display for Linux in the player.
- Fixed the taskbar icon for Windows in the player.
- Fixed the player margins.
- Automatically detect the player size based on the smallest image.
### New Contributors
- [flolep2607](https://github.com/flolep2607)
## [3.3.0] - 2024-07-14 ## [3.3.0] - 2024-07-14
### Added ### Added
@@ -82,6 +104,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Initial release. - Initial release.
[3.3.1]: https://github.com/hyugogirubato/cbz/releases/tag/v3.3.1
[3.3.0]: https://github.com/hyugogirubato/cbz/releases/tag/v3.3.0 [3.3.0]: https://github.com/hyugogirubato/cbz/releases/tag/v3.3.0
[3.2.0]: https://github.com/hyugogirubato/cbz/releases/tag/v3.2.0 [3.2.0]: https://github.com/hyugogirubato/cbz/releases/tag/v3.2.0
[3.1.2]: https://github.com/hyugogirubato/cbz/releases/tag/v3.1.2 [3.1.2]: https://github.com/hyugogirubato/cbz/releases/tag/v3.1.2
+1
View File
@@ -150,6 +150,7 @@ comic_from_cbz = ComicInfo.from_cbz('/path/to/your_comic.cbz')
<a href="https://github.com/OleskiiPyskun"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/75667382?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="OleskiiPyskun"/></a> <a href="https://github.com/OleskiiPyskun"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/75667382?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="OleskiiPyskun"/></a>
<a href="https://github.com/domenicoblanco"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/9018104?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="domenicoblanco"/></a> <a href="https://github.com/domenicoblanco"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/9018104?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="domenicoblanco"/></a>
<a href="https://github.com/RivMt"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/40086827?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="RivMt"/></a> <a href="https://github.com/RivMt"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/40086827?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="RivMt"/></a>
<a href="https://github.com/flolep2607"><img src="https://images.weserv.nl/?url=avatars.githubusercontent.com/u/24566964?v=4&h=25&w=25&fit=cover&mask=circle&maxage=7d" alt="flolep2607"/></a>
## Licensing ## Licensing
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

+45 -2
View File
@@ -7,6 +7,8 @@ from typing import Union
from functools import cache from functools import cache
from pathlib import Path from pathlib import Path
import fitz
import xmltodict import xmltodict
from cbz.constants import XML_NAME, COMIC_FIELDS, IMAGE_FORMAT, PAGE_FIELDS from cbz.constants import XML_NAME, COMIC_FIELDS, IMAGE_FORMAT, PAGE_FIELDS
@@ -64,10 +66,51 @@ class ComicInfo(ComicModel):
""" """
if not isinstance(path, (Path, str)): if not isinstance(path, (Path, str)):
raise ValueError(f'Expecting Path object or path string, got {path!r}') raise ValueError(f'Expecting Path object or path string, got {path!r}')
return cls.__unpack(path) return cls.__unpack_zip(path)
@classmethod
def from_pdf(cls, path: Union[Path, str]) -> ComicInfo:
"""
Create a ComicInfo instance from a PDF file.
Args:
path (Union[Path, str]): Path to the PDF file.
Returns:
ComicInfo: An instance of ComicInfo.
Raises:
ValueError: If the provided path is not a Path object or a string.
"""
if not isinstance(path, (Path, str)):
raise ValueError(f'Expecting Path object or path string, got {path!r}')
return cls.__unpack_pdf(path)
@staticmethod @staticmethod
def __unpack(path: Path) -> ComicInfo: def __unpack_pdf(path: Path) -> ComicInfo:
"""
Unpack a PDF file and create a ComicInfo instance.
Args:
path (Path): Path to the PDF file.
Returns:
ComicInfo: An instance of ComicInfo.
"""
pages: list[PageInfo] = []
with fitz.open(path) as pf:
for element in pf:
# Check if the page has images
images = element.get_images(full=True)
for i, image in enumerate(images):
base = pf.extract_image(image[0])
pages.append(PageInfo.loads(data=base['image']))
assert pages, 'No valid images present in file'
return ComicInfo.from_pages(pages=pages)
@staticmethod
def __unpack_zip(path: Path) -> ComicInfo:
""" """
Unpack a CBZ file and create a ComicInfo instance. Unpack a CBZ file and create a ComicInfo instance.
+26 -10
View File
@@ -3,6 +3,7 @@ import tkinter as tk
from io import BytesIO from io import BytesIO
from tkinter import ttk from tkinter import ttk
from tkinter.constants import DISABLED, NORMAL from tkinter.constants import DISABLED, NORMAL
from ctypes import windll
from PIL import Image, ImageTk from PIL import Image, ImageTk
from pathlib import Path from pathlib import Path
@@ -10,6 +11,9 @@ from pathlib import Path
from cbz.comic import ComicInfo from cbz.comic import ComicInfo
from cbz.page import PageInfo from cbz.page import PageInfo
from cbz.utils import readable_size from cbz.utils import readable_size
import os
PARENT = Path(__file__).parent
class Player: class Player:
@@ -52,8 +56,12 @@ class Player:
# Set initial window size # Set initial window size
self.root.geometry(self._get_initial_geometry()) self.root.geometry(self._get_initial_geometry())
# Set window icon # Check if windows or linux for window icon
self.root.iconbitmap(Path(__file__).parent / 'cbz.ico') if os.name == 'nt':
windll.shell32.SetCurrentProcessExplicitAppUserModelID('cbz.player')
self.root.iconbitmap(PARENT / 'cbz.ico')
else:
self.root.wm_iconphoto(True, tk.PhotoImage(file=PARENT / 'cbz.png'))
# Create main frame for content # Create main frame for content
self.main_frame = ttk.Frame(self.root) self.main_frame = ttk.Frame(self.root)
@@ -70,6 +78,7 @@ class Player:
self._init_summary_text() self._init_summary_text()
# Display initial page content # Display initial page content
# TODO: Support scrollable image and/or zoom when it is too large for the screen (eg: webtoon)
self.show_page() self.show_page()
# Bind keys for navigation and window resize # Bind keys for navigation and window resize
@@ -87,7 +96,7 @@ class Player:
str: Window title. str: Window title.
""" """
if self.comic_info.series and self.comic_info.title: if self.comic_info.series and self.comic_info.title:
return f"{self.comic_info.series} - {self.comic_info.title}" return f'{self.comic_info.series} - {self.comic_info.title}'
return self.comic_info.title or self.__class__.__name__ return self.comic_info.title or self.__class__.__name__
def _get_initial_geometry(self) -> str: def _get_initial_geometry(self) -> str:
@@ -107,18 +116,25 @@ class Player:
# Calculate scaling factors for width and height # Calculate scaling factors for width and height
if self.comic_info.pages: if self.comic_info.pages:
first_page = self.comic_info.pages[0] # Get the minimum dimensions from all pages
scale_width = available_width / first_page.image_width image_width = self.comic_info.pages[0].image_width
scale_height = available_height / first_page.image_height image_height = self.comic_info.pages[0].image_height
for page in self.comic_info.pages[1:]:
if page.image_width <= image_width and page.image_height <= image_height:
image_width = page.image_width
image_height = page.image_height
scale_width = available_width / image_width
scale_height = available_height / image_height
# Choose the smaller scaling factor to maintain proportions # Choose the smaller scaling factor to maintain proportions
scale_factor = min(scale_width, scale_height) scale_factor = min(scale_width, scale_height)
# Calculate new dimensions # Calculate new dimensions
initial_width = int(first_page.image_width * scale_factor) initial_width = int(image_width * scale_factor * 0.94)
initial_height = int(first_page.image_height * scale_factor) initial_height = int(image_height * scale_factor)
else: else:
initial_width = int(available_width) initial_width = int(available_height * 0.63)
initial_height = int(available_height) initial_height = int(available_height)
# Calculate initial position to center the window on the screen # Calculate initial position to center the window on the screen
@@ -242,7 +258,7 @@ class Player:
self.root.bind('<Right>', lambda event: self.one_next()) self.root.bind('<Right>', lambda event: self.one_next())
# Bind Ctrl+C to exit application # Bind Ctrl+C to exit application
self.root.bind('<Control-c>', lambda event: self.root.quit()) self.root.bind('<Control-q>', lambda event: self.root.quit())
# Bind the configure event to handle window resize # Bind the configure event to handle window resize
self.root.bind('<Configure>', lambda event: self.on_window(event)) self.root.bind('<Configure>', lambda event: self.on_window(event))
Generated
+76 -1
View File
@@ -256,6 +256,81 @@ type = "legacy"
url = "https://pypi.org/simple" url = "https://pypi.org/simple"
reference = "localpypi" reference = "localpypi"
[[package]]
name = "pymupdf"
version = "1.24.7"
description = "A high performance Python library for data extraction, analysis, conversion & manipulation of PDF (and other) documents."
optional = false
python-versions = ">=3.8"
files = [
{file = "PyMuPDF-1.24.7-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:9b6984d57e127e016231b2e89b247f2b0fef07af84d4cc91e4893c6d3fde52c7"},
{file = "PyMuPDF-1.24.7-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:7b8405aac8011b445ceb1bc2d4f4c44b2c969024b301f1178399e0084541d747"},
{file = "PyMuPDF-1.24.7-cp310-none-manylinux2014_aarch64.whl", hash = "sha256:ada392c739f43608611d430305c92d1b8922f66a07bc36a4ea0c7f3f9c1b5dd2"},
{file = "PyMuPDF-1.24.7-cp310-none-manylinux2014_x86_64.whl", hash = "sha256:7a59e24873e6d135f9c07be9f47d98502171210957819c8ffa9a7cca1cac1fb8"},
{file = "PyMuPDF-1.24.7-cp310-none-musllinux_1_2_x86_64.whl", hash = "sha256:bdd9a1b703e3fedd9836d54a13b89ddf772a6eaea3b1e34dcd682b8f0b5b7123"},
{file = "PyMuPDF-1.24.7-cp310-none-win32.whl", hash = "sha256:3a2e8af6e2ef437c4e599c7e520299ea10ef02680be0a8533f78d6ee489c5a60"},
{file = "PyMuPDF-1.24.7-cp310-none-win_amd64.whl", hash = "sha256:8293773e973cf07f5d6398699d5d98151a025c9db04a333fd55a87c8f8c3c74b"},
{file = "PyMuPDF-1.24.7-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:11770619a1d5b90f5f81cc22c11967b2f473310fc9a8f2aa96c1aabff5971c63"},
{file = "PyMuPDF-1.24.7-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:5e9b6018b3af45c6ca04adb0441369eefc0d66e5023f8d54befde9bb4f078c5a"},
{file = "PyMuPDF-1.24.7-cp311-none-manylinux2014_aarch64.whl", hash = "sha256:40743cbfa40a35e873d4b8642709f45849b3315292957d836be647cdd74d1107"},
{file = "PyMuPDF-1.24.7-cp311-none-manylinux2014_x86_64.whl", hash = "sha256:44f4c58040c496fcfc0719df17dab60348c7988d874c5e17233fa664dcf0a984"},
{file = "PyMuPDF-1.24.7-cp311-none-musllinux_1_2_x86_64.whl", hash = "sha256:0d7e8d2155bdc6e61242bdbf5dff2f6d0118f1a3f9e5d83db334a5cf71c90c5f"},
{file = "PyMuPDF-1.24.7-cp311-none-win32.whl", hash = "sha256:3ea0bb27512e72225822d98b6747b51b02de84cc1e17a5579d90ad957760de03"},
{file = "PyMuPDF-1.24.7-cp311-none-win_amd64.whl", hash = "sha256:785c8a40fd5d76b47759f4ade6db0b78a799bb1fb2dd61bbe59784538299ee21"},
{file = "PyMuPDF-1.24.7-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:999f40a6ead5aaad0c9e23b3c2ed009080bf51be9485ae122ff2cedd6487874b"},
{file = "PyMuPDF-1.24.7-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:03facd26907dcbba63429e8b56fdbabd717f22fb6d24b38bdefc591b309ce437"},
{file = "PyMuPDF-1.24.7-cp312-none-manylinux2014_aarch64.whl", hash = "sha256:7ec6da974092de0f842f9ef0e355c58a5529c2d5ec792709d2c6fec5ffcd80b1"},
{file = "PyMuPDF-1.24.7-cp312-none-manylinux2014_x86_64.whl", hash = "sha256:89ccd758b5b7d1e05d615e85fb5d358ff1994ff70aaa5df4f0724bd414847949"},
{file = "PyMuPDF-1.24.7-cp312-none-musllinux_1_2_x86_64.whl", hash = "sha256:8873253ffedb7bcc8dcafa9bfe8f1efa39ac91732ccc579e1c1746eeff4ed83a"},
{file = "PyMuPDF-1.24.7-cp312-none-win32.whl", hash = "sha256:5341440bfc6c89f025990d181896b74097f6b145f5e563e3d5e5fa944c79aae6"},
{file = "PyMuPDF-1.24.7-cp312-none-win_amd64.whl", hash = "sha256:a906b57dae8f3870663f3d3a1d4a66b67cc8f5cf644bcbdd175a391f5f74f2ef"},
{file = "PyMuPDF-1.24.7-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:b18630fead76175059b973230cc175c4ed30e9f4ea03d25963d2c74440bdb78b"},
{file = "PyMuPDF-1.24.7-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:a94d556b7ea25e6195c46dc2c4114d30e8e51233a49f0ed589f8e0190d2cc3b5"},
{file = "PyMuPDF-1.24.7-cp38-none-manylinux2014_aarch64.whl", hash = "sha256:da82dc784e52b3635110995a75189cdef71b02d9a3a2635cd1d216133d547519"},
{file = "PyMuPDF-1.24.7-cp38-none-manylinux2014_x86_64.whl", hash = "sha256:d95c0cc4768ce09d06c31280cda6fc7619026e615d33beee2dbd1c74ea3a1e08"},
{file = "PyMuPDF-1.24.7-cp38-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c7c964e4b3dfbcd7a0ec11f44090002967c9652cf1dbaf5e09de333c479eae3"},
{file = "PyMuPDF-1.24.7-cp38-none-win32.whl", hash = "sha256:5812645087eaf537efb168df1a78b40b76d6b01c694b890d31e362fd007926fe"},
{file = "PyMuPDF-1.24.7-cp38-none-win_amd64.whl", hash = "sha256:b11065d5192bdc6e80046505ed68447276d3698ec1d0a3eea8dc2533f972f8fb"},
{file = "PyMuPDF-1.24.7-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:102d3427fcc3a47084eb2faa670de8a58e5d2061b4e61365b323d12a7bac0afd"},
{file = "PyMuPDF-1.24.7-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:5580c975a166a3fb1908fb055c0427bcd23abe7a7d3113777d15c0e5f8a2133b"},
{file = "PyMuPDF-1.24.7-cp39-none-manylinux2014_aarch64.whl", hash = "sha256:1553df16e6e141314fa33534800aee2bc4eab1daa8057bf791584b318aa114f6"},
{file = "PyMuPDF-1.24.7-cp39-none-manylinux2014_x86_64.whl", hash = "sha256:53cedffedc7ec5c019f8b06d0e18b1f410f4af15e0c122330b79d5e617739042"},
{file = "PyMuPDF-1.24.7-cp39-none-musllinux_1_2_x86_64.whl", hash = "sha256:371b983ba2b396a636518e2cfaa76ea8cccd38c9bdbc942256df678e421f7063"},
{file = "PyMuPDF-1.24.7-cp39-none-win32.whl", hash = "sha256:0a93d0f5c5b5cdc2f1718dbdf4b1c34aafc68ee4e44688b58c0a2894277ca941"},
{file = "PyMuPDF-1.24.7-cp39-none-win_amd64.whl", hash = "sha256:f82db6fd757fb3698075e2e68e4f6df7ae89b82a96ae102e178e5b01a250359b"},
{file = "PyMuPDF-1.24.7.tar.gz", hash = "sha256:a34ceae204f215bad51f49dd43987116c6a6269fc03d8770224f7067013b59b8"},
]
[package.dependencies]
PyMuPDFb = "1.24.6"
[package.source]
type = "legacy"
url = "https://pypi.org/simple"
reference = "localpypi"
[[package]]
name = "pymupdfb"
version = "1.24.6"
description = "MuPDF shared libraries for PyMuPDF."
optional = false
python-versions = ">=3.8"
files = [
{file = "PyMuPDFb-1.24.6-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:21e3ed890f736def68b9a031122ae1fb854d5cb9a53aa144b6e2ca3092416a6b"},
{file = "PyMuPDFb-1.24.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8704d2dfadc9448ce184597d8b0f9c30143e379ac948a517f9c4db7c0c71ed51"},
{file = "PyMuPDFb-1.24.6-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:01662584d5cfa7a91f77585f13fc23a12291cfd76a57e0a28dd5a56bf521cb2c"},
{file = "PyMuPDFb-1.24.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e1f7657353529ae3f88575c83ee49eac9adea311a034b9c97248a65cee7df0e5"},
{file = "PyMuPDFb-1.24.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cebc2cedb870d1e1168e2f502eb06f05938f6df69103b0853a2b329611ec19a7"},
{file = "PyMuPDFb-1.24.6-py3-none-win32.whl", hash = "sha256:ac4b865cd1e239db04674f85e02844a0e405f8255ee7a74dfee0d86aad0d3576"},
{file = "PyMuPDFb-1.24.6-py3-none-win_amd64.whl", hash = "sha256:9224e088a0d3c188dea03831807789e245b812fbd071c8d498da8f7cc33142b2"},
{file = "PyMuPDFb-1.24.6.tar.gz", hash = "sha256:f5a40b1732d65a1e519916d698858b9ce7473e23edf9001ddd085c5293d59d30"},
]
[package.source]
type = "legacy"
url = "https://pypi.org/simple"
reference = "localpypi"
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "70.3.0" version = "70.3.0"
@@ -295,4 +370,4 @@ reference = "localpypi"
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.8" python-versions = "^3.8"
content-hash = "dfb034cdc323648effbcfff969cae65cbca1b04130c64d68c8c8968f0d692e71" content-hash = "080fe35089770ecee25895cdd4ee4aa14b9e9c818c199908f066bc94c4470530"
+2 -1
View File
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry] [tool.poetry]
name = "cbz" name = "cbz"
version = "3.3.0" version = "3.3.1"
description = "CBZ simplifies creating, managing, and viewing comic book files in CBZ format, offering seamless packaging, metadata handling, and built-in viewing capabilities" description = "CBZ simplifies creating, managing, and viewing comic book files in CBZ format, offering seamless packaging, metadata handling, and built-in viewing capabilities"
license = "MIT" license = "MIT"
authors = ["hyugogirubato <65763543+hyugogirubato@users.noreply.github.com>"] authors = ["hyugogirubato <65763543+hyugogirubato@users.noreply.github.com>"]
@@ -34,6 +34,7 @@ python = "^3.8"
xmltodict = "^0.13.0" xmltodict = "^0.13.0"
langcodes = "^3.4.0" langcodes = "^3.4.0"
Pillow = "^10.4.0" Pillow = "^10.4.0"
PyMuPDF = "^1.24.7"
[tool.poetry.scripts] [tool.poetry.scripts]
cbzplayer = "cbz.__main__:main" cbzplayer = "cbz.__main__:main"