Skip to content
Merged
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
102 changes: 84 additions & 18 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,50 +1,116 @@
# Common settings that generally should always be used with your language specific settings

# Auto detect text files and perform LF normalization
* text=auto

.gitattributes export-ignore
.gitignore export-ignore
#
# The above will handle all files NOT found below
#

*.md text diff=markdown
# Documents
*.bibtex text diff=bibtex
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.sql text
*.RTF diff=astextplain
*.md text diff=markdown
*.mdx text diff=markdown
*.tex text diff=tex
*.adoc text
*.textile text
*.mustache text
*.csv text eol=crlf
*.tab text
*.tsv text
*.txt text
*.sql text
*.epub diff=astextplain

*.jpg binary
# Graphics
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
# SVG treated as text by default.
*.svg text
# If you want to treat it as binary,
# use the following line instead.
# *.svg binary
*.eps binary

# Scripts
*.bash text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.fish text eol=lf
*.ps1 text eol=crlf
*.sh text eol=lf
*.zsh text eol=lf
# These are explicitly windows files and should use crlf
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

*.csv text
# Serialisation
*.json text
*.toml text
*.xml text
*.yaml text
*.yml text

# Archives
*.7z binary
*.gz binary
*.tar binary
*.tgz binary
*.zip binary

# Java
*.gradle text diff=java
*.gradle.kts text diff=kotlin
*.groovy text diff=java
*.java text diff=java
*.kt text diff=kotlin
*.scala text diff=java
# Text files where line endings should be preserved
*.patch -text

#
# Exclude files from exporting
#

.gitattributes export-ignore
.gitignore export-ignore
.gitkeep export-ignore
# Apply override to all files in the directory
*.md linguist-detectable
# Basic .gitattributes for a python repo.

# Python
# Source files
# ============
*.pxd text diff=python
*.py text diff=python
*.py3 text diff=python
*.pyi text diff=python
*.pyw text diff=python
*.pyx text diff=python
*.pyz text diff=python
*.pyi text diff=python

# Binary files
# ============
*.db binary
*.p binary
*.pkl binary
*.pickle binary
*.pyc binary export-ignore
*.pyo binary export-ignore
*.pyd binary

# Jupyter notebook
*.ipynb text eol=lf

