diff options
author | Luke Macken <lmacken@redhat.com> | 2011-04-12 12:20:04 -0400 |
---|---|---|
committer | Luke Macken <lmacken@redhat.com> | 2011-04-12 12:20:04 -0400 |
commit | c83e57b8e9faf717b1372da987f5c2327f42dbe8 (patch) | |
tree | 42cff2943b9d2e21d60d8ebaaa86d34a9bfe2c08 /leafymiracle | |
download | leafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.tar.gz leafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.tar.xz leafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.zip |
Initial commit of LeafyMiracle
Diffstat (limited to 'leafymiracle')
-rw-r--r-- | leafymiracle/__init__.py | 40 | ||||
-rw-r--r-- | leafymiracle/models.py | 122 | ||||
-rw-r--r-- | leafymiracle/populate.py | 78 | ||||
-rw-r--r-- | leafymiracle/resources.py | 59 | ||||
-rw-r--r-- | leafymiracle/templates/model.pt | 9 | ||||
-rw-r--r-- | leafymiracle/views.py | 24 | ||||
-rw-r--r-- | leafymiracle/widgets.py | 38 |
7 files changed, 370 insertions, 0 deletions
diff --git a/leafymiracle/__init__.py b/leafymiracle/__init__.py new file mode 100644 index 0000000..46e19d9 --- /dev/null +++ b/leafymiracle/__init__.py @@ -0,0 +1,40 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from pyramid.config import Configurator +from sqlalchemy import engine_from_config + +from leafymiracle.resources import appmaker +from leafymiracle.widgets import LeafyGraph + +def main(global_config, **settings): + """ This function returns a WSGI application. + """ + print settings + engine = engine_from_config(settings, 'sqlalchemy.') + get_root = appmaker(engine) + config = Configurator(settings=settings, root_factory=get_root) + config.add_view('leafymiracle.views.view_root', + context='leafymiracle.resources.MyApp', + renderer="templates/root.pt") + config.add_view('leafymiracle.views.view_model', + context='leafymiracle.models.Root', + renderer="templates/model.pt") + + # Create the data view for our tw2.jit.SQLARadialGraph + jit_view = lambda context, request: LeafyGraph.request(request) + config.add_route('data', '/data', view=jit_view, xhr=True) + + return config.make_wsgi_app() diff --git a/leafymiracle/models.py b/leafymiracle/models.py new file mode 100644 index 0000000..0e86aa1 --- /dev/null +++ b/leafymiracle/models.py @@ -0,0 +1,122 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from sqlalchemy import Integer, Column, Unicode, UnicodeText, ForeignKey +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import relationship, scoped_session, sessionmaker + +from kitchen.text.converters import to_unicode + +DBSession = scoped_session(sessionmaker()) +Base = declarative_base() +Base.query = DBSession.query_property() + +# Icon Hack. Throw these in a config file. +icons = ['admin-tools', 'apps', 'authoring-and-publishing', 'base-system', 'base-x', 'clustering', 'content', 'core', 'desktops', 'development', 'development-tools', 'dial-up', 'directory-server', 'eclipse', 'editors', 'education', 'electronic-lab', 'engineering-and-scientific', 'font-design', 'fonts', 'games', 'gnome-desktop', 'gnome-software-development', 'graphical-internet', 'graphics', 'hardware-support', 'haskell', 'input-methods', 'java-development', 'java', 'kde-desktop', 'kde-software-development', 'language-support', 'legacy-fonts', 'legacy-network-server', 'lxde-desktop', 'mail-server', 'mysql', 'office', 'printing', 'ruby', 'server-cfg', 'servers', 'sound-and-video', 'sql-server', 'sugar-desktop', 'system-tools', 'text-internet', 'uncategorized', 'virtualization', 'window-managers', 'xfce-desktop', 'xfce-software-development', 'x-software-development'] +icon_link = '<img src="http://lmacken.fedorapeople.org/comps-extras/%s.png"/ style="vertical-align:middle;"> %s' + + +class Root(Base): + __tablename__ = 'root' + + id = Column(Integer, primary_key=True) + name = Column(Unicode(255), unique=True) + + categories = relationship("Category", backref="root") + + def __init__(self, name): + self.name = to_unicode(name) + + def __unicode__(self): + return icon_link % (self.name.lower(), self.name) + + +class Category(Base): + __tablename__ = 'categories' + + id = Column(Integer, primary_key=True) + category_id = Column(Unicode(255), unique=True) + name = Column(Unicode(255), unique=True) + description = Column(UnicodeText) + root_id = Column(Integer, ForeignKey('root.id')) + + groups = relationship("Group", backref="category") + + def __init__(self, id, name, description): + self.category_id = to_unicode(id) + self.name = to_unicode(name) + self.description = to_unicode(description) + + def __unicode__(self): + if self.category_id in icons: + return icon_link % (self.category_id, self.name) + return self.name + + +class Group(Base): + __tablename__ = 'groups' + + id = Column(Integer, primary_key=True) + group_id = Column(Unicode(255), unique=True) + name = Column(Unicode(255), unique=True) + description = Column(UnicodeText) + category_id = Column(Integer, ForeignKey('categories.id')) + + packages = relationship("Package", backref="group") + + def __init__(self, id, name, description): + self.group_id = to_unicode(id) + self.name = to_unicode(name) + self.description = to_unicode(description) + + def __unicode__(self): + if self.group_id in icons: + return icon_link % (self.group_id, self.name) + return self.name + + +class Package(Base): + __tablename__ = 'packages' + + id = Column(Integer, primary_key=True) + name = Column(Unicode(255), unique=True) + + group_id = Column(Integer, ForeignKey('groups.id')) + + def __init__(self, name): + self.name = to_unicode(name) + + def __unicode__(self): + return self.name + + def __jit_data__(self): + return { + 'hover_html' : """ + <h2>{name}</h2> + <li><img src="https://admin.fedoraproject.org/community/images/16_pkgdb.png"/><a href="https://admin.fedoraproject.org/community/?package={name}#package_maintenance/details/downloads" target="_blank">Downloads</a></li> + <li><img src="https://admin.fedoraproject.org/community/images/16_koji.png"/><a href="http://koji.fedoraproject.org/koji/search?terms={name}&type=package&match=exact" target="_blank">Builds</a></li> + <li><img src="https://admin.fedoraproject.org/community/images/16_bodhi.png"/><a href="https://admin.fedoraproject.org/updates/{name}" target="_blank">Updates</a></li> + <li><img src="https://admin.fedoraproject.org/community/images/16_bugs.png"/><a href="https://admin.fedoraproject.org/pkgdb/acls/bugs/{name}" target="_blank">Bugs</a></li> + <li><img src="https://admin.fedoraproject.org/community/images/16_sources.png"/><a href="http://pkgs.fedoraproject.org/gitweb/?p={name}.git" target="_blank">Source</a></li> + <li><img src="https://admin.fedoraproject.org/community/images/16_pkgdb.png"/><a href="https://admin.fedoraproject.org/pkgdb/acls/name/{name}" target="_blank">Package Info</a></li> + </ul> + """.format(**self.__dict__) + } + + +def initialize_sql(engine): + DBSession.configure(bind=engine) + Base.metadata.bind = engine + Base.metadata.create_all(engine) diff --git a/leafymiracle/populate.py b/leafymiracle/populate.py new file mode 100644 index 0000000..9f78fc5 --- /dev/null +++ b/leafymiracle/populate.py @@ -0,0 +1,78 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from sqlalchemy import create_engine +from sqlalchemy.exc import IntegrityError +from kitchen.text.converters import to_unicode + +from models import Root, Category, Group, Package, DBSession, initialize_sql + +def populate(comps='comps-f16'): + from yum.comps import Comps + + session = DBSession() + + c = Comps() + c.add('comps/%s.xml' % comps) + + for group in c.groups: + g = Group(id=group.groupid, name=group.name, description=group.description) + session.add(g) + + for package in group.packages: + p = session.query(Package).filter_by(name=to_unicode(package)).first() + if not p: + p = Package(name=package) + session.add(p) + p.group = g + + session.flush() + + root = Root(name=u'Fedora') + session.add(root) + session.flush() + + for category in c.categories: + c = Category(id=category.categoryid, name=category.name, + description=category.description) + session.add(c) + root.categories.append(c) + for group in category.groups: + g = session.query(Group).filter_by(group_id=to_unicode(group)).first() + if not g: + print "Cannot find group: %s" % group + else: + g.category = c + + session.flush() + + session.commit() + +def build_comps(): + import subprocess + subprocess.call('git clone git://git.fedorahosted.org/comps.git', shell=True) + subprocess.call('make comps-f16.xml', cwd='comps', shell=True) + + +if __name__ == '__main__': + print "Initializing LeafyMiracle..." + engine = create_engine('sqlite:///leafymiracle.db') + initialize_sql(engine) + build_comps() + try: + populate() + print "Complete!" + except IntegrityError, e: + DBSession.rollback() diff --git a/leafymiracle/resources.py b/leafymiracle/resources.py new file mode 100644 index 0000000..8185f9f --- /dev/null +++ b/leafymiracle/resources.py @@ -0,0 +1,59 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from sqlalchemy.orm.exc import NoResultFound +from models import DBSession, Root, initialize_sql + +class MyApp(object): + __name__ = None + __parent__ = None + + def __getitem__(self, key): + session = DBSession() + try: + id = int(key) + except (ValueError, TypeError): + raise KeyError(key) + + query = session.query(Root).filter_by(id=id) + + try: + item = query.one() + item.__parent__ = self + item.__name__ = key + return item + except NoResultFound: + raise KeyError(key) + + def get(self, key, default=None): + try: + item = self.__getitem__(key) + except KeyError: + item = default + return item + + def __iter__(self): + session= DBSession() + query = session.query(Root) + return iter(query) + +root = MyApp() + +def default_get_root(request): + return root + +def appmaker(engine): + initialize_sql(engine) + return default_get_root diff --git a/leafymiracle/templates/model.pt b/leafymiracle/templates/model.pt new file mode 100644 index 0000000..cb452a4 --- /dev/null +++ b/leafymiracle/templates/model.pt @@ -0,0 +1,9 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal"> +<head> + <title>Fedora Comps Visualization, by Luke Macken</title> +</head> +<body bgcolor="#444444"> + <div tal:content="structure jitwidget.display()"></div> +</body> +</html> diff --git a/leafymiracle/views.py b/leafymiracle/views.py new file mode 100644 index 0000000..f1df955 --- /dev/null +++ b/leafymiracle/views.py @@ -0,0 +1,24 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from pyramid.httpexceptions import HTTPFound +from widgets import LeafyGraph + +def view_root(context, request): + return HTTPFound(location='/1') + +def view_model(context, request): + return {'item':context, 'project':'leafymiracle', + 'jitwidget': LeafyGraph(rootObject=context)} diff --git a/leafymiracle/widgets.py b/leafymiracle/widgets.py new file mode 100644 index 0000000..cf17342 --- /dev/null +++ b/leafymiracle/widgets.py @@ -0,0 +1,38 @@ +# Copyright (C) 2011 Luke Macken <lmacken@redhat.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from tw2.jit import SQLARadialGraph +from tw2.core.resources import JSSymbol + +from leafymiracle import models + +class LeafyGraph(SQLARadialGraph): + id = 'leafy_graph' + entities = [models.Root, models.Category, models.Group, models.Package] + base_url = '/data' + width = '1000' + height = '650' + depth = 2 + levelDistance = 150 + backgroundcolor = '#444444' + alphabetize_relations = 24 + alphabetize_minimal = True + show_attributes = False + imply_relations = True + auto_labels = False + excluded_columns = ['group'] + deep_linking = True + #transition = JSSymbol(src='$jit.Trans.Back.easeInOut') + duration = 200 |