Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactoring part 2. New views, templates, classmethods in models etc.…

… New beta release is very close.
  • Loading branch information...
commit 2ef613aa67da3a04708d775340fb9f707159966f 1 parent b803957
Jukka Ojaniemi authored
View
43 whiskers/__init__.py
@@ -2,6 +2,9 @@
from sqlalchemy import engine_from_config
from whiskers.models import initialize_sql
+from whiskers.views.buildouts import BuildoutsView
+from whiskers.views.hosts import HostsView
+from whiskers.views.packages import PackagesView
def main(global_config, **settings):
@@ -12,34 +15,36 @@ def main(global_config, **settings):
config = Configurator(settings=settings)
config.add_static_view('static', 'whiskers:static', cache_max_age=3600)
- config.add_route('home', '/')
+ config.add_route('home', '/', request_method='GET')
+ config.add_route('post_buildout', '/',
+ request_method='POST')
config.add_view('whiskers.views.main.whiskers_view',
route_name='home',
renderer='views/templates/main.pt')
- config.add_route('buildouts', '/buildouts')
- # config.add_view('whiskers.views.buildout.buildouts_view',
- # route_name='buildouts',
- # renderer='views/templates/buildouts.pt')
+ config.add_route('buildouts', '/buildouts', request_method="GET")
+ config.add_view(BuildoutsView, route_name='buildouts',
+ renderer='views/templates/buildouts.pt')
- config.add_route('add_buildout', '/buildouts/add')
- # config.add_view('whiskers.views.buildout.add_buildout_view',
- # route_name='add')
+ # BBB
+ config.add_route('add_buildout', '/buildouts/add',
+ request_method='POST')
+ config.add_view(BuildoutsView, route_name='post_buildout', attr="post")
+ # BBB
+ config.add_view(BuildoutsView, route_name='add_buildout', attr="post")
config.add_route('buildout_view', '/buildouts/{buildout_id}')
- # config.add_view('whiskers.views.buildout.buildout_view',
- # route_name='buildout_view',
- # renderer='views/templates/buildout.pt')
+ config.add_view(BuildoutsView, route_name='buildout_view',
+ renderer='views/templates/buildout.pt',
+ attr="buildout_view")
config.add_route('packages', '/packages')
- config.add_view('whiskers.views.packages.packages_view',
- route_name='packages',
+ config.add_view(PackagesView, route_name='packages',
renderer='views/templates/packages.pt')
config.add_route('package_view', '/packages/{package_name}*id')
- config.add_view('whiskers.views.package.package_view',
- route_name='package_view',
- renderer='views/templates/package.pt')
+ config.add_view(PackagesView, route_name='package_view',
+ attr='package_view', renderer='views/templates/package.pt')
config.add_route('about', '/about')
config.add_view('whiskers.views.about.about_view',
@@ -47,11 +52,11 @@ def main(global_config, **settings):
renderer='views/templates/about.pt')
config.add_route('hosts', '/hosts')
+ config.add_view(HostsView, route_name='hosts',
+ renderer='views/templates/hosts.pt')
config.add_route('host', '/hosts/{host_id}')
- config.add_view('whiskers.views.host.host_view',
- route_name='host',
+ config.add_view(HostsView, route_name='host', attr="host_view",
renderer='views/templates/host.pt')
- config.scan()
return config.make_wsgi_app()
View
65 whiskers/jsonwrapper.py
@@ -0,0 +1,65 @@
+import json
+
+
+class JsonDataWrapper(object):
+ """Wrapper for json-data."""
+
+ def __init__(self, data):
+ self.data = json.loads(data)
+
+ @property
+ def hostname(self):
+ return self.data.get('hostname', None)
+
+ @property
+ def name(self):
+ return self.data.get('buildoutname', None) or\
+ self.path.rsplit('/', 1)[-1]
+
+ @property
+ def path(self):
+ return self.data.get('directory', None)
+
+ @property
+ def packages(self):
+ for package in self.data['packages'].keys():
+ package_dict = {
+ 'name': package,
+ 'requirements': self.data['packages'][package]['requirements'],
+ 'version': self.get_package_version(package)}
+ yield package_dict
+
+ @property
+ def executable(self):
+ return self.data.get('executable', None)
+
+ @property
+ def allow_picked_versions(self):
+ return self.data.get('allow_picked_versions', None)
+
+ @property
+ def newest(self):
+ return self.data.get('newest', None)
+
+ @property
+ def versionmap(self):
+ return self.data.get('versionmap', None)
+
+ @property
+ def config(self):
+ tmp = self.data.copy()
+ tmp.pop('packages')
+ tmp.pop('versionmap')
+ return json.dumps(tmp)
+
+ def get_package_version(self, package):
+ """Return package version."""
+
+ if not self.data['packages'][package]['version']:
+ try:
+ version = self.versionmap[package['name']]
+ except KeyError:
+ version = 'stdlib'
+ else:
+ version = self.data['packages'][package]['version']
+ return version
View
118 whiskers/models.py
@@ -1,12 +1,16 @@
+from datetime import datetime
+
from sqlalchemy import (
Column,
Text,
Integer,
+ DateTime,
Unicode,
ForeignKey,
Table)
from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import (
scoped_session,
@@ -30,11 +34,6 @@
Column('package_id', Integer, ForeignKey('package.id'))
)
-# packageversion_table = Table('packageversion_table', Base.metadata,
-# Column('package_id', Integer, ForeignKey('package.id')),
-# Column('version_id', Integer, ForeignKey('version.id'))
-# )
-
packagerequires_table = Table(
'packagerequires_table',
Base.metadata,
@@ -50,19 +49,41 @@ class Buildout(Base):
id = Column(Integer, primary_key=True)
name = Column(Unicode(255))
+ datetime = Column(DateTime)
+ checksum = Column(Integer, unique=True)
host_id = Column(Integer, ForeignKey('host.id'))
- host = relationship("Host", backref=backref('buildouts', order_by=id))
+ host = relationship("Host",
+ backref=backref('buildouts',
+ order_by=datetime.desc()))
packages = relationship("Package", secondary=buildoutpackage_table,
- backref=backref('buildouts', order_by=id))
+ backref=backref('buildouts', order_by=name))
config = Column(Text)
- def __init__(self, name, host, packages=None, config=None):
+ def __init__(self, name, host, checksum, packages=None, config=None):
self.name = name
self.host = host
if packages:
self.packages = packages
if config:
self.config = config
+ self.datetime = datetime.now()
+ self.checksum = checksum
+
+ @classmethod
+ def get_by_checksum(klass, checksum):
+ query = DBSession.query(klass).\
+ filter(klass.checksum == checksum).first()
+ return query
+
+ @classmethod
+ def by_name(klass):
+ query = DBSession.query(klass).order_by(klass.name)
+ return query
+
+ @classmethod
+ def by_host(klass):
+ query = DBSession.query(klass).order_by(klass.host)
+ return query
@implementer(interfaces.IHost)
@@ -76,6 +97,33 @@ class Host(Base):
def __init__(self, name):
self.name = name
+ @classmethod
+ def all_by_name(klass):
+ query = DBSession.query(klass).order_by(klass.name)
+ return query
+
+ @classmethod
+ def get_by_name(klass, name):
+ host = DBSession.query(klass).\
+ join(klass.buildouts).\
+ filter(klass.name == name).\
+ order_by(klass.name).first()
+ return host
+
+ @classmethod
+ def get_by_id(klass, id):
+ host = DBSession.query(klass).\
+ join(klass.buildouts).\
+ filter(klass.id == id).\
+ order_by(klass.name)
+ return host.one()
+
+ @classmethod
+ def add(klass, hostname):
+ host = klass(hostname)
+ DBSession.add(host)
+ return host
+
@implementer(interfaces.IPackage)
class Package(Base):
@@ -95,7 +143,8 @@ class Package(Base):
secondary=packagerequires_table,
primaryjoin=id == packagerequires_table.c.package_id,
secondaryjoin=id == packagerequires_table.c.required_package_id,
- backref="required_by")
+ backref="required_by",
+ order_by=name)
def __init__(self, name, version=None, requires=None):
self.name = name
@@ -109,6 +158,45 @@ def __init__(self, name, version=None, requires=None):
# We don't know what requires is so we just ignore it
pass
+ @classmethod
+ def get_packages_by_name(klass, name):
+ """Return package filtered by name."""
+ try:
+ query = DBSession.query(klass).join(Version).\
+ filter(klass.name == name).\
+ order_by(Version.version.desc())
+ return query
+ except NoResultFound:
+ return None
+
+ @classmethod
+ def by_name(klass):
+ """Return packages grouped and ordered by name."""
+ query = DBSession.query(klass).group_by(klass.name).\
+ order_by(klass.name)
+ return query
+
+ @classmethod
+ def get_by_nameversion(klass, name, version=None):
+ query = DBSession.query(klass).join(klass.version).\
+ filter(klass.name == name)
+ if version:
+ query = query.filter(Version.version == version)
+ return query.first()
+
+ @classmethod
+ def get_by_id(klass, id):
+ package = DBSession.query(klass).filter_by(id)
+
+ if package.count():
+ return package.first().id
+
+ @classmethod
+ def add(klass, name, version=None, requires=None):
+ package = klass(name, version=version, requires=requires)
+ DBSession.add(package)
+ return package
+
@implementer(interfaces.IVersion)
class Version(Base):
@@ -125,6 +213,18 @@ def __init__(self, version, equation=None):
if equation:
self.equation = equation
+ @classmethod
+ def get_by_version(klass, version):
+ version = DBSession.query(klass).\
+ filter(klass.version == version).first()
+ return version
+
+ @classmethod
+ def add(klass, version, equation):
+ version = klass(version, equation=equation)
+ DBSession.add(version)
+ return version
+
def initialize_sql(engine):
DBSession.configure(bind=engine)
View
22 whiskers/scripts/initializedb.py
@@ -1,21 +1,21 @@
import os
import sys
-import transaction
+# import transaction
from sqlalchemy import engine_from_config
from pyramid.paster import (
get_appsettings,
setup_logging,
- )
+)
from ..models import (
DBSession,
- Host,
- Buildout,
+ # Host,
+ # Buildout,
# MyModel,
Base,
- )
+)
def usage(argv):
@@ -34,9 +34,9 @@ def main(argv=sys.argv):
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
- with transaction.manager:
- model = Host('latitude')
- DBSession.add(model)
- buildout = Buildout('testbuildout', '/path/to/buildout', host=model,
- packages=[])
- DBSession.add(buildout)
+ # with transaction.manager:
+ # model = Host('latitude')
+ # DBSession.add(model)
+ # buildout = Buildout('testbuildout', '/path/to/buildout', host=model,
+ # packages=[])
+ # DBSession.add(buildout)
View
9 whiskers/static/whiskers.css
@@ -29,12 +29,3 @@ body {
.package-details a.all-versions {
font-size: 80%;
}
-
-.package-details ul, p {
- margin-left: 20pt;
- margin-top: 5pt;
-}
-
-.footer {
- background-color: #ccc;
-}
View
73 whiskers/tests/test_views.py
@@ -1,6 +1,5 @@
import transaction
import unittest
-import json
import os
from pyramid import testing
@@ -101,52 +100,26 @@ def get_testjson(self):
class PackagesViewTests(unittest.TestCase):
def setUp(self):
- self.session = _initTestinDB()
-# class AddBuildoutTests(unittest.TestCase):
-# def setUp(self):
-# self.session = _initTestingDB()
-# self.config = testing.setUp()
-#
-# def tearDown(self):
-# self.session.remove()
-# testing.tearDown()
-#
-# def _callFUT(self, request):
-# from whiskers.views import add_buildout_view
-# return add_buildout_view(request)
-#
-# def add_buildout(self, test_data=test_data):
-# _registerRoutes(self.config)
-# request = testing.DummyRequest()
-# request.params = {'data': json.dumps(test_data)}
-# self._callFUT(request)
-#
-# def test_it_nodata(self):
-# _registerRoutes(self.config)
-# request = testing.DummyRequest()
-# info = self._callFUT(request)
-# self.assertEqual(info.status, u'200 OK')
-# self.assertEqual(info.text, u'No data. Nothing added.')
-#
-# def test_it_submitted(self):
-# self.add_buildout()
-# from whiskers.models import Buildout
-# buildout = self.session.query(Buildout).filter_by(name='test').one()
-# self.assertEqual(buildout.name, u'test')
-# packages = [i.name for i in buildout.packages]
-# for p in ['distribute', 'nose', 'zc.buildout', 'zc.recipe.egg']:
-# self.assertTrue(p in packages)
-#
-# def test_update_data(self):
-# from whiskers.models import Buildout
-# # First we add default data and check it's there
-# self.add_buildout()
-# buildout = self.session.query(Buildout).filter_by(name='test').one()
-# packages = [(i.name, i.version.version) for i in buildout.packages]
-# self.assertTrue((u'distribute', u'0.6.24') in packages)
-# # Lets update our data
-# test_data['packages'][0]['version'] = '0.6.25'
-# self.add_buildout(test_data)
-# buildout = self.session.query(Buildout).filter_by(name='test').one()
-# packages = [(i.name, i.version.version) for i in buildout.packages]
-# self.assertTrue((u'distribute', u'0.6.25') in packages)
+ self.session = _initTestingDB()
+
+ def _createDummyContent(self):
+ from whiskers.models import Package, Version
+ version = Version('1.0')
+ package = Package('req-package-1', version)
+ self.session.add(package)
+ self.session.flush()
+ transaction.commit()
+
+ def _callFUT(self, request):
+ from whiskers.views.packages import PackagesView
+ return PackagesView(request).package_view()
+
+ def test_it(self):
+ from sqlalchemy import create_engine
+ engine = create_engine('sqlite:///:memory:')
+ self._callFUT(engine)
+ self._createDummyContent()
+ _registerRoutes(self.config)
+ request = testing.DummyRequest()
+ info = self._callFUT(request)
+ import pdb; pdb.set_trace()
View
284 whiskers/views/buildout.py
@@ -1,284 +0,0 @@
-import json
-# import transaction
-
-from pyramid.view import view_config
-from pyramid.response import Response
-from pyramid.renderers import get_renderer
-from sqlalchemy.orm.exc import NoResultFound
-from whiskers.models import DBSession
-from whiskers.models import Buildout, Package, Host, Version
-from whiskers.views.version import get_version
-from whiskers.views.package import get_package
-
-
-class BuildoutView(object):
- """Buildout views."""
-
- def __init__(self, request):
- self.main = get_renderer(
- 'whiskers:views/templates/master.pt').implementation()
- self.request = request
- self.session = DBSession()
-
- @view_config(route_name='buildouts')
- def buildouts_view(self):
- """Main view for whiskers/buildouts."""
-
- return {'buildouts': self.buildouts,
- 'project': 'whiskers',
- 'main': self.main}
-
- @property
- def buildouts(self):
- """Return all buildouts"""
- return self.session.query(Buildout).order_by(Buildout.name).all()
-
- @view_config(route_name='add_buildout')
- def add_buildout_view(self):
- """Add a new buildout to database."""
-
- try:
- self.jsondata = JsonDataWrapper(self.request.params['data'])
- except KeyError:
- return Response('No data. Nothing added.')
-
- host = self.get_host(self.jsondata.hostname)
-
- if host:
- buildout = self.get_existing_buildout(self.jsondata)
- if buildout:
- # self.update(buildout, data)
- pass
- else:
- self.add_buildout(self.jsondata, host)
- else:
- host = self.add_host(self.jsondata.hostname)
- buildout = self.add_buildout(self.jsondata, host)
-
- return Response('OK. Added buildout')
-
- def add_package(self, data):
- package = Package(data['name'])
-
- version = self.get_version(data)
- package.version = version
-
- if 'requirements' in data:
- requirements = []
- for req in data['requirements']:
- requirements.append(self.get_package(req))
- package.requires = requirements
-
- self.session.add(package)
- return package
-
- def get_package(self, package):
- try:
- if not 'version' in package:
- try:
- version = self.jsondata.versionmap[package['name']]
- except KeyError:
- version = 'stdlib'
- else:
- version = package['version']
-
- package = self.session.query(Package).join(Package.version).\
- filter(Package.name == package['name']).\
- filter(Version.version == version).one()
- except NoResultFound:
- package = self.add_package(package)
-
- return package
-
- def get_version(self, data):
- try:
- if not 'version' in data:
- try:
- data['version'] = self.jsondata.versionmap[data['name']]
- except KeyError:
- # maybe we have standardlib requirement (eg. unittest2)
- data['version'] = 'stdlib'
- version = self.session.query(Version).filter(
- Version.version == data['version']).one()
- except NoResultFound:
- version = self.add_version(data)
-
- return version
-
- def add_version(self, data):
- version = Version(data['version'])
- if 'equation' in data:
- version.equation = data['equation']
- self.session.add(version)
-
- return version
-
- def add_host(self, hostname):
- host = Host(hostname)
- self.session.add(host)
- return host
-
- def add_buildout(self, data, host):
- packages = []
-
- for package in data.packages:
- packages.append(self.get_package(package))
-
- buildout = Buildout(data.name, data.path, host, packages,
- data.config)
- self.session.add(buildout)
- return buildout
-
- def get_host(self, hostname):
- """Return host object if found."""
- try:
- host = self.session.query(Host).filter(Host.name == hostname).one()
- return host
- except NoResultFound:
- return None
-
- def get_existing_buildout(self, data):
- """Return buildout if it already exists in db."""
- try:
- buildout = self.session.query(Host).join(Host.buildouts).\
- filter(Host.name == data.hostname).\
- filter(Buildout.name == data.name).one()
- return buildout
- except NoResultFound:
- return None
-
- # def add(self, data):
- # """Add buildout to db."""
-
- # if packages:
- # packages_list = []
- # for package in packages:
- # requires = []
- # if package.get('requires'):
- # for req in package['requires']:
- # pass
-
- # buildout = Buildout(name, path, hostname, packages)
- # return buildout
-
- @view_config(route_name='buildout_view',
- renderer='templates/buildout.pt')
- def get(self):
- """Return a buildout specified by buildout_id."""
- buildout_id = self.request.matchdict['buildout_id']
- buildout = self.session.query(Buildout).filter_by(
- id=int(buildout_id)).one()
- packages = self.session.query(Package).join(Package.buildouts).filter(
- Buildout.id == buildout_id).order_by(Package.name).all()
- config = json.loads(buildout.config)
-
- return {'buildout': buildout, 'main': self.main, 'config': config}
-
- def update(self, buildout_id):
- """Update existing buildout."""
- # Update buildout path information
- # path = data.get('buildoutpath', None)
- # if path:
- # buildout.path = path
-
- # # Update hostname information
- # hostname = data.get('hostname', None)
- # if hostname:
- # buildout.hostname = hostname
-
- # # Update packages used by buildout
- # packages = data.get('packages', None)
- # if packages:
- # buildout.packages = update_buildout_packages(buildout, packages)
- pass
-
- def delete(self, buildout_id):
- """Delete existing buildout."""
- pass
-
- def get_buildouts(self):
- """Return all buildouts from database."""
- pass
-
-
-def update_existing_buildout(buildout, data):
- """Updates buildout information"""
-
- # Update buildout path information
- path = data.get('buildoutpath', None)
- if path:
- buildout.path = path
-
- # Update hostname information
- hostname = data.get('hostname', None)
- if hostname:
- buildout.hostname = hostname
-
- # Update packages used by buildout
- packages = data.get('packages', None)
- if packages:
- buildout.packages = update_buildout_packages(buildout, packages)
-
-
-def update_buildout_packages(buildout, packages):
- """Update buildout packages"""
-
- packages_list = []
-
- for package in packages:
- version_id = get_version(package['version'])
- package_id = get_package(package['name'], version_id)
- packages_list.append(package_id)
-
- return packages_list
-
-
-class JsonDataWrapper(object):
- """Wrapper for json-data."""
-
- def __init__(self, data):
- self.data = json.loads(data)
-
- @property
- def hostname(self):
- return self.data.get('hostname', None)
-
- @property
- def name(self):
- return self.data.get('buildoutname', None) or\
- self.path.rsplit('/', 1)[-1]
-
- @property
- def path(self):
- return self.data.get('directory', None)
-
- @property
- def packages(self):
- for package in self.data['packages'].keys():
- yield {'name': package,
- 'version': self.data['packages'][package]['version'],
- 'requirements':
- self.data['packages'][package]['requirements']}
-
- @property
- def executable(self):
- return self.data.get('executable', None)
-
- @property
- def allow_picked_versions(self):
- return self.data.get('allow_picked_versions', None)
-
- @property
- def newest(self):
- return self.data.get('newest', None)
-
- @property
- def versionmap(self):
- return self.data.get('versionmap', None)
-
- @property
- def config(self):
- tmp = self.data.copy()
- tmp.pop('packages')
- tmp.pop('versionmap')
- return json.dumps(tmp)
View
140 whiskers/views/buildouts.py
@@ -0,0 +1,140 @@
+import json
+import zlib
+import logging
+
+from datetime import datetime
+
+from pyramid.response import Response
+from pyramid.renderers import get_renderer
+from whiskers.jsonwrapper import JsonDataWrapper
+from whiskers.models import (
+ Buildout,
+ Package,
+ Host,
+ Version,
+ DBSession)
+
+
+class BuildoutsView(object):
+ """Buildout views."""
+
+ def __init__(self, request):
+ self.main = get_renderer(
+ 'whiskers:views/templates/master.pt').implementation()
+ self.request = request
+
+ def __call__(self):
+ """Main view for whiskers/buildouts."""
+
+ buildouts = self.get_buildouts_info()
+
+ return {'buildouts': buildouts,
+ 'project': 'whiskers',
+ 'main': self.main}
+
+ def get_buildouts_info(self):
+ """Return list of dicts containing Buildout info."""
+
+ query = DBSession.query(Buildout).join(Buildout.host).\
+ group_by(Buildout.name).order_by(Buildout.datetime).\
+ all()
+
+ return query
+
+ def post(self):
+ """Add a new buildout to database."""
+ try:
+ data = self.request.params['data']
+ incoming = data.encode('utf-8')
+ checksum = zlib.adler32(incoming)
+ checksum_buildout = Buildout.get_by_checksum(checksum)
+ if checksum_buildout:
+ logging.info("Checksum matched")
+ logging.info("Updating datetime..")
+ checksum_buildout.datetime = datetime.now()
+ DBSession.flush()
+ raise Exception("No changes with existing data.")
+ logging.info("New checksum")
+ jsondata = JsonDataWrapper(data)
+ except KeyError:
+ return Response('No data. Nothing added.')
+ except Exception as e:
+ return Response(str(e))
+
+ host = Host.get_by_name(jsondata.hostname)
+
+ if not host:
+ host = Host.add(jsondata.hostname)
+
+ self.add_buildout(jsondata, host, checksum)
+
+ return Response('Added buildout info to Whiskers.')
+
+ def add_buildout(self, data, host, checksum):
+ packages = []
+
+ for package_info in data.packages:
+ package = Package.get_by_nameversion(package_info['name'],
+ package_info['version'])
+ if not package:
+ equation = package_info.get('equation', None)
+ version = Version.get_by_version(package_info['version']) or\
+ Version.add(package_info['version'], equation)
+ requirements = self.get_requirements(
+ package_info['requirements'])
+ package = Package.add(package_info['name'],
+ version,
+ requirements)
+
+ packages.append(package)
+
+ buildout = Buildout(data.name, host, checksum, packages,
+ data.config)
+
+ DBSession.add(buildout)
+ return buildout
+
+ def get_requirements(self, requirements):
+ """Return list of package requirements."""
+ packages = []
+
+ for req in requirements:
+ name = req.get('name')
+ version = req.get('version')
+ package = Package.get_by_nameversion(name,
+ version)
+ if not package:
+ equation = req.get('equation', None)
+ version = req.get('version', 'stdlib')
+ version = Version.get_by_version(version) or\
+ Version.add(version, equation)
+ package = Package.add(req['name'], version)
+ packages.append(package)
+
+ return packages
+
+ def buildout_view(self):
+ """Return a buildout specified by buildout_id."""
+ buildout_id = self.request.matchdict['buildout_id']
+ buildout = DBSession.query(Buildout).filter_by(
+ id=int(buildout_id)).one()
+
+ new_buildouts = DBSession.query(Buildout).join(Buildout.host).\
+ filter(Buildout.host == buildout.host,
+ Buildout.name == buildout.name,
+ Buildout.id != buildout_id,
+ Buildout.datetime > buildout.datetime).\
+ order_by(Buildout.datetime).all()
+
+ older_buildouts = DBSession.query(Buildout).join(Buildout.host).\
+ filter(Buildout.host == buildout.host,
+ Buildout.name == buildout.name,
+ Buildout.datetime < buildout.datetime,
+ Buildout.id != buildout_id).\
+ order_by(Buildout.datetime).all()
+
+ config = json.loads(buildout.config)
+
+ return {'buildout': buildout, 'main': self.main, 'config': config,
+ 'older_buildouts': older_buildouts,
+ 'new_buildouts': new_buildouts}
View
21 whiskers/views/host.py
@@ -1,11 +1,16 @@
from pyramid.renderers import get_renderer
-from whiskers.models import (DBSession,
- Host)
+from whiskers.models import DBSession
+from whiskers.models import Host
-def host_view(request):
- main = get_renderer('whiskers:views/templates/master.pt').implementation()
- session = DBSession()
- host_id = request.matchdict['host_id']
- host = session.query(Host).filter_by(id=int(host_id)).one()
- return {'host': host, 'main': main}
+class HostView(object):
+
+ def __init__(self, request):
+ self.main = get_renderer(
+ 'whiskers:views/templates/master.pt').implementation()
+ self.request = request
+
+ def __call__(self):
+ host_id = self.request.matchdict['host_id']
+ host = DBSession.query(Host).filter_by(id=int(host_id)).one()
+ return {'host': host, 'main': self.main}
View
49 whiskers/views/hosts.py
@@ -1,15 +1,10 @@
-import json
-
-from pyramid.view import view_config
-from pyramid.response import Response
+from sqlalchemy.sql.expression import func
from pyramid.renderers import get_renderer
-from sqlalchemy.orm.exc import NoResultFound
from whiskers.models import DBSession
-from whiskers.models import Host
+from whiskers.models import Host, Buildout
class HostsView(object):
- """Hosts views."""
def __init__(self, request):
self.main = get_renderer(
@@ -17,20 +12,28 @@ def __init__(self, request):
self.request = request
self.session = DBSession()
- @view_config(route_name='hosts',
- renderer='templates/hosts.pt')
- def hosts_view(self):
+ def __call__(self):
"""Hosts main view."""
- hosts = self.get_hosts()
- return {'hosts': hosts, 'project': 'whiskers', 'main': self.main}
-
- def get_host(self, host):
- """Return host"""
- result = DBSession.query(Host).filter_by(name=host)
- if result.count() > 0:
- return result
- else:
- return None
-
- def get_hosts(self):
- return self.session.query(Host).order_by(Host.name).all()
+ query = self.get_hosts_info()
+ return {'results': query, 'main': self.main}
+
+ def host_view(self):
+ host_id = self.request.matchdict['host_id']
+ host = Host.get_by_id(int(host_id))
+ return {'host': host, 'main': self.main}
+
+ def get_hosts_info(self):
+ """Return list of dicts containing Host info."""
+
+ result_list = []
+
+ query = DBSession.query(Host, func.count(Buildout.id)).join(Buildout).\
+ filter(Host.id == Buildout.host).all()
+
+ for result in query:
+ tmp = {}
+ tmp['host'] = result[0]
+ tmp['count'] = result[1]
+ result_list.append(tmp)
+
+ return result_list
View
60 whiskers/views/package.py
@@ -1,60 +0,0 @@
-from whiskers.models import DBSession
-from whiskers.models import Package
-from pyramid.renderers import get_renderer
-from pkg_resources import parse_version
-
-
-def package_view(request):
- main = get_renderer('whiskers:views/templates/master.pt').implementation()
- package_name = request.matchdict['package_name']
- package_id = request.matchdict['id']
-
- results = DBSession.query(Package).filter(
- Package.name == package_name)
- packages = results.all()
- packages = sort_versionnumbers(packages)
- requires = None
-
- if len(package_id) > 0:
- package = results.filter_by(id=int(package_id[0])).first()
- requires = package.requires
- else:
- package = None
- if results.count() > 1:
- other_versions = True
- else:
- other_versions = False
-
- return {'packages': packages, 'package': package,
- 'package_name': package_name, 'main': main,
- 'other_versions': other_versions,
- 'requires': requires}
-
-
-def sort_versionnumbers(packages):
- try:
- packages.sort(key=lambda x: [
- parse_version(x.version.version)])
- except AttributeError:
- pass
- return packages
-
-
-def get_package(name, version):
- """Returns package id"""
-
- package = DBSession.query(Package).filter_by(name).\
- filter_by(version=version)
-
- if package.count():
- return package.first().id
- else:
- new_package_id = add_package(name, version)
- return new_package_id
-
-
-def add_package(name, version):
- """Adds new package and returns its id"""
-
- package = Package(name, version)
- return package.id
View
42 whiskers/views/packages.py
@@ -1,15 +1,39 @@
-from whiskers.models import DBSession
from whiskers.models import Package
from pyramid.renderers import get_renderer
-def packages_view(request):
- main = get_renderer('whiskers:views/templates/master.pt').implementation()
- packages = get_packages()
- return {'packages': packages, 'project': 'whiskers', 'main': main}
+class PackagesView(object):
+ def __init__(self, request):
+ self.request = request
+ self.main = get_renderer(
+ 'whiskers:views/templates/master.pt').implementation()
-def get_packages():
- """Return packages"""
- session = DBSession()
- return session.query(Package).group_by(Package.name).all()
+ def __call__(self):
+ """Main view for packages."""
+ packages = Package.by_name()
+ return {'packages': packages, 'project': 'whiskers', 'main': self.main}
+
+ def package_view(self):
+ """View for individual package."""
+ package_name = self.request.matchdict.get('package_name', None)
+ package_id = self.request.matchdict.get('id', None)
+
+ packages = Package.get_packages_by_name(package_name)
+ requires = None
+ other_versions = False
+
+ if len(package_id) > 0:
+ package = packages.filter(Package.id == int(package_id[0])).first()
+ if package and package.requires:
+ requires = package.requires
+ else:
+ package = None
+
+ if packages.count() > 1:
+ other_versions = True
+
+ return {'packages': packages.all(), 'package': package,
+ 'package_name': package_name, 'main': self.main,
+ 'other_versions': other_versions,
+ 'requires': requires}
View
37 whiskers/views/templates/buildout.pt
@@ -7,7 +7,17 @@
<tal:block metal:use-macro="main.macros['body']">
<div metal:fill-slot="content">
<div class="container">
- <h2 class="title">${buildout.name}</h2>
+ <h2 class="title">Buildout name: ${buildout.name}</h2>
+ <dl>
+ <dt>Host</dt>
+ <dd>
+ <a href="${request.route_url('host', host_id=buildout.host.id)}">
+ ${buildout.host.name}
+ </a>
+ </dd>
+ <dt>Added or modified</dt>
+ <dd>${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}</dd>
+ </dl>
<div class="config">
<a href="#buildoutConfig" role="button" class="" data-toggle="modal">Show buildout config</a>
@@ -45,6 +55,31 @@
</p>
</div>
</div>
+
+ <div tal:condition="new_buildouts">
+ <hr />
+ <h4>View new versions of this buildout</h4>
+ <ul tal:repeat="buildout new_buildouts">
+ <li>
+ <a href="${request.route_url('buildout_view', buildout_id=buildout.id)}">
+ ${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}
+ </a>
+ </li>
+ </ul>
+ </div>
+
+ <div tal:condition="older_buildouts">
+ <hr />
+ <h4>View older versions of this buildout</h4>
+ <ul tal:repeat="buildout older_buildouts">
+ <li>
+ <a href="${request.route_url('buildout_view', buildout_id=buildout.id)}">
+ ${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}
+ </a>
+ </li>
+ </ul>
+
+ </div>
</div>
</div>
</tal:block>
View
26 whiskers/views/templates/buildouts.pt
@@ -7,11 +7,27 @@
<tal:block metal:use-macro="main.macros['body']">
<div metal:fill-slot="content">
<div class="container">
- <div class="listing">
- <p tal:repeat="buildout buildouts">
- <a tal:attributes="href string: buildouts/${buildout.id}"
- tal:content="buildout.name" />
- </p>
+ <h3>All the unique buildouts</h3>
+ <hr />
+
+ <div class="row">
+ <tal:block tal:repeat="buildout buildouts">
+ <div class="span3">
+ <h4>
+ <a href="${request.route_url('buildouts')}/${buildout.id}">
+ ${buildout.name}
+ </a>
+ </h4>
+ <dl>
+ <dt>Host</dt>
+ <dd>${buildout.host.name}</dd>
+ <dt>Updated</dt>
+ <dd>${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}</dd>
+ <dt>Packages</dt>
+ <dd tal:content="len(buildout.packages)" />
+ </dl>
+ </div>
+ </tal:block>
</div>
</div>
</div>
View
21 whiskers/views/templates/host.pt
@@ -8,12 +8,21 @@
<div metal:fill-slot="content">
<div class="container">
<h3>${host.name}</h3>
- <h6>Host contains following buildouts</h6>
- <div class="listing">
- <p tal:repeat="buildout host.buildouts">
- <a tal:attributes="href string: ${request.route_url('buildouts')}/${buildout.id}"
- tal:content="buildout.name" />
- </p>
+ <hr />
+
+ <div class="row">
+ <tal:block tal:repeat="buildout host.buildouts">
+ <div class="span2">
+ <h4>
+ <a href="${request.route_url('buildouts')}/${buildout.id}">
+ ${buildout.name}
+ </a>
+ </h4>
+ <small>Date: <span>${buildout.datetime.strftime("%Y-%m-%d")}</span></small><br />
+ <small>Time: <span>${buildout.datetime.strftime("%H:%M:%S")}</span></small><br />
+ <small>Packages: <span tal:content="len(buildout.packages)" /></small>
+ </div>
+ </tal:block>
</div>
</div>
</div>
View
20 whiskers/views/templates/hosts.pt
@@ -8,11 +8,21 @@
<div metal:fill-slot="content">
<div class="container">
<h3>Hosts where buildouts are executed</h3>
- <div class="listing">
- <p tal:repeat="host hosts">
- <a tal:attributes="href string: hosts/${host.id}"
- tal:content="host.name" />
- </p>
+ <hr />
+
+ <div class="row-fluid">
+ <div class="span4" tal:repeat="result results">
+ <h4>
+ <a href="${request.route_url('host', host_id=result.host.id)}">
+ ${result.host.name}
+ </a>
+ </h4>
+ <p tal:condition="result.count">
+ Contains information of
+ <span tal:omit-tag="" tal:content="result.count" />
+ buildouts.
+ </p>
+ </div>
</div>
</div>
</div>
View
36 whiskers/views/templates/package.pt
@@ -7,18 +7,27 @@
<tal:block metal:use-macro="main.macros['body']">
<div metal:fill-slot="content">
<div class="container">
- <h2 class="title" tal:content="string: ${package_name}"/>
+ <h2 class="title">
+ ${package_name}
+ </h2>
<div tal:condition="package" class="package-details">
- <h3 tal:condition="package.version" tal:content="string:Version ${package.version.version}" />
- <a class="all-versions" tal:condition="other_versions" href="${request.route_url('packages')}/${package_name}">(all versions)</a>
+ <h3 tal:condition="package.version">
+ ${package.version.version}
+ </h3>
+
+ <a class="all-versions" tal:condition="other_versions"
+ href="${request.route_url('packages')}/${package_name}">
+ (all versions)
+ </a>
<div class="used_by" tal:condition="package.buildouts">
<h5>This package is used by following buildouts:</h5>
<ul>
<li tal:repeat="buildout package.buildouts">
- <a href="${request.route_url('buildouts')}/${buildout.id}"
- tal:content="string: ${buildout.name}" />
+ <a href="${request.route_url('buildouts')}/${buildout.id}">
+ ${buildout.name} - ${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}
+ </a>
</li>
</ul>
</div>
@@ -46,17 +55,22 @@
</div>
</div>
- <tal:packages tal:condition="not: package" tal:repeat="package packages">
- <div tal:condition="package.buildouts" class="package-details">
- <h3 tal:content="string:Version ${package.version.version}" />
+ <tal:packages tal:condition="not: package" tal:repeat="result packages">
+ <div tal:condition="result.buildouts" class="package-details">
+ <h3>${result.version.version}</h3>
<p>This package is used by following buildouts:</p>
<ul>
- <li tal:repeat="buildout package.buildouts">
- <a href="${request.route_url('buildouts')}/${buildout.id}"
- tal:content="string: ${buildout.name}" />
+ <li tal:repeat="buildout result.buildouts">
+ <a href="${request.route_url('buildouts')}/${buildout.id}">
+ ${buildout.name} - ${buildout.datetime.strftime("%Y-%m-%d %H:%M:%S")}
+ </a>
</li>
</ul>
</div>
+ <div tal:condition="not: result.buildouts" class="package-details">
+ <h3>${result.version.version}</h3>
+ <p>This package is not used by any buildouts anymore.</p>
+ </div>
</tal:packages>
</div>
</div>
View
2  whiskers/views/templates/packages.pt
@@ -7,6 +7,8 @@
<tal:block metal:use-macro="main.macros['body']">
<div metal:fill-slot="content">
<div class="container">
+ <h3>Packages from buildouts</h3>
+ <hr />
<div class="listing">
<p tal:repeat="package packages">
<a tal:attributes="href string: packages/${package.name}"
View
27 whiskers/views/versions.py
@@ -1,10 +1,25 @@
-from pyramid.renderers import get_renderer
from whiskers.models import DBSession
from whiskers.models import Version
-def versions_view(request):
- main = get_renderer('whiskers:views/templates/master.pt').implementation()
- session = DBSession()
- versions = session.query(Version).order_by(Version.name).all()
- return {'versions': versions, 'main': main}
+def get_version(version):
+ """Returns version id for package"""
+
+ existing_version = Version.get_by_version(version)
+
+ if existing_version.count():
+ return existing_version.first().id
+ else:
+ new_version_id = add_version(version)
+ return new_version_id
+
+
+def add_version(package, version):
+ """Add a new version and return its id"""
+
+ existing_version = DBSession.query(Version).filter_by(version=version)
+
+ if not existing_version.count():
+ new_version = Version(version)
+ DBSession.merge()
+ return new_version.id
Please sign in to comment.
Something went wrong with that request. Please try again.