ics-fusion/app/tools/caching.py
Jules Dejaeghere 9c61cc6234 Implement caching of calendar files
TODO:
- Documentation
- Adjust README
2020-10-24 23:42:12 +02:00

91 lines
2.5 KiB
Python

import json
import os
import threading
import time
from hashlib import sha256
import arrow
import requests
from ics import Calendar
def cache(entry: dict) -> None:
if not os.path.isdir('cache'):
os.mkdir('cache')
url = entry['url']
path = "cache/" + sha256(url.encode()).hexdigest() + ".ics"
r = requests.get(entry["url"], allow_redirects=True)
if "encoding" in entry:
cal = Calendar(imports=r.content.decode(encoding=entry["encoding"]))
else:
cal = Calendar(imports=r.content.decode())
cal = horodate(cal, 'Cached at')
open(path, 'w').writelines(cal)
def get_from_cache(entry: dict) -> Calendar:
url = entry['url']
path = "cache/" + sha256(url.encode()).hexdigest() + ".ics"
if not os.path.isfile(path):
print("Not cached")
raise FileNotFoundError("The calendar is not cached")
with open(path, 'r') as file:
data = file.read()
return Calendar(imports=data)
def load_cal(entry: dict) -> Calendar:
if "cache" in entry and entry["cache"]:
print("Getting", entry["name"], "from cache")
return get_from_cache(entry)
else:
print("Getting", entry["name"], "from remote")
r = requests.get(entry["url"], allow_redirects=True)
if "encoding" in entry:
cal = Calendar(imports=r.content.decode(encoding=entry["encoding"]))
else:
cal = Calendar(imports=r.content.decode())
cal = horodate(cal, 'Downloaded at')
return cal
def horodate(cal: Calendar, prefix='') -> Calendar:
now = arrow.now().format("YYYY-MM-DD HH:mm:ss")
for event in cal.events:
event.description = event.description + '\n' + prefix + ' ' + now \
if event.description is not None else prefix + ' ' + now
return cal
def background_cache() -> None:
path = "config"
files = [os.path.join(path, f) for f in os.listdir(path)
if os.path.isfile(os.path.join(path, f)) and f.endswith('.json')]
for file in files:
with open(file, 'r') as config_file:
config = json.loads(config_file.read())
for entry in config:
if 'cache' in entry and entry['cache']:
cache(entry)
print('Cache renewed', arrow.now().format("YYYY-MM-DD HH:mm:ss"))
class CacheThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print("Starting cache process")
while True:
background_cache()
time.sleep(10*60)