Eerste commit

celery-integration
peter.fong 11 months ago
commit 81b2ea2405

@ -0,0 +1,8 @@
FROM python:3.9-slim
RUN apt-get update && apt-get install -y git
WORKDIR /workspace
# CMD om de container niet direct te stoppen
CMD ["sleep", "infinity"]

@ -0,0 +1,39 @@
{
"name": "Multi-Python DevContainer",
"build": {
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/python:1": {
"version": "3.9"
}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.flake8", // Voeg Flake8 toe voor linting
"visualstudioexptteam.vscodeintellicode"
],
"settings": {
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.pylintEnabled": false, // Als je Flake8 wilt gebruiken, zet Pylint uit
"python.linting.lintOnSave": true, // Lint bij opslaan
"python.linting.flake8Args": [
"--max-line-length=88" // Optionele linting instelling voor max lijnlengte
]
}
}
},
"postCreateCommand": "find /workspace -type f -name 'requirements.txt' -exec pip install --no-cache-dir -r {} \\;",
"remoteUser": "root",
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind"
],
"runArgs": ["--entrypoint", "bash"],
"settings": {
"python.pythonPath": "/usr/local/bin/python"
}
}

@ -0,0 +1 @@
-Open deze in devcontainer om te ontwikkelen(CTRL+SH+O, open in devcontainer)

@ -0,0 +1,30 @@
import os
from dotenv import load_dotenv
# Geef het absolute pad op naar je .env bestand
env_path = "./.env" # Pas dit pad aan!
# Laad de .env bestand expliciet
load_dotenv(env_path)
def get_db_config():
"""Haalt de database configuratie op uit de .env bestand."""
return {
"host": os.getenv("DB_HOST"),
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"database": os.getenv("DB_NAME"),
}
def get_mqtt_config():
"""Haalt de MQTT configuratie op uit de .env bestand."""
return {
"broker": os.getenv("MQTT_BROKER"),
"port": int(os.getenv("MQTT_PORT")),
"topic_price": os.getenv("MQTT_TOPIC_PRICE"),
"topic_costs": os.getenv("MQTT_TOPIC_ELCOST"),
"username": os.getenv("MQTT_USER"),
"password": os.getenv("MQTT_PASSWORD"),
}

@ -0,0 +1,76 @@
import time
from db import Database
from mqtt_publisher import MQTTPublisher
from logger import setup_logger
from config import get_db_config, get_mqtt_config
from dotenv import load_dotenv
def main():
try:
# Laad de configuratie uit het .env bestand
load_dotenv()
print("Configuratie geladen.")
logger = setup_logger()
logger.debug("Logger ingesteld.")
# Verkrijg de database configuratie
db_config = get_db_config()
logger.debug(f"Database configuratie geladen: {db_config}")
# Verkrijg de MQTT configuratie
mqtt_config = get_mqtt_config()
logger.debug(f"MQTT configuratie geladen: {mqtt_config}")
# Maak een verbinding met de database
db = Database(db_config, logger)
logger.debug(
"db initialiseerd...")
mqtt_publisher = MQTTPublisher(mqtt_config, logger)
logger.debug(
"mqtt_publisher initialiseerd...")
logger.debug(
"Start met het ophalen en publiceren van de elektriciteitsprijs...")
# Periodieke publicatie in een loop (elke 30 minuten)
while True:
# Haal de prijs op uit de database
price = db.fetch_current_price()
if price is not None:
logger.debug(f"Huidige prijs opgehaald: {price} EUR/kWh")
mqtt_publisher.publish(price, mqtt_config['topic_price'])
logger.debug(
f"Prijs gepubliceerd naar MQTT-topic {mqtt_config['topic_price']}: {price}")
else:
logger.warning("Geen prijs gevonden voor het huidige uur.")
total_costs_today = db.fetch_daily_costs()
if total_costs_today is not None:
rounded_costs = round(total_costs_today, 2)
# Afgerond op 2 decimalen en met euroteken
formatted_costs = f"{rounded_costs:.2f}"
logger.debug(f"Huidige kosten voor vandaag: {formatted_costs}")
mqtt_publisher.publish(
formatted_costs, mqtt_config['topic_costs'])
logger.debug(
f"Huidige kosten voor vandaag: {formatted_costs} EUR")
mqtt_publisher.publish(
formatted_costs, mqtt_config['topic_costs'])
logger.debug(
f"Kosten gepubliceerd naar MQTT-topic {mqtt_config['topic_costs']}: {formatted_costs}")
else:
logger.warning("Geen kosten gevonden voor de huidige dag.")
# Wacht 30 minuten (1800 seconden) voor de volgende publicatie
print("Wachten op de volgende publicatie...")
logger.debug("Wachten op de volgende publicatie...")
time.sleep(60)
except Exception as e:
logger.error(f"Fout in main loop: {e}")
exit(1) # Stop de applicatie als er een fout optreedt
if __name__ == "__main__":
main()

@ -0,0 +1,47 @@
import mysql.connector
class Database:
def __init__(self, config, logger):
self.config = config
self.logger = logger
def fetch_current_price(self):
"""Haalt de huidige elektriciteitsprijs op uit de database."""
try:
conn = mysql.connector.connect(**self.config)
cursor = conn.cursor()
query = """
SELECT price_fr
FROM daillyprices
WHERE DATE(timestamp) = CURRENT_DATE
AND HOUR(timestamp) = HOUR(NOW());
"""
cursor.execute(query)
result = cursor.fetchone()
cursor.close()
conn.close()
return result[0] if result else None
except Exception as e:
self.logger.error(f"Database fout: {e}")
return None
def fetch_daily_costs(self):
try:
conn = mysql.connector.connect(**self.config)
cursor = conn.cursor()
query = """
SELECT SUM(el_costs) AS total_costs_today
FROM energy_costs
WHERE DATE(starttime) = CURDATE();
"""
cursor.execute(query)
result = cursor.fetchone()
if result:
return result[0] # De eerste kolom is de som van de kosten
else:
return None
except Exception as e:
self.logger.error(
f"Fout bij het ophalen van de dagelijkse kosten: {e}")
return None

File diff suppressed because it is too large Load Diff

@ -0,0 +1,41 @@
import logging
import os
from dotenv import load_dotenv
# Laad .env bestand
load_dotenv()
def setup_logger():
"""Stelt de logger in op basis van de configuratie in de .env bestand."""
log_level = os.getenv("LOG_LEVEL", "INFO").upper(
) # Standaard naar INFO als het niet is ingesteld
# Maak de logger aan
logger = logging.getLogger()
# Zet het logniveau op basis van de waarde uit de .env
log_levels = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL
}
# Gebruik het juiste logniveau
# Standaard naar INFO als het onbekend is
logger.setLevel(log_levels.get(log_level, logging.INFO))
# Maak een console handler
ch = logging.StreamHandler()
ch.setLevel(log_levels.get(log_level, logging.INFO))
# Maak een formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# Voeg de handler toe aan de logger
logger.addHandler(ch)
return logger

@ -0,0 +1,36 @@
import paho.mqtt.client as mqtt
class MQTTPublisher:
def __init__(self, config, logger):
self.broker = config["broker"]
self.port = config["port"]
self.username = config["username"]
self.password = config["password"]
self.logger = logger
def publish(self, message, topic):
"""Publiceert een bericht naar het MQTT-topic."""
try:
self.logger.debug(f"Verbinden met MQTT broker {self.broker}...")
client = mqtt.Client()
# Authenticatie toevoegen
client.username_pw_set(self.username, self.password)
client.connect(self.broker, self.port, 60)
self.logger.debug(
f"Verbonden met MQTT broker op poort {self.port}.")
# Zet het bericht om naar een string als het geen string is
# Zorg ervoor dat het bericht een string is
message_str = str(message)
self.logger.debug(f"Publiceren naar MQTT-topic: {topic}")
# Publiceer de string versie van het bericht
client.publish(topic, message_str)
self.logger.debug(
f"Bericht gepubliceerd naar {topic}: {message_str}")
client.disconnect()
self.logger.debug("Verbinding met MQTT broker gesloten.")
except Exception as e:
self.logger.error(f"MQTT fout: {e}")

@ -0,0 +1,3 @@
requests
mysql-connector-python
python-dotenv

@ -0,0 +1,3 @@
paho-mqtt
mysql-connector-python
python-dotenv

