some refactoring
This commit is contained in:
75
databinding/CalendarSync.py
Normal file
75
databinding/CalendarSync.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import caldav
|
||||
import datetime
|
||||
import logging
|
||||
import re
|
||||
import vobject
|
||||
|
||||
class CalendarSync(object):
|
||||
log = logging.getLogger("CalendarSync")
|
||||
|
||||
startTime = "06:00"
|
||||
|
||||
def __init__(self):
|
||||
self._calendar = None
|
||||
self._client = None
|
||||
|
||||
def connect(self, url, user, passwd):
|
||||
self._client = caldav.DAVClient(url=url, username=user, password=passwd)
|
||||
|
||||
@property
|
||||
def is_connected(self) -> bool:
|
||||
return self._client is not None
|
||||
|
||||
def getExistingMuellEvents(self) -> list[caldav.Event]:
|
||||
events = self._calendar.events()
|
||||
ret = []
|
||||
for e in events:
|
||||
try:
|
||||
uid = e.vobject_instance.vevent.uid.value
|
||||
m = re.match(r'(.+)@MyMuell', uid)
|
||||
if m is not None:
|
||||
ret.append(e)
|
||||
except AttributeError:
|
||||
continue
|
||||
return ret
|
||||
|
||||
def createEvent(self, uid, summary, date):
|
||||
date_start = datetime.datetime.combine(date, datetime.time.fromisoformat(CalendarSync.startTime))
|
||||
date_end = date_start + datetime.timedelta(minutes=5)
|
||||
|
||||
cal = vobject.iCalendar()
|
||||
ev = cal.add('vevent')
|
||||
ev.add("summary").value = summary
|
||||
ev.add("dtstart").value = date_start
|
||||
ev.add("dtend").value = date_end
|
||||
ev.add("uid").value = str(uid) + "@MyMuell"
|
||||
ev.add("valarm").add("trigger").value = datetime.timedelta(hours=-12)
|
||||
ev.add("valarm").add("trigger").value = datetime.timedelta(hours=0)
|
||||
|
||||
self._calendar.save_event(cal.serialize())
|
||||
|
||||
def syncEvents(self, e):
|
||||
self.createEvent(
|
||||
e["id"],
|
||||
e["title"],
|
||||
datetime.datetime.strptime(e["day"], "%Y-%m-%d"))
|
||||
|
||||
def getCalendars(self):
|
||||
principal = self._client.principal()
|
||||
cals = principal.calendars()
|
||||
ret = []
|
||||
for c in cals:
|
||||
ret.append(c.name)
|
||||
return ret
|
||||
|
||||
def createCalendar(self, cal):
|
||||
principal = self._client.principal()
|
||||
cals = principal.calendars()
|
||||
|
||||
for c in cals:
|
||||
if c.name == cal:
|
||||
self._calendar = c
|
||||
|
||||
if self._calendar is None:
|
||||
CalendarSync.log.info("creating new calendar \"{}\"".format(cal))
|
||||
self._calendar = principal.make_calendar(name=cal)
|
||||
75
databinding/LocalDataStorage.py
Normal file
75
databinding/LocalDataStorage.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from appdirs import *
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import copy
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
class LocalDataStorage(object):
|
||||
def __init__(self):
|
||||
self.appname = "MyMuellDav"
|
||||
self.appauthor = "Av3m"
|
||||
self.__fernet = Fernet(b'kWUFurHmtMWX6nOMhpFR45DpuNVPckSQ9t95_ADG2dA=')
|
||||
|
||||
if not os.path.exists(self.user_data_dir):
|
||||
os.makedirs(self.user_data_dir)
|
||||
|
||||
DefaultSettings = {
|
||||
'url': '',
|
||||
'user': '',
|
||||
'password': '',
|
||||
'calendar': '',
|
||||
'mymuellcity': '',
|
||||
}
|
||||
|
||||
@property
|
||||
def user_data_dir(self):
|
||||
return user_data_dir(self.appname, self.appauthor)
|
||||
|
||||
@property
|
||||
def file_settings(self):
|
||||
return os.path.join(self.user_data_dir, "settings.json")
|
||||
@property
|
||||
def file_city_data(self):
|
||||
return os.path.join(self.user_data_dir, "city_data.json")
|
||||
|
||||
@property
|
||||
def settings(self):
|
||||
if os.path.exists(self.file_settings):
|
||||
with open(self.file_settings, "r") as f:
|
||||
j = json.load(f)
|
||||
j["password"] = str(self.__fernet.decrypt(bytes(j["password"], encoding="utf-8")), encoding="utf-8")
|
||||
return j
|
||||
else:
|
||||
return LocalDataStorage.DefaultSettings
|
||||
|
||||
@settings.setter
|
||||
def settings(self, val):
|
||||
if val is None and os.path.exists(self.file_settings):
|
||||
os.remove(self.file_settings)
|
||||
return
|
||||
|
||||
with open(self.file_settings, "w+") as f:
|
||||
v = copy.copy(val)
|
||||
v["password"] = str(self.__fernet.encrypt(bytes(v["password"], encoding="utf-8")), encoding="utf-8")
|
||||
json.dump(v, f)
|
||||
|
||||
os.chmod(self.file_settings, 0o0600)
|
||||
|
||||
@property
|
||||
def city_data(self):
|
||||
if os.path.exists(self.file_city_data):
|
||||
with open(self.file_city_data, "r") as f:
|
||||
return json.load(f)
|
||||
else:
|
||||
return None
|
||||
|
||||
@city_data.setter
|
||||
def city_data(self, val):
|
||||
if val is None and os.path.exists(self.file_city_data):
|
||||
os.remove(self.file_city_data)
|
||||
return
|
||||
|
||||
with open(self.file_city_data, "w+") as f:
|
||||
json.dump(val, f)
|
||||
|
||||
77
databinding/MyMuellDataModel.py
Normal file
77
databinding/MyMuellDataModel.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import http.client
|
||||
import json
|
||||
import databinding.LocalDataStorage as LocalDataStorage
|
||||
import logging
|
||||
import re
|
||||
|
||||
class MyMuellDataModel(object):
|
||||
MyMuellHost = 'mymuell.jumomind.com'
|
||||
log = logging.getLogger("MyMuellDataModel")
|
||||
|
||||
def __init__(self):
|
||||
self.client = http.client.HTTPSConnection(MyMuellDataModel.MyMuellHost)
|
||||
|
||||
self.storage = LocalDataStorage.LocalDataStorage()
|
||||
self.cities = self.__get_cities()
|
||||
|
||||
def get_cities_by_request(self):
|
||||
self.client.request('GET', '/mmapp/loxone/lox.php?r=cities')
|
||||
response = self.client.getresponse()
|
||||
return json.loads(str(response.read(), encoding='utf-8'))
|
||||
|
||||
def get_events(self, city_id, area_id):
|
||||
self.client.request('GET', '/mmapp/loxone/lox.php?r=dates/0&city_id={city_id}&area_id={area_id}'.format(city_id=city_id, area_id=area_id))
|
||||
response = self.client.getresponse()
|
||||
ret = str(response.read(), encoding='utf-8')
|
||||
return json.loads(ret)
|
||||
|
||||
def __get_cities(self):
|
||||
cities = self.storage.city_data
|
||||
if cities is not None:
|
||||
MyMuellDataModel.log.debug("using stored values")
|
||||
return cities
|
||||
else:
|
||||
cities = self.get_cities_by_request()
|
||||
self.storage.city_data = cities
|
||||
|
||||
return cities
|
||||
|
||||
def get_city_names(self, indices):
|
||||
ret = []
|
||||
for idx in indices:
|
||||
e = self.get_city_by_index(idx)
|
||||
if e is not None:
|
||||
ret.append(e["name"])
|
||||
return ret
|
||||
|
||||
def match_city(self, pattern):
|
||||
ret = []
|
||||
|
||||
n = 0
|
||||
for i in self.cities:
|
||||
|
||||
m = re.search(pattern, i["name"], re.IGNORECASE)
|
||||
if m is not None:
|
||||
ret.append(n)
|
||||
n = n + 1
|
||||
|
||||
return ret
|
||||
|
||||
def get_city_by_index(self, idx):
|
||||
if len(self.cities) < idx:
|
||||
return None
|
||||
|
||||
return self.cities[idx]
|
||||
|
||||
def get_city_by_id(self, id):
|
||||
for i in self.cities:
|
||||
if i["id"] == id:
|
||||
return i
|
||||
|
||||
return None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
model = MyMuellDataModel()
|
||||
matches = model.match_city("eich")
|
||||
0
databinding/__init__.py
Normal file
0
databinding/__init__.py
Normal file
Reference in New Issue
Block a user