| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| #-*- python -*- |
| import logging |
| from pylons import tmpl_context as c |
| |
| # Non-stdlib imports |
| from ming.utils import LazyProperty |
| from ming.orm.ormsession import ThreadLocalORMSession |
| from tg import expose, redirect, validate, flash |
| from tg.decorators import with_trailing_slash, without_trailing_slash |
| from timermiddleware import Timer |
| |
| # Pyforge-specific imports |
| import allura.tasks.repo_tasks |
| from allura.controllers import BaseController |
| from allura.controllers.repository import RepoRootController |
| from allura.lib.decorators import require_post |
| from allura.lib.repository import RepositoryApp, RepoAdminController |
| from allura.app import SitemapEntry, ConfigOption |
| from allura.lib import helpers as h |
| from allura import model as M |
| |
| # Local imports |
| from . import model as SM |
| from . import version |
| from . import widgets |
| from .controllers import BranchBrowser |
| from .model.svn import svn_path_exists |
| |
| log = logging.getLogger(__name__) |
| |
| class ForgeSVNApp(RepositoryApp): |
| '''This is the SVN app for PyForge''' |
| __version__ = version.__version__ |
| config_options = RepositoryApp.config_options + [ |
| ConfigOption('checkout_url', str, '') |
| ] |
| permissions_desc = dict(RepositoryApp.permissions_desc, **{ |
| 'write': 'Repo commit access.', |
| 'admin': 'Set permissions, checkout url, and viewable files. Import a remote repo.', |
| }) |
| tool_label='SVN' |
| tool_description=""" |
| Enterprise-class centralized version control for the masses. |
| """ |
| ordinal=4 |
| forkable=False |
| default_branch_name='HEAD' |
| |
| def __init__(self, project, config): |
| super(ForgeSVNApp, self).__init__(project, config) |
| self.root = BranchBrowser() |
| default_root = RepoRootController() |
| self.root.refresh = default_root.refresh |
| self.root.commit_browser = default_root.commit_browser |
| self.root.commit_browser_data = default_root.commit_browser_data |
| self.root.status = default_root.status |
| self.admin = SVNRepoAdminController(self) |
| |
| @LazyProperty |
| def repo(self): |
| return SM.Repository.query.get(app_config_id=self.config._id) |
| |
| def install(self, project): |
| '''Create repo object for this tool''' |
| super(ForgeSVNApp, self).install(project) |
| SM.Repository( |
| name=self.config.options.mount_point, |
| tool='svn', |
| status='initializing', |
| fs_path=self.config.options.get('fs_path')) |
| ThreadLocalORMSession.flush_all() |
| init_from_url = self.config.options.get('init_from_url') |
| init_from_path = self.config.options.get('init_from_path') |
| if init_from_url or init_from_path: |
| allura.tasks.repo_tasks.clone.post( |
| cloned_from_path=init_from_path, |
| cloned_from_name=None, |
| cloned_from_url=init_from_url) |
| else: |
| allura.tasks.repo_tasks.init.post() |
| |
| def admin_menu(self): |
| links = [] |
| links.append(SitemapEntry( |
| 'Checkout URL', |
| c.project.url()+'admin/'+self.config.options.mount_point+'/' + 'checkout_url', |
| className='admin_modal')) |
| links.append(SitemapEntry( |
| 'Import Repo', |
| c.project.url()+'admin/'+self.config.options.mount_point+'/' + 'importer/')) |
| links += super(ForgeSVNApp, self).admin_menu() |
| return links |
| |
| class SVNRepoAdminController(RepoAdminController): |
| def __init__(self, app): |
| super(SVNRepoAdminController, self).__init__(app) |
| self.importer = SVNImportController(self.app) |
| |
| @without_trailing_slash |
| @expose('jinja:forgesvn:templates/svn/checkout_url.html') |
| def checkout_url(self, **kw): |
| return dict(app=self.app, |
| allow_config=True, |
| checkout_url=self.app.config.options.get('checkout_url')) |
| |
| @without_trailing_slash |
| @expose() |
| @require_post() |
| def set_checkout_url(self, **post_data): |
| if svn_path_exists("file://%s%s/%s" % |
| (self.app.repo.fs_path, |
| self.app.repo.name, |
| post_data['checkout_url'])): |
| self.app.config.options['checkout_url'] = post_data['checkout_url'] |
| flash("Checkout URL successfully changed") |
| else: |
| flash("%s is not a valid path for this repository" % post_data['checkout_url'], "error") |
| |
| |
| class SVNImportController(BaseController): |
| import_form=widgets.ImportForm() |
| |
| def __init__(self, app): |
| self.app = app |
| |
| @with_trailing_slash |
| @expose('jinja:forgesvn:templates/svn/import.html') |
| def index(self, **kw): |
| c.is_empty = self.app.repo.is_empty() |
| c.form = self.import_form |
| return dict() |
| |
| @without_trailing_slash |
| @expose() |
| @require_post() |
| @validate(import_form, error_handler=index) |
| def do_import(self, checkout_url=None, **kwargs): |
| if self.app.repo.is_empty(): |
| with h.push_context( |
| self.app.config.project_id, |
| app_config_id=self.app.config._id): |
| allura.tasks.repo_tasks.reclone.post( |
| cloned_from_path=None, |
| cloned_from_name=None, |
| cloned_from_url=checkout_url) |
| M.Notification.post_user( |
| c.user, self.app.repo, 'importing', |
| text='''Repository import scheduled, |
| an email notification will be sent when complete.''') |
| else: |
| M.Notification.post_user( |
| c.user, self.app.repo, 'error', |
| text="Can't import into non empty repository.") |
| redirect(c.project.url() + 'admin/tools') |
| |
| |
| def svn_timers(): |
| return Timer('svn_lib.{method_name}', SM.svn.SVNLibWrapper, 'checkout', 'add', |
| 'checkin', 'info2', 'log', 'cat', 'list') |
| |
| |
| def forgesvn_timers(): |
| return Timer('svn_tool.{method_name}', SM.svn.SVNImplementation, '*') |