Scrapes appointments from termine.stadt-koeln.de an sends a message to a ntfy server.
Find a file
2024-09-17 22:49:27 +02:00
.idea 🚀 release version 1.0.3 2024-09-17 22:25:51 +02:00
src/cgnappointments 🚀 release version 1.1.0 2024-09-17 22:49:27 +02:00
.gitignore 🎉 Initial commit 2024-09-16 00:13:31 +02:00
pyproject.toml require python >=3.12 2024-09-17 22:25:05 +02:00
README.md implement a maximum time delta for appointment notification 2024-09-17 22:49:27 +02:00

cgn-appointments

This programm allows you to scrape the appointments from the website of the city of Cologne (Stadt Köln) and send a notification via ntfy if a new appointment is available.

Installation

A good way to install cgn-appointments is via pipx.

pipx install --index-url https://git.pub.solar/api/packages/marc/pypi/simple/ --pip-args="--extra-index-url https://pypi.org/simple" cgn-appointments

Configuration

Execute cgn-appointments for the first time to create the configuration file. Then edit the configuration file and adapt it to your needs.

---
# If this url does not work anymore, visit https://www.stadt-koeln.de/service/produkte/00416/index.html,
# copy the url of the "Termin Buchen" tile and replace the url below.
url: 'https://termine.stadt-koeln.de/m/kundenzentren/extern/calendar/?uid=b5a5a394-ec33-4130-9af3-490f99517071&wsid=e570a1ea-7b3d-43f6-bf43-3e60b3d7d888&lang=de&set_lang_ui=de&rev=rfOtF#top'

# Which services should be checked for free appointments?
# Copy the exact name of the service from the website.
services:
  - 'Personalausweis - Antrag'
  - 'Reisepass - Antrag (seit 01.01.2024 auch für Kinder unter 12 Jahren)'

# In which locations should the services be checked?
# Use the name as displayed on the website.
locations:
  - Ehrenfeld
  - Kalk
    
# Max time between today and a new appointment to notify about the new
# appointment. Set to -1 to notify about all new appointments.
max_timedelta: 14

# Path to the CSV file to store the scraped appointments
# csv_path: ~/Termine.csv

# Name of the CSV file to store the scraped appointments
csv_name: 'appointments.csv'

# Regex to extract the date from the website
# There should be no need to change this
date_regex: '(\\d{2}\\.\\d{2}\\.\\d{4}\\s\\d{2}:\\d{2})'

# Date format to store the date in the CSV file (should match the date_regex)
# There should be no need to change this
date_format: '%d.%m.%Y %H:%M'

# ntfy configuration
# See https://ntfy.sh/ for more information
# Choose a topic name that is unique to you
ntfy:
  server: https://ntfy.sh/
  topic: public_cgn_appintments_83e0c8db1f51a7044b6431ddb2814c11
  title: 'A new appointment is available!'
  message: 'A new appointment is available in %s: %s'
  tags:
    - tada
  priority: 3 # 1-5

# Configure logging
# Advanced users can change the logging configuration here
# The loglevel can be set to DEBUG, INFO, WARNING, ERROR, CRITICAL
logging:
  version: 1
  disable_existing_loggers: false
  formatters:
    simple:
      format: '[%(levelname)s|%(module)s|L%(lineno)d] %(asctime)s: %(message)s'
      datefmt: '%Y-%m-%dT%H:%M:%S%z'
    json:
      fmt_keys:
        level: levelname
        message: message
        timestamp: timestamp
        logger: name
        module: module
        function: funcName
        line: lineno
        thread_name: threadName
  handlers:
    stderr:
      class: logging.StreamHandler
      formatter: simple
      stream: ext://sys.stderr
      level: DEBUG
    file:
      class: logging.handlers.RotatingFileHandler
      formatter: json
      level: INFO
      maxBytes: 10000000
      backupCount: 3
    queue_handler:
      class: logging.handlers.QueueHandler
      handlers:
        - stderr
        - file
      respect_handler_level: true
  loggers:
    root:
      handlers:
        - queue_handler
      level: DEBUG

Usage

You can use cg-appointments with only the configuration file or with additional command line arguments which will override the values set in the configuration file.

Using the --services flag, make sure to use "double quotes" around the service name if it contains spaces.

usage: cgn-appointments [-h] [-s SERVICES [SERVICES ...]]
                        [-l LOCATIONS [LOCATIONS ...]] [-t MAX_TIMEDELTA]
                        [--config-file CONFIG_FILE] [--csv-file CSV_FILE]
                        [--log-file LOG_FILE]
                        [--log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG,NOTSET}]

Scrapes appointments from termine.stadt-koeln.de an sends a message to a ntfy
server.

options:
  -h, --help            show this help message and exit
  -s SERVICES [SERVICES ...], --services SERVICES [SERVICES ...]
                        Services to check
  -l LOCATIONS [LOCATIONS ...], --locations LOCATIONS [LOCATIONS ...]
                        Locations to check
  -t MAX_TIMEDELTA, --max-timedelta MAX_TIMEDELTA
                        Maximum timedelta in days to notify about new
                        appointments
  --config-file CONFIG_FILE
                        Path to the configuration file
  --csv-file CSV_FILE   Path to the csv file, which stores the last fetched
                        dates
  --log-file LOG_FILE   Path to logfile
  --log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG,NOTSET}
                        Logging Level

Example

cgn-apppointments \ 
  --services "Personalausweis - Antrag" "Reisepass - Antrag (seit 01.01.2024 auch für Kinder unter 12 Jahren)" \
  --locations Ehrenfeld Kalk \
  --max-timedelta 7 \
  --config-file /path/to/config.yaml \
  --csv-file /path/to/csvfile.csv \
  --log-file /path/to/logfile.log \
  --log-level INFO

Scheduled Execution via cron

On linux systems you can use cron to schedule the execution of cgn-appointments.

Find the path to the cgn-appointments executable

which cgn-appointments 

Open the crontab file

crontab -e

Add the following line to the crontab file to execute cgn-appointments every 30 minutes

*/30 * * * * /path/to/cgn-appointments > /dev/null 2>&1