Skip to content

Reference🔗

berhoel.get_comics 🔗

Download various daily comics.

Modules:

  • __main__ –

    Allow execution of module directly.

  • garfield –

    Download Garfield comic strips.

  • gen_pdf –

    Generate PDF from several comic PDFs.

  • gocomics –

    Download comics from gocomic.

  • peanuts –

    Download Peanuts comics since Oct 2, 1950.

  • tests –

    Tests for get_comics.

Functions:

  • get_comics –

    Download various periodic comics.

Functions🔗

berhoel.get_comics.get_comics 🔗

get_comics() -> None

Download various periodic comics.

Source code in src/berhoel/get_comics/__init__.py
@click.command()
@click.version_option(version=f"{metadata.version('pyGetComics')}")
def get_comics() -> None:
    """Download various periodic comics."""
    with sync_playwright() as playwright:
        sys.stdout.write("Get Peanuts.\n")
        peanuts.Peanuts(playwright)()
        sys.stdout.write("Get Garfield.\n")
        garfield.Garfield(playwright)()

berhoel.get_comics.gocomics 🔗

Download comics from gocomic.

Classes:

  • GoComics –

    Download comics from GoComics.

  • SaveState –

    Save state information on already downloaded files and dates tried.

Functions:

  • mk_dir_tree –

    Generate directory including missing upper directories.

  • savestate –

    Save state dictionary.

Classes🔗

berhoel.get_comics.gocomics.GoComics 🔗

GoComics(playwright: Playwright)

Download comics from GoComics.

Methods:

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __init__(self, playwright: Playwright) -> None:
    """Initialize class instance."""
    self.start_date = date(
        self.start_year,
        self.start_month,
        self.start_day,
    )

    self.delta = dtm.timedelta(days=1)
    self.browser = playwright.chromium.launch(headless=True)
Functions🔗
__call__ 🔗
__call__() -> None

Control program flow.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __call__(self) -> None:  # noqa: PLR0915, C901
    """Control program flow."""
    state = self._open_statefile()

    cur_date = datetime.now(tz=dtm.UTC).date()

    count = self.max_num

    cur_year = 0
    cur_month = 0

    devidor = 7

    while (cur_date := cur_date - self.delta) >= self.start_date:
        if cur_date in self.skip:
            continue
        if count <= 0:
            break
        cur_year, cur_month = self._progres_cur_date(cur_year, cur_month, cur_date)

        png_path = Path(f"{cur_date:{self.png_path_fmt}}")
        pic_id = None
        if not png_path.is_file():
            key = png_path.with_suffix("").parts[-3:]
            state.tried[key] = (state.tried.get(key, -1) + 1) % devidor  # type:ignore[index,arg-type]
            if state.tried[key] != 0:  # type:ignore[index]
                sys.stdout.write("+")
                state.downloaded[2] += 1
                continue

            sys.stdout.flush()

            gif_path = Path(f"{cur_date:{self.gif_path_fmt}}")
            if not gif_path.is_file():
                data_norm = None
                img = self._get_img(cur_date, png_path)
                if img is None:
                    state.downloaded[3] += 1
                    continue

                pic_id = gif_path.with_suffix("").parts[-3:]

                if state.loaded.get(pic_id) is not None:  # type:ignore[arg-type]
                    sys.stdout.write(".")
                    sys.stdout.flush()
                    sys.stdout.write(
                        f"\r{png_path} is same as of {state.loaded.get(pic_id)}\n",  # type:ignore[arg-type]
                    )
                    state.downloaded[3] += 1
                    count -= 1
                    continue

                mk_dir_tree(png_path.parent)

                with urlopen(img) as response:  # noqa: S310
                    if response.headers.get_default_type() == "text/html":
                        if not isinstance(data_norm, str):
                            raise TypeError
                        self._retrieve_image(data_norm, gif_path)
                    else:
                        with Path(gif_path).open("wb") as outp:
                            outp.write(response.read())

            self._postprocess_image(gif_path, png_path)

            state.downloaded[0] += 1

            cur_datetime = datetime.combine(cur_date, datetime.min.time())

            os.utime(
                f"{png_path}", (cur_datetime.timestamp(), cur_datetime.timestamp())
            )
        else:
            state.downloaded[1] += 1
            sys.stdout.write("*")

        sys.stdout.flush()

    sys.stdout.write(
        f"\ndownloaded {state.downloaded[0]:d} strips, "
        f"kept {state.downloaded[1]:d}, "
        f"skipped {state.downloaded[2]:d}, "
        f"failed {state.downloaded[3]:d}\n",
    )

