diff options
author | Priit Laes <plaes@plaes.org> | 2010-07-07 13:40:07 +0300 |
---|---|---|
committer | Priit Laes <plaes@plaes.org> | 2010-07-07 15:28:29 +0300 |
commit | 1cede66b7ffb6a76705b126899e1a2f9da0b9711 (patch) | |
tree | d0fdb2a4804cbbbdf7e823f3fe72d6c022bc60f1 | |
parent | Added GSoC report #3 (diff) | |
download | gsoc2010-grumpy-1cede66b7ffb6a76705b126899e1a2f9da0b9711.tar.gz gsoc2010-grumpy-1cede66b7ffb6a76705b126899e1a2f9da0b9711.tar.bz2 gsoc2010-grumpy-1cede66b7ffb6a76705b126899e1a2f9da0b9711.zip |
Added Flask-based web app with Flask-SQLAlchemy dependency
-rw-r--r-- | grumpy/__init__.py | 4 | ||||
-rw-r--r-- | grumpy/database.py | 29 | ||||
-rw-r--r-- | grumpy/grumpy.cfg | 4 | ||||
-rw-r--r-- | grumpy/models.py | 91 | ||||
-rw-r--r-- | grumpy/webapp.py | 18 | ||||
-rwxr-xr-x | utils/grumpy_sync.py | 32 |
6 files changed, 87 insertions, 91 deletions
diff --git a/grumpy/__init__.py b/grumpy/__init__.py index e69de29..72e6636 100644 --- a/grumpy/__init__.py +++ b/grumpy/__init__.py @@ -0,0 +1,4 @@ +from flask import Flask + +app = Flask(__name__) +app.config.from_pyfile('grumpy.cfg') diff --git a/grumpy/database.py b/grumpy/database.py deleted file mode 100644 index bbc5802..0000000 --- a/grumpy/database.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -""" - grumpy.database - ~~~~~~~~~~~~~~~ - - This module contains high-level database glue for the application. - - :copyright: (c) by 2010 Priit Laes. - :license: BSD, see LICENSE for details. -""" -from grumpy.models import Base - -from sqlalchemy import create_engine -from sqlalchemy.orm import scoped_session, sessionmaker - -# FIXME: Hardcoded ;) -engine = create_engine('postgresql://grumpy:grumpy@localhost/grumpy') -session = scoped_session(sessionmaker(autocommit=False, - autoflush=False, - bind=engine)) -Base.query = session.query_property() - -def init_db(): - """Initialize database schema""" - Base.metadata.create_all(bind=engine) - -def drop_db(): - """Drop all database data and schema""" - Base.metadata.drop_all(bind=engine) diff --git a/grumpy/grumpy.cfg b/grumpy/grumpy.cfg new file mode 100644 index 0000000..c3c7233 --- /dev/null +++ b/grumpy/grumpy.cfg @@ -0,0 +1,4 @@ +DEBUG = True +SQLALCHEMY_ECHO=False +SQLALCHEMY_DATABASE_URI='postgresql://grumpy:grumpy@localhost/grumpy' +SECRET_KEY='Change me' diff --git a/grumpy/models.py b/grumpy/models.py index f22b42b..7916a23 100644 --- a/grumpy/models.py +++ b/grumpy/models.py @@ -9,33 +9,30 @@ :copyright: (c) by 2010 Priit Laes. :license: BSD, see LICENSE for details. """ +from . import app from datetime import datetime - -from sqlalchemy import (Column, DateTime, ForeignKey, Integer, String, \ - Table, Text) -from sqlalchemy.orm import relationship -from sqlalchemy.ext.declarative import declarative_base +from flaskext.sqlalchemy import SQLAlchemy import json -Base = declarative_base() +db = SQLAlchemy(app) # Association tables -package_developers = Table('package_developers', Base.metadata, - Column('package_id', Integer, ForeignKey('packages.id')), - Column('developer_id', Integer, ForeignKey('developers.id')) +package_developers = db.Table('package_developers', db.Model.metadata, + db.Column('package_id', db.Integer, db.ForeignKey('packages.id')), + db.Column('developer_id', db.Integer, db.ForeignKey('developers.id')) ) -package_herds = Table('package_herds', Base.metadata, - Column('package_id', Integer, ForeignKey('packages.id')), - Column('herd_id', Integer, ForeignKey('herds.id')) +package_herds = db.Table('package_herds', db.Model.metadata, + db.Column('package_id', db.Integer, db.ForeignKey('packages.id')), + db.Column('herd_id', db.Integer, db.ForeignKey('herds.id')) ) -class Category(Base): +class Category(db.Model): """Represents portage categories""" __tablename__ = 'categories' - id = Column('id', Integer, primary_key=True) - cat = Column('category', String, nullable=False, unique=True) + id = db.Column('id', db.Integer, primary_key=True) + cat = db.Column('category', db.String, nullable=False, unique=True) def __init__(self, cat): self.cat = cat @@ -43,36 +40,36 @@ class Category(Base): def __repr__(self): return '<%s> "%s"' % (self.__class__.__name__, self.cat) -class Developer(Base): +class Developer(db.Model): """Represents developers in the system""" __tablename__ = 'developers' - id = Column('id', Integer, primary_key=True) - email = Column('email', String, nullable=False, unique=True) + id = db.Column('id', db.Integer, primary_key=True) + email = db.Column('email', db.String, nullable=False, unique=True) def __init__(self, email): self.email = email -class Ebuild(Base): +class Ebuild(db.Model): """Represents single ebuilds (cpv) in the system""" __tablename__ = 'ebuilds' - id = Column('id', Integer, primary_key=True) - cpv = Column('cpv', String, nullable=False, unique=True) - eapi = Column('eapi', Integer, nullable=False) + id = db.Column('id', db.Integer, primary_key=True) + cpv = db.Column('cpv', db.String, nullable=False, unique=True) + eapi = db.Column('eapi', db.Integer, nullable=False) # Regular USE flags - iuse = Column('iuse', String) + iuse = db.Column('iuse', db.String) # Forced USE flags (+use) - fiuse = Column('fiuse', String) - keywords = Column('keywords', String) - slot = Column('slot', String) - version = Column('version', String, nullable=False) - _package = Column('package_id', Integer, ForeignKey('packages.id')) + fiuse = db.Column('fiuse', db.String) + keywords = db.Column('keywords', db.String) + slot = db.Column('slot', db.String) + version = db.Column('version', db.String, nullable=False) + _package = db.Column('package_id', db.Integer, db.ForeignKey('packages.id')) # TODO: depend, rdepend, licenses # TODO: extra info? - package = relationship("Package") + package = db.relationship("Package") def __init__(self, package, version, eapi, slot, keywords, \ iuse, fiuse): @@ -88,13 +85,13 @@ class Ebuild(Base): def __repr__(self): return '<%s> - %s' % (self.__class__.__name__, self.cpv) -class Setting(Base): +class Setting(db.Model): """Housekeeping table for storing various system settings and info.""" __tablename__ = 'settings' - name = Column('name', String, primary_key=True, unique=True) - rawdata = Column('data', Text) + name = db.Column('name', db.String, primary_key=True, unique=True) + rawdata = db.Column('data', db.Text) def __init__(self, name, data): self.name = name @@ -108,37 +105,37 @@ class Setting(Base): return '<%s> - %s' % (self.__class__.__name__, self.name) -class Herd(Base): +class Herd(db.Model): """Represents herds in the system""" __tablename__ = 'herds' - id = Column('id', Integer, primary_key=True) - name = Column('name', String, nullable=False, unique=True) + id = db.Column('id', db.Integer, primary_key=True) + name = db.Column('name', db.String, nullable=False, unique=True) # TODO: Do we really need to store other information about herds here? def __init__(self, name): self.name = name -class Package(Base): +class Package(db.Model): """Represents packages in the system""" __tablename__ = 'packages' - id = Column('id', Integer, primary_key=True) - cat = Column('cat', String, nullable=False) - pkg = Column('pkg', String, nullable=False) - cp = Column('cp', String, nullable=False, unique=True) - desc = Column('desc', String) - ldesc = Column('ldesc', String) - homepage = Column('homepage', String) - mtime = Column('mtime', DateTime) + id = db.Column('id', db.Integer, primary_key=True) + cat = db.Column('cat', db.String, nullable=False) + pkg = db.Column('pkg', db.String, nullable=False) + cp = db.Column('cp', db.String, nullable=False, unique=True) + desc = db.Column('desc', db.String) + ldesc = db.Column('ldesc', db.String) + homepage = db.Column('homepage', db.String) + mtime = db.Column('mtime', db.DateTime) - ebuilds = relationship(Ebuild, backref='ebuilds', \ + ebuilds = db.relationship(Ebuild, backref='ebuilds', \ cascade='all, delete-orphan') - devs = relationship(Developer, secondary=package_developers, \ + devs = db.relationship(Developer, secondary=package_developers, \ backref='packages') - herds = relationship(Herd, secondary=package_herds, backref='packages') + herds = db.relationship(Herd, secondary=package_herds, backref='packages') def __init__(self, cat, pkg, desc, ldesc, homepage, mtime): self.cat = cat diff --git a/grumpy/webapp.py b/grumpy/webapp.py new file mode 100644 index 0000000..b8b065f --- /dev/null +++ b/grumpy/webapp.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +""" + grumpy.webapp + ~~~~~~~~~~~~~ + + This module contains web application data. + + :copyright: (c) by 2010 Priit Laes. + :license: BSD, see LICENSE for details. +""" +from . import app +from .models import db, Category + +from flask import render_template + +@app.route('/') +def show_categories(): + return render_template('category_index.html', cats=Category.query.all()) diff --git a/utils/grumpy_sync.py b/utils/grumpy_sync.py index 9b1e745..58f0083 100755 --- a/utils/grumpy_sync.py +++ b/utils/grumpy_sync.py @@ -16,8 +16,8 @@ path = os.path.join(os.path.dirname(__file__), os.path.pardir) sys.path.insert(0, path) del path -from grumpy.database import session -from grumpy.models import (Category, Developer, Ebuild, Herd, \ +from grumpy import app +from grumpy.models import (db, Category, Developer, Ebuild, Herd, \ Package, Setting) UPDATE_DB_KEY = 'updates_info' @@ -88,8 +88,8 @@ def main(path): # Parse (again) latest moves file and store its info in database if prev_updates: - session.delete(prev_updates) - session.flush() + db.session.delete(prev_updates) + db.session.flush() moves = {} for line in iter_read_bash(update_path): line = line.split() @@ -97,8 +97,8 @@ def main(path): moves[line[1]] = line[2] data = dict(file=update_file, moves=moves, \ mtime=int(os.stat(update_path).st_mtime)) - session.add(Setting(UPDATE_DB_KEY, data)) - session.commit() + db.session.add(Setting(UPDATE_DB_KEY, data)) + db.session.commit() def package_sync(cat, pkg, files, mtime): """Update package information in database.""" @@ -119,7 +119,7 @@ def main(path): if not package: package = Package(pack.category, pack.package, pack.description, \ pack.longdescription, pack.homepage, mtime) - session.add(package) + db.session.add(package) else: # Update package fields package.cat = pack.category @@ -171,7 +171,7 @@ def main(path): if not ebuild: print "DEBUG: Corruption detected: ebuild not found in database" raise RuntimeError - session.delete(ebuild) + db.session.delete(ebuild) # Updates/add new ebuilds for ver in new: @@ -210,7 +210,7 @@ def main(path): oeb.slot = ebuild.slot oeb.keywords = list(ebuild.keywords) - session.commit() + db.session.commit() # Compare list of categories in portage vs database old = [c.cat for c in Category.query.all()] @@ -222,12 +222,12 @@ def main(path): if Package.query.filter_by(cat=cat).count() > 0: # We shouldn't have anything with this category in db raise RuntimeError - session.delete(c) + db.session.delete(c) # Add new categories for cat in cats: if cat not in old: - session.add(Category(cat)) - session.commit() + db.session.add(Category(cat)) + db.session.commit() # Traverse portage for cat in cats: @@ -242,8 +242,8 @@ def main(path): # Handle package deletion print "DEBUG: package has been removed:", pkg package = Package.query.filter_by(cat=cat).filter_by(pkg=pkg).one() - session.delete(package) - session.commit() + db.session.delete(package) + db.session.commit() for pkg in new: dir = os.path.join(catdir, pkg) files = [f for f in os.listdir(dir) if fnmatch(f, '*.ebuild')] @@ -255,4 +255,6 @@ if __name__ == '__main__': if len(args) != 1: parser.error("please provide path to portagedir as first argument") sys.exit(1) - main(args[0]) + # Setup database for application + with app.test_request_context(): + main(args[0]) |