Changeset - e7eef7a1db6a
[Not reviewed]
beta
1 13 1
Marcin Kuzminski - 14 years ago 2011-11-25 23:11:32
marcin@python-works.com
#235 forking page repo group selection
- group is selected as parent repo
- refactoring of session behavior to get more atomic operations in models
14 files changed with 289 insertions and 200 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/routing.py
Show inline comments
 
@@ -465,19 +465,20 @@ def make_map(config):
 
                conditions=dict(function=check_repo))
 

	
 
    rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
 
                controller='settings', action='fork_create',
 
                controller='forks', action='fork_create',
 
                conditions=dict(function=check_repo, method=["POST"]))
 

	
 
    rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
 
                controller='settings', action='fork',
 
                controller='forks', action='fork',
 
                conditions=dict(function=check_repo))
 

	
 
    rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
 
                 controller='forks', action='forks',
 
                 conditions=dict(function=check_repo))
 

	
 
    rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
 
                 controller='followers', action='followers',
 
                 conditions=dict(function=check_repo))
 

	
 
    rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
 
                 controller='forks', action='forks',
 
                 conditions=dict(function=check_repo))
 

	
 
    return rmap
rhodecode/controllers/admin/repos.py
Show inline comments
 
@@ -29,9 +29,10 @@ import formencode
 
from formencode import htmlfill
 

	
 
from paste.httpexceptions import HTTPInternalServerError
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons import request, session, tmpl_context as c, url
 
from pylons.controllers.util import redirect
 
from pylons.i18n.translation import _
 
from sqlalchemy.exc import IntegrityError
 

	
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
@@ -39,11 +40,11 @@ from rhodecode.lib.auth import LoginRequ
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug
 
from rhodecode.lib.helpers import get_token
 
from rhodecode.model.meta import Session
 
from rhodecode.model.db import User, Repository, UserFollowing, RepoGroup
 
from rhodecode.model.forms import RepoForm
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.repo import RepoModel
 
from sqlalchemy.exc import IntegrityError
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -65,7 +66,7 @@ class ReposController(BaseController):
 
    def __load_defaults(self):
 
        c.repo_groups = RepoGroup.groups_choices()
 
        c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
 
        
 

	
 
        repo_model = RepoModel()
 
        c.users_array = repo_model.get_users_js()
 
        c.users_groups_array = repo_model.get_users_groups_js()
 
@@ -127,13 +128,13 @@ class ReposController(BaseController):
 
        """
 
        POST /repos: Create a new item"""
 
        # url('repos')
 
        repo_model = RepoModel()
 

	
 
        self.__load_defaults()
 
        form_result = {}
 
        try:
 
            form_result = RepoForm(repo_groups=c.repo_groups_choices)()\
 
                            .to_python(dict(request.POST))
 
            repo_model.create(form_result, self.rhodecode_user)
 
            RepoModel().create(form_result, self.rhodecode_user)
 
            if form_result['clone_uri']:
 
                h.flash(_('created repository %s from %s') \
 
                    % (form_result['repo_name'], form_result['clone_uri']),
 
@@ -143,13 +144,13 @@ class ReposController(BaseController):
 
                    category='success')
 

	
 
            if request.POST.get('user_created'):
 
                #created by regular non admin user
 
                # created by regular non admin user
 
                action_logger(self.rhodecode_user, 'user_created_repo',
 
                              form_result['repo_name_full'], '', self.sa)
 
            else:
 
                action_logger(self.rhodecode_user, 'admin_created_repo',
 
                              form_result['repo_name_full'], '', self.sa)
 

	
 
            Session().commit()
 
        except formencode.Invalid, errors:
 

	
 
            c.new_repo = errors.value['repo_name']
 
@@ -207,7 +208,7 @@ class ReposController(BaseController):
 
            changed_name = repo.repo_name
 
            action_logger(self.rhodecode_user, 'admin_updated_repo',
 
                              changed_name, '', self.sa)
 

	
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            defaults = self.__load_data(repo_name)
 
            defaults.update(errors.value)
 
@@ -251,7 +252,7 @@ class ReposController(BaseController):
 
            repo_model.delete(repo)
 
            invalidate_cache('get_repo_cached_%s' % repo_name)
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 

	
 
            Session().commit()
 
        except IntegrityError, e:
 
            if e.message.find('repositories_fork_id_fkey'):
 
                log.error(traceback.format_exc())
rhodecode/controllers/forks.py
Show inline comments
 
@@ -23,13 +23,23 @@
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
import formencode
 
import traceback
 
