diff --git a/README.md b/README.md index 549a8a4..a8dad7d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Kalente -Kalente logo +Kalente logo Kalente is a simple Python script for generating PDF calendars. diff --git a/pyproject.toml b/pyproject.toml index 895e1d8..1d66344 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "kalente" -version = "0.1.2" +version = "0.1.3" authors = [ { name="Kumi Mitterer", email="kalente@kumi.email" }, ] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..195adb7 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +djlint +black \ No newline at end of file diff --git a/src/kalente/__main__.py b/src/kalente/__main__.py index 98c5585..b0450d8 100644 --- a/src/kalente/__main__.py +++ b/src/kalente/__main__.py @@ -6,12 +6,15 @@ from datetime import date, timedelta from pathlib import Path from typing import Optional from locale import setlocale, LC_ALL +from base64 import b64encode from jinja2 import Environment, FileSystemLoader from dateutil.parser import parse import math +NO_LOGO = "" + def get_day( for_date: date = None, @@ -25,11 +28,14 @@ def get_day( "date_obj": day, "day": day.strftime("%A"), "date": day.strftime(date_format), - "holiday": holidays.CountryHoliday(country_code, years=[for_date.year]).get(day), + "holiday": holidays.CountryHoliday(country_code, years=[for_date.year]).get( + day + ), "is_weekend": (day.weekday() in [5, 6]), } return day_info + def get_week( for_date: date = None, country_code: Optional[str] = None, @@ -60,6 +66,7 @@ def get_week( week_days.append(day_info) return week_days + def get_month( for_date: date = None, country_code: Optional[str] = None, @@ -87,6 +94,7 @@ def get_month( return month_weeks + def get_year( for_date: date = None, country_code: Optional[str] = None, @@ -107,7 +115,10 @@ def get_year( return year_months -def generate_html(content, content_type, template_path: str = None): + +def generate_html( + content, content_type, template_path: str = None, logo_path: str = None +): if not template_path: template_name = "{}.html".format(content_type) file_loader = FileSystemLoader(Path(__file__).parent.absolute() / "templates") @@ -115,20 +126,35 @@ def generate_html(content, content_type, template_path: str = None): template_name = template_path file_loader = FileSystemLoader() + if logo_path is None: + logo_path = Path(__file__).parent / "static" / "logo.png" + + if logo_path: + # Let it throw, let it throw, let it throw... + with Path(logo_path).open("rb") as logo_file: + logo = b64encode(logo_file.read()).decode("utf-8") + mime_type = ( + "image/png" if str(logo_path).endswith(".png") else "image/jpeg" + ) # Doesn't matter much anyway. + data_uri = f"data:image/png;base64,{logo}" + env = Environment(loader=file_loader) template = env.get_template(template_name) + context = {"logo": data_uri} + if content_type == "yearly": - return template.render(year=content) + return template.render(year=content, **context) elif content_type == "monthly": - return template.render(month=content, month_obj=content[1][0]["date_obj"]) + return template.render(month=content, **context) elif content_type == "weekly": - return template.render(week=content) + return template.render(week=content, **context) elif content_type == "daily": - return template.render(day=content) + return template.render(day=content, **context) else: raise ValueError("Invalid content type: {}".format(content_type)) + def convert_html_to_pdf(content, output_filename, options=None): options.setdefault("page-size", "A4") options.setdefault("orientation", "Landscape") @@ -224,6 +250,20 @@ def main(): default=None, ) + logo_group = parser.add_mutually_exclusive_group() + logo_group.add_argument( + "--logo", + help="Path to the logo to use", + required=False, + default=None, + ) + logo_group.add_argument( + "--no-logo", + action="store_true", + help="Don't use a logo", + required=False, + ) + args = parser.parse_args() # Set locale to en_US.UTF-8 – for now, only English is supported @@ -277,20 +317,27 @@ def main(): if not args.type in ["daily", "weekly", "monthly", "yearly"]: raise ValueError(f"Invalid calendar type: {args.type}") + if args.no_logo: + logo_path = NO_LOGO + else: + logo_path = args.logo + for i in range(count): - data = ({ - "daily": get_day, - "weekly": get_week, - "monthly": get_month, - "yearly": get_year - }[args.type])(for_date, country_code, args.date_format) - html_content = generate_html(data, args.type, args.template) + data = ( + { + "daily": get_day, + "weekly": get_week, + "monthly": get_month, + "yearly": get_year, + }[args.type] + )(for_date, country_code, args.date_format) + html_content = generate_html(data, args.type, args.template, logo_path) pages.append(html_content) for_date = { "daily": lambda x: x["date_obj"] + timedelta(days=1), "weekly": lambda x: x[-1]["date_obj"] + timedelta(days=1), "monthly": lambda x: x[1][0]["date_obj"] + timedelta(days=31), - "yearly": lambda x: x[11][5][0]["date_obj"] + timedelta(days=365) + "yearly": lambda x: x[11][5][0]["date_obj"] + timedelta(days=365), }[args.type](data) conversion_options = {"orientation": "Portrait"} if args.type == "daily" else {} diff --git a/img/kalente.png b/src/kalente/static/logo.png similarity index 100% rename from img/kalente.png rename to src/kalente/static/logo.png diff --git a/src/kalente/templates/daily.html b/src/kalente/templates/daily.html index f2003fe..1e5e2b7 100644 --- a/src/kalente/templates/daily.html +++ b/src/kalente/templates/daily.html @@ -44,7 +44,9 @@ - + {% if logo %} + + {% endif %}

Day Planner

diff --git a/src/kalente/templates/monthly.html b/src/kalente/templates/monthly.html index 19e2ff5..462637e 100644 --- a/src/kalente/templates/monthly.html +++ b/src/kalente/templates/monthly.html @@ -54,9 +54,9 @@ - + {% if logo %}{% endif %}
-

Monthly Calendar for {{ month_obj.strftime("%B %Y") }}

+

Monthly Calendar for {{ month[1][0]["date_obj"].strftime("%B %Y") }}

@@ -68,18 +68,20 @@ {% for week in month %} - - {% for day in week %} {% if day %} - - {% else %} - - {% endif %} {% endfor %} - + + {% for day in week %} + {% if day %} + + {% else %} + + {% endif %} + {% endfor %} + {% endfor %}
MondaySunday
- {{ day.date }}
{% if day.holiday %}{{ day.holiday }}{% endif %} -
+ {{ day.date }} +
+ {% if day.holiday %}{{ day.holiday }}{% endif %} +
diff --git a/src/kalente/templates/weekly.html b/src/kalente/templates/weekly.html index 6599648..3e68398 100644 --- a/src/kalente/templates/weekly.html +++ b/src/kalente/templates/weekly.html @@ -44,20 +44,22 @@ - + {% if logo %}{% endif %}

Weekly Calendar

{% for day in week %} - + {% endfor %} {% for day in week %} {% endfor %} diff --git a/src/kalente/templates/yearly.html b/src/kalente/templates/yearly.html index 5f7db8c..5b0be67 100644 --- a/src/kalente/templates/yearly.html +++ b/src/kalente/templates/yearly.html @@ -54,51 +54,48 @@ - {% set splits = ((0, 6), (6,12)) %} {% for start, end in splits %} - -

Yearly Calendar

- - - -
{{ day.day }}
{{ day.date }}
+ {{ day.day }} +
+ {{ day.date }} +
- {% if day.holiday %} - {{ day.holiday }} - {% endif %} + {% if day.holiday %}{{ day.holiday }}{% endif %}
- - {% for month in year %} {% if start|int <= - (month[1][1].date_obj.month|int - 1) and (month[1][1].date_obj.month|int - - 1 < end|int) %} - - {% endif %} {% endfor %} - - - {% set last_month = namespace(prev=start) %} {% for date in range(1, 32) - %} - - {% for month in year %} {% if start|int <= - (month[1][1].date_obj.month|int - 1) and (month[1][1].date_obj.month|int - - 1 < end|int) %} {% for week in month %} {% for day in week %} {% if - day.date_obj.day == date and day.date_obj.month == - month[1][1].date_obj.month %}{% if last_month.prev < - (month[1][1].date_obj.month - 1) %} - - {% endif %} - - {% set last_month.prev = month[1][1].date_obj.month %} {% endif %} {% - endfor %} {% endfor %} {% endif %} {% endfor %} - {% if last_month.prev < end|int %} - - {% endif %} - - {% endfor %} -
-
- {{ month[1][1].date_obj.strftime("%B") }} -
-
- {{ day.date_obj.strftime("%d") }} {% if day.holiday %}{{ - day.holiday }}{% endif %} -
- + {% set splits = (0, 6), (6, 12) %} + {% for start, end in splits %} +

Yearly Calendar for {{ year.1.1.1.date_obj.year }}

+ {% if logo %} + + {% endif %} + + + {% for month in year %} + {% if start <= (month[1][1].date_obj.month - 1) and + (month[1][1].date_obj.month - 1 < end) %} + + {% endif %} + {% endfor %} + + {% set last_month = namespace(prev=start) %} + {% for date in range(1, 32) %} + + {% for month in year %} + {% if start <= (month[1][1].date_obj.month - 1) and + (month[1][1].date_obj.month - 1 < end|int) %} + {% for week in month %} + {% for day in week %} + {% if day.date_obj.day == date and + day.date_obj.month == month[1][1].date_obj.month %} + {% if last_month.prev < (month[1][1].date_obj.month - 1) %}{% endif %} + + {% set last_month.prev = month[1][1].date_obj.month %} + {% endif %} + {% endfor %} + {% endfor %} + {% endif %} + {% endfor %} + {% if last_month.prev < end %}{% endif %} + + {% endfor %} +
+
{{ month[1][1].date_obj.strftime("%B") }}
+
+ {{ day.date_obj.strftime("%d") }} + {% if day.holiday %}{{ day.holiday }}{% endif %} +
{% endfor %}