Permalink
Browse files

Refactored SQLAlchemy connector into its own module so that it can be…

… used by both CherryPy and background threads
  • Loading branch information...
1 parent 083e026 commit 293e33a629c91518734956db81cf27bed6b48607 Jonathan Fritz committed Sep 25, 2012
Showing with 59 additions and 44 deletions.
  1. +13 −44 musik.py
  2. 0 musik/__init__.py
  3. +46 −0 musik/db.py
View
@@ -1,69 +1,38 @@
+from musik.db import DB
+
from multiprocessing import Process
-import os, os.path
import re
import time
from threading import Lock
-
+
import cherrypy
from cherrypy.process import wspbus, plugins
from mako.template import Template
from mako.lookup import TemplateLookup
-from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy import Column
-from sqlalchemy.types import String, Integer
-
-# Helper to map and register a Python class a db table
-Base = declarative_base()
# Template looker-upper that handles loading and caching of mako templates
templates = TemplateLookup(directories=['templates'], module_directory='templates/compiled')
-# Represents a media file on the local hard drive
-class Media(Base):
- __tablename__ = 'media'
- id = Column(Integer, primary_key=True)
- path = Column(String)
-
- def __init__(self, path):
- Base.__init__(self)
- self.path = path
-
- def __str__(self):
- return self.path.encode('utf-8')
-
- def __unicode__(self):
- return self.path
-
- @staticmethod
- def list(session):
- return session.query(Media).all()
-
-
-#TODO: create an object to represent tags for media objects
-
-
# A plugin to help SQLAlchemy bind correctly to CherryPy threads
# See http://www.defuze.org/archives/222-integrating-sqlalchemy-into-a-cherrypy-application.html
class SAEnginePlugin(plugins.SimplePlugin):
def __init__(self, bus):
plugins.SimplePlugin.__init__(self, bus)
self.sa_engine = None
self.bus.subscribe("bind", self.bind)
-
+
def start(self):
- db_path = os.path.abspath(os.path.join(os.curdir, 'musik.db'))
- self.sa_engine = create_engine('sqlite:///%s' % db_path, echo=True)
- Base.metadata.create_all(self.sa_engine)
-
+ self.db = DB()
+ self.sa_engine = self.db.getEngine()
+
def stop(self):
if self.sa_engine:
self.sa_engine.dispose()
self.sa_engine = None
-
+
def bind(self, session):
session.configure(bind=self.sa_engine)
@@ -73,21 +42,21 @@ class SATool(cherrypy.Tool):
def __init__(self):
cherrypy.Tool.__init__(self, 'on_start_resource', self.bind_session, priority=20)
self.session = scoped_session(sessionmaker(autoflush=True, autocommit=False))
-
+
def _setup(self):
cherrypy.Tool._setup(self)
cherrypy.request.hooks.attach('on_end_resource', self.commit_transaction, priority=80)
-
+
def bind_session(self):
cherrypy.engine.publish('bind', self.session)
cherrypy.request.db = self.session
-
+
def commit_transaction(self):
cherrypy.request.db = None
try:
self.session.commit()
except:
- self.session.rollback()
+ self.session.rollback()
raise
finally:
self.session.remove()
@@ -106,7 +75,7 @@ class Import:
@cherrypy.expose
def directory(self, path):
-
+
#TODO: enumerate the directory at path into a list of files
#TODO: for each file - if file mime type is valid, add it to database import table
#TODO: ensure that importmedia_process thread is started - it will process the import table
View
No changes.
View
@@ -0,0 +1,46 @@
+from sqlalchemy import create_engine
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy import Column
+from sqlalchemy.types import String, Integer
+
+import os, os.path
+
+# Loosely wraps the SQLAlchemy database types and access methods.
+# The goal here isn't to encapsulate SQLAlchemy. Rather, we want to
+# dictate the process of connecting to and disconnecting from the db,
+# as well as the data types that the application uses once connected.
+class DB:
+ # Helper to map and register a Python class a db table
+ Base = declarative_base()
+
+ # Represents a media file on the local hard drive
+ class Media(Base):
+ __tablename__ = 'media'
+ id = Column(Integer, primary_key=True)
+ path = Column(String)
+
+ def __init__(self, path):
+ Base.__init__(self)
+ self.path = path
+
+ def __str__(self):
+ return self.path.encode('utf-8')
+
+ def __unicode__(self):
+ return self.path
+
+ @staticmethod
+ def list(session):
+ return session.query(Media).all()
+
+
+ # constructs the database path, creates a database engine
+ # and initializes the database if necessary.
+ def __init__(self):
+ db_path = os.path.abspath(os.path.join(os.curdir, 'musik.db'))
+ self.sa_engine = create_engine('sqlite:///%s' % db_path, echo=True)
+ self.Base.metadata.create_all(self.sa_engine)
+
+ # returns an initialized instance of sqlalchemy.engine.base.Engine
+ def getEngine(self):
+ return self.sa_engine

0 comments on commit 293e33a

Please sign in to comment.