[TASK] Add CitaviProject class, integrate first handling for uploaded projects.

This commit is contained in:
Jan Philipp Timme 2014-09-16 11:34:53 +02:00
parent c3b32d5de3
commit f92e780380
2 changed files with 102 additions and 26 deletions

View File

@ -125,20 +125,37 @@ class UpdateProjectView(ProtectedFormView, SingleObjectMixin):
self.success_url = self.success_url + self.project_id + '/update'
return super(UpdateProjectView, self).post(request, *args, **kwargs)
""" This form_valid handles the file uploads and triggers a citavi schema import and things. """
def form_valid(self, form, *args, **kwargs):
""" This form_valid handles the file upload. """
original_file = form.files[u'file']
original_filename = str(original_file)
relative_path = default_storage.save('tmp/project_' + self.project_id + '.ctt4', ContentFile(original_file.read()))
path = os.path.join(settings.MEDIA_ROOT, relative_path)
#TODO: Actually validate that we get an SQLite3 file!
""" Put file into temporary folder for analysis """
relative_path = default_storage.save('tmp/project_' + str(self.project_id) + '.ctt4', ContentFile(original_file.read()))
temp_sqlite = os.path.join(settings.MEDIA_ROOT, relative_path)
# Store this in the project model
project = Project.objects.get(id=self.project_id)
project.associated_filename = original_filename
project.save()
""" Test if SQLite is a valid citavi project. """
from service import Citavi
citavi_project = Citavi.CitaviProject(temp_sqlite)
citavi_project_valid = citavi_project.is_valid()
""" Free temporary ressources. """
del citavi_project
default_storage.delete(temp_sqlite)
if citavi_project_valid == False:
""" TODO: Put up an error message or something. """
pass
else:
""" Actually store file in citavi folder """
relative_path = default_storage.save('citavi/project_' + str(self.project_id) + '.ctt4', ContentFile(original_file.read()))
sqlite_path = os.path.join(settings.MEDIA_ROOT, relative_path)
""" Store new original filename in Project """
project = Project.objects.get(id=self.project_id)
project.associated_filename = original_filename
project.save()
""" Refresh identities from citavi project. """
# TODO
return super(UpdateProjectView, self).form_valid(form)

View File

@ -1,7 +1,80 @@
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
class CitaviProject():
""" 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. """
self.open()
return self._is_open and not self._is_error
def get_persons(self):
try:
PersonClass = self._sa_sqlite_autobase.classes.Person
except:
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('sqlite+pysqlite:///' + self.sqlite_file)
self._sa_sqlite_session = Session(self._sa_sqlite_engine)
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
pass
"""
def import_sqlite(project_id, sqlite_file):
print "This is import_sqlite speaking!"
@ -9,11 +82,6 @@ def import_sqlite(project_id, sqlite_file):
print sqlite_file
print "Importing data..."
from sqlalchemy import *
from sqlalchemy.schema import CreateSchema
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
# Initialize sqlite part
sqlite_engine = create_engine('sqlite+pysqlite:///project_import_9.ctt4', echo=True)
sqlite_session = Session(sqlite_engine)
@ -26,11 +94,9 @@ def import_sqlite(project_id, sqlite_file):
psql_engine.execute(CreateSchema('alchemytest')) # TODO: Catch Exception/Warning/Whatever here
psql_meta = MetaData(bind=psql_engine, schema='alchemytest')
"""
# Reflect the origin - maybe psql_meta.reflect() is enough?
sqlite_autobase = automap_base()
sqlite_autobase.prepare(sqlite_engine, reflect=True)
"""
# This small snippet prints python class code for sqlalchemy reflected classes
@ -59,7 +125,6 @@ def import_sqlite(project_id, sqlite_file):
#meta.tables['ReferenceAuthor'].select().execute().fetchall()
# Now we need to "convert" unsupported types :-/
"""
for table in meta.sorted_tables:
table_name = str(table)
columns = table.columns.items()
@ -70,10 +135,4 @@ def import_sqlite(project_id, sqlite_file):
print table_name + "." + column_name + ': ' + column_type
print
print
"""
""" TODO: since DATETIME (sqlite3) does not map onto TIMESTAMP / DATE (postgresql), some mapping/migrating is required! """
pass
"""