diff --git a/README.md b/README.md index 034bdbb..442989d 100644 --- a/README.md +++ b/README.md @@ -58,20 +58,3 @@ Create a list of lemmas for the given phrase. ```sh python lemmatize.py ``` - -## Build PDF - -Build all required files for a rower. - -```sh -python fillforms.py - # -on: SignOn date to use in the documents (DD/MM/YYYY). - # -t, --type: Specifies the list of files to be generate (['all']). ['national', 'image', 'fegar', 'xogade', 'all'] - # -p, --parent: Specifies if the rower requires parents data. (False) - # -i, --images: Folder containing the images for fegar generator. - # --coach: Create the files for a coach. - # --directive: Create the files for a delegate. - # --no-preset: Asks to input more information. - # --no-entity: Asks to input entity information. - # --debug: Logs and autofilled data. -``` diff --git a/fillforms.py b/fillforms.py deleted file mode 100755 index bb356f7..0000000 --- a/fillforms.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import logging -import os -from datetime import datetime - -from rscraping.builder import ( - PdfItem, - fill_fegar_form, - fill_image_form, - fill_national_form, - fill_xogade_form, -) - -logger = logging.getLogger(__name__) - - -def main( - signed_on: str, - types: list[str], - image_path: str, - use_preset: bool, - prompt_entity: bool, - is_coach: bool, - is_directive: bool, - has_parent: bool, - debug: bool, -): - data = PdfItem.preset() if use_preset else PdfItem() - data.sign_on(signed_on) - - data.is_coach = is_coach - data.is_directive = is_directive - data.is_rower = not is_coach and not is_directive - - data.prompt_data(prompt_entity=prompt_entity, has_parent=has_parent, use_preset=use_preset, debug=debug) - - if "national" in types or "all" in types: - fill_national_form(data, with_parent=has_parent) - if "image" in types or "all" in types: - fill_image_form(data, with_parent=args.parent) - if "fegar" in types or "all" in types: - fill_fegar_form(data, images_folder=image_path, with_parent=has_parent, remove_temp_files=not debug) - if has_parent and ("xogade" in types or "all" in types): - fill_xogade_form(data) - - -def _parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("-on", type=str, help="Date signed (DD/MM/YYYY", default=datetime.now().strftime("%d/%m/%Y")) - parser.add_argument("-t", "--type", nargs="*", help="List of files to generate", default=["all"]) - parser.add_argument( - "-p", - "--parent", - action="store_true", - help="Whether to ask for parental data. (False)", - default=False, - ) - parser.add_argument( - "-i", - "--images", - type=str, - action="store", - help="Folder containing the images for fegar generator.", - default=None, - ) - parser.add_argument( - "--preset", - action=argparse.BooleanOptionalAction, - help="Whether to use the preset data. (True)", - default=True, - ) - parser.add_argument( - "--entity", - action=argparse.BooleanOptionalAction, - help="Whether to ask for entity data. (True)", - default=True, - ) - parser.add_argument( - "--coach", - action="store_true", - help="Whether the licence should be for a coach. (False)", - default=False, - ) - parser.add_argument( - "--directive", - action="store_true", - help="Whether the licence should be for a directive. (False)", - default=False, - ) - parser.add_argument("--debug", action="store_true", default=False) - return parser.parse_args() - - -if __name__ == "__main__": - args = _parse_arguments() - logging.info(f"{os.path.basename(__file__)}:: args -> {args.__dict__}") - - signed_on, types, image_path, use_preset, prompt_entity, is_coach, is_directive, has_parent, debug = ( - args.on, - args.type, - args.images, - args.preset or args.debug, - args.entity, - args.coach, - args.directive, - args.parent, - args.debug, - ) - - if image_path: - assert os.path.isdir(image_path) - - main(signed_on, types, image_path, use_preset, prompt_entity, is_coach, is_directive, has_parent, debug) diff --git a/requirements.txt b/requirements.txt index 4eb474d..7196539 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -fillpdf==0.7.2 inquirer==3.2.1 matplotlib==3.8.2 numpy==1.26.3 diff --git a/rscraping/builder/__init__.py b/rscraping/builder/__init__.py deleted file mode 100644 index 78ac0b5..0000000 --- a/rscraping/builder/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from ._item import PdfItem # pyright: ignore -from .fegar import fill_fegar_form # pyright: ignore -from .image import fill_image_form # pyright: ignore -from .national import fill_national_form # pyright: ignore -from .xogade import fill_xogade_form # pyright: ignore diff --git a/rscraping/builder/_fields.py b/rscraping/builder/_fields.py deleted file mode 100644 index 05b8e69..0000000 --- a/rscraping/builder/_fields.py +++ /dev/null @@ -1,31 +0,0 @@ -class Fields: - FORM_NAME = "name" - FORM_SURNAME = "surname" - FORM_FULL_NAME = "full_name" - FORM_NIF = "nif" - FORM_GENDER = "gender" - FORM_BIRTH = "birth" - FORM_CATEGORY = "category" - FORM_NATIONALITY = "nationality" - - FORM_ADDRESS = "address" - FORM_ADDRESS_NUMBER = "address_number" - FORM_POSTAL_CODE = "postal_code" - FORM_TOWN = "town" - FORM_STATE = "state" - FORM_COUNTRY = "country" - FORM_PHONE = "phone" - FORM_EMAIL = "email" - - FORM_ENTITY = "entity" - FORM_ENTITY_ADDRESS = "entity_address" - FORM_ENTITY_STATE = "entity_state" - - FORM_SIGN_IN = "sign_in" - FORM_SIGN_ON_DAY = "sign_on_day" - FORM_SIGN_ON_MONTH = "sign_on_month" - FORM_SIGN_ON_YEAR = "sign_on_year" - - FORM_ROWER = "checkbox_rower" - FORM_COACH = "checkbox_coach" - FORM_DIRECTIVE = "checkbox_directive" diff --git a/rscraping/builder/_item.py b/rscraping/builder/_item.py deleted file mode 100644 index ad3a40a..0000000 --- a/rscraping/builder/_item.py +++ /dev/null @@ -1,243 +0,0 @@ -from dataclasses import dataclass -from datetime import datetime - -import inquirer - -from pyutils.validators import is_valid_dni, is_valid_email - - -@dataclass -class PdfItem: - name: str | None = None - surname: str | None = None - nif: str | None = None - gender: str | None = None - birth: str | None = None - nationality: str | None = None - category: str | None = None - - address: str | None = None - address_number: str | None = None - postal_code: str | None = None - town: str | None = None - state: str | None = None - country: str | None = None - phone: str | None = None - email: str | None = None - - entity: str | None = None - entity_town: str | None = None - entity_state: str | None = None - - sign_in: str | None = None - sign_on_day: str | None = None - sign_on_month: str | None = None - sign_on_year: str | None = None - - parent_name: str | None = None - parent_surname: str | None = None - parent_dni: str | None = None - parent_category: str | None = None - is_rower: bool | None = False - - is_coach: bool | None = False - is_directive: bool | None = False - - @classmethod - def preset(cls) -> "PdfItem": - return PdfItem( - country="ESPAÑA", - nationality="ESPAÑOLA", - phone="609262163", - email="remopuebla@gmail.com", - entity="CLUB REMO PUEBLA", - entity_town="A POBRA DO CARAMIÑAL", - entity_state="A CORUÑA", - sign_in="A POBRA DO CARAMIÑAL", - parent_category="TUTOR", - ) - - def prompt_data(self, prompt_entity: bool, has_parent: bool, use_preset: bool, debug: bool = False) -> "PdfItem": - if debug: - self.name = "name" - self.surname = "surname" - self.nif = "11753905P" - self.gender = "HOMBRE" - self.birth = "23/11/2000" - self.address = "address" - self.address_number = "15" - self.postal_code = "15940" - self.town = "A POBRA DO CARAMIÑAL" - self.state = "A CORUÑA" - self.category = "CATEGORIA" - - self.parent_name = "parent_name" - self.parent_surname = "parent_surname" - self.parent_dni = "11753905P" - return self - - self.prompt_rower_data() - if has_parent: - self.prompt_parent_data() - if not prompt_entity: - self.prompt_entity_data() - if not use_preset: - self.prompt_extra_data() - return self - - def prompt_rower_data(self) -> "PdfItem": - answers = inquirer.prompt( - [ - inquirer.Text("name", message="Nombre", validate=lambda _, x: bool(x)), - inquirer.Text("surname", message="Apellidos", validate=lambda _, x: bool(x)), - inquirer.Text("nif", message="DNI", validate=lambda _, x: is_valid_dni(x.upper())), - inquirer.Text( - "birth", - message="Fecha nacimiento (DD/MM/YYYY)", - validate=lambda _, x: len(x.split("/")) == 3, - ), - inquirer.Text("gender", message="Sexo", choices=["HOMBRE", "MUJER"], validate=lambda _, x: bool(x)), - inquirer.Text("address", message="Dirección (calle, número)", validate=lambda _, x: bool(x)), - inquirer.Text( - "town", - message="Localidad", - default="A POBRA DO CARAMIÑAL", - validate=lambda _, x: bool(x), - ), - inquirer.Text( - "postal_code", - message="Código Postal", - default="15940", - validate=lambda _, x: len(x) == 5, - ), - inquirer.Text("state", message="Provincia", default="A CORUÑA", validate=lambda _, x: bool(x)), - ] - ) - - if not answers: - raise ValueError(f"error in {answers=}") - - self.name = answers["name"].upper() - self.surname = answers["surname"].upper() - self.nif = answers["nif"].upper() - self.birth = answers["birth"] - self.gender = answers["gender"].upper() - self.town = answers["town"].upper() - self.postal_code = answers["postal_code"] - self.state = answers["state"].upper() - - address = answers["address"].upper().split(",") - if len(address) == 1: - self.address = address[0] - else: - self.address = " ".join(address[:-1]) - self.address_number = address[-1] - - self.category = self._compute_category(int(self.birth.split("/")[-1])) - return self - - def prompt_extra_data(self) -> "PdfItem": - answers = inquirer.prompt( - [ - inquirer.Text("nationality", message="Nacionalidad", default="ESPAÑOLA", validate=lambda _, x: bool(x)), - inquirer.Text("country", message="Pais", default="ESPAÑA", validate=lambda _, x: bool(x)), - inquirer.Text( - "sign_in", - message="Firmado en", - default="A POBRA DO CARAMIÑAL", - validate=lambda _, x: bool(x), - ), - ] - ) - - if not answers: - raise ValueError(f"error in {answers=}") - - self.nationality = answers["nationality"].upper() - self.country = answers["country"].upper() - self.sign_in = answers["sign_in"].upper() - - return self - - def prompt_entity_data(self) -> "PdfItem": - answers = inquirer.prompt( - [ - inquirer.Text("phone", message="Telefono", default="609262163", validate=lambda _, x: len(x) == 9), - inquirer.Text( - "email", - message="Correo", - default="remopuebla@gmail.com", - validate=lambda _, x: is_valid_email(x), - ), - inquirer.Text("entity", message="Club", default="CLUB REMO PUEBLA", validate=lambda _, x: bool(x)), - inquirer.Text( - "entity_town", - message="Localidad Club", - default="A POBRA DO CARAMIÑAL", - validate=lambda _, x: bool(x), - ), - inquirer.Text( - "entity_state", - message="Provincia Club", - default="A CORUÑA", - validate=lambda _, x: bool(x), - ), - ] - ) - - if not answers: - raise ValueError(f"error in {answers=}") - - self.phone = answers["phone"] - self.email = answers["email"].lower() - self.entity = answers["entity"].upper() - self.entity_town = answers["entity_town"].upper() - self.entity_state = answers["entity_state"].upper() - - return self - - def prompt_parent_data(self) -> "PdfItem": - answers = inquirer.prompt( - [ - inquirer.Text("parent_name", message="Nombre Tutor", validate=lambda _, x: bool(x)), - inquirer.Text("parent_surname", message="Apellidos Tutor", validate=lambda _, x: bool(x)), - inquirer.Text("parent_dni", message="DNI Tutor", validate=lambda _, x: is_valid_dni(x.upper())), - inquirer.Text( - "parent_category", - message="Tipo de Tutor", - default="TUTOR", - validate=lambda _, x: bool(x), - ), - ] - ) - - if not answers: - raise ValueError(f"error in {answers=}") - - self.parent_name = answers["parent_name"] - self.parent_surname = answers["parent_surname"].upper() - self.parent_dni = answers["parent_dni"].upper() - self.parent_category = answers["parent_category"].upper() - - return self - - def sign_on(self, date: str) -> "PdfItem": - day, month, year = date.split("/") - self.sign_on_day = day - self.sign_on_month = month - self.sign_on_year = year - return self - - def _compute_category(self, birth_year: int) -> str: - age = datetime.now().year - birth_year - category_ranges = { - "SENIOR": (19, float("inf")), - "JUVENIL": (17, 18), - "CADETE": (15, 16), - "INFANTIL": (13, 14), - "ALEVIN": (0, 12), - } - for category, (min_age, max_age) in category_ranges.items(): - if min_age <= age <= max_age: - return category - raise ValueError(f"not found category for {birth_year=}") diff --git a/rscraping/builder/fegar.py b/rscraping/builder/fegar.py deleted file mode 100644 index e0fbff5..0000000 --- a/rscraping/builder/fegar.py +++ /dev/null @@ -1,127 +0,0 @@ -import logging -import os - -from fillpdf import fillpdfs - -from ._fields import Fields -from ._item import PdfItem - -FILE = "templates/fegar.pdf" -NIF_SIZE = (245, 150) -IMAGE_SIZE = (90, 110) - - -def fill_fegar_form( - data: PdfItem, with_parent: bool, images_folder: str | None = None, remove_temp_files: bool = True -): - logging.info("fegar:: starting fegar form") - - values = { - Fields.FORM_NAME: data.name, - Fields.FORM_SURNAME: data.surname, - Fields.FORM_NIF: data.nif, - Fields.FORM_GENDER: data.gender, - Fields.FORM_BIRTH: data.birth, - Fields.FORM_CATEGORY: data.category, - Fields.FORM_TOWN: data.town, - Fields.FORM_STATE: data.state, - Fields.FORM_NATIONALITY: data.nationality, - Fields.FORM_ADDRESS: data.address, - Fields.FORM_ADDRESS_NUMBER: data.address_number, - Fields.FORM_POSTAL_CODE: data.postal_code, - Fields.FORM_COUNTRY: data.country, - Fields.FORM_PHONE: data.phone, - Fields.FORM_ENTITY: data.entity, - Fields.FORM_EMAIL: data.email, - Fields.FORM_SIGN_IN: data.sign_in, - Fields.FORM_SIGN_ON_DAY: data.sign_on_day, - Fields.FORM_SIGN_ON_MONTH: data.sign_on_month, - Fields.FORM_SIGN_ON_YEAR: data.sign_on_year[2:] if data.sign_on_year else None, - Fields.FORM_ENTITY_ADDRESS: data.entity_town, - Fields.FORM_ENTITY_STATE: data.entity_state, - Fields.FORM_ROWER: "Yes" if data.is_rower else None, - Fields.FORM_COACH: "Yes" if data.is_coach else None, - Fields.FORM_DIRECTIVE: "Yes" if data.is_directive else None, - } - assert data.birth - - if with_parent: - values[f"parent_{Fields.FORM_NAME}"] = data.parent_name - values[f"parent_{Fields.FORM_SURNAME}"] = data.parent_surname - values[f"parent_{Fields.FORM_NIF}"] = data.parent_dni - values[f"parent_{Fields.FORM_ADDRESS}"] = data.address - values[f"parent_{Fields.FORM_ADDRESS_NUMBER}"] = data.address_number - values[f"parent_{Fields.FORM_TOWN}"] = data.town - values[f"parent_{Fields.FORM_POSTAL_CODE}"] = data.postal_code - - logging.info(f"fegar:: {values=}") - file_name = f"./out/{data.birth.split('/')[-1]} - {data.surname}, {data.name}_fegar" - fillpdfs.write_fillable_pdf(FILE, f"{file_name}.pdf", values) - - if images_folder: - add_images(data, images_folder, file_name, remove_temp_files=remove_temp_files) - - -def add_images(data: PdfItem, images_folder: str, file_name: str, remove_temp_files: bool): - assert data.name and data.surname - image_file = front_file = back_file = None - - for file in os.listdir(images_folder): - file_lower = file.lower() - if not os.path.isfile(file) and not any(file_lower.endswith(x) for x in ["png", "jpg", "jpeg"]): - continue - - if data.name.lower() in file_lower and data.surname.lower() in file_lower: - if "image" in file_lower: - image_file = os.path.join(images_folder, file) - if "back" in file_lower: - back_file = os.path.join(images_folder, file) - if "front" in file_lower: - front_file = os.path.join(images_folder, file) - - if any(x is None for x in [image_file, front_file, back_file]): - raise ValueError("Image not found") - - logging.info(f"fegar:: adding {image_file=}") - fillpdfs.place_image( - file_name=image_file, - x=460, - y=95, - input_pdf_path=f"{file_name}.pdf", - output_map_path=f"{file_name}_with_image.pdf", - page_number=0, - width=IMAGE_SIZE[0], - height=IMAGE_SIZE[1], - ) - - logging.info(f"fegar:: adding {front_file=}") - fillpdfs.place_image( - file_name=front_file, - x=76, - y=625, - input_pdf_path=f"{file_name}_with_image.pdf", - output_map_path=f"{file_name}_with_front.pdf", - page_number=0, - width=NIF_SIZE[0], - height=NIF_SIZE[1], - ) - - logging.info(f"fegar:: adding {back_file=}") - fillpdfs.place_image( - file_name=back_file, - x=322, - y=625, - input_pdf_path=f"{file_name}_with_front.pdf", - output_map_path=f"{file_name}_complete.pdf", - page_number=0, - width=NIF_SIZE[0], - height=NIF_SIZE[1], - ) - - if remove_temp_files: - logging.info("fegar:: removing temporal files") - os.remove(f"{file_name}.pdf") - os.remove(f"{file_name}_with_image.pdf") - os.remove(f"{file_name}_with_front.pdf") - - os.rename(f"{file_name}_complete.pdf", f"{file_name}.pdf") diff --git a/rscraping/builder/image.py b/rscraping/builder/image.py deleted file mode 100644 index 17a95f4..0000000 --- a/rscraping/builder/image.py +++ /dev/null @@ -1,35 +0,0 @@ -import logging - -from fillpdf import fillpdfs - -from ._fields import Fields -from ._item import PdfItem - -FILE = "templates/image.pdf" -MINOR_FILE = "templates/image_minor.pdf" - - -def fill_image_form(data: PdfItem, with_parent: bool): - logging.info("image:: starting image form") - - values = { - Fields.FORM_FULL_NAME: f"{data.name} {data.surname}", - Fields.FORM_NIF: data.nif, - Fields.FORM_SIGN_IN: data.sign_in, - Fields.FORM_SIGN_ON_DAY: data.sign_on_day, - Fields.FORM_SIGN_ON_MONTH: data.sign_on_month, - Fields.FORM_SIGN_ON_YEAR: data.sign_on_year[2:] if data.sign_on_year else None, - } - assert data.birth - - if with_parent: - values[f"parent_{Fields.FORM_FULL_NAME}"] = f"{data.parent_name} {data.parent_surname}" - values[f"parent_{Fields.FORM_NIF}"] = data.parent_dni - values[f"parent_{Fields.FORM_CATEGORY}"] = data.parent_category - - logging.info(f"image:: {values=}") - fillpdfs.write_fillable_pdf( - MINOR_FILE if with_parent else FILE, - f"./out/{data.birth.split('/')[-1]} - {data.surname}, {data.name}_image.pdf", - values, - ) diff --git a/rscraping/builder/national.py b/rscraping/builder/national.py deleted file mode 100644 index 1b09afc..0000000 --- a/rscraping/builder/national.py +++ /dev/null @@ -1,44 +0,0 @@ -import logging - -from fillpdf import fillpdfs - -from ._fields import Fields -from ._item import PdfItem - -FILE = "templates/national.pdf" - - -def fill_national_form(data: PdfItem, with_parent: bool): - logging.info("national:: starting national form") - - values = { - Fields.FORM_FULL_NAME: f"{data.name} {data.surname}", - Fields.FORM_ADDRESS: f"{data.address}, {data.address_number}" if data.address_number else data.address, - Fields.FORM_POSTAL_CODE: data.postal_code, - Fields.FORM_TOWN: data.town, - Fields.FORM_STATE: data.state, - Fields.FORM_PHONE: data.phone, - Fields.FORM_BIRTH: data.birth, - Fields.FORM_GENDER: data.gender, - Fields.FORM_NATIONALITY: data.nationality, - Fields.FORM_NIF: data.nif, - Fields.FORM_ENTITY: data.entity, - Fields.FORM_EMAIL: data.email, - Fields.FORM_SIGN_IN: data.sign_in, - Fields.FORM_SIGN_ON_DAY: data.sign_on_day, - Fields.FORM_SIGN_ON_MONTH: data.sign_on_month, - Fields.FORM_SIGN_ON_YEAR: data.sign_on_year[2:] if data.sign_on_year else None, - Fields.FORM_ROWER: "Yes" if data.is_rower else None, - Fields.FORM_COACH: "Yes" if data.is_coach else None, - Fields.FORM_DIRECTIVE: "Yes" if data.is_directive else None, - } - assert data.birth - - if with_parent: - values[f"parent_{Fields.FORM_FULL_NAME}"] = f"{data.parent_name} {data.parent_surname}" - values[f"parent_{Fields.FORM_NIF}"] = data.parent_dni - - logging.info(f"national:: {values=}") - fillpdfs.write_fillable_pdf( - FILE, f"./out/{data.birth.split('/')[-1]} - {data.surname}, {data.name}_national.pdf", values - ) diff --git a/rscraping/builder/xogade.py b/rscraping/builder/xogade.py deleted file mode 100644 index 479ea9c..0000000 --- a/rscraping/builder/xogade.py +++ /dev/null @@ -1,29 +0,0 @@ -import logging - -from fillpdf import fillpdfs - -from ._fields import Fields -from ._item import PdfItem - -FILE = "templates/xogade.pdf" - - -def fill_xogade_form(data: PdfItem): - logging.info("xogade:: starting xogade form") - - values = { - Fields.FORM_FULL_NAME: f"{data.name} {data.surname}", - Fields.FORM_ENTITY: data.entity, - Fields.FORM_SIGN_IN: data.sign_in, - Fields.FORM_SIGN_ON_DAY: data.sign_on_day, - Fields.FORM_SIGN_ON_MONTH: data.sign_on_month, - Fields.FORM_SIGN_ON_YEAR: data.sign_on_year[2:] if data.sign_on_year else None, - f"parent_{Fields.FORM_FULL_NAME}": f"{data.parent_name} {data.parent_surname}", - f"parent_{Fields.FORM_NIF}": data.parent_dni, - } - assert data.birth - - logging.info(f"xogade:: {values=}") - fillpdfs.write_fillable_pdf( - FILE, f"./out/{data.birth.split('/')[-1]} - {data.surname}, {data.name}_xogade.pdf", values - ) diff --git a/templates/fegar.pdf b/templates/fegar.pdf deleted file mode 100644 index e489e11..0000000 Binary files a/templates/fegar.pdf and /dev/null differ diff --git a/templates/image.pdf b/templates/image.pdf deleted file mode 100644 index c799ea0..0000000 Binary files a/templates/image.pdf and /dev/null differ diff --git a/templates/image_minor.pdf b/templates/image_minor.pdf deleted file mode 100644 index deb8b37..0000000 Binary files a/templates/image_minor.pdf and /dev/null differ diff --git a/templates/national.pdf b/templates/national.pdf deleted file mode 100644 index 3468f73..0000000 Binary files a/templates/national.pdf and /dev/null differ diff --git a/templates/xogade.pdf b/templates/xogade.pdf deleted file mode 100644 index fcef964..0000000 Binary files a/templates/xogade.pdf and /dev/null differ