aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPriit Laes <plaes@plaes.org>2010-07-07 13:40:07 +0300
committerPriit Laes <plaes@plaes.org>2010-07-07 15:28:29 +0300
commit1cede66b7ffb6a76705b126899e1a2f9da0b9711 (patch)
treed0fdb2a4804cbbbdf7e823f3fe72d6c022bc60f1
parentAdded GSoC report #3 (diff)
downloadgsoc2010-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__.py4
-rw-r--r--grumpy/database.py29
-rw-r--r--grumpy/grumpy.cfg4
-rw-r--r--grumpy/models.py91
-rw-r--r--grumpy/webapp.py18
-rwxr-xr-xutils/grumpy_sync.py32
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])