summaryrefslogtreecommitdiff
path: root/app/python
diff options
context:
space:
mode:
Diffstat (limited to 'app/python')
-rw-r--r--app/python/.gitignore1
-rw-r--r--app/python/rcal/__init__.py0
-rw-r--r--app/python/rcal/db.py34
-rw-r--r--app/python/rcal/model.py122
4 files changed, 157 insertions, 0 deletions
diff --git a/app/python/.gitignore b/app/python/.gitignore
new file mode 100644
index 0000000..df04015
--- /dev/null
+++ b/app/python/.gitignore
@@ -0,0 +1 @@
+rcal/*.pyc
diff --git a/app/python/rcal/__init__.py b/app/python/rcal/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/python/rcal/__init__.py
diff --git a/app/python/rcal/db.py b/app/python/rcal/db.py
new file mode 100644
index 0000000..68d5b0d
--- /dev/null
+++ b/app/python/rcal/db.py
@@ -0,0 +1,34 @@
+import json
+from os import path
+
+import sqlalchemy.engine.url as url
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+
+
+class Session(object):
+
+ engine = None
+
+ def __init__(self):
+ config = json.load(
+ open(path.join(path.dirname(
+ path.realpath(__file__)), '../../..', 'conf', 'db.json')))
+ db_str = url.URL(
+ drivername=config['type'],
+ host=config['host'],
+ username=config['user'],
+ password=config['pass'],
+ database=config['name'],
+ query={'charset': config['cset']}
+ )
+ self.engine = create_engine(db_str, encoding=config['cset'])
+
+ def get_maker(self):
+ return sessionmaker(bind=self.engine)
+
+ @staticmethod
+ def create():
+ session = Session()
+ maker = session.get_maker()
+ return maker()
diff --git a/app/python/rcal/model.py b/app/python/rcal/model.py
new file mode 100644
index 0000000..faed188
--- /dev/null
+++ b/app/python/rcal/model.py
@@ -0,0 +1,122 @@
+# pylint: disable=too-few-public-methods, invalid-name
+from sqlalchemy import Column, ForeignKey
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
+from sqlalchemy.types import (TIMESTAMP, Boolean, DateTime, Integer, String,
+ TypeDecorator)
+
+from dateutil.tz import tzutc
+
+
+class UTCDateTime(TypeDecorator):
+ impl = DateTime
+
+ def process_bind_param(self, value, engine):
+ if value is not None:
+ return value.astimezone(tzutc())
+
+ def process_result_value(self, value, engine):
+ if value is not None:
+ return value.replace(tzinfo=tzutc())
+
+
+BASE = declarative_base()
+
+
+class Calendar(BASE):
+ __tablename__ = 'calendars'
+
+ uid = Column(String(255), primary_key=True)
+ url = Column(String(255))
+ name = Column(String(255), index=True)
+ website = Column(String(255))
+ visible = Column(Boolean, index=True)
+ last_updated = Column(TIMESTAMP)
+
+ _category = Column(
+ Integer,
+ ForeignKey(
+ 'categories.id',
+ onupdate='CASCADE',
+ ondelete='SET NULL'))
+ category = relationship(
+ 'Category',
+ back_populates='calendars',
+ order_by='Calendar.name')
+
+ entries = relationship(
+ 'Entry',
+ back_populates='calendar',
+ cascade="all",
+ passive_deletes=True,
+ order_by='Entry.begin_date')
+
+ @staticmethod
+ def fetch(uid, session, name=None, url=None):
+ calendar = session.query(Calendar).filter(Calendar.uid == uid).first()
+ if not calendar:
+ calendar = Calendar()
+ calendar.uid = uid
+ session.add(calendar)
+ if name:
+ calendar.name = name
+ if url:
+ calendar.url = url
+ return calendar
+
+
+class Entry(BASE):
+ __tablename__ = 'entries'
+
+ id = Column(Integer, primary_key=True)
+ uid = Column(String(255), index=True, unique=True)
+ begin_date = Column(UTCDateTime, index=True)
+ end_date = Column(UTCDateTime)
+ all_day = Column(Boolean)
+ name = Column(String(255))
+ location = Column(String(255))
+
+ _calendar = Column(
+ String(255),
+ ForeignKey(
+ 'calendars.uid',
+ onupdate='CASCADE',
+ ondelete='CASCADE'))
+ calendar = relationship(
+ 'Calendar',
+ back_populates='entries',
+ order_by='Entry.begin_date')
+
+ @staticmethod
+ def fetch(uid, session):
+ entry = session.query(Entry).filter(Entry.uid == uid).first()
+ if not entry:
+ entry = Entry()
+ session.add(entry)
+ return entry
+
+
+class Category(BASE):
+ __tablename__ = 'categories'
+
+ id = Column(Integer, primary_key=True)
+ name = Column(String(255), index=True)
+
+ calendars = relationship(
+ 'Calendar',
+ back_populates='category',
+ cascade="all",
+ passive_deletes=True,
+ order_by='Calendar.name')
+
+ @staticmethod
+ def fetch(name, session):
+ category = session.query(Category).filter(
+ Category.name == name).first()
+ if not category:
+ category = Category()
+ category.name = name
+ session.add(category)
+ return category
+
+__all__ = ('Calendar', 'Entry', 'Category')