#-*- python -*-
import logging
import sys
import shutil
sys.path.append('/usr/lib/python2.6/dist-packages')
# Non-stdlib imports
import pkg_resources
from pylons import c, g
from tg import redirect, expose
from tg.decorators import with_trailing_slash, without_trailing_slash
# Pyforge-specific imports
from allura import model as M
from allura.app import Application, SitemapEntry, DefaultAdminController
from allura.lib import helpers as h
from allura.lib.decorators import audit
from allura.lib.security import has_artifact_access
# Local imports
from forgesvn import model
from forgesvn import version
from .reactors import reactors
from .controllers import BranchBrowser
log = logging.getLogger(__name__)
class ForgeSVNApp(Application):
'''This is the SVN app for PyForge'''
__version__ = version.__version__
permissions = [ 'read', 'write', 'create', 'admin', 'configure' ]
tool_label='SVN'
default_mount_label='SVN'
default_mount_point='svn'
ordinal=4
def __init__(self, project, config):
Application.__init__(self, project, config)
self.root = BranchBrowser()
self.admin = SVNAdminController(self)
@property
@h.exceptionless([], log)
def sitemap(self):
menu_id = self.config.options.mount_label.title()
with h.push_config(c, app=self):
return [
SitemapEntry(menu_id, '.')[self.sidebar_menu()] ]
def admin_menu(self):
admin_url = c.project.url()+'admin/'+self.config.options.mount_point+'/'
links = [SitemapEntry('Viewable Files', admin_url + 'extensions', className='nav_child')]
# if self.permissions and has_artifact_access('configure', app=self)():
# links.append(SitemapEntry('Permissions', admin_url + 'permissions', className='nav_child'))
return links
def sidebar_menu(self):
links = []
if c.app.repo.latest:
links.append(SitemapEntry('Browse',c.app.url+"LATEST/tree/", ui_icon='folder-collapsed'))
links.append(SitemapEntry('History',c.app.url+"log/", ui_icon='document-b', small=c.app.repo.count()))
if has_artifact_access('admin', app=c.app)():
links.append(SitemapEntry('Admin', c.project.url()+'admin/'+self.config.options.mount_point, ui_icon='tool-admin'))
return links
@property
def repo(self):
return model.SVNRepository.query.get(app_config_id=self.config._id)
@property
def templates(self):
return pkg_resources.resource_filename('forgesvn', 'templates')
def install(self, project):
'Set up any default permissions and roles here'
self.config.options['project_name'] = project.name
super(ForgeSVNApp, self).install(project)
# Setup permissions
role_developer = M.ProjectRole.query.get(name='Developer')._id
self.config.acl.update(
configure=c.project.acl['tool'],
read=c.project.acl['read'],
create=[role_developer],
write=[role_developer],
admin=c.project.acl['tool'])
repo = model.SVNRepository(
name=self.config.options.mount_point,
tool = 'svn',
status = 'creating')
g.publish('audit', 'scm.svn.init', dict(repo_name=repo.name, repo_path=repo.fs_path))
def uninstall(self, project):
g.publish('audit', 'scm.svn.uninstall', dict(project_id=project._id))
@audit('scm.svn.uninstall')
def _uninstall(self, routing_key, data):
"Remove all the tool's artifacts and the physical repository"
repo = self.repo
if repo is not None:
shutil.rmtree(repo.full_fs_path, ignore_errors=True)
model.SVNRepository.query.remove(dict(app_config_id=self.config._id))
super(ForgeSVNApp, self).uninstall(project_id=data['project_id'])
class SVNAdminController(DefaultAdminController):
def __init__(self, app):
self.app = app
self.repo = app.repo
@with_trailing_slash
def index(self, **kw):
redirect('permissions')
@without_trailing_slash
@expose('jinja:svn/admin_extensions.html')
def extensions(self, **kw):
return dict(app=self.app,
allow_config=has_artifact_access('configure', app=self.app)(),
additional_viewable_extensions=getattr(self.repo, 'additional_viewable_extensions', ''))
@without_trailing_slash
@expose()
def set_extensions(self, **post_data):
self.repo.additional_viewable_extensions = post_data['additional_viewable_extensions']
h.mixin_reactors(ForgeSVNApp, reactors)