--- a/ForgeSCM/forgescm/main.py
+++ b/ForgeSCM/forgescm/main.py
@@ -1,24 +1,16 @@
#-*- python -*-
import os
-import shutil
import logging
-from cStringIO import StringIO
-from pprint import pformat
# Non-stdlib imports
import pkg_resources
-from tg import expose, validate, redirect, flash
-from pylons import g, c, request
-from formencode import validators
-from pymongo.bson import ObjectId
+from pylons import g, c
from ming import schema
# Pyforge-specific imports
from pyforge.app import Application, ConfigOption, SitemapEntry
-from pyforge.lib.helpers import push_config
-from pyforge.lib.search import search
-from pyforge.lib.decorators import audit, react
+from pyforge.lib.helpers import push_config, mixin_reactors
from pyforge.lib.security import require, has_artifact_access
from pyforge.model import ProjectRole
@@ -26,7 +18,8 @@
from . import model
from . import version
from .wsgi import WSGIHook
-from .lib import hg
+from .reactors import hg_react
+from .controllers import root
log = logging.getLogger(__name__)
@@ -40,102 +33,11 @@
def __init__(self, project, config):
Application.__init__(self, project, config)
- self.root = RootController()
+ self.root = root.RootController()
@property
def repo(self):
return model.Repository.m.get(app_config_id=self.config._id)
-
- @audit('scm.hg.init')
- def scm_hg_init(self, routing_key, data):
- repo = self.repo
- cmd = hg.init()
- cmd.clean_dir()
- repo.clear_commits()
- repo.parent = None
- cmd.run()
- if cmd.sp.returncode:
- g.publish('react', 'error', dict(
- message=cmd.output))
- else:
- log.info('Setting repo status for %s', repo)
- repo.status = 'Ready'
- repo.m.save()
-
- @audit('scm.hg.clone')
- def scm_hg_clone(self, routing_key, data):
- repo = self.repo
- log.info('Begin cloning %s', data['url'])
- # Perform the clone
- cmd = hg.clone(data['url'], '.')
- cmd.clean_dir()
- cmd.run()
- log.info('Clone complete for %s', data['url'])
- if cmd.sp.returncode:
- errmsg = cmd.output
- g.publish('react', 'error', dict(
- message=errmsg))
- repo.status = 'Error: %s' % errmsg
- repo.m.save()
- return
- # Update the repo status
- repo.status = 'Ready'
- repo.m.save()
- # Load the log & create refresh commit messages
- cmd = hg.scm_log('-q')
- cmd.run()
- for line in cmd.output.split('\n'):
- rev, hash = line.split(':')
- g.publish('audit', 'scm.hg.refresh_commit', dict(
- hash=hash))
-
- # log.info('Begin log %s', data['url'])
- # cmd = hg.scm_log('-g', '-p')
- # cmd.run()
- # log.info('Log complete %s', data['url'])
- # # Clear the old set of commits
- # repo.clear_commits()
- # repo.parent = data['url']
- # parser = hg.LogParser(repo._id)
- # log.info('Begin parsing log')
- # parser.feed(StringIO(cmd.output))
-
- @audit('scm.hg.refresh_commit')
- def scm_hg_refresh_commit(self, routing_key, data):
- repo = self.repo
- hash = data['hash']
- log.info('Refresh commit %s', hash)
- # Load the log
- cmd = hg.scm_log('-g', '-p', '-r', hash)
- cmd.run()
- parser = hg.LogParser(repo._id)
- parser.feed(StringIO(cmd.output))
-
- @audit('scm.hg.fork')
- def scm_hg_fork(self, routing_key, data):
- assert False
-
- @audit('scm.hg.reclone')
- def scm_hg_reclone(self, routing_key, data):
- repo = self.repo
- # Perform the clone
- cmd = hg.clone(repo.parent, '.')
- cmd.clean_dir()
- cmd.run()
- if cmd.sp.returncode:
- g.publish('react', 'error', dict(
- message=cmd.sp.stdout.read()))
- return
- # Load the log
- cmd = hg.log('-g', '-p')
- cmd.run()
- # Clear the old set of commits
- repo.clear_commits()
- parser = hg.LogParser(repo._id)
- parser.feed(StringIO(cmd.output))
- # Update the repo status
- repo.status = 'Ready'
- repo.m.save()
@property
def sitemap(self):
@@ -145,10 +47,16 @@
SitemapEntry(menu_id, '.')[self.sidebar_menu()] ]
def sidebar_menu(self):
- return [
+ result = [
SitemapEntry('Home', '.'),
- SitemapEntry('Search', 'search'),
+ SitemapEntry('Search', 'search'),
]
+ if self.config.options.type == 'hg':
+ repo = self.repo
+ result += [
+ SitemapEntry('HgWeb', repo.native_url()),
+ SitemapEntry('Files', repo.native_url() + '/file') ]
+ return result
@property
def templates(self):
@@ -174,99 +82,13 @@
# Create a repository
repo = model.Repository.make(dict(
description='This is the repository object',
- status='Pending'))
+ status='Pending',
+ type=self.config.options['type']))
repo.m.insert()
- rk = 'scm.%s.init' % self.config.options.type
- g.publish('audit', rk, {})
def uninstall(self, project):
"Remove all the plugin's artifacts from the database"
model.Repository.m.remove(dict(app_config_id=self.config._id))
-class RootController(object):
+mixin_reactors(ForgeSCMApp, hg_react)
- def __init__(self):
- self.repo = CommitsController()
-
- @expose('forgescm.templates.index')
- def index(self):
- return dict(repo=c.app.repo)
-
- @expose('forgescm.templates.fork')
- def fork(self, project, mount_point):
- new_repo = c.app.repo.fork(project, mount_point)
- # Find projects where we can mount things
- flash('Project %s forked' % c.app.repo.url())
- redirect(new_repo.url())
-
-
- @expose('forgescm.templates.search')
- @validate(dict(q=validators.UnicodeString(if_empty=None),
- history=validators.StringBool(if_empty=False)))
- def search(self, q=None, history=None):
- 'local plugin search'
- results = []
- count=0
- if not q:
- q = ''
- else:
- search_query = '''%s
- AND is_history_b:%s
- AND mount_point_s:%s''' % (
- q, history, c.app.config.options.mount_point)
- results = search(search_query)
- if results: count=results.hits
- return dict(q=q, history=history, results=results or [], count=count)
-
- @expose()
- def reinit(self):
- repo = c.app.repo
- repo.status = 'Pending Reinit'
- repo.m.save()
- g.publish('audit', 'scm.%s.init' % c.app.config.options.type, {})
- redirect('.')
-
- @expose()
- def reclone(self):
- repo = c.app.repo
- repo.status = 'Pending Reclone'
- repo.m.save()
- g.publish('audit', 'scm.%s.reclone' % c.app.config.options.type, {})
- redirect('.')
-
- @expose()
- def clone_from(self, url=None):
- repo = c.app.repo
- repo.status = 'Pending Clone'
- repo.m.save()
- g.publish('audit', 'scm.%s.clone' % c.app.config.options.type, dict(
- url=url))
- redirect('.')
-
-class CommitsController(object):
-
- def _lookup(self, id, *remainder):
- if ':' in id: id = id.split(':')[-1]
- if '%3A' in id: id = id.split('%3A')[-1]
- return CommitController(id), remainder
-
-class CommitController(object):
-
- def __init__(self, id):
- self.commit = model.Commit.m.get(hash=id)
-
- @expose('forgescm.templates.commit_index')
- def index(self):
- return dict(value=self.commit)
-
- def _lookup(self, id, *remainder):
- return PatchController(id), remainder
-
-class PatchController(object):
-
- def __init__(self, id):
- self.patch = model.Patch.m.get(_id=ObjectId.url_decode(id))
-
- @expose('forgescm.templates.patch_index')
- def index(self):
- return dict(value=self.patch)