Skip to content
Draft
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Your Python installation must have the `tkinter`.

Optional features:
- **Modern theme**: This application will make use of _ttkbootstrap_ if available. Just run `pip install ausweiskopie[modern]`
- **XDG Desktop Portals** (native file open/save-as dialogs on Linux): If your desktop manager provides XDG portals, just install `pip install ausweiskopie[portals]`.
- **XDG Desktop Portals** (native file open/save-as dialogs on Linux/BSD): If your desktop manager provides XDG portals, just install `pip install ausweiskopie[portals]`.
- **Drag-and-Drop**: If your Tk/Tcl environment has the `tkdnd` extension, Drag-and-drop support is automatically enabled.

# Meine Ausweiskopie
Expand Down Expand Up @@ -129,5 +129,5 @@ Deine Python-Installation muss `tkinter` installiert haben.

Optionale-Features:
- **Modernes Look-and-Feel**: Mittels *ttkbootstrap* kann der Anwendung ein modernes Aussehen übergestülpt werden, zur Installation `pip install ausweiskopie[modern]` ausführen.
- **XDK Desktop Portals** (Natives Datei-Öffenen-/Speichern-Unter unter Linux): Die meisten Desktop-Umgebungen stellen diese mittlerweile bereit. Zur Installation `pip install ausweiskopie[portals]` durchführen.
- **XDG Desktop Portals** (Natives Datei-Öffenen-/Speichern-Unter unter Linux/BSDs): Die meisten Desktop-Umgebungen stellen diese mittlerweile bereit. Zur Installation `pip install ausweiskopie[portals]` durchführen.
- **Drag-and-Drop**: Wenn `tkdnd` in deiner Tk/Tcl-Installation vorhanden ist, funktioniert Drag-und-Drop von Bildern.
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ authors = [
]
dependencies = [
"pillow >= 8.0.0",
"importlib-resources"
"importlib-resources",
"pydantic",
"tomli; python_version<='3.11'"
]

[project.optional-dependencies]
portals = [
"dbus-python; sys_platform=='linux'", "pygobject; sys_platform=='linux'"
"dbus-python; platform_system=='Linux' or platform_system=='FreeBSD' or platform_system=='OpenBSD'",
"pygobject; platform_system=='Linux' or platform_system=='FreeBSD' or platform_system=='OpenBSD'"
]
modern = [
"ttkbootstrap >= 1.0"
Expand Down
119 changes: 119 additions & 0 deletions src/ausweiskopie/redact/document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import dataclasses
import datetime
import enum
import uuid
from typing import Optional, Tuple, Dict, List
from annotated_types import Gt

from pydantic import BaseModel
from typing_extensions import NotRequired, Annotated, TypedDict


class Side(str, enum.Enum):
"""Sides of id documents."""
FRONT = "front"
BACK = "back"


class Rectangle(TypedDict):
"""Rectangle on a side."""
tl: Tuple[Annotated[float, Gt(0)], Annotated[float, Gt(0)]]
br: Tuple[Annotated[float, Gt(0)], Annotated[float, Gt(0)]]


Layout = TypedDict("Layout", {
Side.FRONT: Dict[str, List[Rectangle]],
Side.BACK: NotRequired[Dict[str, List[Rectangle]]],
})


class MRZ(str, enum.Enum):
"""Possible ICAO MRZ variants.

Other forms of MRZ (QR codes, PDF417, bar code) will get their own field.
"""
TD1 = "TD-1"
TD2 = "TD-2"
TD3 = "TD-3"

def coordinates(self) -> Dict[Side, Rectangle]:
"""Return the positions of the MRZ."""
if self == MRZ.TD1:
return {}
elif self == MRZ.TD2:
return {}
elif self == MRZ.TD3:
return {}


class Type(str, enum.Enum):
"""Possible document types"""
# ID cards or papers
ID = "id"

# Passport (usually the copy of the bio card)
PASSPORT = "passport"

# Driving permits or similar licenses, they might serve as an id document
DRIVING_PERMIT = "driving-permit"

# Special passport-like travel documents for members of some organizations
# (e.g., UN, Red-Cross, EU)
LAISSEZ_PASSER = "laissez-passer"

# Documents allowing to live in some country
RESIDENCY_PERMIT = "residency-permit"

# Some countries issue special seafarer documents (similar to passports) to
# ease traveling from / to ships
SEAFARER = "seafarer"

# Other documents
OTHER = "other"


class Subtype(str, enum.Enum):
"""Possible document subtypes"""
# Temporary or emergency documents, issued if the original documents were
# lost, or they need to be issued in a short amount of time
TEMPORARY = "temporary"

# Diplomatic passports issued for diplomats
DIPLOMATIC = "diplomatic"

# Service passports, issued for members of the state
SERVICE = "service"

# Other non-standard type of the document
OTHER = "other"


@dataclasses.dataclass
class Metadata:
"""Document metadata"""
issuer: str
type: Type
subtype: str
issuedSince: datetime.date
issuedUntil: Optional[datetime.date] = None
revision: Optional[str] = None
mrz: Optional[MRZ] = None
mrzId: Optional[str] = None
dimensions: Optional[str] = None
dimensionsCustom: Optional[Tuple[float, float]] = None

@property
def dimensionSize(self) -> Tuple[float, float]:
pass

@dataclasses.dataclass
class Document(BaseModel):
id: uuid.UUID
meta: Metadata
layout: Layout
i18n: Dict[str, Dict[str, str]]

def merged_side(self, side: Side) -> List[Rectangle]:
pass


Loading