summaryrefslogtreecommitdiffstats
path: root/leafymiracle
diff options
context:
space:
mode:
authorLuke Macken <lmacken@redhat.com>2011-04-12 12:20:04 -0400
committerLuke Macken <lmacken@redhat.com>2011-04-12 12:20:04 -0400
commitc83e57b8e9faf717b1372da987f5c2327f42dbe8 (patch)
tree42cff2943b9d2e21d60d8ebaaa86d34a9bfe2c08 /leafymiracle
downloadleafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.tar.gz
leafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.tar.xz
leafymiracle-c83e57b8e9faf717b1372da987f5c2327f42dbe8.zip
Initial commit of LeafyMiracle
Diffstat (limited to 'leafymiracle')
-rw-r--r--leafymiracle/__init__.py40
-rw-r--r--leafymiracle/models.py122
-rw-r--r--leafymiracle/populate.py78
-rw-r--r--leafymiracle/resources.py59
-rw-r--r--leafymiracle/templates/model.pt9
-rw-r--r--leafymiracle/views.py24
-rw-r--r--leafymiracle/widgets.py38
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