from formencode import htmlfill
 

	
 
from pylons import tmpl_context as c, request
 
from pylons import tmpl_context as c, request, url
 
from pylons.controllers.util import redirect
 
from pylons.i18n.translation import _
 

	
 
import rhodecode.lib.helpers as h
 

	
 
from rhodecode.lib.helpers import Page
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \
 
    NotAnonymous
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.model.db import Repository, User, UserFollowing
 
from rhodecode.model.db import Repository, RepoGroup, UserFollowing, User
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.forms import RepoForkForm
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -37,11 +47,59 @@ log = logging.getLogger(__name__)
 
class ForksController(BaseRepoController):
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def __before__(self):
 
        super(ForksController, self).__before__()
 

	
 
    def __load_defaults(self):
 
        c.repo_groups = RepoGroup.groups_choices()
 
        c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
 

	
 
    def __load_data(self, repo_name=None):
 
        """
 
        Load defaults settings for edit, and update
 

	
 
        :param repo_name:
 
        """
 
        self.__load_defaults()
 

	
 
        c.repo_info = db_repo = Repository.get_by_repo_name(repo_name)
 
        repo = db_repo.scm_instance
 

	
 
        if c.repo_info is None:
 
            h.flash(_('%s repository is not mapped to db perhaps'
 
                      ' it was created or renamed from the filesystem'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % repo_name,
 
                      category='error')
 

	
 
            return redirect(url('repos'))
 

	
 
        c.default_user_id = User.get_by_username('default').user_id
 
        c.in_public_journal = UserFollowing.query()\
 
            .filter(UserFollowing.user_id == c.default_user_id)\
 
            .filter(UserFollowing.follows_repository == c.repo_info).scalar()
 

	
 
        if c.repo_info.stats:
 
            last_rev = c.repo_info.stats.stat_on_revision
 
        else:
 
            last_rev = 0
 
        c.stats_revision = last_rev
 

	
 
        c.repo_last_rev = repo.count() - 1 if repo.revisions else 0
 

	
 
        if last_rev == 0 or c.repo_last_rev == 0:
 
            c.stats_percentage = 0
 
        else:
 
            c.stats_percentage = '%.2f' % ((float((last_rev)) /
 
                                            c.repo_last_rev) * 100)
 

	
 
        defaults = RepoModel()._get_defaults(repo_name)
 
        # add prefix to fork
 
        defaults['repo_name'] = 'fork-' + defaults['repo_name']
 
        return defaults
 

	
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def forks(self, repo_name):
 
        p = int(request.params.get('page', 1))
 
        repo_id = c.rhodecode_db_repo.repo_id
 
@@ -54,3 +112,63 @@ class ForksController(BaseRepoController
 
            return c.forks_data
 

	
 
        return render('/forks/forks.html')
 

	
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def fork(self, repo_name):
 
        c.repo_info = Repository.get_by_repo_name(repo_name)
 
        if not c.repo_info:
 
            h.flash(_('%s repository is not mapped to db perhaps'
 
                      ' it was created or renamed from the file system'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % repo_name,
 
                      category='error')
 

	
 
            return redirect(url('home'))
 

	
 
        defaults = self.__load_data(repo_name)
 

	
 
        return htmlfill.render(
 
            render('forks/fork.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 

	
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def fork_create(self, repo_name):
 
        self.__load_defaults()
 
        c.repo_info = Repository.get_by_repo_name(repo_name)
 
        _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
 
                             repo_groups=c.repo_groups_choices,)()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            # add org_path of repo so we can do a clone from it later
 
            form_result['org_path'] = c.repo_info.repo_name
 

	
 
            # create fork is done sometimes async on celery, db transaction
 
            # management is handled there.
 
            RepoModel().create_fork(form_result, self.rhodecode_user)
 
            h.flash(_('forked %s repository as %s') \
 
                      % (repo_name, form_result['repo_name']),
 
                    category='success')
 
        except formencode.Invalid, errors:
 
            c.new_repo = errors.value['repo_name']
 

	
 
            return htmlfill.render(
 
                render('forks/fork.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during repository forking %s') %
 
                    repo_name, category='error')
 

	
 
        return redirect(url('home'))
rhodecode/controllers/journal.py
Show inline comments
 
@@ -23,21 +23,22 @@
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
from itertools import groupby
 

	
 
from sqlalchemy import or_
 
from sqlalchemy.orm import joinedload, make_transient
 
from sqlalchemy.orm import joinedload
 
from webhelpers.paginate import Page
 
from itertools import groupby
 
from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
 

	
 
from paste.httpexceptions import HTTPBadRequest
 
from pylons import request, tmpl_context as c, response, url
 
from pylons.i18n.translation import _
 
from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
 

	
 
import rhodecode.lib.helpers as h
 
from rhodecode.lib.auth import LoginRequired, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.db import UserLog, UserFollowing
 
from rhodecode.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -124,6 +125,7 @@ class JournalController(BaseController):
 
                try:
 
                    self.scm_model.toggle_following_user(user_id,
 
                                                self.rhodecode_user.user_id)
 
                    Session().commit()
 
                    return 'ok'
 
                except:
 
                    raise HTTPBadRequest()
 
@@ -133,6 +135,7 @@ class JournalController(BaseController):
 
                try:
 
                    self.scm_model.toggle_following_repo(repo_id,
 
                                                self.rhodecode_user.user_id)
 
                    Session().commit()
 
                    return 'ok'
 
                except:
 
                    raise HTTPBadRequest()
rhodecode/controllers/settings.py
Show inline comments
 
@@ -35,14 +35,14 @@ from pylons.i18n.translation import _
 

	
 
import rhodecode.lib.helpers as h
 

	
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator, \
 
    HasRepoPermissionAnyDecorator, NotAnonymous
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import invalidate_cache, action_logger
 

	
 
from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
 
from rhodecode.model.forms import RepoSettingsForm
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.db import RepoGroup
 
from rhodecode.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -52,15 +52,15 @@ class SettingsController(BaseRepoControl
 
    @LoginRequired()
 
    def __before__(self):
 
        super(SettingsController, self).__before__()
 
    
 

	
 
    def __load_defaults(self):
 
        c.repo_groups = RepoGroup.groups_choices()
 
        c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
 
        
 

	
 
        repo_model = RepoModel()
 
        c.users_array = repo_model.get_users_js()
 
        c.users_groups_array = repo_model.get_users_groups_js()
 
        
 

	
 
    @HasRepoPermissionAllDecorator('repository.admin')
 
    def index(self, repo_name):
 
        repo_model = RepoModel()
 
@@ -89,15 +89,15 @@ class SettingsController(BaseRepoControl
 
    def update(self, repo_name):
 
        repo_model = RepoModel()
 
        changed_name = repo_name
 
        
 

	
 
        self.__load_defaults()
 
        
 

	
 
        _form = RepoSettingsForm(edit=True,
 
                                 old_data={'repo_name': repo_name},
 
                                 repo_groups=c.repo_groups_choices)()
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            
 

	
 
            repo_model.update(repo_name, form_result)
 
            invalidate_cache('get_repo_cached_%s' % repo_name)
 
            h.flash(_('Repository %s updated successfully' % repo_name),
 
@@ -105,6 +105,7 @@ class SettingsController(BaseRepoControl
 
            changed_name = form_result['repo_name_full']
 
            action_logger(self.rhodecode_user, 'user_updated_repo',
 
                          changed_name, '', self.sa)
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            c.repo_info = repo_model.get_by_repo_name(repo_name)
 
            c.users_array = repo_model.get_users_js()
 
@@ -148,61 +149,10 @@ class SettingsController(BaseRepoControl
 
            repo_model.delete(repo)
 
            invalidate_cache('get_repo_cached_%s' % repo_name)
 
            h.flash(_('deleted repository %s') % repo_name, category='success')
 
            Session().commit()
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during deletion of %s') % repo_name,
 
                    category='error')
 

	
 
        return redirect(url('home'))
 

	
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def fork(self, repo_name):
 
        repo_model = RepoModel()
 
        c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
 
        if not repo:
 
            h.flash(_('%s repository is not mapped to db perhaps'
 
                      ' it was created or renamed from the file system'
 
                      ' please run the application again'
 
                      ' in order to rescan repositories') % repo_name,
 
                      category='error')
 

	
 
            return redirect(url('home'))
 

	
 
        return render('settings/repo_fork.html')
 

	
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def fork_create(self, repo_name):
 
        repo_model = RepoModel()
 
        c.repo_info = repo_model.get_by_repo_name(repo_name)
 
        _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type})()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            form_result.update({'repo_name': repo_name})
 
            repo_model.create_fork(form_result, self.rhodecode_user)
 
            h.flash(_('forked %s repository as %s') \
 
                      % (repo_name, form_result['fork_name']),
 
                    category='success')
 
            action_logger(self.rhodecode_user,
 
                          'user_forked_repo:%s' % form_result['fork_name'],
 
                           repo_name, '', self.sa)
 
        except formencode.Invalid, errors:
 
            c.new_repo = errors.value['fork_name']
 
            r = render('settings/repo_fork.html')
 

	
 
            return htmlfill.render(
 
                r,
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during repository forking %s') %
 
                    repo_name, category='error')
 

	
 
        return redirect(url('home'))
rhodecode/lib/celerylib/tasks.py
Show inline comments
 
@@ -37,29 +37,28 @@ from string import lower
 
from pylons import config, url
 
from pylons.i18n.translation import _
 

	
 
from vcs import get_backend
 

	
 
from rhodecode.lib import LANGUAGES_EXTENSIONS_MAP, safe_str
 
from rhodecode.lib.celerylib import run_task, locked_task, str2bool, \
 
    __get_lockkey, LockHeld, DaemonLock
 
from rhodecode.lib.helpers import person
 
from rhodecode.lib.rcmail.smtp_mailer import SmtpMailer
 
from rhodecode.lib.utils import add_cache
 
from rhodecode.lib.utils import add_cache, action_logger
 
from rhodecode.lib.compat import json, OrderedDict
 

	
 
from rhodecode.model import init_model
 
from rhodecode.model import meta
 
from rhodecode.model.db import RhodeCodeUi, Statistics, Repository, User
 

	
 
from vcs.backends import get_repo
 
from rhodecode.model.db import Statistics, Repository, User
 

	
 
from sqlalchemy import engine_from_config
 

	
 

	
 
add_cache(config)
 

	
 
__all__ = ['whoosh_index', 'get_commits_stats',
 
           'reset_user_password', 'send_email']
 

	
 

	
 
CELERY_ON = str2bool(config['app_conf'].get('use_celery'))
 

	
 

	
 
@@ -81,17 +80,13 @@ def get_logger(cls):
 

	
 
    return log
 

	
 
def get_repos_path():
 
    sa = get_session()
 
    q = sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
 
    return q.ui_value
 

	
 

	
 
@task(ignore_result=True)
 
@locked_task
 
def whoosh_index(repo_location, full_index):
 
    from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
 

	
 
    #log = whoosh_index.get_logger()
 
    from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
 

	
 
    index_location = config['index_dir']
 
    WhooshIndexingDaemon(index_location=index_location,
 
                         repo_location=repo_location, sa=get_session())\
 
@@ -111,13 +106,12 @@ def get_commits_stats(repo_name, ts_min_
 
        sa = get_session()
 
        lock = l = DaemonLock(file_=jn(lockkey_path, lockkey))
 

	
 
        #for js data compatibilty cleans the key for person from '
 
        # for js data compatibilty cleans the key for person from '
 
        akc = lambda k: person(k).replace('"', "")
 

	
 
        co_day_auth_aggr = {}
 
        commits_by_day_aggregate = {}
 
        repos_path = get_repos_path()
 
        repo = get_repo(safe_str(os.path.join(repos_path, repo_name)))
 
        repo = Repository.get_by_repo_name(repo_name).scm_instance
 
        repo_size = len(repo.revisions)
 
        #return if repo have no revisions
 
        if repo_size < 1:
 
@@ -139,9 +133,9 @@ def get_commits_stats(repo_name, ts_min_
 
            last_rev = cur_stats.stat_on_revision
 

	
 
        if last_rev == repo.get_changeset().revision and repo_size > 1:
 
            #pass silently without any work if we're not on first revision or
 
            #current state of parsing revision(from db marker) is the
 
            #last revision
 
            # pass silently without any work if we're not on first revision or
 
            # current state of parsing revision(from db marker) is the
 
            # last revision
 
            lock.release()
 
            return True
 

	
 
@@ -255,10 +249,11 @@ def get_commits_stats(repo_name, ts_min_
 

	
 
@task(ignore_result=True)
 
def send_password_link(user_email):
 
    from rhodecode.model.notification import EmailNotificationModel
 

	
 
    log = get_logger(send_password_link)
 

	
 
    try:
 
        from rhodecode.model.notification import EmailNotificationModel
 
        sa = get_session()
 
        user = User.get_by_email(user_email)
 
        if user:
 
@@ -283,9 +278,9 @@ def send_password_link(user_email):
 

	
 
@task(ignore_result=True)
 
def reset_user_password(user_email):
 
    log = get_logger(reset_user_password)
 
    from rhodecode.lib import auth
 

	
 
    from rhodecode.lib import auth
 
    log = get_logger(reset_user_password)
 

	
 
    try:
 
        try:
 
@@ -361,27 +356,39 @@ def send_email(recipients, subject, body
 

	
 
@task(ignore_result=True)
 
def create_repo_fork(form_data, cur_user):
 
    """
 
    Creates a fork of repository using interval VCS methods
 
    
 
    :param form_data:
 
    :param cur_user:
 
    """
 
    from rhodecode.model.repo import RepoModel
 

	
 
    log = get_logger(create_repo_fork)
 

	
 
    from rhodecode.model.repo import RepoModel
 
    from vcs import get_backend
 
    Session = get_session()
 
    base_path = Repository.base_path()
 

	
 
    RepoModel(Session).create(form_data, cur_user, just_db=True, fork=True)
 

	
 
    alias = form_data['repo_type']
 
    org_repo_name = form_data['org_path']
 
    source_repo_path = os.path.join(base_path, org_repo_name)
 
    destination_fork_path = os.path.join(base_path, form_data['repo_name_full'])
 

	
 
    repo_model = RepoModel(get_session())
 
    repo_model.create(form_data, cur_user, just_db=True, fork=True)
 
    repo_name = form_data['repo_name']
 
    repos_path = get_repos_path()
 
    repo_path = os.path.join(repos_path, repo_name)
 
    repo_fork_path = os.path.join(repos_path, form_data['fork_name'])
 
    alias = form_data['repo_type']
 

	
 
    log.info('creating repo fork %s as %s', repo_name, repo_path)
 
    log.info('creating fork of %s as %s', source_repo_path,
 
             destination_fork_path)
 
    backend = get_backend(alias)
 
    backend(str(repo_fork_path), create=True, src_url=str(repo_path))
 

	
 
    backend(safe_str(destination_fork_path), create=True,
 
            src_url=safe_str(source_repo_path))
 
    action_logger(cur_user, 'user_forked_repo:%s' % org_repo_name,
 
                   org_repo_name, '', Session)
 
    # finally commit at latest possible stage
 
    Session.commit()
 

	
 
def __get_codes_stats(repo_name):
 
    repos_path = get_repos_path()
 
    repo = get_repo(safe_str(os.path.join(repos_path, repo_name)))
 
    repo = Repository.get_by_repo_name(repo_name).scm_instance
 

	
 
    tip = repo.get_changeset()
 
    code_stats = {}
 

	
rhodecode/lib/hooks.py
Show inline comments
 
@@ -33,7 +33,8 @@ from rhodecode.lib.utils import action_l
 

	
 

	
 
def repo_size(ui, repo, hooktype=None, **kwargs):
 
    """Presents size of repository after push
 
    """
 
    Presents size of repository after push
 

	
 
    :param ui:
 
    :param repo:
 
@@ -65,7 +66,8 @@ def repo_size(ui, repo, hooktype=None, *
 

	
 

	
 
def log_pull_action(ui, repo, **kwargs):
 
    """Logs user last pull action
 
    """
 
    Logs user last pull action
 

	
 
    :param ui:
 
    :param repo:
 
@@ -76,13 +78,15 @@ def log_pull_action(ui, repo, **kwargs):
 
    repository = extra_params['repository']
 
    action = 'pull'
 

	
 
    action_logger(username, action, repository, extra_params['ip'])
 
    action_logger(username, action, repository, extra_params['ip'],
 
                  commit=True)
 

	
 
    return 0
 

	
 

	
 
def log_push_action(ui, repo, **kwargs):
 
    """Maps user last push action to new changeset id, from mercurial
 
    """
 
    Maps user last push action to new changeset id, from mercurial
 

	
 
    :param ui:
 
    :param repo:
 
@@ -110,6 +114,7 @@ def log_push_action(ui, repo, **kwargs):
 

	
 
    action = action % ','.join(revs)
 

	
 
    action_logger(username, action, repository, extra_params['ip'])
 
    action_logger(username, action, repository, extra_params['ip'],
 
                  commit=True)
 

	
 
    return 0
rhodecode/lib/utils.py
Show inline comments
 
@@ -93,7 +93,7 @@ def get_repo_slug(request):
 
    return request.environ['pylons.routes_dict'].get('repo_name')
 

	
 

	
 
def action_logger(user, action, repo, ipaddr='', sa=None):
 
def action_logger(user, action, repo, ipaddr='', sa=None, commit=False):
 
    """
 
    Action logger for various actions made by users
 

	
 
@@ -138,12 +138,13 @@ def action_logger(user, action, repo, ip
 
        user_log.action_date = datetime.datetime.now()
 
        user_log.user_ip = ipaddr
 
        sa.add(user_log)
 
        sa.commit()
 

	
 
        log.info('Adding user %s, action %s on %s', user_obj, action, repo)
 
        if commit:
 
            sa.commit()
 
    except:
 
        log.error(traceback.format_exc())
 
        sa.rollback()
 
        raise
 

	
 

	
 
def get_repos(path, recursive=False):
rhodecode/model/forms.py
Show inline comments
 
@@ -185,7 +185,7 @@ class ValidPassword(formencode.validator
 
class ValidPasswordsMatch(formencode.validators.FancyValidator):
 

	
 
    def validate_python(self, value, state):
 
        
 

	
 
        pass_val = value.get('password') or value.get('new_password')
 
        if pass_val != value['password_confirmation']:
 
            e_dict = {'password_confirmation':
 
@@ -198,7 +198,7 @@ class ValidAuth(formencode.validators.Fa
 
        'invalid_login':_('invalid user name'),
 
        'disabled_account':_('Your account is disabled')
 
    }
 
    
 

	
 
    # error mapping
 
    e_dict = {'username':messages['invalid_login'],
 
              'password':messages['invalid_password']}
 
@@ -208,7 +208,7 @@ class ValidAuth(formencode.validators.Fa
 
        password = value['password']
 
        username = value['username']
 
        user = User.get_by_username(username)
 
        
 

	
 
        if authenticate(username, password):
 
            return value
 
        else:
 
@@ -254,7 +254,7 @@ def ValidRepoName(edit, old_data):
 
                # db key This is an actual just the name to store in the
 
                # database
 
                repo_name_full = group_path + RepoGroup.url_sep() + repo_name
 
                
 

	
 
            else:
 
                group_path = ''
 
                repo_name_full = repo_name
 
@@ -289,24 +289,8 @@ def ValidRepoName(edit, old_data):
 

	
 
    return _ValidRepoName
 

	
 
def ValidForkName():
 
    class _ValidForkName(formencode.validators.FancyValidator):
 
        def to_python(self, value, state):
 

	
 
            repo_name = value.get('fork_name')
 

	
 
            slug = repo_name_slug(repo_name)
 
            if slug in [ADMIN_PREFIX, '']:
 
                e_dict = {'repo_name': _('This repository name is disallowed')}
 
                raise formencode.Invalid('', value, state, error_dict=e_dict)
 

	
 
            if RepoModel().get_by_repo_name(repo_name):
 
                e_dict = {'fork_name':_('This repository '
 
                                        'already exists')}
 
                raise formencode.Invalid('', value, state,
 
                                         error_dict=e_dict)
 
            return value
 
    return _ValidForkName
 
def ValidForkName(*args, **kwargs):
 
    return ValidRepoName(*args, **kwargs)
 

	
 

	
 
def SlugifyName():
 
@@ -513,7 +497,7 @@ def UserForm(edit=False, old_data={}):
 
        else:
 
            password = All(UnicodeString(strip=True, min=6, not_empty=True))
 
            password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=False))
 
            
 

	
 
        active = StringBoolean(if_missing=False)
 
        name = UnicodeString(strip=True, min=1, not_empty=True)
 
        lastname = UnicodeString(strip=True, min=1, not_empty=True)
 
@@ -605,17 +589,20 @@ def RepoForm(edit=False, old_data={}, su
 
        chained_validators = [ValidRepoName(edit, old_data), ValidPerms]
 
    return _RepoForm
 

	
 
def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
 
def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
 
                 repo_groups=[]):
 
    class _RepoForkForm(formencode.Schema):
 
        allow_extra_fields = True
 
        filter_extra_fields = False
 
        fork_name = All(UnicodeString(strip=True, min=1, not_empty=True),
 
        repo_name = All(UnicodeString(strip=True, min=1, not_empty=True),
 
                        SlugifyName())
 
        repo_group = OneOf(repo_groups, hideList=True)
 
        repo_type = All(ValidForkType(old_data), OneOf(supported_backends))
 
        description = UnicodeString(strip=True, min=1, not_empty=True)
 
        private = StringBoolean(if_missing=False)
 
        repo_type = All(ValidForkType(old_data), OneOf(supported_backends))
 

	
 
        chained_validators = [ValidForkName()]
 
        copy_permissions = StringBoolean(if_missing=False)
 
        fork_parent_id = UnicodeString()
 
        chained_validators = [ValidForkName(edit, old_data)]
 

	
 
    return _RepoForkForm
 

	
 
@@ -630,7 +617,7 @@ def RepoSettingsForm(edit=False, old_dat
 
        repo_group = OneOf(repo_groups, hideList=True)
 
        private = StringBoolean(if_missing=False)
 

	
 
        chained_validators = [ValidRepoName(edit, old_data), ValidPerms, 
 
        chained_validators = [ValidRepoName(edit, old_data), ValidPerms,
 
                              ValidSettings]
 
    return _RepoForm
 

	
rhodecode/model/notification.py
Show inline comments
 
@@ -35,8 +35,6 @@ from pylons.i18n.translation import _
 
from rhodecode.lib import helpers as h
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import Notification, User, UserNotification
 
from rhodecode.lib.celerylib import run_task
 
from rhodecode.lib.celerylib.tasks import send_email
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -74,6 +72,7 @@ class NotificationModel(BaseModel):
 
        :param recipients: list of int, str or User objects
 
        :param type_: type of notification
 
        """
 
        from rhodecode.lib.celerylib import tasks, run_task
 

	
 
        if not getattr(recipients, '__iter__', False):
 
            raise Exception('recipients must be a list of iterable')
 
@@ -100,7 +99,7 @@ class NotificationModel(BaseModel):
 
            email_body_html = EmailNotificationModel()\
 
                            .get_email_tmpl(type_, **{'subject':subject,
 
                                                      'body':h.rst(body)})
 
            run_task(send_email, rec.email, email_subject, email_body,
 
            run_task(tasks.send_email, rec.email, email_subject, email_body,
 
                     email_body_html)
 

	
 
        return notif
rhodecode/model/repo.py
Show inline comments
 
@@ -212,36 +212,33 @@ class RepoModel(BaseModel):
 
            raise
 

	
 
    def create(self, form_data, cur_user, just_db=False, fork=False):
 
        from rhodecode.model.scm import ScmModel
 

	
 
        try:
 
            if fork:
 
                repo_name = form_data['fork_name']
 
                org_name = form_data['repo_name']
 
                org_full_name = org_name
 
                fork_parent_id = form_data['fork_parent_id']
 

	
 
            else:
 
                org_name = repo_name = form_data['repo_name']
 
                repo_name_full = form_data['repo_name_full']
 
            # repo name is just a name of repository
 
            # while repo_name_full is a full qualified name that is combined
 
            # with name and path of group
 
            repo_name = form_data['repo_name']
 
            repo_name_full = form_data['repo_name_full']
 

	
 
            new_repo = Repository()
 
            new_repo.enable_statistics = False
 

	
 
            for k, v in form_data.items():
 
                if k == 'repo_name':
 
                    if fork:
 
                        v = repo_name
 
                    else:
 
                        v = repo_name_full
 
                    v = repo_name_full
 
                if k == 'repo_group':
 
                    k = 'group_id'
 

	
 
                if k == 'description':
 
                    v = v or repo_name
 

	
 
                setattr(new_repo, k, v)
 

	
 
            if fork:
 
                parent_repo = self.sa.query(Repository)\
 
                        .filter(Repository.repo_name == org_full_name).one()
 
                parent_repo = Repository.get(fork_parent_id)
 
                new_repo.fork = parent_repo
 

	
 
            new_repo.user_id = cur_user.user_id
 
@@ -271,19 +268,21 @@ class RepoModel(BaseModel):
 
                                   form_data['repo_group'],
 
                                   form_data['clone_uri'])
 

	
 
            self.sa.commit()
 

	
 
            #now automatically start following this repository as owner
 
            from rhodecode.model.scm import ScmModel
 
            # now automatically start following this repository as owner
 
            ScmModel(self.sa).toggle_following_repo(new_repo.repo_id,
 
                                             cur_user.user_id)
 
                                                    cur_user.user_id)
 
            return new_repo
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def create_fork(self, form_data, cur_user):
 
        """
 
        Simple wrapper into executing celery task for fork creation
 
        
 
        :param form_data:
 
        :param cur_user:
 
        """
 
        from rhodecode.lib.celerylib import tasks, run_task
 
        run_task(tasks.create_repo_fork, form_data, cur_user)
 

	
 
@@ -325,6 +324,11 @@ class RepoModel(BaseModel):
 
            raise
 

	
 
    def delete_stats(self, repo_name):
 
        """
 
        removes stats for given repo
 
        
 
        :param repo_name:
 
        """
 
        try:
 
            obj = self.sa.query(Statistics)\
 
                    .filter(Statistics.repository == \
rhodecode/model/scm.py
Show inline comments
 
@@ -208,17 +208,14 @@ class ScmModel(BaseModel):
 
            .filter(UserFollowing.user_id == user_id).scalar()
 

	
 
        if f is not None:
 

	
 
            try:
 
                self.sa.delete(f)
 
                self.sa.commit()
 
                action_logger(UserTemp(user_id),
 
                              'stopped_following_repo',
 
                              RepoTemp(follow_repo_id))
 
                return
 
            except:
 
                log.error(traceback.format_exc())
 
                self.sa.rollback()
 
                raise
 

	
 
        try:
 
@@ -226,13 +223,12 @@ class ScmModel(BaseModel):
 
            f.user_id = user_id
 
            f.follows_repo_id = follow_repo_id
 
            self.sa.add(f)
 
            self.sa.commit()
 

	
 
            action_logger(UserTemp(user_id),
 
                          'started_following_repo',
 
                          RepoTemp(follow_repo_id))
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def toggle_following_user(self, follow_user_id, user_id):
 
@@ -243,11 +239,9 @@ class ScmModel(BaseModel):
 
        if f is not None:
 
            try:
 
                self.sa.delete(f)
 
                self.sa.commit()
 
                return
 
            except:
 
                log.error(traceback.format_exc())
 
                self.sa.rollback()
 
                raise
 

	
 
        try:
 
@@ -255,10 +249,8 @@ class ScmModel(BaseModel):
 
            f.user_id = user_id
 
            f.follows_user_id = follow_user_id
 
            self.sa.add(f)
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def is_following_repo(self, repo_name, user_id, cache=False):
 
@@ -317,8 +309,8 @@ class ScmModel(BaseModel):
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def commit_change(self, repo, repo_name, cs, user, author, message, content,
 
                      f_path):
 
    def commit_change(self, repo, repo_name, cs, user, author, message,
 
                      content, f_path):
 

	
 
        if repo.alias == 'hg':
 
            from vcs.backends.hg import MercurialInMemoryChangeset as IMC
rhodecode/public/css/style.css
Show inline comments
 
@@ -1790,6 +1790,10 @@ div.form div.fields div.field div.button
 
	padding: 0 !important;
 
}
 
 
.trending_language_tbl,.trending_language_tbl tr {
 
    border-spacing: 1px;
 
}
 
 
.trending_language {
 
	background-color: #003367;
 
	color: #FFF;
 
@@ -1797,7 +1801,7 @@ div.form div.fields div.field div.button
 
	min-width: 20px;
 
	text-decoration: none;
 
	height: 12px;
 
	margin-bottom: 4px;
 
	margin-bottom: 0px;
 
	margin-left: 5px;
 
	white-space: pre;
 
	padding: 3px;
rhodecode/templates/forks/fork.html
Show inline comments
 
file renamed from rhodecode/templates/settings/repo_fork.html to rhodecode/templates/forks/fork.html
 
@@ -27,14 +27,23 @@
 
        <!-- fields -->
 
        <div class="fields">
 
            <div class="field">
 
	            <div class="label">
 
	                <label for="repo_name">${_('Fork name')}:</label>
 
	            </div>
 
	            <div class="input">
 
	                ${h.text('fork_name',class_="small")}
 
	                ${h.hidden('repo_type',c.repo_info.repo_type)}
 
	            </div>
 
             </div>
 
              <div class="label">
 
                  <label for="repo_name">${_('Fork name')}:</label>
 
              </div>
 
              <div class="input">
 
                  ${h.text('repo_name',class_="small")}
 
                  ${h.hidden('repo_type',c.repo_info.repo_type)}
 
                  ${h.hidden('fork_parent_id',c.repo_info.repo_id)}
 
              </div>
 
            </div>
 
            <div class="field">
 
                 <div class="label">
 
                     <label for="repo_group">${_('Repository group')}:</label>
 
                 </div>
 
                 <div class="input">
 
                     ${h.select('repo_group','',c.repo_groups,class_="medium")}
 
                 </div>
 
            </div>                 
 
            <div class="field">
 
                <div class="label label-textarea">
 
                    <label for="description">${_('Description')}:</label>
 
@@ -50,7 +59,15 @@
 
                <div class="checkboxes">
 
                    ${h.checkbox('private',value="True")}
 
                </div>
 
             </div>
 
            </div>
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="private">${_('Copy permissions')}:</label>
 
                </div>
 
                <div class="checkboxes">
 
                    ${h.checkbox('copy_permissions',value="True")}
 
                </div>
 
             </div>             
 
	        <div class="buttons">
 
	          ${h.submit('',_('fork this repository'),class_="ui-button")}
 
	        </div>                                                          
0 comments (0 inline, 0 general)