# Note: .db, .p, and .pkl files are associated
# with the python modules ``pickle``, ``dbm.*``,
# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb``
# (among others).
# Fix syntax highlighting on GitHub to allow comments
.vscode/*.json linguist-language=JSON-with-Comments
2 changes: 1 addition & 1 deletion .github/workflows/linting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
env:
PY_VERSION: '3.10'
PY_VERSION: '3.11'
permissions: {}

jobs:
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/publishing.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
name: Publishing
on: push
on:
pull_request:
branches:
- main
paths-ignore:
- docs/**
push:
branches:
- main
paths-ignore:
- docs/**
tags:
- '*'

concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
env:
PY_VERSION: '3.14'
PY_VERSION: '3.11'
permissions: {}

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ jobs:
- macos-latest
- windows-latest
python-version:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
- '3.14'
- '3.15'

runs-on: ${{ matrix.os }}
steps:
Expand Down
8 changes: 4 additions & 4 deletions .github/zizmor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ rules:
anonymous-definition:
ignore:
- 'linting.yaml:22'
- 'publishing.yaml:12'
- 'publishing.yaml:33'
- 'publishing.yaml:49'
- 'publishing.yaml:24'
- 'publishing.yaml:45'
- 'publishing.yaml:61'
- 'testing.yaml:20'
- 'testing.yaml:50'
undocumented-permissions:
ignore:
- 'publishing.yaml:58'
- 'publishing.yaml:70'
2 changes: 1 addition & 1 deletion perdoo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"get_state_home",
"setup_logging",
]
__version__ = "2026.2.0"
__version__ = "2026.3.0"
__project__ = "perdoo"

import logging
Expand Down
4 changes: 2 additions & 2 deletions perdoo/cli/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_StoreTrueAction,
)
from collections.abc import Callable
from enum import Enum
from enum import Enum, StrEnum
from pathlib import Path

from rich.markup import escape
Expand Down Expand Up @@ -75,7 +75,7 @@ def convert(value: str) -> Enum:
return convert


class ArchiveType(str, Enum):
class ArchiveType(StrEnum):
CB7 = "cb7"
CBR = "cbr"
CBT = "cbt"
Expand Down
2 changes: 1 addition & 1 deletion perdoo/cli/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,5 @@ def run(args: Namespace) -> None:
try:
with Comic.open(file=entry) as comic:
clean_comic(comic=comic, remove_exts=settings.output.remove_extensions)
except UnsupportedArchiveError: # noqa: PERF203
except UnsupportedArchiveError:
pass
2 changes: 1 addition & 1 deletion perdoo/cli/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,5 @@ def run(args: Namespace) -> None:
comic.convert(
archive_type=target_format, delete_original=True, raise_on_existing=False
)
except UnsupportedArchiveError: # noqa: PERF203
except UnsupportedArchiveError:
pass
2 changes: 1 addition & 1 deletion perdoo/cli/rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def run(args: Namespace) -> None:
for entry in progress.track(files, description="Renaming comics"):
try:
rename_entry(entry=entry, target=args.target, settings=settings)
except UnsupportedArchiveError: # noqa: PERF203
except UnsupportedArchiveError:
CONSOLE.print(f"'{entry.name}' is not a supported archive, skipping")
except Exception as err: # noqa: BLE001
CONSOLE.print(
Expand Down
20 changes: 11 additions & 9 deletions perdoo/cli/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from collections.abc import Sequence
from datetime import datetime

from msgspec import ValidationError
from rich_argparse import HelpPreviewAction
from shortbox import Comic
from shortbox.errors import ArchiveCapabilityError, UnsupportedArchiveError
Expand Down Expand Up @@ -73,14 +74,15 @@ def should_sync(metron_info: MetronInfo | None, comic_info: ComicInfo | None, da


def sync_comic(comic: Comic, services: Sequence[Service], days: int, force: bool = False) -> None:
if (
not should_sync(
metron_info=comic.get_metadata(MetronInfo),
comic_info=comic.get_metadata(ComicInfo),
days=days,
)
and not force
):
try:
metron_info = comic.get_metadata(MetronInfo)
except ValidationError as err:
CONSOLE.print(str(err), style="logging.level.error")
try:
comic_info = comic.get_metadata(ComicInfo)
except ValidationError as err:
CONSOLE.print(str(err), style="logging.level.error")
if not should_sync(metron_info=metron_info, comic_info=comic_info, days=days) and not force:
return
query = Search.build(comic=comic)
try:
Expand Down Expand Up @@ -117,5 +119,5 @@ def run(args: Namespace) -> None:
sync_comic(
comic=comic, services=services, days=settings.sync.days, force=args.force
)
except UnsupportedArchiveError: # noqa: PERF203
except UnsupportedArchiveError:
pass
2 changes: 1 addition & 1 deletion perdoo/services/metron.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def wrapper(*args, **kwargs) -> T: # noqa: ANN002, ANN003
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except RateLimitError as err: # noqa: PERF203
except RateLimitError as err:
if attempt == max_retries - 1:
raise
CONSOLE.print(
Expand Down
11 changes: 3 additions & 8 deletions perdoo/settings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
__all__ = ["Settings"]

from collections.abc import Sequence
from enum import Enum
from enum import StrEnum
from pathlib import Path
from typing import Annotated, ClassVar, Literal
from typing import Annotated, ClassVar, Literal, Self

from msgspec import Meta, Struct, ValidationError, field, to_builtins
from msgspec.toml import decode, encode
Expand All @@ -13,11 +13,6 @@
from perdoo.console import CONSOLE
from perdoo.utils import flatten_dict

try:
from typing import Self # Python >= 3.11 # ty:ignore[unresolved-import]
except ImportError:
from typing_extensions import Self # Python < 3.11


class ComicInfo(Struct, rename="kebab"):
create: bool = True
Expand Down Expand Up @@ -51,7 +46,7 @@ class Metron(Struct, rename="kebab"):
token: str | None = None


class Service(str, Enum):
class Service(StrEnum):
COMICVINE = "Comicvine"
METRON = "Metron"

Expand Down
Loading
Loading