@ -0,0 +1,82 @@
import requests
import mysql.connector
from mysql.connector import Error
import datetime
# Configuratievariabelen
ENERVER_API_URL = "https://enever.nl/api/stroomprijs_laatste30dagen.php" # API URL
ENERVER_API_TOKEN = "10d856e7b6b63a4d4e554c10b00e6b0d" # Vervang met je token
MYSQL_CONFIG = {
"host": "localhost",
"user": "root",
"password": "<your_password>",
"database": "energieprijzen",
}
def fetch_enever_prices():
"""Haal stroomprijsgegevens op van de EneVer API."""
params = {"token": ENERVER_API_TOKEN}
try:
response = requests.get(ENERVER_API_URL, params=params)
response.raise_for_status()
return response.json() # Verwacht JSON als antwoord
except requests.RequestException as e:
print(f"Fout bij ophalen EneVer-prijzen: {e}")
return None
def store_prices_to_db(prices):
"""Sla de relevante stroomprijzen op in een MySQL-database."""
try:
connection = mysql.connector.connect(**MYSQL_CONFIG)
if connection.is_connected():
cursor = connection.cursor()
# Zorg dat de tabel bestaat
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS stroomprijzen (
id INT AUTO_INCREMENT PRIMARY KEY,
timestamp DATETIME,
price_ti DECIMAL(10, 5)
)
"""
)
# Voeg de prijzen toe
for price_entry in prices:
timestamp = datetime.datetime.strptime(
price_entry["datum"], "%Y-%m-%d %H:%M:%S"
)
price_ti = float(price_entry["prijsTI"])
cursor.execute(
"""
INSERT INTO stroomprijzen (timestamp, price_ti)
VALUES (%s, %s)
""",
(timestamp, price_ti),
)
connection.commit()
print("Relevante prijzen succesvol opgeslagen in de database.")
except Error as e:
print(f"Fout bij verbinden met de database: {e}")
finally:
if connection.is_connected():
cursor.close()
connection.close()
if __name__ == "__main__":
# Prijzen ophalen van EneVer API
enever_prices = fetch_enever_prices()
# if enever_prices:
# # Prijzen opslaan in de database
# store_prices_to_db(enever_prices)
# else:
# print("Geen prijzen beschikbaar om op te slaan.")

@ -0,0 +1,88 @@
2025-01-30 08:11:07,499 - qrcodegen.py - Script gestart voor platform: spotify. CSV bestand: nummers.csv, Output PDF: nummers_met_qr.pdf
2025-01-30 08:11:07,572 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:07,695 - qrcodegen.py - URL voor 'Bohemian Rhapsody - Queen' gevonden.
2025-01-30 08:11:07,770 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:08,043 - qrcodegen.py - URL voor 'Roller Coaster - Danny Vera' gevonden.
2025-01-30 08:11:08,110 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:08,231 - qrcodegen.py - URL voor 'Hotel California - Eagles' gevonden.
2025-01-30 08:11:08,312 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:08,437 - qrcodegen.py - URL voor 'Piano Man - Billy Joel' gevonden.
2025-01-30 08:11:08,518 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:08,694 - qrcodegen.py - URL voor 'Fix You - Coldplay' gevonden.
2025-01-30 08:11:08,774 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:08,920 - qrcodegen.py - URL voor 'Stairway To Heaven - Led Zeppelin' gevonden.
2025-01-30 08:11:08,995 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:09,110 - qrcodegen.py - URL voor 'Black - Pearl Jam' gevonden.
2025-01-30 08:11:09,188 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:09,328 - qrcodegen.py - URL voor 'Avond - Boudewijn de Groot' gevonden.
2025-01-30 08:11:09,401 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:09,525 - qrcodegen.py - URL voor 'Nothing Else Matters (Albumversie) - Metallica' gevonden.
2025-01-30 08:11:09,595 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:11:09,715 - qrcodegen.py - URL voor 'Love Of My Life - Queen' gevonden.
2025-01-30 08:11:09,729 - qrcodegen.py - PDF succesvol gegenereerd: nummers_met_qr.pdf
2025-01-30 08:12:59,529 - qrcodegen.py - Script gestart voor platform: spotify. CSV bestand: nummers.csv, Output PDF: nummers_met_qr.pdf
2025-01-30 08:12:59,597 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:12:59,709 - qrcodegen.py - URL voor 'Bohemian Rhapsody - Queen' gevonden.
2025-01-30 08:12:59,806 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:12:59,978 - qrcodegen.py - URL voor 'Roller Coaster - Danny Vera' gevonden.
2025-01-30 08:13:00,061 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:00,180 - qrcodegen.py - URL voor 'Hotel California - Eagles' gevonden.
2025-01-30 08:13:00,256 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:00,380 - qrcodegen.py - URL voor 'Piano Man - Billy Joel' gevonden.
2025-01-30 08:13:00,449 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:00,572 - qrcodegen.py - URL voor 'Fix You - Coldplay' gevonden.
2025-01-30 08:13:00,644 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:00,756 - qrcodegen.py - URL voor 'Stairway To Heaven - Led Zeppelin' gevonden.
2025-01-30 08:13:00,816 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:00,964 - qrcodegen.py - URL voor 'Black - Pearl Jam' gevonden.
2025-01-30 08:13:01,040 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:01,167 - qrcodegen.py - URL voor 'Avond - Boudewijn de Groot' gevonden.
2025-01-30 08:13:01,253 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:01,371 - qrcodegen.py - URL voor 'Nothing Else Matters (Albumversie) - Metallica' gevonden.
2025-01-30 08:13:01,458 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:01,614 - qrcodegen.py - URL voor 'Love Of My Life - Queen' gevonden.
2025-01-30 08:13:01,638 - qrcodegen.py - PDF succesvol gegenereerd: nummers_met_qr.pdf
2025-01-30 08:13:52,844 - qrcodegen.py - Script gestart voor platform: spotify. CSV bestand: nummers.csv, Output PDF: nummers_met_qr.pdf
2025-01-30 08:13:52,936 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:53,050 - qrcodegen.py - URL voor 'Bohemian Rhapsody - Queen' gevonden.
2025-01-30 08:13:53,136 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:53,262 - qrcodegen.py - URL voor 'Roller Coaster - Danny Vera' gevonden.
2025-01-30 08:13:53,353 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:53,491 - qrcodegen.py - URL voor 'Hotel California - Eagles' gevonden.
2025-01-30 08:13:53,562 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:53,678 - qrcodegen.py - URL voor 'Piano Man - Billy Joel' gevonden.
2025-01-30 08:13:53,750 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:53,904 - qrcodegen.py - URL voor 'Fix You - Coldplay' gevonden.
2025-01-30 08:13:53,977 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:54,103 - qrcodegen.py - URL voor 'Stairway To Heaven - Led Zeppelin' gevonden.
2025-01-30 08:13:54,175 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:54,350 - qrcodegen.py - URL voor 'Black - Pearl Jam' gevonden.
2025-01-30 08:13:54,429 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:54,540 - qrcodegen.py - URL voor 'Avond - Boudewijn de Groot' gevonden.
2025-01-30 08:13:54,612 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:54,739 - qrcodegen.py - URL voor 'Nothing Else Matters (Albumversie) - Metallica' gevonden.
2025-01-30 08:13:54,812 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:13:54,976 - qrcodegen.py - URL voor 'Love Of My Life - Queen' gevonden.
2025-01-30 08:13:54,999 - qrcodegen.py - PDF succesvol gegenereerd: nummers_met_qr.pdf
2025-01-30 08:14:55,877 - qrcodegen.py - Script gestart voor platform: spotify. CSV bestand: nummers.csv, Output PDF: nummers_met_qr.pdf
2025-01-30 08:14:55,941 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:56,058 - qrcodegen.py - URL voor 'Bohemian Rhapsody - Queen' gevonden.
2025-01-30 08:14:56,146 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:56,264 - qrcodegen.py - URL voor 'Roller Coaster - Danny Vera' gevonden.
2025-01-30 08:14:56,342 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:56,454 - qrcodegen.py - URL voor 'Hotel California - Eagles' gevonden.
2025-01-30 08:14:56,519 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:56,698 - qrcodegen.py - URL voor 'Piano Man - Billy Joel' gevonden.
2025-01-30 08:14:56,775 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:56,896 - qrcodegen.py - URL voor 'Fix You - Coldplay' gevonden.
2025-01-30 08:14:56,983 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:57,122 - qrcodegen.py - URL voor 'Stairway To Heaven - Led Zeppelin' gevonden.
2025-01-30 08:14:57,196 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:57,330 - qrcodegen.py - URL voor 'Black - Pearl Jam' gevonden.
2025-01-30 08:14:57,408 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:57,532 - qrcodegen.py - URL voor 'Avond - Boudewijn de Groot' gevonden.
2025-01-30 08:14:57,613 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:57,740 - qrcodegen.py - URL voor 'Nothing Else Matters (Albumversie) - Metallica' gevonden.
2025-01-30 08:14:57,828 - qrcodegen.py - Succesvol Spotify toegangstoken verkregen.
2025-01-30 08:14:57,973 - qrcodegen.py - URL voor 'Love Of My Life - Queen' gevonden.
2025-01-30 08:14:57,998 - qrcodegen.py - PDF succesvol gegenereerd: nummers_met_qr.pdf

@ -0,0 +1,11 @@
positie;titel;artiest;jaar;
1;Bohemian Rhapsody;Queen;1975;
2;Roller Coaster;Danny Vera;2019;
3;Hotel California;Eagles;1977;
4;Piano Man;Billy Joel;1973;
5;Fix You;Coldplay;2005;
6;Stairway To Heaven;Led Zeppelin;1971;
7;Black;Pearl Jam;1992;
8;Avond;Boudewijn de Groot;1997;
9;Nothing Else Matters (Albumversie);Metallica;1992;
10;Love Of My Life;Queen;1975;
1 positie titel artiest jaar
2 1 Bohemian Rhapsody Queen 1975
3 2 Roller Coaster Danny Vera 2019
4 3 Hotel California Eagles 1977
5 4 Piano Man Billy Joel 1973
6 5 Fix You Coldplay 2005
7 6 Stairway To Heaven Led Zeppelin 1971
8 7 Black Pearl Jam 1992
9 8 Avond Boudewijn de Groot 1997
10 9 Nothing Else Matters (Albumversie) Metallica 1992
11 10 Love Of My Life Queen 1975

File diff suppressed because one or more lines are too long

@ -0,0 +1,190 @@
import os
import base64
import requests
from dotenv import load_dotenv
import urllib.parse
import pandas as pd
import qrcode
from PIL import Image, ImageDraw, ImageFont
# Geef het absolute pad op naar je .env bestand
env_path = "./.env" # Pas dit pad aan!
# Laad de .env bestand expliciet
load_dotenv(env_path)
# Controleer of de variabelen goed zijn geladen
CLIENT_ID = os.getenv('SPOTIFY_CLIENT_ID')
CLIENT_SECRET = os.getenv('SPOTIFY_CLIENT_SECRET')
def get_spotify_access_token():
auth_url = "https://accounts.spotify.com/api/token"
auth_data = {
'grant_type': 'client_credentials'
}
auth_headers = {
'Authorization': f"Basic {base64.b64encode(f'{CLIENT_ID}:{CLIENT_SECRET}'.encode('utf-8')).decode('utf-8')}"
}
response = requests.post(auth_url, data=auth_data, headers=auth_headers)
if response.status_code == 200:
access_token = response.json().get('access_token')
return access_token
else:
print("Fout bij het verkrijgen van Spotify toegangstoken")
return None
# Functie om de Spotify track link te verkrijgen
def get_spotify_track_url(title, artist):
access_token = get_spotify_access_token()
if access_token is None:
return None
# Encodeer de titel en artiest voor de zoekopdracht
query = f"{title} {artist}"
encoded_query = urllib.parse.quote_plus(query)
# Voer de zoekopdracht uit via de Spotify API
search_url = f"https://api.spotify.com/v1/search?q={encoded_query}&type=track&limit=1"
search_headers = {
'Authorization': f"Bearer {access_token}"
}
response = requests.get(search_url, headers=search_headers)
if response.status_code == 200:
results = response.json()
tracks = results.get('tracks', {}).get('items', [])
if tracks:
track_url = tracks[0]['external_urls']['spotify']
return track_url
print(f"Fout bij het zoeken naar track voor '{title} - {artist}'")
return None
# Functie om QR-codes te genereren met titels
def generate_qr_codes_with_titles(csv_file, output_folder, position_column, title_column, artist_column, year_column):
# Maak de outputmap aan als die nog niet bestaat
os.makedirs(output_folder, exist_ok=True)
# Lees het CSV-bestand
try:
data = pd.read_csv(csv_file, delimiter=";")
except Exception as e:
print(f"Fout bij het lezen van de CSV: {e}")
return
# Controleer of de benodigde kolommen bestaan
if position_column not in data.columns or title_column not in data.columns or artist_column not in data.columns or year_column not in data.columns:
print(
f"Kolommen '{position_column}', '{title_column}', '{artist_column}' en/of '{year_column}' niet gevonden in CSV-bestand.")
return
# Loop door de rijen in de CSV
for index, row in data.iterrows():
position = row[position_column]
title = row[title_column]
artist = row[artist_column]
year = row[year_column]
# Verkrijg de Spotify link voor het nummer
url = get_spotify_track_url(title, artist)
if url:
# Print de URL in de console
print(f"Genereerde URL voor '{title} - {artist}': {url}")
try:
# Maak QR-code
qr = qrcode.QRCode(
version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
qr.add_data(url)
qr.make(fit=True)
qr_img = qr.make_image(
fill='black', back_color='white').convert("RGB")
# Maak een nieuwe afbeelding met ruimte voor de titel en URL
title_height = 50 # Hoogte voor de titeltekst
url_height = 30 # Hoogte voor de URL
total_width = qr_img.size[0]
total_height = qr_img.size[1] + title_height + url_height
img_with_title_and_url = Image.new(
"RGB", (total_width, total_height), "white")
draw = ImageDraw.Draw(img_with_title_and_url)
# Voeg de titel toe boven de QR-code
font_size = 20
try:
# Probeer een systeemfont te laden (je kunt dit aanpassen aan je systeem)
font = ImageFont.truetype("arial.ttf", font_size)
except:
# Gebruik een standaardfont als `arial.ttf` niet beschikbaar is
font = ImageFont.load_default()
# Gebruik textbbox() om de breedte en hoogte van de tekst te berekenen
text_bbox = draw.textbbox((0, 0), title, font=font)
text_width = text_bbox[2] - \
text_bbox[0] # breedte van de tekst
text_height = text_bbox[3] - \
text_bbox[1] # hoogte van de tekst
# Bereken de positie om de titel in het midden te plaatsen
text_x = (total_width - text_width) // 2
text_y = (title_height - text_height) // 2
draw.text((text_x, text_y), title, fill="black", font=font)
# Voeg de QR-code toe onder de titel
img_with_title_and_url.paste(qr_img, (0, title_height))
# Voeg de URL onder de QR-code toe
url_font_size = 15 # Kleinere tekst voor de URL
try:
# Probeer een systeemfont te laden voor de URL
url_font = ImageFont.truetype("arial.ttf", url_font_size)
except:
# Gebruik een standaardfont als `arial.ttf` niet beschikbaar is
url_font = ImageFont.load_default()
# Gebruik textbbox() om de breedte van de URL te berekenen
url_bbox = draw.textbbox((0, 0), url, font=url_font)
url_width = url_bbox[2] - url_bbox[0] # breedte van de URL
url_height = url_bbox[3] - url_bbox[1] # hoogte van de URL
# Bereken de positie om de URL in het midden te plaatsen
url_x = (total_width - url_width) // 2
url_y = total_height - url_height - 10 # 10 pixels van de onderkant
draw.text((url_x, url_y), url, fill="black", font=url_font)
# Maak de bestandsnaam: positie_titel.png
filename = f"{position}_{title}.png"
# Verwijder ongewenste tekens uit de bestandsnaam (zoals slashes, dubbele punten, enz.)
filename = filename.replace("/", "_").replace(":", "_")
# Sla de afbeelding op
img_with_title_and_url.save(
os.path.join(output_folder, filename))
print(
f"QR-code met titel '{title}' gegenereerd als '{filename}'")
except Exception as e:
print(
f"Fout bij het genereren van QR-code voor '{title}': {e}")
else:
print(f"Geen Spotify link gevonden voor '{title} - {artist}'")
# Voorbeeldgebruik
csv_file = "nummers.csv" # Vervang door je eigen CSV-bestand
output_folder = "qr_codes_with_titles" # Map waar QR-codes worden opgeslagen
position_column = "positie" # De kolomnaam in de CSV met de posities
title_column = "titel" # De kolomnaam in de CSV met de titels
artist_column = "artiest" # De kolomnaam in de CSV met de artiesten
year_column = "jaar" # De kolomnaam in de CSV met de jaren
generate_qr_codes_with_titles(
csv_file, output_folder, position_column, title_column, artist_column, year_column)

@ -0,0 +1,164 @@
import pandas as pd
import qrcode
from PIL import Image, ImageDraw, ImageFont
from dotenv import load_dotenv
import os
import requests
import urllib.parse
# Geef het absolute pad op naar je .env bestand
env_path = "./.env" # Pas dit pad aan!
# Laad de .env bestand expliciet
load_dotenv(env_path)
# Controleer of de variabelen goed zijn geladen
YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY')
# Functie om de YouTube video link te verkrijgen
def get_youtube_video_url(title, artist):
# Encodeer de titel en artiest voor de zoekopdracht
query = f"{title} {artist}"
encoded_query = urllib.parse.quote_plus(query)
# Zoek naar de video op YouTube via de API
search_url = f"https://www.googleapis.com/youtube/v3/search?part=snippet&q={encoded_query}&key={YOUTUBE_API_KEY}&maxResults=1"
response = requests.get(search_url)
if response.status_code == 200:
results = response.json()
items = results.get('items', [])
if items:
# Haal de video-ID op van het zoekresultaat
video_id = items[0]['id'].get('videoId')
if video_id:
video_url = f"https://www.youtube.com/watch?v={video_id}"
return video_url
print(f"Fout bij het zoeken naar video voor '{title} - {artist}'")
return None
def generate_qr_codes_with_titles(csv_file, output_folder, position_column, title_column, artist_column, year_column):
# Maak de outputmap aan als die nog niet bestaat
os.makedirs(output_folder, exist_ok=True)
# Lees het CSV-bestand
try:
data = pd.read_csv(csv_file, delimiter=";")
except Exception as e:
print(f"Fout bij het lezen van de CSV: {e}")
return
# Controleer of de benodigde kolommen bestaan
if position_column not in data.columns or title_column not in data.columns or artist_column not in data.columns or year_column not in data.columns:
print(
f"Kolommen '{position_column}', '{title_column}', '{artist_column}' en/of '{year_column}' niet gevonden in CSV-bestand.")
return
# Loop door de rijen in de CSV
for index, row in data.iterrows():
position = row[position_column]
title = row[title_column]
artist = row[artist_column]
year = row[year_column]
# Verkrijg de YouTube link voor het nummer
url = get_youtube_video_url(title, artist)
if url:
# Print de URL in de console
print(f"Genereerde URL voor '{title} - {artist}': {url}")
try:
# Maak QR-code
qr = qrcode.QRCode(
version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
qr.add_data(url)
qr.make(fit=True)
qr_img = qr.make_image(
fill='black', back_color='white').convert("RGB")
# Maak een nieuwe afbeelding met ruimte voor de titel en URL
title_height = 50 # Hoogte voor de titeltekst
url_height = 30 # Hoogte voor de URL
total_width = qr_img.size[0]
total_height = qr_img.size[1] + title_height + url_height
img_with_title_and_url = Image.new(
"RGB", (total_width, total_height), "white")
draw = ImageDraw.Draw(img_with_title_and_url)
# Voeg de titel toe boven de QR-code
font_size = 20
try:
# Probeer een systeemfont te laden (je kunt dit aanpassen aan je systeem)
font = ImageFont.truetype("arial.ttf", font_size)
except:
# Gebruik een standaardfont als `arial.ttf` niet beschikbaar is
font = ImageFont.load_default()
# Gebruik textbbox() om de breedte en hoogte van de tekst te berekenen
text_bbox = draw.textbbox((0, 0), title, font=font)
text_width = text_bbox[2] - \
text_bbox[0] # breedte van de tekst
text_height = text_bbox[3] - \
text_bbox[1] # hoogte van de tekst
# Bereken de positie om de titel in het midden te plaatsen
text_x = (total_width - text_width) // 2
text_y = (title_height - text_height) // 2
draw.text((text_x, text_y), title, fill="black", font=font)
# Voeg de QR-code toe onder de titel
img_with_title_and_url.paste(qr_img, (0, title_height))
# Voeg de URL onder de QR-code toe
url_font_size = 15 # Kleinere tekst voor de URL
try:
# Probeer een systeemfont te laden voor de URL
url_font = ImageFont.truetype("arial.ttf", url_font_size)
except:
# Gebruik een standaardfont als `arial.ttf` niet beschikbaar is
url_font = ImageFont.load_default()
# Gebruik textbbox() om de breedte van de URL te berekenen
url_bbox = draw.textbbox((0, 0), url, font=url_font)
url_width = url_bbox[2] - url_bbox[0] # breedte van de URL
url_height = url_bbox[3] - url_bbox[1] # hoogte van de URL
# Bereken de positie om de URL in het midden te plaatsen
url_x = (total_width - url_width) // 2
url_y = total_height - url_height - 10 # 10 pixels van de onderkant
draw.text((url_x, url_y), url, fill="black", font=url_font)
# Maak de bestandsnaam: positie_titel.png
filename = f"{position}_{title}.png"
# Verwijder ongewenste tekens uit de bestandsnaam (zoals slashes, dubbele punten, enz.)
filename = filename.replace("/", "_").replace(":", "_")
# Sla de afbeelding op
img_with_title_and_url.save(
os.path.join(output_folder, filename))
print(
f"QR-code met titel '{title}' gegenereerd als '{filename}'")
except Exception as e:
print(
f"Fout bij het genereren van QR-code voor '{title}': {e}")
else:
print(f"Geen YouTube link gevonden voor '{title} - {artist}'")
# Voorbeeldgebruik
csv_file = "nummers.csv" # Vervang door je eigen CSV-bestand
output_folder = "qr_codes_with_titles" # Map waar QR-codes worden opgeslagen
position_column = "positie" # De kolomnaam in de CSV met de posities
title_column = "titel" # De kolomnaam in de CSV met de titels
artist_column = "artiest" # De kolomnaam in de CSV met de artiesten
year_column = "jaar" # De kolomnaam in de CSV met de jaren
generate_qr_codes_with_titles(
csv_file, output_folder, position_column, title_column, artist_column, year_column)

@ -0,0 +1,173 @@
import os
import sys
import base64
import requests
import urllib.parse
import pandas as pd
import qrcode
import logging
from PIL import Image, ImageDraw, ImageFont
from dotenv import load_dotenv
from reportlab.pdfgen import canvas
# Geef het absolute pad op naar je .env bestand
env_path = "./.env" # Pas dit pad aan!
# Laad de .env bestand expliciet
load_dotenv(env_path)
# Haal API-sleutels op
CLIENT_ID = os.getenv('SPOTIFY_CLIENT_ID')
CLIENT_SECRET = os.getenv('SPOTIFY_CLIENT_SECRET')
YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY')
# Configureren van logging
logging.basicConfig(filename="log.txt", level=logging.INFO,
format="%(asctime)s - %(message)s")
def log_message(message):
logging.info(f"{sys.argv[0]} - {message}")
def get_spotify_access_token():
auth_url = "https://accounts.spotify.com/api/token"
auth_data = {'grant_type': 'client_credentials'}
auth_headers = {
'Authorization': f"Basic {base64.b64encode(f'{CLIENT_ID}:{CLIENT_SECRET}'.encode('utf-8')).decode('utf-8')}"
}
response = requests.post(auth_url, data=auth_data, headers=auth_headers)
if response.status_code == 200:
log_message(f"Succesvol Spotify toegangstoken verkregen.")
return response.json().get('access_token')
else:
log_message(
f"Fout bij het verkrijgen van Spotify toegangstoken: {response.status_code}")
return None
def get_spotify_track_url(title, artist):
access_token = get_spotify_access_token()
if not access_token:
log_message(
f"Geen toegangstoken voor Spotify beschikbaar voor {title} - {artist}.")
return None
query = urllib.parse.quote_plus(f"{title} {artist}")
search_url = f"https://api.spotify.com/v1/search?q={query}&type=track&limit=1"
headers = {'Authorization': f"Bearer {access_token}"}
response = requests.get(search_url, headers=headers)
tracks = response.json().get('tracks', {}).get(
'items', []) if response.status_code == 200 else []
if tracks:
log_message(f"URL voor '{title} - {artist}' gevonden.")
return tracks[0]['external_urls']['spotify']
else:
log_message(f"Geen URL gevonden voor '{title} - {artist}' op Spotify.")
return None
def get_youtube_video_url(title, artist):
query = urllib.parse.quote_plus(f"{title} {artist}")
search_url = f"https://www.googleapis.com/youtube/v3/search?part=snippet&q={query}&key={YOUTUBE_API_KEY}&maxResults=1&type=video"
response = requests.get(search_url)
items = response.json().get('items', []) if response.status_code == 200 else []
if items and 'videoId' in items[0]['id']:
log_message(f"URL voor '{title} - {artist}' gevonden op YouTube.")
return f"https://www.youtube.com/watch?v={items[0]['id']['videoId']}"
else:
log_message(f"Geen URL gevonden voor '{title} - {artist}' op YouTube.")
return None
def generate_qr_codes_and_pdf(csv_file, output_pdf, position_col, title_col, artist_col, year_col, platform):
data = pd.read_csv(csv_file, delimiter=";")
c = canvas.Canvas(output_pdf)
for _, row in data.iterrows():
position, title, artist, year = row[position_col], row[title_col], row[artist_col], row[year_col]
url = get_spotify_track_url(
title, artist) if platform == "spotify" else get_youtube_video_url(title, artist)
if url:
# Genereer QR-code
qr = qrcode.QRCode(
version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
qr.add_data(url)
qr.make(fit=True)
qr_img = qr.make_image(
fill='black', back_color='white').convert("RGB")
# Sla de QR-code op als afbeelding
qr_image_path = f"temp_qr.png"
qr_img.save(qr_image_path)
# Haal de afmetingen van de QR-code op
qr_width, qr_height = qr_img.size
# Pas de pagina grootte aan
page_width = qr_width
page_height = qr_height + 100 # Voeg extra ruimte bovenaan de pagina voor tekst
# Stel de pagina grootte in
c.setPageSize((page_width, page_height))
# Voeg de QR-code toe aan de PDF (Pagina 1)
c.drawImage(qr_image_path, 0, page_height - qr_height,
width=qr_width, height=qr_height)
c.showPage() # Maak een nieuwe pagina
# Bereken de breedte van de tekst
text_artist = f"Artiest: {artist}"
text_title = f"Titel: {title}"
text_year = f"Jaar: {year}"
text_url = f"Link: {url}"
# Stel het lettertype in en meet de tekstgrootte
c.setFont("Helvetica", 12)
text_artist_width = c.stringWidth(text_artist, "Helvetica", 12)
text_title_width = c.stringWidth(text_title, "Helvetica", 12)
text_year_width = c.stringWidth(text_year, "Helvetica", 12)
text_url_width = c.stringWidth(text_url, "Helvetica", 12)
# Bereken de X-coördinaten voor gecentreerde tekst
x_artist = (page_width - text_artist_width) / 2
x_title = (page_width - text_title_width) / 2
x_year = (page_width - text_year_width) / 2
x_url = (page_width - text_url_width) / 2
# Verhoog de Y-positie voor de tekst zodat deze niet onder de QR-code valt
y_start = page_height - qr_height - 30 # Verhoog naar boven
# Voeg de teksten toe aan de PDF (Pagina 2)
c.drawString(x_artist, y_start, text_artist)
c.drawString(x_title, y_start - 20, text_title)
c.drawString(x_year, y_start - 40, text_year)
c.drawString(x_url, y_start - 60, text_url)
c.showPage() # Maak een nieuwe pagina voor de volgende nummer
os.remove(qr_image_path) # Verwijder tijdelijke QR-code afbeelding
else:
log_message(f"Geen link gevonden voor '{title} - {artist}'.")
c.save()
log_message(f"PDF succesvol gegenereerd: {output_pdf}")
if __name__ == "__main__":
if len(sys.argv) != 2 or sys.argv[1] not in ["spotify", "youtube"]:
log_message("Gebruik: python scriptnaam.py <mode>")
log_message("<mode> moet 'spotify' of 'youtube' zijn.")
print("Gebruik: python scriptnaam.py <mode>")
sys.exit(1)
platform = sys.argv[1]
csv_file = "nummers.csv"
output_pdf = "nummers_met_qr.pdf"
position_col, title_col, artist_col, year_col = "positie", "titel", "artiest", "jaar"
log_message(
f"Script gestart voor platform: {platform}. CSV bestand: {csv_file}, Output PDF: {output_pdf}")
generate_qr_codes_and_pdf(csv_file, output_pdf, position_col,
title_col, artist_col, year_col, platform)

@ -0,0 +1,6 @@
pandas
qrcode[pil]
Pillow
reportlab
requests
python-dotenv

@ -0,0 +1,2 @@
pandas
matplotlib

@ -0,0 +1,3 @@
requests
mysql-connector-python
python-dotenv

@ -0,0 +1,132 @@
import requests
import mysql.connector
from datetime import datetime, timezone
from dotenv import load_dotenv
import os
# Laad .env bestand
load_dotenv()
# Configuratie
GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_API_KEY")
WEATHER_API_KEY = os.getenv("WEATHER_API_KEY")
HOME_ADDRESS = os.getenv("HOME_ADDRESS")
WORK_ADDRESS = os.getenv("WORK_ADDRESS")
LOG_FILE = "log.txt"
SCRIPT_NAME = "LogTravelTime.py"
db_config = {
"host": os.getenv("DB_HOST"),
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"database": os.getenv("DB_NAME")
}
def log_message(message):
with open(LOG_FILE, "a") as log_file:
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
log_file.write(f"[{timestamp}] {SCRIPT_NAME}: {message}\n")
def create_table():
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor()
query = """
CREATE TABLE IF NOT EXISTS travel_times (
utc_datetime CHAR(16),
origin VARCHAR(255),
destination VARCHAR(255),
travel_time INT,
direction ENUM('heen', 'terug'),
mode ENUM('driving', 'bicycling', 'transit'),
temperature FLOAT,
weather VARCHAR(255),
PRIMARY KEY (utc_datetime, mode, direction)
)
"""
cursor.execute(query)
connection.commit()
cursor.close()
connection.close()
def get_weather():
url = f"https://api.openweathermap.org/data/2.5/weather?q=Amsterdam&appid={WEATHER_API_KEY}&units=metric"
response = requests.get(url)
data = response.json()
if data["cod"] == 200:
temperature = data["main"]["temp"]
weather = data["weather"][0]["description"]
return temperature, weather
else:
log_message("Error fetching weather data")
return None, None
def get_travel_time(origin, destination, mode):
url = "https://maps.googleapis.com/maps/api/distancematrix/json"
params = {
"origins": origin,
"destinations": destination,
"mode": mode,
"departure_time": "now",
"traffic_model": "best_guess",
"key": GOOGLE_MAPS_API_KEY
}
response = requests.get(url, params=params)
data = response.json()
if data["status"] == "OK":
if mode == "driving":
duration = data["rows"][0]["elements"][0]["duration_in_traffic"]["value"]
else:
duration = data["rows"][0]["elements"][0]["duration"]["value"]
return duration // 60 # Minuten
else:
log_message(f"Error fetching travel time for {mode}")
return None
def save_travel_time(origin, destination, travel_time, direction, mode, temperature, weather):
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor()
query = """
INSERT INTO travel_times (utc_datetime, origin, destination, travel_time, direction, mode, temperature, weather)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE travel_time = VALUES(travel_time), direction = VALUES(direction), temperature = VALUES(temperature), weather = VALUES(weather)
"""
utc_now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M")
cursor.execute(query, (utc_now, origin, destination,
travel_time, direction, mode, temperature, weather))
connection.commit()
cursor.close()
connection.close()
log_message(
f"Saved travel time for {mode} {direction}: {travel_time} minutes, weather: {weather}, temp: {temperature}°C")
def main():
create_table()
temperature, weather = get_weather()
if temperature is None or weather is None:
log_message("Skipping travel time logging due to missing weather data")
return
for mode in ["driving", "bicycling", "transit"]:
travel_time_morning = get_travel_time(HOME_ADDRESS, WORK_ADDRESS, mode)
if travel_time_morning:
save_travel_time(HOME_ADDRESS, WORK_ADDRESS,
travel_time_morning, "heen", mode, temperature, weather)
travel_time_evening = get_travel_time(WORK_ADDRESS, HOME_ADDRESS, mode)
if travel_time_evening:
save_travel_time(WORK_ADDRESS, HOME_ADDRESS,
travel_time_evening, "terug", mode, temperature, weather)
if __name__ == "__main__":
main()

@ -0,0 +1,2 @@
flask
numpy

@ -0,0 +1,22 @@
from flask import Flask, jsonify
import numpy as np
app = Flask(__name__)
@app.route('/')
def hello_world():
# Genereer een willekeurige matrix van 3x3 met NumPy
matrix = np.random.rand(3, 3).tolist()
# Maak een bericht met de matrix
message = {
"message": "Welkom bij de Flask API!",
"random_matrix": matrix
}
return jsonify(message)
if __name__ == '__main__':
app.run(debug=True)

@ -0,0 +1,141 @@
#!/bin/bash
export TZ=Europe/Amsterdam
#SNAP_BASE="/mnt/hgfs/Disk2/UniFi-Snaps"
SNAP_BASE="/files/img"
OUT_DIR="$SNAP_BASE/timelapse"
DATE_EXT=`date '+%F %H%M'`
VERBOSE=1
declare -A CAMS
CAMS["Front Garden"]="http://192.168.10.23/snap.jpeg"
CAMS["Frontdoor"]="http://192.168.1.131/snap.jpeg"
CAMS["Driveway"]="http://192.1.1.112/snap.jpeg"
CAMS["Back Garden"]="http://192.168.1.134/snap.jpeg"
# If we are in a terminal, be verbose.
# if [[ -z $VERBOSE && -t 1 ]]; then
# VERBOSE=1
# fi
log()
{
if [ ! -z $VERBOSE ]; then echo "$@"; fi
}
logerr()
{
echo "$@" 1>&2;
}
createDir()
{
if [ ! -d "$1" ]; then
mkdir "$1"
# check error here
fi
}
getSnap() {
snapDir="$SNAP_BASE/$1"
if [ ! -d "$snapDir" ]; then
mkdir -p "$snapDir"
# check error here
fi
snapFile="$snapDir/$1 - $DATE_EXT.jpg"
log savingSnap "$2" to "$snapFile"
wget --quiet -O "$snapFile" "$2"
}
createMovie()
{
snapDir="$SNAP_BASE/$1"
snapTemp="$snapDir/temp-$DATE_EXT"
snapFileList="$snapDir/temp-$DATE_EXT/files.list"
if [ ! -d "$snapDir" ]; then
logedd "Error : No media files in '$snapDir'"
exit 2
fi
createDir "$snapTemp"
if [ "$2" = "today" ]; then
log "Creating video of $1 from today's images"
ls "$snapDir/"*`date '+%F'`*.jpg | sort > "$snapFileList"
elif [ "$2" = "yesterday" ]; then
log "Creating video of $1 from yesterday's images"
ls "$snapDir/"*`date '+%F' -d "1 day ago"`*.jpg | sort > "$snapFileList"
elif [ "$2" = "file" ]; then
if [ ! -f "$3" ]; then
logerr "ERROR file '$3' not found"
exit 1
fi
log "Creating video of $1 from images in $3"
cp "$3" "$snapFileList"
else
log "Creating video of $1 from all images"
`ls "$snapDir/"*.jpg | sort > "$snapFileList"`
fi
# need to chance current dir so links work over network mounts
cwd=`pwd`
cd "$snapTemp"
x=1
#for file in $snapSearch; do
while IFS= read -r file; do
counter=$(printf %06d $x)
ln -s "../`basename "$file"`" "./$counter.jpg"
x=$(($x+1))
done < "$snapFileList"
#done
if [ $x -eq 1 ]; then
logerr "ERROR no files found"
exit 2
fi
createDir "$OUT_DIR"
outfile="$OUT_DIR/$1 - $DATE_EXT.mp4"
ffmpeg -r 15 -start_number 1 -i "$snapTemp/"%06d.jpg -c:v libx264 -preset slow -crf 18 -c:a copy -pix_fmt yuv420p "$outfile" -hide_banner -loglevel panic
log "Created $outfile"
cd $cwd
rm -rf "$snapTemp"
}
case $1 in
savesnap)
for ((i = 2; i <= $#; i++ )); do
if [ -z "${CAMS[${!i}]}" ]; then
logerr "ERROR, can't find camera '${!i}'"
else
getSnap "${!i}" "${CAMS[${!i}]}"
fi
done
;;
createvideo)
createMovie "${2}" "${3}" "${4}"
;;
*)
logerr "Bad Args use :-"
logerr "$0 savesnap \"camera name\""
logerr "$0 createvideo \"camera name\" today"
logerr "options (today|yesterday|all|filename)"
;;
esac

@ -0,0 +1,101 @@
import mysql.connector
from mysql.connector import Error
def create_db_connection(config, logger):
"""
Maakt verbinding met de MySQL-database.
:param config: Configuratie voor databaseverbinding.
:param logger: Logger object voor loggen.
:return: De databaseverbinding
"""
try:
connection = mysql.connector.connect(
host=config['host'],
port=config['port'],
user=config['user'],
password=config['password'],
database=config['database']
)
if connection.is_connected():
logger.debug("Successfully connected to the database.")
return connection
except Error as e:
logger.error(f"Error while connecting to MySQL: {e}")
raise e
def create_table_if_not_exists(cursor, logger):
"""
Maakt de tabel aan in de database als deze nog niet bestaat.
:param cursor: De database cursor
:param logger: Logger object voor loggen.
"""
try:
# SQL query om de tabel aan te maken
create_table_query = """
CREATE TABLE IF NOT EXISTS weather_forecast (
id INT AUTO_INCREMENT PRIMARY KEY,
utc DATETIME UNIQUE NOT NULL,
temperature FLOAT NOT NULL,
weather_description VARCHAR(255) NOT NULL,
wind_speed FLOAT NOT NULL,
rain FLOAT DEFAULT 0,
solar_performance FLOAT DEFAULT 0,
sunrise DATETIME NOT NULL,
sunset DATETIME NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
cursor.execute(create_table_query)
logger.debug("Weather forecast table is ready (created or exists).")
except Error as e:
logger.error(f"Error creating table: {e}")
raise e
def insert_or_update_forecast_data(cursor, utc_dt, temp, weather, wind_speed, rain, solar_performance, sunrise, sunset, logger):
"""
Voegt een record toe aan de tabel of werkt het bij als het record al bestaat.
:param cursor: De database cursor
:param utc_dt: UTC-tijd van de voorspelling
:param temp: Temperatuur
:param weather: Weersomstandigheden
:param wind_speed: Windsnelheid
:param rain: Hoeveelheid regen
:param solar_performance: Schatting van de zonneprestaties
:param sunrise: Tijd van zonsopgang
:param sunset: Tijd van zonsondergang
:param logger: Logger object voor loggen.
"""
try:
# Check of het record al bestaat
check_query = """
SELECT id FROM weather_forecast WHERE utc = %s;
"""
cursor.execute(check_query, (utc_dt,))
result = cursor.fetchone()
if result:
# Als het record bestaat, werk het dan bij
update_query = """
UPDATE weather_forecast
SET temperature = %s, weather_description = %s, wind_speed = %s, rain = %s, solar_performance = %s, sunrise = %s, sunset = %s
WHERE utc = %s;
"""
cursor.execute(update_query, (temp, weather, wind_speed,
rain, solar_performance, sunrise, sunset, utc_dt))
logger.debug(f"Updated existing record for {utc_dt}.")
else:
# Als het record niet bestaat, voeg het dan toe
insert_query = """
INSERT INTO weather_forecast (utc, temperature, weather_description, wind_speed, rain, solar_performance, sunrise, sunset)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s);
"""
cursor.execute(insert_query, (utc_dt, temp, weather,
wind_speed, rain, solar_performance, sunrise, sunset))
logger.debug(f"Inserted new record for {utc_dt}.")
except Error as e:
logger.error(f"Error inserting or updating data for {utc_dt}: {e}")
raise e

@ -0,0 +1,106 @@
import requests
import datetime
import mysql.connector
from dotenv import load_dotenv
import os
# Laad de .env bestand
print("Loading environment variables from .env...")
load_dotenv()
# Haal de API-sleutel uit de omgevingsvariabelen
api_key = os.getenv('OPENWEATHERMAP_API_KEY')
# Haal de MySQL-gegevens uit de omgevingsvariabelen
db_host = os.getenv('DB_HOST')
db_user = os.getenv('DB_USER')
db_password = os.getenv('DB_PASSWORD')
db_database = os.getenv('DB_DATABASE')
# Haal de locatie uit de omgevingsvariabelen
location = os.getenv('LOCATION')
print(f"Using OpenWeatherMap API key: {api_key}")
print(f"Using location: {location}")
# URL van de OpenWeatherMap API voor de forecast
url = f'http://api.openweathermap.org/data/2.5/forecast?q={location}&units=metric&cnt=7&appid={api_key}'
print(f"Fetching weather forecast from OpenWeatherMap for {location}...")
# Haal de data op
response = requests.get(url)
if response.status_code == 200:
print("Data successfully fetched from OpenWeatherMap API.")
data = response.json()
else:
print(f"Error fetching data: {response.status_code}")
data = {}
# Verbinding maken met MySQL-database
print("Connecting to MySQL database...")
db_connection = mysql.connector.connect(
host=db_host,
user=db_user,
password=db_password,
database=db_database
)
cursor = db_connection.cursor()
# Maak de tabel aan als deze nog niet bestaat
print("Ensuring the forecast_data table exists...")
create_table_query = """
CREATE TABLE IF NOT EXISTS forecast_data (
id INT AUTO_INCREMENT PRIMARY KEY,
utc_datetime DATETIME UNIQUE,
temperature FLOAT,
weather_description VARCHAR(255),
wind_speed FLOAT,
rain FLOAT
);
"""
cursor.execute(create_table_query)
print("Table `forecast_data` is ready.")
# Toon de forecast en sla deze op in de database
print(f"Processing forecast data for {len(data.get('list', []))} entries...")
for entry in data.get('list', []):
# Converteer de tijd naar UTC
utc_dt = datetime.datetime.utcfromtimestamp(entry['dt'])
temp = entry['main']['temp']
weather = entry['weather'][0]['description']
wind_speed = entry['wind']['speed']
# Regensomstandigheden (indien aanwezig)
rain = entry.get('rain', {}).get('3h', 0)
# Print de data
print(f"\nProcessing data for {utc_dt.strftime('%Y-%m-%d %H:%M:%S')} UTC:")
print(f"Temperature: {temp}°C")
print(f"Weather: {weather.capitalize()}")
print(f"Wind Speed: {wind_speed} m/s")
print(f"Rain: {rain} mm")
# Voeg de data toe aan de database of update als het record al bestaat
query = """
INSERT INTO forecast_data (utc_datetime, temperature, weather_description, wind_speed, rain)
VALUES (%s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
temperature = VALUES(temperature),
weather_description = VALUES(weather_description),
wind_speed = VALUES(wind_speed),
rain = VALUES(rain);
"""
print(
f"Executing query to insert/update data for {utc_dt.strftime('%Y-%m-%d %H:%M:%S')}...")
cursor.execute(query, (utc_dt, temp, weather, wind_speed, rain))
print(
f"Data for {utc_dt.strftime('%Y-%m-%d %H:%M:%S')} successfully inserted/updated.")
# Commit de veranderingen en sluit de verbinding
print("Committing changes to the database...")
db_connection.commit()
print("Changes committed successfully.")
cursor.close()
db_connection.close()
print("Database connection closed.")

@ -0,0 +1,17 @@
import logging
def setup_logger(app_name, log_level=logging.DEBUG, log_format='%(asctime)s - %(levelname)s - %(message)s'):
# Naam van de app wordt hier dynamisch ingesteld
logger = logging.getLogger(app_name)
logger.setLevel(log_level)
ch = logging.StreamHandler() # Loggen naar de console
ch.setLevel(log_level)
# Formatter wordt hier als parameter gegeven
formatter = logging.Formatter(log_format)
ch.setFormatter(formatter)
logger.addHandler(ch)
return logger

@ -0,0 +1,129 @@
import os
from dotenv import load_dotenv
from datetime import datetime, timezone
from weather import fetch_weather_data, estimate_solar_performance, get_sun_times
from database import create_db_connection, create_table_if_not_exists, insert_or_update_forecast_data
from logger import setup_logger, logging
from pprint import pprint
# Initialisatie van variabelen en instellingen
def initialize_app():
load_dotenv()
app_name = "weather_forecast_app"
log_format = '%(asctime)s - %(levelname)s - %(message)s'
logger = setup_logger(
app_name, log_level=logging.INFO, log_format=log_format)
logger.info("Starting weather forecast application...")
API_KEY = os.getenv('OPENWEATHER_API_KEY')
LOCATION = os.getenv('LOCATION', 'Rijswijk')
db_config = {
'host': os.getenv('DB_HOST'),
'port': os.getenv('DB_PORT'),
'user': os.getenv('DB_USER'),
'password': os.getenv('DB_PASSWORD'),
'database': os.getenv('DB_NAME')
}
return API_KEY, LOCATION, db_config, logger
# Database functionaliteit
def handle_database_operations(db_config, logger):
try:
db_connection = create_db_connection(db_config, logger)
except Exception as e:
logger.error(f"Failed to connect to the database: {e}")
raise
cursor = db_connection.cursor()
try:
create_table_if_not_exists(cursor, logger)
except Exception as e:
logger.error(f"Error creating table: {e}")
db_connection.close()
raise
return db_connection, cursor
# Weather functionaliteit
def fetch_and_process_weather_data(API_KEY, LOCATION, logger):
try:
logger.info(
f"Fetching weather forecast from OpenWeatherMap for {LOCATION}...")
data = fetch_weather_data(API_KEY, LOCATION, logger)
# pprint(data)
except Exception as e:
logger.error(f"Error fetching weather data: {e}")
raise
return data
# Hoofdproces: het verwerken van de weersvoorspellingen en opslaan in de database
def process_forecasts(data, cursor, logger, location):
logger.info(
f"Processing forecast data for {len(data.get('list', []))} entries...")
for entry in data.get('list', []):
utc_dt = datetime.fromtimestamp(entry['dt'], tz=timezone.utc)
temp = entry['main']['temp']
weather = entry['weather'][0]['description']
wind_speed = entry['wind']['speed']
rain = entry.get('rain', {}).get('3h', 0)
logger.debug(
f"Processing entry at {utc_dt}: Temp={temp}, Weather={weather}, Wind={wind_speed}, Rain={rain}"
)
# Haal de sunrise en sunset tijden op per forecast entry
sunrise, sunset = get_sun_times(utc_dt, location, logger=logger)
solar_performance = estimate_solar_performance(
entry, utc_dt, location, sunrise, sunset, logger)
logger.debug(f"Estimated solar performance: {solar_performance}%")
insert_or_update_forecast_data(
cursor, utc_dt, temp, weather, wind_speed, rain, solar_performance, sunrise, sunset, logger)
# Hoofdfunctie
def main():
API_KEY, LOCATION, db_config, logger = initialize_app()
try:
db_connection, cursor = handle_database_operations(db_config, logger)
except Exception as e:
logger.error(f"Error during database operations: {e}")
return
try:
data = fetch_and_process_weather_data(
API_KEY, LOCATION, logger)
except Exception as e:
logger.error(f"Error fetching weather data: {e}")
return
try:
process_forecasts(data, cursor, logger, LOCATION)
except Exception as e:
logger.error(f"Error processing forecasts: {e}")
return
logger.info("Committing changes to the database...")
db_connection.commit()
logger.info("Changes committed successfully.")
cursor.close()
db_connection.close()
logger.info("Database connection closed.")
if __name__ == "__main__":
main()

@ -0,0 +1,4 @@
astral
requests
python-dotenv
mysql-connector-python

@ -0,0 +1,119 @@
from astral import LocationInfo
from astral.sun import sun
import pytz
from datetime import datetime
import requests
def fetch_weather_data(api_key, location, logger):
"""
Haalt de weersvoorspelling op van OpenWeatherMap.
Parameters:
- api_key: API sleutel voor OpenWeatherMap
- location: Locatienaam (stad)
- logger: Logger instance
Returns:
- JSON data van de weersvoorspelling
"""
base_url = "https://api.openweathermap.org/data/2.5/forecast"
params = {
'q': location,
'appid': api_key,
'units': 'metric'
}
try:
response = requests.get(base_url, params=params)
response.raise_for_status()
logger.info(f"Weather data fetched successfully for {location}.")
return response.json()
except requests.RequestException as e:
logger.error(f"Error fetching weather data: {e}")
return None
def get_sun_times(utc_datetime, location_name="Rijswijk", country="Netherlands", logger=None):
"""
Haalt de zonsopgang en zonsondergang op voor een bepaalde UTC tijd en locatie.
Returns:
- sunrise, sunset (beide datetime objects in UTC).
"""
location = LocationInfo(location_name, country,
"Europe/Amsterdam", 52.0345, 4.3186)
# Bereken zon-op/zon-onder tijden met Astral
sun_times = sun(location.observer,
date=utc_datetime.date(), tzinfo=pytz.utc)
# Overtuig dat het datetime-objecten zijn
sunrise = sun_times["sunrise"]
sunset = sun_times["sunset"]
if isinstance(sunrise, str): # Als het toch een string is, fix het
sunrise = datetime.fromisoformat(sunrise).replace(tzinfo=pytz.utc)
if isinstance(sunset, str):
sunset = datetime.fromisoformat(sunset).replace(tzinfo=pytz.utc)
if logger:
logger.debug(
f"For {utc_datetime.date()} in {location_name}: Sunrise at {sunrise} , Sunset at {sunset} ")
return sunrise, sunset
def estimate_solar_performance(entry, utc_dt, location, sunrise, sunset, logger):
"""
Schat de zonne-energieproductie op basis van de zonshoogte en weersfactoren.
Parameters:
- entry: JSON entry met de weerdata
- utc_dt: Tijdstip van de voorspelling (UTC)
- location: Naam van de locatie voor berekening van zonsopgang/zonsondergang
- logger: Logger voor debugging
Returns:
- Een percentage (0-100) dat de zonne-energieproductie schat.
"""
# 🚀 Zorg ervoor dat sunrise en sunset datetime-objecten zijn
if isinstance(sunrise, str):
sunrise = datetime.fromisoformat(sunrise).replace(tzinfo=pytz.utc)
if isinstance(sunset, str):
sunset = datetime.fromisoformat(sunset).replace(tzinfo=pytz.utc)
# Temperatuur en bewolking ophalen
temperature = entry["main"]["temp"]
cloudiness = entry["clouds"]["all"] # % bewolking
weather_desc = entry["weather"][0]["description"]
# Logging
logger.debug(
f"UTC: {utc_dt}, Temp: {temperature}, Clouds: {cloudiness}%, Weather: {weather_desc}")
# Stap 1: Bereken een initiële waarde op basis van zonshoogte (factor van 0 tot 1)
if utc_dt < sunrise or utc_dt > sunset:
sun_factor = 0.0 # Nacht
elif utc_dt == sunrise or utc_dt == sunset:
sun_factor = 0.1 # 10% bij zonsopkomst/ondergang
else:
# Bereken de relatieve tijd binnen de zonnedag (0 = zonsopgang, 1 = zonsondergang)
day_fraction = (utc_dt - sunrise) / (sunset - sunrise)
# Gebruik een parabolische curve voor maximale intensiteit op het midden van de dag
sun_factor = -4 * (day_fraction - 0.5) ** 2 + 1
sun_factor = max(0, min(sun_factor, 1)) # Beperken tot 0-1
# Stap 2: Pas weerfactoren toe (bewolking beïnvloedt zonne-intensiteit)
# Omrekenen van % naar 0-1 schaal
weather_factor = (100 - cloudiness) / 100
# Totale zonneprestaties berekenen
solar_performance = sun_factor * weather_factor * 100 # Omzetten naar percentage
# Logging
logger.debug(
f"Sun factor: {sun_factor}, Weather factor: {weather_factor}, Solar performance: {solar_performance:.2f}%")
return round(solar_performance, 2)

@ -0,0 +1,67 @@
from flask import Flask, render_template
from modules import database
from dotenv import load_dotenv
import os
# Laad omgevingsvariabelen vanuit .env bestand
load_dotenv()
app = Flask(__name__)
# Configuratie voor database en logging uit omgevingsvariabelen
config = {
'user': os.getenv('DB_USER'),
'password': os.getenv('DB_PASSWORD'),
'host': os.getenv('DB_HOST'),
'database': os.getenv('DB_NAME')
}
logger = app.logger # Flask loggers
def calculate_windkracht(wind_speed):
"""Berekent de windkracht op basis van de wind_snelheid (m/s)."""
if wind_speed <= 0.2:
return "Windstil", 0
elif wind_speed <= 1.5:
return "Zwak", 1
elif wind_speed <= 3.3:
return "Matig", 2
elif wind_speed <= 5.4:
return "Frisse wind", 3
elif wind_speed <= 7.9:
return "Harde wind", 4
elif wind_speed <= 10.7:
return "Stormachtig", 5
else:
return "Storm", 6
@app.route('/')
def index():
# Maak een database-object (pas de naam aan naar Database)
db = database.Database(config, logger) # Veranderd naar database.Database
# Haal de weerdata op uit de database
weather_data = db.get_weather_data()
# Verwerk de windkracht op basis van de gemiddelde wind_speed
for entry in weather_data:
wind_speed = entry['avg_wind_speed']
if wind_speed is not None:
entry['windkracht_tekst'], entry['windkracht_num'] = calculate_windkracht(
wind_speed)
else:
entry['windkracht_tekst'] = "Gegevens niet beschikbaar"
entry['windkracht_num'] = None
# Voeg de dag van de week toe (bijvoorbeeld 'Maandag', 'Dinsdag', etc.)
# Gebruik direct strftime op een datetime object
entry['dag_van_de_week'] = entry['date'].strftime('%A')
# Geef de verwerkte data door aan de template
return render_template('index.html', weather_data=weather_data)
if __name__ == '__main__':
app.run(debug=True)

@ -0,0 +1,38 @@
import mysql.connector
class Database:
def __init__(self, config, logger):
self.config = config
self.logger = logger
def connect(self):
"""Maakt een databaseverbinding."""
try:
conn = mysql.connector.connect(**self.config)
return conn
except mysql.connector.Error as err:
self.logger.error(f"Database connectiefout: {err}")
return None
def get_weather_data(self):
"""Haalt de gemiddelde weergegevens per dag op."""
conn = self.connect()
if not conn:
return []
cursor = conn.cursor(dictionary=True)
query = """
SELECT DATE(utc) as date,
AVG(temperature) as avg_temp,
AVG(solar_performance) as avg_solar,
AVG(wind_speed) as avg_wind_speed,
GROUP_CONCAT(DISTINCT weather_description) as descriptions
FROM weather_forecast
GROUP BY DATE(utc)
ORDER BY date ASC
"""
cursor.execute(query)
data = cursor.fetchall()
conn.close()
return data

@ -0,0 +1,73 @@
/* Algemene body-stijlen */
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
color: #333;
margin: 0;
padding: 20px;
}
/* Weer-container */
.weather-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
/* Weer-box styling */
.weather-box {
background-color: white;
border: 2px solid #ddd;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
/* Hover-effect voor weer-boxen */
.weather-box:hover {
transform: translateY(-5px);
}
/* Windkracht styling */
.weather-box p {
margin: 10px 0;
}
/* Toevoegen van zonprestatie-kleur (voorbeeld) */
.low-solar {
border-color: blue;
background-color: lightblue;
}
.medium-solar {
border-color: green;
background-color: lightgreen;
}
.high-solar {
border-color: orange;
background-color: lightyellow;
}
.very-high-solar {
border-color: yellow;
background-color: lightgoldenrodyellow;
}
/* Specifieke styling voor de dagen van de week */
.weather-box h2 {
font-size: 1.2em;
font-weight: bold;
}
/* Styling voor de zonnetjes (per zonne-rating) */
.sun-rating {
font-size: 1.5em;
color: gold;
}
/* Alternatief voor een duidelijker onderscheid tussen de dagen */
.weather-box:nth-child(odd) {
background-color: #f9f9f9;
}

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weervoorspelling</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Weervoorspelling per dag</h1>
<div class="weather-container">
{% for day in weather_data %}
<div class="weather-box
{% if day.avg_solar <= 20 %}
low-solar
{% elif day.avg_solar <= 50 %}
medium-solar
{% elif day.avg_solar <= 75 %}
high-solar
{% else %}
very-high-solar
{% endif %}
">
<h2>{{ day.dag_van_de_week }} - {{ day.date }}</h2>
<p><strong>Gemiddelde temperatuur:</strong> {{ '%.1f' % day.avg_temp }} °C</p>
<p><strong>Weersomstandigheden:</strong> {{ day.descriptions }}</p>
<p><strong>Windkracht:</strong> {{ day.windkracht_tekst }} (Windkracht {{ day.windkracht_num }})</p>
<!-- Zonprestatie (afhankelijk van de solar performance) -->
<div class="sun-rating">
{% if day.avg_solar <= 20 %}
🌑
{% elif day.avg_solar <= 50 %}
🌒
{% elif day.avg_solar <= 75 %}
🌞🌞
{% else %}
🌞🌞🌞
{% endif %}
</div>
</div>
{% endfor %}
</div>
</body>
</html>

@ -0,0 +1,117 @@
import sys, os
import xml.etree.ElementTree as ET
def main():
# list file in directory
CheckDir(path)
dryrun = False
def CheckDir(path):
# if dir has nfo file
path2 = os.path.join(path, "")
for root, dirs, files in os.walk(path):
for name in dirs:
# print(name)
orgpath = os.path.join(root, name)
fullpath = orgpath
if "Unknown" in name:
# name = name.replace("Ai Iijima", baseinfo["actress"])
if not dryrun:
newpath = os.path.join(root, name)
os.rename(orgpath, newpath)
fullpath = newpath
# print("orgpath= {0}, newpath={1}".format(orgpath, newpath))
# print("name= {0}, path={1}".format(name, subdir))
procesSubdir(fullpath)
rootdir = "/Volumes/Docker/Syncthing/config/Sync"
path = os.path.join(rootdir, "manualsort")
baseinfo = {}
baseinfo["actress"] = "@Unknown"
baseinfo["altname"] = "Ai Iijima"
def procesSubdir(path):
hasnfo = False
for root, dirs, files in os.walk(path):
for name in files:
fullpath = os.path.join(root, name)
if ".nfo" in name:
hasnfo = True
setnfofile(root, fullpath)
# create nfo file withe same filename as mediafile\
# setnfofile
def setnfofile(root, nfofile):
#
# # add baseinfo into nfo file
root, basename = os.path.split(root)
# print(basename)
# print("root= {0} basename={1}".format(root, basename))
tree = ET.parse(nfofile)
xmlroot = tree.getroot()
for title in xmlroot.findall("title"):
title.text = basename
# Create a new element
new_element = ET.Element("tag")
new_element.text = "uncensored"
# tag = xmlroot.findall("tag")
xmlroot.append(new_element)
new_element = ET.Element("tag")
new_element.text = "subtitled"
# tag = xmlroot.findall("tag")
xmlroot.append(new_element)
if not dryrun:
print("writing")
tree.write(nfofile)
# for actor in xmlroot.findall("actor"):
# name = actor.find("name")
# if name.text == "ai iijima":
# name.text = baseinfo["actress"]
# altname = actor.find("altname")
# altname.text = baseinfo["altname"]
# print(ET.tostring(actor))
# for actor in xmlroot.findall("actor"):
# name = actor.find("name")
# if name.text == "Unknown":
# name.text = baseinfo["actress"]
# altname = actor.find("altname")
# altname.text = baseinfo["altname"]
# # print(ET.tostring(actor))
# if not dryrun:
# tree.write(nfofile)
# print(xmlroot)
# for root, dirs, files in os.walk(root):
# for name in dirs:
# print(name)
# print(root)
# def tryscrape():
# def getcover():
if __name__ == "__main__":
main()
Loading…
Cancel
Save