berhoel.get_comics.gocomics.SaveState 🔗

SaveState()

Save state information on already downloaded files and dates tried.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __init__(self) -> None:
    """Initialize class instance."""
    self.loaded: dict[tuple[str, str, str] | str, tuple[str, str, str] | str] = {}
    self.tried: dict[tuple[str, str, str], int] = {}
    self.downloaded = [0, 0, 0, 0]
Functions🔗

Functions🔗

berhoel.get_comics.gocomics.mk_dir_tree 🔗

mk_dir_tree(path: Path) -> None

Generate directory including missing upper directories.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def mk_dir_tree(path: Path) -> None:
    """Generate directory including missing upper directories."""
    if not path.is_dir():
        mode = (
            stat.S_ISGID
            | stat.S_IRWXU
            | stat.S_IRGRP
            | stat.S_IXGRP
            | stat.S_IROTH
            | stat.S_IXOTH
        )
        path.mkdir(mode=mode, parents=True)
        path.chmod(mode)

berhoel.get_comics.gocomics.savestate 🔗

savestate(state: SaveState, statfile: Path) -> None

Save state dictionary.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def savestate(state: SaveState, statfile: Path) -> None:
    """Save state dictionary."""
    with statfile.open("wb") as _statfile:
        fcntl.fcntl(_statfile, fcntl.LOCK_EX)
        pickle.dump(state, _statfile, protocol=5)
        fcntl.fcntl(_statfile, fcntl.LOCK_UN)

berhoel.get_comics.peanuts 🔗

Download Peanuts comics since Oct 2, 1950.

Modules:

  • __main__ –

    Allow execution of module directly.

  • clean_up –

    Prepare to delete Wrong Peanut downloads based on MD5.

  • gen_book –

    Generate Book of all Peanuts comics from images.

Classes:

  • Peanuts –

    Download daily Peanuts comics from GoComics.

Functions:

Classes🔗

berhoel.get_comics.peanuts.Peanuts 🔗

Peanuts(playwright: Playwright)

Download daily Peanuts comics from GoComics.

Methods:

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __init__(self, playwright: Playwright) -> None:
    """Initialize class instance."""
    self.start_date = date(
        self.start_year,
        self.start_month,
        self.start_day,
    )

    self.delta = dtm.timedelta(days=1)
    self.browser = playwright.chromium.launch(headless=True)
Functions🔗
__call__ 🔗
__call__() -> None

