summaryrefslogtreecommitdiff
path: root/app/backend/rcal
diff options
context:
space:
mode:
authoremkael <emkael@tlen.pl>2016-06-07 15:16:59 +0200
committeremkael <emkael@tlen.pl>2016-06-10 11:46:41 +0200
commitdf401552aac363655ab8f056a6c910a7611954d6 (patch)
treeccd02b63b8f915f02959b7890d71507e44679917 /app/backend/rcal
parentfaa340586f78beacff2e32df65d2f37c08f0df2b (diff)
* renaming python directory
Diffstat (limited to 'app/backend/rcal')
-rw-r--r--app/backend/rcal/__init__.py0
-rw-r--r--app/backend/rcal/db.py34
-rw-r--r--app/backend/rcal/model.py153
3 files changed, 187 insertions, 0 deletions
diff --git a/app/backend/rcal/__init__.py b/app/backend/rcal/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/backend/rcal/__init__.py
diff --git a/app/backend/rcal/db.py b/app/backend/rcal/db.py
new file mode 100644
index 0000000..7e892a1
--- /dev/null
+++ b/app/backend/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__)), '..', 'config', '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/backend/rcal/model.py b/app/backend/rcal/model.py
new file mode 100644
index 0000000..512c75e
--- /dev/null
+++ b/app/backend/rcal/model.py
@@ -0,0 +1,153 @@
+# pylint: disable=too-few-public-methods, invalid-name
+from sqlalchemy import Column, ForeignKey, Table
+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
+
+
+# pylint: disable=abstract-method, unused-argument
+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)
+ custom_name = Column(String(255))
+ custom_image = Column(String(255))
+ custom_url = Column(String(255), unique=True, nullable=False, 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, nullable=False)
+ begin_date = Column(UTCDateTime, index=True)
+ end_date = Column(UTCDateTime)
+ all_day = Column(Boolean)
+ name = Column(String(255))
+ location = Column(String(255))
+ last_modified = Column(UTCDateTime)
+
+ _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)
+ priority = Column(Integer, 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
+
+
+user_selections = Table(
+ 'user_selections', BASE.metadata,
+ Column('_user', Integer,
+ ForeignKey('users.id', onupdate='CASCADE', ondelete='CASCADE'),
+ primary_key=True),
+ Column('_calendar', String(255),
+ ForeignKey('calendars.uid', onupdate='CASCADE', ondelete='CASCADE'),
+ primary_key=True)
+)
+
+
+class User(BASE):
+ __tablename__ = 'users'
+
+ id = Column(Integer, primary_key=True)
+ login = Column(String(255), unique=True, index=True)
+ password = Column(String(255))
+ is_admin = Column(Boolean)
+ timezone = Column(String(255))
+ last_login = Column(UTCDateTime)
+
+ calendars = relationship('Calendar',
+ secondary=user_selections)
+
+__all__ = ('Calendar', 'Entry', 'Category', 'User')