Packaging and docker publishing

This commit is contained in:
Yax 2025-09-14 16:02:25 +02:00
parent e4fb12d173
commit 5797dc0dee
7 changed files with 127 additions and 32 deletions

31
Dockerfile Normal file
View file

@ -0,0 +1,31 @@
FROM python:3.13.1-alpine3.20
ARG DIST_VERSION=1.0
ARG DIST_FILENAME=dumbremind-${DIST_VERSION}-py3-none-any.whl
RUN apk update && apk add bash && apk add wget
# Timezone
RUN apk add tzdata
RUN cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
RUN echo "Europe/Paris" > /etc/timezone
# Clean apk cache
RUN rm -rf /var/cache/apk/*
COPY docker/docker-init.sh /usr/local/bin/
RUN chmod +x usr/local/bin/docker-init.sh
RUN cd /
COPY dist/${DIST_FILENAME} /
RUN python3 -m pip install ${DIST_FILENAME}
# --target /app
RUN rm -f ${DIST_FILENAME}
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# NEVER PUBLISH IMAGE ON PUBLIC REPOSITORY
COPY .env /.env
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
WORKDIR /
CMD ["docker-init.sh"]

39
Makefile Normal file
View file

@ -0,0 +1,39 @@
ifeq (run,$(firstword $(MAKECMDGOALS)))
# use the rest as arguments for "run"
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(RUN_ARGS):;@:)
endif
.PHONY: all build run test
# code quality
all: black typehint lint
black:
uv run isort --multi-line 3 --profile black src/ tests/
uv run black --target-version py311 src/ tests/
typehint:
uv run mypy --ignore-missing-imports src/ tests/
lint:
uv run pylint src/
# check
check: all
# build
build:
# https://stackoverflow.com/questions/24347450/how-do-you-add-additional-files-to-a-wheel
rm -rf build/* dist/* *.egg-info
uv sync
uv build --wheel --out-dir dist
docker build -t source.madyanne.fr/yax/dumbremind .
publish:
docker push source.madyanne.fr/yax/dumbremind
# run
run:
uv run -m dumbremind

View file

@ -2,6 +2,25 @@
Dumb CalDAV Reminder: definitively not a kind name but a very useful tool to retrieve CalDAV events and tasks and output them in a concise way. Combined with a cron and a notification system it should help my poor brain to be more efficient.
Usage : copy .env.default as .env then edit CalDAV connection parameters and and number of days to get.
## Usage
copy .env.default as .env then edit CalDAV connection parameters and number of days to retrieve.
uv run -m dumbremind
# or make
make run
## Docker :
Warning: docker image is designed to be published on a private repository because it includes credentials from your .env file
# build local image
make build
# change publish target first (mine is source.madyanne.fr/yax/dumbremind)
make publish
# run dumbremind in docker (adapt URI) and remove container on exit
docker run --rm source.madyanne.fr/yax/dumbremind
More to come: docker packaging

6
docker/docker-init.sh Normal file
View file

@ -0,0 +1,6 @@
#!/bin/bash
python3 -m dumbremind
# catch for debug
#tail -f /dev/null

View file

@ -1,7 +1,7 @@
[project]
name = "caldav-reminder"
name = "dumbremind"
version = "1.0"
description = "CalDav Reminder"
description = "Dumb Remind"
readme = "README.md"
authors = [
{ name = "Yax" }
@ -12,14 +12,9 @@ dependencies = [
"python-dotenv>=1.1.1",
]
[dependency-groups]
dev = [
]
[tool.setuptools]
[tool.setuptools.package-data]
[project.scripts]
dumbremind = "dumbremind:main"
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
requires = ["uv_build>=0.8.17,<0.9.0"]
build-backend = "uv_build"

View file

View file

@ -56,25 +56,30 @@ def display_todo(todo: dict[str, str]):
print("Todo : " + todo["summary"])
url = 'https://' + quote_plus(USERNAME) + ":" + quote_plus(PASSWORD) \
+ '@' + BASE_URL + quote_plus(USERNAME) + '/'
start = date.today()
end = start + timedelta(days=NEXT_DAYS)
client = caldav.DAVClient(url)
calendars = client.principal().calendars()
def main():
url = 'https://' + quote_plus(USERNAME) + ":" + quote_plus(PASSWORD) \
+ '@' + BASE_URL + quote_plus(USERNAME) + '/'
start = date.today()
end = start + timedelta(days=NEXT_DAYS)
client = caldav.DAVClient(url)
calendars = client.principal().calendars()
if not calendars:
print("No calendars defined for " + USERNAME)
sys.exit(0)
if not calendars:
print("No calendars defined for " + USERNAME)
sys.exit(0)
for cal in calendars:
events = cal.search(event=True, start=start, end=end, expand=True) \
+ cal.search(todo=True)
for event in events:
for component in event.icalendar_instance.walk():
if component.name == "VEVENT":
display_event(fill_event(component, cal))
elif component.name == "VTODO":
display_todo(fill_todo(component, cal))
for cal in calendars:
events = cal.search(event=True, start=start, end=end, expand=True) \
+ cal.search(todo=True)
for event in events:
for component in event.icalendar_instance.walk():
if component.name == "VEVENT":
display_event(fill_event(component, cal))
elif component.name == "VTODO":
display_todo(fill_todo(component, cal))
print(".")
print(".")
if __name__ == "__main__":
main()