Control program flow.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __call__(self) -> None:  # noqa: PLR0915, C901
    """Control program flow."""
    state = self._open_statefile()

    cur_date = datetime.now(tz=dtm.UTC).date()

    count = self.max_num

    cur_year = 0
    cur_month = 0

    devidor = 7

    while (cur_date := cur_date - self.delta) >= self.start_date:
        if cur_date in self.skip:
            continue
        if count <= 0:
            break
        cur_year, cur_month = self._progres_cur_date(cur_year, cur_month, cur_date)

        png_path = Path(f"{cur_date:{self.png_path_fmt}}")
        pic_id = None
        if not png_path.is_file():
            key = png_path.with_suffix("").parts[-3:]
            state.tried[key] = (state.tried.get(key, -1) + 1) % devidor  # type:ignore[index,arg-type]
            if state.tried[key] != 0:  # type:ignore[index]
                sys.stdout.write("+")
                state.downloaded[2] += 1
                continue

            sys.stdout.flush()

            gif_path = Path(f"{cur_date:{self.gif_path_fmt}}")
            if not gif_path.is_file():
                data_norm = None
                img = self._get_img(cur_date, png_path)
                if img is None:
                    state.downloaded[3] += 1
                    continue

                pic_id = gif_path.with_suffix("").parts[-3:]

                if state.loaded.get(pic_id) is not None:  # type:ignore[arg-type]
                    sys.stdout.write(".")
                    sys.stdout.flush()
                    sys.stdout.write(
                        f"\r{png_path} is same as of {state.loaded.get(pic_id)}\n",  # type:ignore[arg-type]
                    )
                    state.downloaded[3] += 1
                    count -= 1
                    continue

                mk_dir_tree(png_path.parent)

                with urlopen(img) as response:  # noqa: S310
                    if response.headers.get_default_type() == "text/html":
                        if not isinstance(data_norm, str):
                            raise TypeError
                        self._retrieve_image(data_norm, gif_path)
                    else:
                        with Path(gif_path).open("wb") as outp:
                            outp.write(response.read())

            self._postprocess_image(gif_path, png_path)

            state.downloaded[0] += 1

            cur_datetime = datetime.combine(cur_date, datetime.min.time())

            os.utime(
                f"{png_path}", (cur_datetime.timestamp(), cur_datetime.timestamp())
            )
        else:
            state.downloaded[1] += 1
            sys.stdout.write("*")

        sys.stdout.flush()

    sys.stdout.write(
        f"\ndownloaded {state.downloaded[0]:d} strips, "
        f"kept {state.downloaded[1]:d}, "
        f"skipped {state.downloaded[2]:d}, "
        f"failed {state.downloaded[3]:d}\n",
    )

Functions🔗

berhoel.get_comics.peanuts.get_peanuts 🔗

get_peanuts() -> None

Download daily Peanuts comics.

Source code in src/berhoel/get_comics/peanuts/__init__.py
@click.command()
@click.version_option(version=f"{metadata.version('pyGetComics')}")
def get_peanuts() -> None:
    """Download daily Peanuts comics."""
    with sync_playwright() as playwright:
        Peanuts(playwright)()

berhoel.get_comics.peanuts.gen_book 🔗

Generate Book of all Peanuts comics from images.

Classes:

Functions:

  • main –

    Execute main processing.

Classes🔗

berhoel.get_comics.peanuts.gen_book.DayOfWeek 🔗

Day of week.

berhoel.get_comics.peanuts.gen_book.PeanutsBook 🔗

PeanutsBook(fname: Path)

Generate LaTeX file for Peanuts comic book.

Methods:

  • do_di –

    Place Tuesday figure.

  • do_do –

    Place Thursday figure.

  • do_fr –

    Place Friday figure.

  • do_mi –

    Place Wednesday figure.

  • do_mo –

    Place Monday figure.

  • do_sa –

    Place Saturday figure.

  • do_so –

    Place Sunday figure.

  • graphicspath –

    Write appropriate Graphicspath information.

  • place_img –

    Place image in grid.

  • run –

    Do the actual processing.

  • wr_image –

    Write information for including image.

  • write_epilog –

    Write LaTeX epilogue.

  • write_prologue –

    Write LaTeX prologue.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def __init__(self, fname: Path) -> None:
    """Initialize class instance."""
    self.cur_date = START_DATE
    self.fname = fname
    self.grpath: Path | None = None
    self.outp_done = False
    self.side_weekd = PrintPageSide.LEFT
    self.side_sund = PrintPageSide.RIGHT
    self.with_sund = False
    self.days: list[tuple[Callable, Path, datetime.datetime]] = []
Functions🔗
do_di 🔗
do_di(out: TextIOWrapper, fname: str, date: date) -> None

