#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""Manage entries for c't.
"""
# Standard library imports.
from datetime import datetime, timedelta
# Local library imports.
from .ctientry import CTIEntry
__date__ = "2023/12/01 17:29:55 hoel"
__author__ = "Berthold Höllmann"
__copyright__ = "Copyright © 2022 by Berthold Höllmann"
__credits__ = ["Berthold Höllmann"]
__maintainer__ = "Berthold Höllmann"
__email__ = "berhoel@gmail.com"
[docs]class IssueMap:
"""Class for determinig issue date for c't issues."""
[docs] def __init__(self):
self._issue_max: tuple[int, int] = (2022, 16)
self._issue_min: tuple[int, int] = self._issue_max
self._date_max: datetime = datetime(year=2022, month=7, day=16)
self._date_min: datetime = self._date_max
self._cache: dict[tuple[int, int], datetime] = {
self._issue_max: self._date_max,
(2018, 27): datetime(2018, 10, 23),
(2019, 27): datetime(2019, 10, 21),
(2020, 27): datetime(2020, 10, 20),
(2021, 27): datetime(2021, 10, 19),
(2022, 27): datetime(2022, 11, 26),
(2023, 26): datetime(2022, 11, 11),
(2023, 27): datetime(2023, 11, 18),
(2023, 28): datetime(2023, 12, 2),
(2023, 29): datetime(2023, 12, 16),
}
[docs] def __call__(self, year: int, issue: int) -> datetime:
"""Generate release dates for c't."""
key = (year, issue)
diff = timedelta(days=14)
if self._cache.get(key) is not None:
return self._cache[key]
while key > self._issue_max:
step_year, step_issue = self._issue_max
step_issue += 1
if step_issue >= 27:
step_issue = 1
step_year += 1
self._issue_max = (step_year, step_issue)
if (step_year, step_issue) == (2023, 12):
self._date_max = datetime(2023, 5, 13)
elif (step_year, step_issue) == (2023, 13):
self._date_max = datetime(2023, 5, 20)
else:
self._date_max += diff
self._cache[self._issue_max] = self._date_max
assert self._date_max < datetime.now() + timedelta(
days=16
), f"{self._date_max=} < {datetime.now() + timedelta(days=14)=}, {key=}"
while key < self._issue_min:
if self._date_min <= datetime(1997, 10, 13):
step_issue -= 1
if step_issue < 1:
step_issue = 12
step_year -= 1
self._date_min = datetime(step_year, step_issue, 1)
self._issue_min = (step_year, step_issue)
else:
self._date_min -= diff
step_year, step_issue = self._issue_min
step_issue -= 1
if self._date_min == datetime(2014, 6, 28):
self._date_min += timedelta(days=2)
if step_issue < 1:
step_year -= 1
if step_year in {2015}:
step_issue = 27
elif self._date_min < datetime(1997, 1, 1):
step_issue = 12
elif self._date_min < datetime(1998, 1, 5):
step_issue = 16
else:
step_issue = 26
self._issue_min = (step_year, step_issue)
self._cache[self._issue_min] = self._date_min
assert self._date_min > datetime(
1983, 1, 1
), f"{self._date_min=} > {datetime(1983, 1, 1)=}"
return self._cache[key]
[docs]class Ct:
"""Prepare c't issue information."""
issue_map = IssueMap()
month_issue_map = {
1: "Januar",
2: "Februar",
3: "März",
4: "April",
5: "Mai",
6: "Juni",
7: "Juli",
8: "August",
9: "September",
10: "Oktober",
11: "November",
12: "Dezember",
}
[docs] def __init__(
self,
shorttitle: str,
title: str,
author: list[str],
pages: int,
issue: int,
info: str,
year: int,
references: str,
keywords: str,
):
"""Add information for a c't issue.
Args:
shorttitle (str):
title (str):
author (str):
pages (int):
issue (int):
info (str):
year (int):
keywords (str):
"""
full_issue = self.year_issue2full_issue(year, issue)
self.date = self.issue_map(year, issue)
if not title:
self.shorttitle, self.title = None, shorttitle
else:
self.shorttitle, self.title = (
shorttitle,
title,
)
self.author = author
self.pages = pages
self.full_issue = full_issue
self.info = info
self.references = references
self.keywords = keywords
[docs] def __call__(self):
return CTIEntry(
self.shorttitle,
self.title,
self.author,
self.pages,
self.full_issue,
self.info,
"c't magazin für computertechnik",
self.date.strftime("%Y-%m-%d"),
self.references,
self.keywords,
)
[docs] @staticmethod
def year_issue2full_issue(year, issue):
"""Retrieve full issue for c't from year and issue number.
Args:
year (int):
issue (int):
Returns:
str
"""
if issue == 27:
if year == 2022:
issue = "c't Jahresrückblick 2022"
elif year > 2015:
issue = "retro"
if year < 1997 or year == 1997 and issue < 11:
return f"{year:04d} / {Ct.month_issue_map[issue]}"
return f"{year:04d} / {issue}"
# Local Variables:
# mode: python
# compile-command: "poetry run tox"
# time-stamp-pattern: "30/__date__ = \"%:y/%02m/%02d %02H:%02M:%02S %u\""
# End: