repo.py
705 lines
| 25.7 KiB
| text/x-python
|
PythonLexer
r786 | # -*- coding: utf-8 -*- | |||
""" | ||||
r811 | rhodecode.model.repo | |||
~~~~~~~~~~~~~~~~~~~~ | ||||
r786 | ||||
Repository model for rhodecode | ||||
r1203 | ||||
r786 | :created_on: Jun 5, 2010 | |||
:author: marcink | ||||
r1824 | :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> | |||
r786 | :license: GPLv3, see COPYING for more details. | |||
""" | ||||
r1206 | # This program is free software: you can redistribute it and/or modify | |||
# it under the terms of the GNU General Public License as published by | ||||
# the Free Software Foundation, either version 3 of the License, or | ||||
# (at your option) any later version. | ||||
r1203 | # | |||
r629 | # This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
# GNU General Public License for more details. | ||||
r1203 | # | |||
r629 | # You should have received a copy of the GNU General Public License | |||
r1206 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
r2404 | from __future__ import with_statement | |||
r786 | import os | |||
import shutil | ||||
import logging | ||||
import traceback | ||||
r629 | from datetime import datetime | |||
r786 | ||||
r2007 | from rhodecode.lib.vcs.backends import get_backend | |||
r2142 | from rhodecode.lib.compat import json | |||
r3089 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode,\ | |||
remove_prefix | ||||
r1669 | from rhodecode.lib.caching_query import FromCache | |||
r2904 | from rhodecode.lib.hooks import log_create_repository, log_delete_repository | |||
r1401 | ||||
r786 | from rhodecode.model import BaseModel | |||
r1633 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ | |||
r3056 | Statistics, UsersGroup, UsersGroupRepoToPerm, RhodeCodeUi, RepoGroup,\ | |||
r3308 | RhodeCodeSetting, RepositoryField | |||
r2142 | from rhodecode.lib import helpers as h | |||
r3154 | from rhodecode.lib.auth import HasRepoPermissionAny | |||
r3309 | from rhodecode.lib.vcs.backends.base import EmptyChangeset | |||
r786 | ||||
r1982 | ||||
r629 | log = logging.getLogger(__name__) | |||
r1271 | ||||
r752 | class RepoModel(BaseModel): | |||
r629 | ||||
r2522 | cls = Repository | |||
r2524 | URL_SEPARATOR = Repository.url_sep() | |||
r2522 | ||||
r1982 | def __get_users_group(self, users_group): | |||
return self._get_instance(UsersGroup, users_group, | ||||
callback=UsersGroup.get_by_group_name) | ||||
r2631 | def _get_repos_group(self, repos_group): | |||
r1982 | return self._get_instance(RepoGroup, repos_group, | |||
callback=RepoGroup.get_by_group_name) | ||||
r1036 | @LazyProperty | |||
def repos_path(self): | ||||
r1716 | """ | |||
Get's the repositories root path from database | ||||
r1036 | """ | |||
r1017 | ||||
r1036 | q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one() | |||
return q.ui_value | ||||
r1013 | ||||
r629 | def get(self, repo_id, cache=False): | |||
repo = self.sa.query(Repository)\ | ||||
r735 | .filter(Repository.repo_id == repo_id) | |||
r629 | ||||
if cache: | ||||
repo = repo.options(FromCache("sql_cache_short", | ||||
r735 | "get_repo_%s" % repo_id)) | |||
r629 | return repo.scalar() | |||
r2010 | def get_repo(self, repository): | |||
r2432 | return self._get_repo(repository) | |||
r2010 | ||||
r735 | def get_by_repo_name(self, repo_name, cache=False): | |||
repo = self.sa.query(Repository)\ | ||||
.filter(Repository.repo_name == repo_name) | ||||
if cache: | ||||
repo = repo.options(FromCache("sql_cache_short", | ||||
"get_repo_%s" % repo_name)) | ||||
r752 | return repo.scalar() | |||
r735 | ||||
r3163 | def get_all_user_repos(self, user): | |||
""" | ||||
Get's all repositories that user have at least read access | ||||
:param user: | ||||
:type user: | ||||
""" | ||||
from rhodecode.lib.auth import AuthUser | ||||
user = self._get_user(user) | ||||
repos = AuthUser(user_id=user.user_id).permissions['repositories'] | ||||
access_check = lambda r: r[1] in ['repository.read', | ||||
'repository.write', | ||||
'repository.admin'] | ||||
repos = [x[0] for x in filter(access_check, repos.items())] | ||||
return Repository.query().filter(Repository.repo_name.in_(repos)) | ||||
r629 | def get_users_js(self): | |||
users = self.sa.query(User).filter(User.active == True).all() | ||||
r2142 | return json.dumps([ | |||
{ | ||||
'id': u.user_id, | ||||
'fname': u.name, | ||||
'lname': u.lastname, | ||||
'nname': u.username, | ||||
'gravatar_lnk': h.gravatar_url(u.email, 14) | ||||
} for u in users] | ||||
) | ||||
r629 | ||||
r1013 | def get_users_groups_js(self): | |||
users_groups = self.sa.query(UsersGroup)\ | ||||
.filter(UsersGroup.users_group_active == True).all() | ||||
r2142 | return json.dumps([ | |||
{ | ||||
'id': gr.users_group_id, | ||||
'grname': gr.users_group_name, | ||||
'grmembers': len(gr.members), | ||||
} for gr in users_groups] | ||||
) | ||||
r1013 | ||||
r3154 | @classmethod | |||
def _render_datatable(cls, tmpl, *args, **kwargs): | ||||
import rhodecode | ||||
from pylons import tmpl_context as c | ||||
from pylons.i18n.translation import _ | ||||
_tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup | ||||
template = _tmpl_lookup.get_template('data_table/_dt_elements.html') | ||||
tmpl = template.get_def(tmpl) | ||||
kwargs.update(dict(_=_, h=h, c=c)) | ||||
return tmpl.render(*args, **kwargs) | ||||
r3309 | @classmethod | |||
def update_repoinfo(cls, repositories=None): | ||||
if not repositories: | ||||
repositories = Repository.getAll() | ||||
for repo in repositories: | ||||
scm_repo = repo.scm_instance_no_cache | ||||
last_cs = EmptyChangeset() | ||||
if scm_repo: | ||||
last_cs = scm_repo.get_changeset() | ||||
repo.update_changeset_cache(last_cs) | ||||
r3245 | def get_repos_as_dict(self, repos_list=None, admin=False, perm_check=True, | |||
super_user_actions=False): | ||||
r3154 | _render = self._render_datatable | |||
def quick_menu(repo_name): | ||||
return _render('quick_menu', repo_name) | ||||
def repo_lnk(name, rtype, private, fork_of): | ||||
return _render('repo_name', name, rtype, private, fork_of, | ||||
short_name=not admin, admin=False) | ||||
def last_change(last_change): | ||||
return _render("last_change", last_change) | ||||
def rss_lnk(repo_name): | ||||
return _render("rss", repo_name) | ||||
def atom_lnk(repo_name): | ||||
return _render("atom", repo_name) | ||||
def last_rev(repo_name, cs_cache): | ||||
return _render('revision', repo_name, cs_cache.get('revision'), | ||||
cs_cache.get('raw_id'), cs_cache.get('author'), | ||||
cs_cache.get('message')) | ||||
def desc(desc): | ||||
from pylons import tmpl_context as c | ||||
if c.visual.stylify_metatags: | ||||
return h.urlify_text(h.desc_stylize(h.truncate(desc, 60))) | ||||
else: | ||||
return h.urlify_text(h.truncate(desc, 60)) | ||||
def repo_actions(repo_name): | ||||
r3245 | return _render('repo_actions', repo_name, super_user_actions) | |||
r3154 | ||||
def owner_actions(user_id, username): | ||||
return _render('user_name', user_id, username) | ||||
repos_data = [] | ||||
for repo in repos_list: | ||||
if perm_check: | ||||
# check permission at this level | ||||
if not HasRepoPermissionAny( | ||||
'repository.read', 'repository.write', 'repository.admin' | ||||
)(repo.repo_name, 'get_repos_as_dict check'): | ||||
continue | ||||
cs_cache = repo.changeset_cache | ||||
row = { | ||||
"menu": quick_menu(repo.repo_name), | ||||
"raw_name": repo.repo_name.lower(), | ||||
"name": repo_lnk(repo.repo_name, repo.repo_type, | ||||
repo.private, repo.fork), | ||||
"last_change": last_change(repo.last_db_change), | ||||
"last_changeset": last_rev(repo.repo_name, cs_cache), | ||||
"raw_tip": cs_cache.get('revision'), | ||||
"desc": desc(repo.description), | ||||
"owner": h.person(repo.user.username), | ||||
"rss": rss_lnk(repo.repo_name), | ||||
"atom": atom_lnk(repo.repo_name), | ||||
} | ||||
if admin: | ||||
row.update({ | ||||
"action": repo_actions(repo.repo_name), | ||||
"owner": owner_actions(repo.user.user_id, | ||||
h.person(repo.user.username)) | ||||
}) | ||||
repos_data.append(row) | ||||
return { | ||||
"totalRecords": len(repos_list), | ||||
"startIndex": 0, | ||||
"sort": "name", | ||||
"dir": "asc", | ||||
"records": repos_data | ||||
} | ||||
r1594 | def _get_defaults(self, repo_name): | |||
""" | ||||
r1818 | Get's information about repository, and returns a dict for | |||
r1594 | usage in forms | |||
r1818 | ||||
r1594 | :param repo_name: | |||
""" | ||||
repo_info = Repository.get_by_repo_name(repo_name) | ||||
if repo_info is None: | ||||
return None | ||||
defaults = repo_info.get_dict() | ||||
group, repo_name = repo_info.groups_and_repo | ||||
defaults['repo_name'] = repo_name | ||||
defaults['repo_group'] = getattr(group[-1] if group else None, | ||||
'group_id', None) | ||||
r3089 | for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'), | |||
(1, 'repo_description'), (1, 'repo_enable_locking'), | ||||
(1, 'repo_landing_rev'), (0, 'clone_uri'), | ||||
(1, 'repo_private'), (1, 'repo_enable_statistics')]: | ||||
attr = k | ||||
if strip: | ||||
attr = remove_prefix(k, 'repo_') | ||||
defaults[k] = defaults[attr] | ||||
r1594 | # fill owner | |||
if repo_info.user: | ||||
defaults.update({'user': repo_info.user.username}) | ||||
else: | ||||
replacement_user = User.query().filter(User.admin == | ||||
True).first().username | ||||
defaults.update({'user': replacement_user}) | ||||
# fill repository users | ||||
for p in repo_info.repo_to_perm: | ||||
defaults.update({'u_perm_%s' % p.user.username: | ||||
p.permission.permission_name}) | ||||
# fill repository groups | ||||
for p in repo_info.users_group_to_perm: | ||||
defaults.update({'g_perm_%s' % p.users_group.users_group_name: | ||||
p.permission.permission_name}) | ||||
return defaults | ||||
r3089 | def update(self, org_repo_name, **kwargs): | |||
r629 | try: | |||
r3089 | cur_repo = self.get_by_repo_name(org_repo_name, cache=False) | |||
r629 | ||||
r1539 | # update permissions | |||
r3089 | for member, perm, member_type in kwargs['perms_updates']: | |||
r1014 | if member_type == 'user': | |||
r1982 | # this updates existing one | |||
RepoModel().grant_user_permission( | ||||
repo=cur_repo, user=member, perm=perm | ||||
) | ||||
r1014 | else: | |||
r1982 | RepoModel().grant_users_group_permission( | |||
repo=cur_repo, group_name=member, perm=perm | ||||
) | ||||
r1539 | # set new permissions | |||
r3089 | for member, perm, member_type in kwargs['perms_new']: | |||
r1014 | if member_type == 'user': | |||
r1982 | RepoModel().grant_user_permission( | |||
repo=cur_repo, user=member, perm=perm | ||||
) | ||||
r1014 | else: | |||
r1982 | RepoModel().grant_users_group_permission( | |||
repo=cur_repo, group_name=member, perm=perm | ||||
) | ||||
r629 | ||||
r3089 | if 'user' in kwargs: | |||
cur_repo.user = User.get_by_username(kwargs['user']) | ||||
if 'repo_group' in kwargs: | ||||
cur_repo.group = RepoGroup.get(kwargs['repo_group']) | ||||
r1323 | ||||
r3089 | for strip, k in [(0, 'repo_type'), (1, 'repo_enable_downloads'), | |||
(1, 'repo_description'), (1, 'repo_enable_locking'), | ||||
(1, 'repo_landing_rev'), (0, 'clone_uri'), | ||||
(1, 'repo_private'), (1, 'repo_enable_statistics')]: | ||||
if k in kwargs: | ||||
val = kwargs[k] | ||||
if strip: | ||||
k = remove_prefix(k, 'repo_') | ||||
setattr(cur_repo, k, val) | ||||
r629 | ||||
r3089 | new_name = cur_repo.get_new_name(kwargs['repo_name']) | |||
r1539 | cur_repo.repo_name = new_name | |||
r3308 | #handle extra fields | |||
for field in filter(lambda k: k.startswith(RepositoryField.PREFIX), kwargs): | ||||
k = RepositoryField.un_prefix_key(field) | ||||
ex_field = RepositoryField.get_by_key_name(key=k, repo=cur_repo) | ||||
if ex_field: | ||||
ex_field.field_value = kwargs[field] | ||||
self.sa.add(ex_field) | ||||
r629 | self.sa.add(cur_repo) | |||
r3089 | if org_repo_name != new_name: | |||
r1323 | # rename repository | |||
r3089 | self.__rename_repo(old=org_repo_name, new=new_name) | |||
r629 | ||||
r1539 | return cur_repo | |||
r629 | except: | |||
log.error(traceback.format_exc()) | ||||
raise | ||||
r2524 | def create_repo(self, repo_name, repo_type, description, owner, | |||
private=False, clone_uri=None, repos_group=None, | ||||
landing_rev='tip', just_db=False, fork_of=None, | ||||
r3056 | copy_fork_permissions=False, enable_statistics=False, | |||
enable_locking=False, enable_downloads=False): | ||||
r2652 | """ | |||
Create repository | ||||
""" | ||||
r1722 | from rhodecode.model.scm import ScmModel | |||
r1366 | ||||
r2524 | owner = self._get_user(owner) | |||
fork_of = self._get_repo(fork_of) | ||||
r2631 | repos_group = self._get_repos_group(repos_group) | |||
r629 | try: | |||
r1722 | # 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 | ||||
r2529 | repo_name_full = repo_name | |||
r2524 | repo_name = repo_name.split(self.URL_SEPARATOR)[-1] | |||
r1361 | ||||
r629 | new_repo = Repository() | |||
r1075 | new_repo.enable_statistics = False | |||
r2524 | new_repo.repo_name = repo_name_full | |||
new_repo.repo_type = repo_type | ||||
new_repo.user = owner | ||||
r2529 | new_repo.group = repos_group | |||
r2524 | new_repo.description = description or repo_name | |||
new_repo.private = private | ||||
new_repo.clone_uri = clone_uri | ||||
new_repo.landing_rev = landing_rev | ||||
r1722 | ||||
r3056 | new_repo.enable_statistics = enable_statistics | |||
new_repo.enable_locking = enable_locking | ||||
new_repo.enable_downloads = enable_downloads | ||||
r2755 | if repos_group: | |||
new_repo.enable_locking = repos_group.enable_locking | ||||
r2524 | if fork_of: | |||
parent_repo = fork_of | ||||
r629 | new_repo.fork = parent_repo | |||
self.sa.add(new_repo) | ||||
r1729 | def _create_default_perms(): | |||
# create default permission | ||||
repo_to_perm = UserRepoToPerm() | ||||
default = 'repository.read' | ||||
for p in User.get_by_username('default').user_perms: | ||||
if p.permission.permission_name.startswith('repository.'): | ||||
default = p.permission.permission_name | ||||
break | ||||
r2524 | default_perm = 'repository.none' if private else default | |||
r1729 | ||||
repo_to_perm.permission_id = self.sa.query(Permission)\ | ||||
.filter(Permission.permission_name == default_perm)\ | ||||
.one().permission_id | ||||
repo_to_perm.repository = new_repo | ||||
repo_to_perm.user_id = User.get_by_username('default').user_id | ||||
self.sa.add(repo_to_perm) | ||||
r629 | ||||
r2524 | if fork_of: | |||
if copy_fork_permissions: | ||||
repo = fork_of | ||||
r1729 | user_perms = UserRepoToPerm.query()\ | |||
.filter(UserRepoToPerm.repository == repo).all() | ||||
group_perms = UsersGroupRepoToPerm.query()\ | ||||
.filter(UsersGroupRepoToPerm.repository == repo).all() | ||||
r629 | ||||
r1729 | for perm in user_perms: | |||
UserRepoToPerm.create(perm.user, new_repo, | ||||
perm.permission) | ||||
r629 | ||||
r1729 | for perm in group_perms: | |||
UsersGroupRepoToPerm.create(perm.users_group, new_repo, | ||||
perm.permission) | ||||
else: | ||||
_create_default_perms() | ||||
else: | ||||
_create_default_perms() | ||||
r1028 | ||||
if not just_db: | ||||
r2524 | self.__create_repo(repo_name, repo_type, | |||
r2529 | repos_group, | |||
r2524 | clone_uri) | |||
r2185 | log_create_repository(new_repo.get_dict(), | |||
r2524 | created_by=owner.username) | |||
r2621 | ||||
r1722 | # now automatically start following this repository as owner | |||
r786 | ScmModel(self.sa).toggle_following_repo(new_repo.repo_id, | |||
r2524 | owner.user_id) | |||
r1539 | return new_repo | |||
r629 | except: | |||
log.error(traceback.format_exc()) | ||||
raise | ||||
r2524 | def create(self, form_data, cur_user, just_db=False, fork=None): | |||
r2652 | """ | |||
Backward compatibility function, just a wrapper on top of create_repo | ||||
:param form_data: | ||||
:param cur_user: | ||||
:param just_db: | ||||
:param fork: | ||||
""" | ||||
r3056 | owner = cur_user | |||
r2524 | repo_name = form_data['repo_name_full'] | |||
repo_type = form_data['repo_type'] | ||||
r3056 | description = form_data['repo_description'] | |||
private = form_data['repo_private'] | ||||
r2524 | clone_uri = form_data.get('clone_uri') | |||
repos_group = form_data['repo_group'] | ||||
r3056 | landing_rev = form_data['repo_landing_rev'] | |||
r2524 | copy_fork_permissions = form_data.get('copy_permissions') | |||
fork_of = form_data.get('fork_parent_id') | ||||
r3056 | ||||
r3115 | ## repo creation defaults, private and repo_type are filled in form | |||
r3056 | defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True) | |||
r3115 | enable_statistics = defs.get('repo_enable_statistics') | |||
r3056 | enable_locking = defs.get('repo_enable_locking') | |||
enable_downloads = defs.get('repo_enable_downloads') | ||||
r2524 | return self.create_repo( | |||
repo_name, repo_type, description, owner, private, clone_uri, | ||||
r3056 | repos_group, landing_rev, just_db, fork_of, copy_fork_permissions, | |||
enable_statistics, enable_locking, enable_downloads | ||||
r2524 | ) | |||
r629 | def create_fork(self, form_data, cur_user): | |||
r1722 | """ | |||
Simple wrapper into executing celery task for fork creation | ||||
r1818 | ||||
r1722 | :param form_data: | |||
:param cur_user: | ||||
""" | ||||
r629 | from rhodecode.lib.celerylib import tasks, run_task | |||
run_task(tasks.create_repo_fork, form_data, cur_user) | ||||
def delete(self, repo): | ||||
r2432 | repo = self._get_repo(repo) | |||
r2524 | if repo: | |||
r2904 | old_repo_dict = repo.get_dict() | |||
owner = repo.user | ||||
r2524 | try: | |||
self.sa.delete(repo) | ||||
self.__delete_repo(repo) | ||||
r2904 | log_delete_repository(old_repo_dict, | |||
deleted_by=owner.username) | ||||
r2524 | except: | |||
log.error(traceback.format_exc()) | ||||
raise | ||||
r629 | ||||
r1982 | def grant_user_permission(self, repo, user, perm): | |||
""" | ||||
Grant permission for user on given repository, or update existing one | ||||
if found | ||||
:param repo: Instance of Repository, repository_id, or repository name | ||||
:param user: Instance of User, user_id or username | ||||
:param perm: Instance of Permission, or permission_name | ||||
""" | ||||
r2432 | user = self._get_user(user) | |||
repo = self._get_repo(repo) | ||||
permission = self._get_perm(perm) | ||||
r1982 | ||||
# check if we have that permission already | ||||
obj = self.sa.query(UserRepoToPerm)\ | ||||
.filter(UserRepoToPerm.user == user)\ | ||||
.filter(UserRepoToPerm.repository == repo)\ | ||||
.scalar() | ||||
if obj is None: | ||||
# create new ! | ||||
obj = UserRepoToPerm() | ||||
obj.repository = repo | ||||
obj.user = user | ||||
obj.permission = permission | ||||
self.sa.add(obj) | ||||
r2820 | log.debug('Granted perm %s to %s on %s' % (perm, user, repo)) | |||
r1982 | ||||
def revoke_user_permission(self, repo, user): | ||||
""" | ||||
Revoke permission for user on given repository | ||||
:param repo: Instance of Repository, repository_id, or repository name | ||||
:param user: Instance of User, user_id or username | ||||
""" | ||||
r2142 | ||||
r2432 | user = self._get_user(user) | |||
repo = self._get_repo(repo) | ||||
r1982 | ||||
obj = self.sa.query(UserRepoToPerm)\ | ||||
.filter(UserRepoToPerm.repository == repo)\ | ||||
.filter(UserRepoToPerm.user == user)\ | ||||
r2820 | .scalar() | |||
if obj: | ||||
self.sa.delete(obj) | ||||
log.debug('Revoked perm on %s on %s' % (repo, user)) | ||||
r629 | ||||
r1982 | def grant_users_group_permission(self, repo, group_name, perm): | |||
""" | ||||
Grant permission for users group on given repository, or update | ||||
existing one if found | ||||
:param repo: Instance of Repository, repository_id, or repository name | ||||
:param group_name: Instance of UserGroup, users_group_id, | ||||
or users group name | ||||
:param perm: Instance of Permission, or permission_name | ||||
""" | ||||
r2432 | repo = self._get_repo(repo) | |||
r1982 | group_name = self.__get_users_group(group_name) | |||
r2432 | permission = self._get_perm(perm) | |||
r1982 | ||||
# check if we have that permission already | ||||
obj = self.sa.query(UsersGroupRepoToPerm)\ | ||||
.filter(UsersGroupRepoToPerm.users_group == group_name)\ | ||||
.filter(UsersGroupRepoToPerm.repository == repo)\ | ||||
.scalar() | ||||
if obj is None: | ||||
# create new | ||||
obj = UsersGroupRepoToPerm() | ||||
obj.repository = repo | ||||
obj.users_group = group_name | ||||
obj.permission = permission | ||||
self.sa.add(obj) | ||||
r2820 | log.debug('Granted perm %s to %s on %s' % (perm, group_name, repo)) | |||
r1982 | ||||
def revoke_users_group_permission(self, repo, group_name): | ||||
""" | ||||
Revoke permission for users group on given repository | ||||
:param repo: Instance of Repository, repository_id, or repository name | ||||
:param group_name: Instance of UserGroup, users_group_id, | ||||
or users group name | ||||
""" | ||||
r2432 | repo = self._get_repo(repo) | |||
r1982 | group_name = self.__get_users_group(group_name) | |||
obj = self.sa.query(UsersGroupRepoToPerm)\ | ||||
.filter(UsersGroupRepoToPerm.repository == repo)\ | ||||
.filter(UsersGroupRepoToPerm.users_group == group_name)\ | ||||
r2820 | .scalar() | |||
if obj: | ||||
self.sa.delete(obj) | ||||
log.debug('Revoked perm to %s on %s' % (repo, group_name)) | ||||
r1015 | ||||
r708 | def delete_stats(self, repo_name): | |||
r1722 | """ | |||
removes stats for given repo | ||||
r1818 | ||||
r1722 | :param repo_name: | |||
""" | ||||
r3314 | repo = self._get_repo(repo_name) | |||
r708 | try: | |||
r1713 | obj = self.sa.query(Statistics)\ | |||
r3314 | .filter(Statistics.repository == repo).scalar() | |||
if obj: | ||||
self.sa.delete(obj) | ||||
r708 | except: | |||
log.error(traceback.format_exc()) | ||||
raise | ||||
r2529 | def __create_repo(self, repo_name, alias, parent, clone_uri=False): | |||
r787 | """ | |||
r1361 | makes repository on filesystem. It's group aware means it'll create | |||
a repository within a group, and alter the paths accordingly of | ||||
group location | ||||
r1203 | ||||
r787 | :param repo_name: | |||
:param alias: | ||||
r1350 | :param parent_id: | |||
:param clone_uri: | ||||
r787 | """ | |||
r1594 | from rhodecode.lib.utils import is_valid_repo, is_valid_repos_group | |||
r2618 | from rhodecode.model.scm import ScmModel | |||
r1517 | ||||
r2529 | if parent: | |||
new_parent_path = os.sep.join(parent.full_path_splitted) | ||||
r1350 | else: | |||
new_parent_path = '' | ||||
r1973 | # we need to make it str for mercurial | |||
r1982 | repo_path = os.path.join(*map(lambda x: safe_str(x), | |||
r1401 | [self.repos_path, new_parent_path, repo_name])) | |||
r1350 | ||||
r1550 | # check if this path is not a repository | |||
if is_valid_repo(repo_path, self.repos_path): | ||||
raise Exception('This path %s is a valid repository' % repo_path) | ||||
r1401 | ||||
r1550 | # check if this path is a group | |||
if is_valid_repos_group(repo_path, self.repos_path): | ||||
raise Exception('This path %s is a valid group' % repo_path) | ||||
r1594 | ||||
r1973 | log.info('creating repo %s in %s @ %s' % ( | |||
repo_name, safe_unicode(repo_path), clone_uri | ||||
) | ||||
) | ||||
r1550 | backend = get_backend(alias) | |||
r2321 | if alias == 'hg': | |||
backend(repo_path, create=True, src_url=clone_uri) | ||||
elif alias == 'git': | ||||
r2404 | r = backend(repo_path, create=True, src_url=clone_uri, bare=True) | |||
# add rhodecode hook into this repo | ||||
r2618 | ScmModel().install_git_hook(repo=r) | |||
r2321 | else: | |||
raise Exception('Undefined alias %s' % alias) | ||||
r629 | ||||
def __rename_repo(self, old, new): | ||||
r787 | """ | |||
renames repository on filesystem | ||||
r1203 | ||||
r787 | :param old: old name | |||
:param new: new name | ||||
""" | ||||
r1976 | log.info('renaming repo from %s to %s' % (old, new)) | |||
r629 | ||||
r1036 | old_path = os.path.join(self.repos_path, old) | |||
new_path = os.path.join(self.repos_path, new) | ||||
r629 | if os.path.isdir(new_path): | |||
r1982 | raise Exception( | |||
'Was trying to rename to already existing dir %s' % new_path | ||||
) | ||||
r629 | shutil.move(old_path, new_path) | |||
r668 | def __delete_repo(self, repo): | |||
r787 | """ | |||
removes repo from filesystem, the removal is acctually made by | ||||
added rm__ prefix into dir, and rename internat .hg/.git dirs so this | ||||
repository is no longer valid for rhodecode, can be undeleted later on | ||||
by reverting the renames on this repository | ||||
r1203 | ||||
r787 | :param repo: repo object | |||
""" | ||||
r1036 | rm_path = os.path.join(self.repos_path, repo.repo_name) | |||
r1976 | log.info("Removing %s" % (rm_path)) | |||
r2327 | # disable hg/git internal that it doesn't get detected as repo | |||
r668 | alias = repo.repo_type | |||
r2327 | ||||
bare = getattr(repo.scm_instance, 'bare', False) | ||||
if not bare: | ||||
# skip this for bare git repos | ||||
shutil.move(os.path.join(rm_path, '.%s' % alias), | ||||
os.path.join(rm_path, 'rm__.%s' % alias)) | ||||
r1749 | # disable repo | |||
r2553 | _now = datetime.now() | |||
r2592 | _ms = str(_now.microsecond).rjust(6, '0') | |||
r2553 | _d = 'rm__%s__%s' % (_now.strftime('%Y%m%d_%H%M%S_' + _ms), | |||
r2949 | repo.just_name) | |||
if repo.group: | ||||
args = repo.group.full_path_splitted + [_d] | ||||
_d = os.path.join(*args) | ||||
r1982 | shutil.move(rm_path, os.path.join(self.repos_path, _d)) | |||