citavi_mapper/service/Citavi.py

118 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session, scoped_session, sessionmaker
class Project():
""" A helper class representing a Citavi project. """
def __init__(self, sqlite_file):
""" Constructor to get absolute path to sqlite. """
self.sqlite_file = sqlite_file
self._is_open = False
self._is_error = False
self._sa = {} # Object namespace for sqlalchemy related objects
def __del__(self):
""" Destructor to close the citavi file. """
self.close()
def is_valid(self):
""" This method returns False in case the given sqlite file is not a valid Citavi project. """
return self._is_open and not self._is_error
def get_persons(self):
""" Returns all persons from the Citavi project. """
try:
person_class = self._sa_sqlite_autobase.classes.Person
citavi_persons = self._sa_sqlite_session.query(person_class).all()
return citavi_persons
except Exception, e:
print e
self._is_error = True
# TODO: better error handling!
print str(u"An error occured within a get_persons call!")
return False
def get_person_by_uuid(self, uuid):
""" Returns a person from the Citavi project by their uuid. """
try:
person_class = self._sa_sqlite_autobase.classes.Person
citavi_person = self._sa_sqlite_session.query(person_class).filter(u'ID=\'' + unicode(uuid) + u'\'').all()
return citavi_person[0]
except Exception, e:
print e
self._is_error = True
# TODO: better error handling!
print str(u"An error occured within a get_person_by_uuid call!")
return False
def open(self):
""" Public method to open a citavi project file. """
if not self._is_open:
self._open()
def close(self):
""" Public method to close a citavi project file. """
if self._is_open:
self._close()
def _open(self):
""" Internal method to open a citavi project file. """
try:
self._sa_sqlite_engine = create_engine(u'sqlite+pysqlite:///' + self.sqlite_file)
self._sa_sqlite_session = scoped_session(sessionmaker(bind=self._sa_sqlite_engine)) # Caution: SQLAlchemy Sessions are per thread!
self._sa_sqlite_meta = MetaData(bind=self._sa_sqlite_engine)
self._sa_sqlite_meta.reflect()
self._sa_sqlite_autobase = automap_base()
self._sa_sqlite_autobase.prepare(self._sa_sqlite_engine, reflect=True)
self._is_open = True
except:
self._is_error = True
self._is_open = False
def _close(self):
""" Internal method to actually close a citavi project file. """
try:
del self._sa.sqlite_engine
del self._sa.sqlite_session
del self._sa.sqlite_meta
del self._sa.sqlite_autobase
del self._sa.sqlite_engine
self._is_open = False
except:
self._is_error = True
self._is_open = True
class ProjectManager():
""" A backend to provide fast access to Citavi identity data. """
def __init__(self):
""" Constructor initializing dictionary for instances of Project. """
self._projects = {}
def __del__(self):
""" Destructor making sure all Project instances are properly deconstructed. """
self._projects.clear()
def get_path_for_project_id(self, project_id):
return u'media/citavi/project_' + unicode(project_id) + u'.ctt4'
def _add_project(self, project_id):
""" Internal method to add a Project instance if not existing. """
if project_id not in self._projects:
self._projects[project_id] = Project(self.get_path_for_project_id(project_id))
self._projects[project_id].open()
def get_person_by_uuid(self, project_id, uuid):
""" Returns the person matching the given uuid. """
self._add_project(project_id)
return self._projects[project_id].get_person_by_uuid(uuid)
def get_persons_from_project(self, project_id):
""" Returns all person from a projects. """
self._add_project(project_id)
return self._projects[project_id].get_persons()