Place Tuesday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_di(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Tuesday figure."""
    self.place_img(out, Pos(self.side_weekd, 2), fname, date)
do_do 🔗
do_do(out: TextIOWrapper, fname: str, date: date) -> None

Place Thursday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_do(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Thursday figure."""
    self.place_img(out, Pos(self.side_weekd, 4), fname, date)
do_fr 🔗
do_fr(out: TextIOWrapper, fname: str, date: date) -> None

Place Friday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_fr(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Friday figure."""
    self.place_img(out, Pos(self.side_weekd, 5), fname, date)
do_mi 🔗
do_mi(out: TextIOWrapper, fname: str, date: date) -> None

Place Wednesday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_mi(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Wednesday figure."""
    self.place_img(out, Pos(self.side_weekd, 3), fname, date)
do_mo 🔗
do_mo(out: TextIOWrapper, fname: str, date: date) -> None

Place Monday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_mo(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Monday figure."""
    self.place_img(out, Pos(self.side_weekd, 1), fname, date)
do_sa 🔗
do_sa(out: TextIOWrapper, fname: str, date: date) -> None

Place Saturday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_sa(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Saturday figure."""
    self.place_img(out, Pos(self.side_weekd, 6), fname, date)
do_so 🔗
do_so(out: TextIOWrapper, fname: str, date: date) -> None

Place Sunday figure.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def do_so(self, out: TextIOWrapper, fname: str, date: datetime.date) -> None:
    """Place Sunday figure."""
    self.place_img(out, Pos(self.side_sund, 1), fname, date)
    self.with_sund = True
graphicspath 🔗
graphicspath(out: TextIOWrapper, path: Path) -> None

Write appropriate Graphicspath information.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def graphicspath(self, out: TextIOWrapper, path: Path) -> None:
    """Write appropriate Graphicspath information."""
    grpath = path.parent
    if grpath != self.grpath:
        out.write(f"\\graphicspath{{{{{grpath}}}}}\n")
        self.grpath = grpath
place_img 🔗
place_img(out: TextIOWrapper, pos: Pos, fname: str, date: date) -> None

Place image in grid.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
    def place_img(
        self,
        out: TextIOWrapper,
        pos: Pos,
        fname: str,
        date: datetime.date,
    ) -> None:
        """Place image in grid."""
        fac = "" if (date.isoweekday() == DayOfWeek.SUNDAY) else 1.0 / 7.0
        out.write(
            f"""\
\\begin{{textblock}}{{1}}({pos.x - 1:d},{pos.y - 1:d})
  {date:%a %d. %B %Y}\\par
  \\centering%
    \\includegraphics[width=.95\\linewidth,height={fac}\\textheight,%
         keepaspectratio]{{{fname}}}
\\end{{textblock}}
""",
        )
run 🔗
run() -> None

Do the actual processing.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def run(self) -> None:
    """Do the actual processing."""
    with self.fname.open("w") as out:
        self.write_prologue(out)

        while self.cur_date <= TODAY:
            self.wr_image(self.cur_date)
            if self.cur_date.isoweekday() == DayOfWeek.SUNDAY and self.outp_done:
                side_weekd = self.side_weekd
                if self.side_weekd == PrintPageSide.RIGHT and self.with_sund:
                    out.write("\\clearpage\n")
                    self.side_weekd = PrintPageSide.LEFT
                for func, path, date in self.days:
                    self.graphicspath(out, path)
                    func(out, path.name, date)
                if self.with_sund or side_weekd == PrintPageSide.RIGHT:
                    out.write("\\clearpage\n")
                    self.side_weekd = PrintPageSide.LEFT
                else:
                    self.side_weekd = PrintPageSide.RIGHT
                self.outp_done = False
                self.with_sund = False
                self.days = []

            self.cur_date += DELTA

        self.write_epilog(out)
wr_image 🔗
wr_image(date: datetime) -> None

Write information for including image.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def wr_image(self, date: datetime.datetime) -> None:
    """Write information for including image."""
    path = Path(f"{date:{PATH_FMT}}")
    if (path := path.with_suffix(".png")).is_file():
        weekday = date.isoweekday()
        self.days.append(
            (
                {
                    DayOfWeek.MONDAY: self.do_mo,
                    DayOfWeek.TUESDAY: self.do_di,
                    DayOfWeek.WEDNESDAY: self.do_mi,
                    DayOfWeek.THURSDAY: self.do_do,
                    DayOfWeek.FRIDAY: self.do_fr,
                    DayOfWeek.STATURDAY: self.do_sa,
                    DayOfWeek.SUNDAY: self.do_so,
                }[DayOfWeek(weekday)],
                path,
                date,
            ),
        )
        self.outp_done = True
write_epilog 🔗
write_epilog(out: TextIOWrapper) -> None

Write LaTeX epilogue.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
    def write_epilog(self, out: TextIOWrapper) -> None:
        """Write LaTeX epilogue."""
        out.write(
            r"""\end{multicols}
\end{document}
""",
        )
write_prologue 🔗
write_prologue(out: TextIOWrapper) -> None

Write LaTeX prologue.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
    def write_prologue(self, out: TextIOWrapper) -> None:
        """Write LaTeX prologue."""
        out.write(
            r"""\documentclass[a4paper,landscape]{book}
\usepackage{graphicx}
\usepackage{textpos}
\usepackage{multicol}
\usepackage[textwidth=277.0mm,textheight=189.9mm,headsep=1mm]{geometry}
\makeatletter
\TPGrid[12mm,12mm]{2}{6}
\setlength{\parindent}{0pt}
\usepackage{fontspec}
%\setmainfont[Ligatures={Common,Rare,Historic}, Numbers=OldStyle]{Linux Libertine O}
\usepackage{libertine}[Ligatures={Common,Rare,Historic}, Numbers=OldStyle]
\begin{document}
\begin{multicols}{2}
""",
        )

berhoel.get_comics.peanuts.gen_book.Pos 🔗

Position information.

berhoel.get_comics.peanuts.gen_book.PrintPageSide 🔗

Side on output.

Functions🔗

berhoel.get_comics.peanuts.gen_book.main 🔗

main() -> None

Execute main processing.

Source code in src/berhoel/get_comics/peanuts/gen_book.py
def main() -> None:
    """Execute main processing."""
    book = PeanutsBook(fname=Path("Peanuts_book.tex"))
    book.run()

berhoel.get_comics.peanuts.clean_up 🔗

Prepare to delete Wrong Peanut downloads based on MD5.

berhoel.get_comics.garfield 🔗

Download Garfield comic strips.

Modules:

  • __main__ –

    Allow execution of module directly.

Classes:

  • Garfield –

    Download daily Garfield comcs fromGoComics.

Functions:

Classes🔗

berhoel.get_comics.garfield.Garfield 🔗

Garfield(playwright: Playwright)

Download daily Garfield comcs fromGoComics.

Methods:

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __init__(self, playwright: Playwright) -> None:
    """Initialize class instance."""
    self.start_date = date(
        self.start_year,
        self.start_month,
        self.start_day,
    )

    self.delta = dtm.timedelta(days=1)
    self.browser = playwright.chromium.launch(headless=True)
Functions🔗
__call__ 🔗
__call__() -> None

Control program flow.

Source code in src/berhoel/get_comics/gocomics/__init__.py
def __call__(self) -> None:  # noqa: PLR0915, C901
    """Control program flow."""
    state = self._open_statefile()

    cur_date = datetime.now(tz=dtm.UTC).date()

    count = self.max_num

    cur_year = 0
    cur_month = 0

    devidor = 7

    while (cur_date := cur_date - self.delta) >= self.start_date:
        if cur_date in self.skip:
            continue
        if count <= 0:
            break
        cur_year, cur_month = self._progres_cur_date(cur_year, cur_month, cur_date)

        png_path = Path(f"{cur_date:{self.png_path_fmt}}")
        pic_id = None
        if not png_path.is_file():
            key = png_path.with_suffix("").parts[-3:]
            state.tried[key] = (state.tried.get(key, -1) + 1) % devidor  # type:ignore[index,arg-type]
            if state.tried[key] != 0:  # type:ignore[index]
                sys.stdout.write("+")
                state.downloaded[2] += 1
                continue

            sys.stdout.flush()

            gif_path = Path(f"{cur_date:{self.gif_path_fmt}}")
            if not gif_path.is_file():
                data_norm = None
                img = self._get_img(cur_date, png_path)
                if img is None:
                    state.downloaded[3] += 1
                    continue

                pic_id = gif_path.with_suffix("").parts[-3:]

                if state.loaded.get(pic_id) is not None:  # type:ignore[arg-type]
                    sys.stdout.write(".")
                    sys.stdout.flush()
                    sys.stdout.write(
                        f"\r{png_path} is same as of {state.loaded.get(pic_id)}\n",  # type:ignore[arg-type]
                    )
                    state.downloaded[3] += 1
                    count -= 1
                    continue

                mk_dir_tree(png_path.parent)

                with urlopen(img) as response:  # noqa: S310
                    if response.headers.get_default_type() == "text/html":
                        if not isinstance(data_norm, str):
                            raise TypeError
                        self._retrieve_image(data_norm, gif_path)
                    else:
                        with Path(gif_path).open("wb") as outp:
                            outp.write(response.read())

            self._postprocess_image(gif_path, png_path)

            state.downloaded[0] += 1

            cur_datetime = datetime.combine(cur_date, datetime.min.time())

            os.utime(
                f"{png_path}", (cur_datetime.timestamp(), cur_datetime.timestamp())
            )
        else:
            state.downloaded[1] += 1
            sys.stdout.write("*")

        sys.stdout.flush()

    sys.stdout.write(
        f"\ndownloaded {state.downloaded[0]:d} strips, "
        f"kept {state.downloaded[1]:d}, "
        f"skipped {state.downloaded[2]:d}, "
        f"failed {state.downloaded[3]:d}\n",
    )

Functions🔗

berhoel.get_comics.garfield.get_garfield 🔗

get_garfield() -> None

Download daily Garfield comics.

Source code in src/berhoel/get_comics/garfield/__init__.py
@click.command()
@click.version_option(version=f"{metadata.version('pyGetComics')}")
def get_garfield() -> None:
    """Download daily Garfield comics."""
    with sync_playwright() as playwright:
        Garfield(playwright)()

berhoel.get_comics.gen_pdf 🔗

Generate PDF from several comic PDFs.

Classes:

Classes🔗

berhoel.get_comics.gen_pdf.GenPDF 🔗

GenPDF(
    *,
    title: str,
    base_path: Path,
    start_date: date,
    paper_orientation: PaperOrientation = PORTRAIT
)

Create pdf for comic collection.

Methods:

Source code in src/berhoel/get_comics/gen_pdf/__init__.py
def __init__(
    self,
    *,
    title: str,
    base_path: Path,
    start_date: datetime.date,
    paper_orientation: PaperOrientation = PaperOrientation.PORTRAIT,
) -> None:
    """Generate PDF in comics path."""
    self.title = title
    self.base_path = base_path
    self.start_date = start_date
    self.paper_orientation = paper_orientation
Functions🔗
__call__ 🔗
__call__(start_date: date | None = None, end_date: date | None = None) -> str

Control program.

Source code in src/berhoel/get_comics/gen_pdf/__init__.py
def __call__(
    self,
    start_date: datetime.date | None = None,
    end_date: datetime.date | None = None,
) -> str:
    """Control program."""
    template = self.latex_jinja_env.get_template("book.tex")
    gen_dates = self._gen_dates(start_date, end_date)
    return template.render(
        paper_orientation=self.paper_orientation == PaperOrientation.PORTRAIT,
        dates=gen_dates,
        base_path=self.base_path,
        keep=Keep(),
    )

berhoel.get_comics.gen_pdf.Keep 🔗

Keep()

Helper class.

Methods:

Source code in src/berhoel/get_comics/gen_pdf/__init__.py
def __init__(self) -> None:
    """Keep values."""
    self.cur_month: int | None = None
Functions🔗
set_cur_month 🔗
set_cur_month(inp: int) -> None

Set current month.

Source code in src/berhoel/get_comics/gen_pdf/__init__.py
def set_cur_month(self, inp: int) -> None:
    """Set current month."""
    self.cur_month = inp

berhoel.get_comics.gen_pdf.PaperOrientation 🔗

Choose paper orientation.