Changeset - 148360f533a4
.hgtags
Show inline comments
 
@@ -50,12 +50,13 @@ d998cc84cf726798486a438763053f0e1dc1b646
 
a5f0bc867edc88be23eb808693e5393a97d4c54a rhodecode-0.0.1.5.0
 
3259dc7caea48687eab018ee646ae6ad7e7ef377 rhodecode-0.0.1.5.1
 
efe23d6c178c11d575a0214181276a3452776e48 rhodecode-0.0.1.5.2
 
1a498b11f1540f5b94b6f6009298f5dc3eaad9e9 rhodecode-0.0.1.5.3
 
3447862ad8c9ceba85857774c526e39fde3a2281 rhodecode-0.0.1.5.4
 
c15d7b336af58df9f1bbc8f8957464e7ea618d4c rhodecode-0.0.1.6.0rc1
 
78b53ee0d247f90d51b028307ff5717851b6c265 rhodecode-0.0.1.6.0
 
351ad34d56321349ff5bd38f537bd768b8efef2e rhodecode-0.0.1.7.0
 
1f71ef689d2a3c9978cea6591a1f4e9107a5ca83 rhodecode-0.0.1.7.1
 
d17e88a1a88a29f6fac948c94498129e405a40d3 0.1
 
ad0ce803b40cb17fc3988373052943e041030b02 0.2
 
c6e32714336345403adf76abb6ebf9b8116fcdc7 0.2.1
 
14f488a5dc4ca6647bc6acf12534fd137e968aa8 0.2.2
docs/api/api.rst
Show inline comments
 
@@ -824,26 +824,27 @@ OUTPUT::
 
                "enable_statistics": "<bool>",
 
              },
 
            }
 
    error:  null
 

	
 

	
 
fork_repo
 
---------
 

	
 
Create a fork of the given repo. If using Celery, this will
 
return success message immediately and a fork will be created
 
asynchronously.
 
This command can only be executed using the api_key of a user with admin rights,
 
or that of a regular user with fork permission and at least read access to the repository.
 
This command can only be executed using the api_key of a user with admin
 
rights, or with the global fork permission, by a regular user with create
 
repository permission and at least read access to the repository.
 
Regular users cannot specify owner parameter.
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "fork_repo"
 
    args:     {
 
                "repoid" :          "<reponame or repo_id>",
 
                "fork_name":        "<forkname>",
 
                "owner":            "<username or user_id = Optional(=apiuser)>",
kallithea/__init__.py
Show inline comments
 
@@ -20,25 +20,25 @@ versioning implementation: http://www.py
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Apr 9, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, (C) 2014 Bradley M. Kuhn, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import sys
 
import platform
 

	
 
VERSION = (0, 2, 1)
 
VERSION = (0, 2, 2)
 
BACKENDS = {
 
    'hg': 'Mercurial repository',
 
    'git': 'Git repository',
 
}
 

	
 
CELERY_ON = False
 
CELERY_EAGER = False
 

	
 
# link to config for pylons
 
CONFIG = {}
 

	
 
# Linked module for extensions
kallithea/controllers/admin/my_account.py
Show inline comments
 
@@ -251,22 +251,22 @@ class MyAccountController(BaseController
 
        description = request.POST.get('description')
 
        ApiKeyModel().create(self.authuser.user_id, description, lifetime)
 
        Session().commit()
 
        h.flash(_("API key successfully created"), category='success')
 
        return redirect(url('my_account_api_keys'))
 

	
 
    def my_account_api_keys_delete(self):
 
        api_key = request.POST.get('del_api_key')
 
        user_id = self.authuser.user_id
 
        if request.POST.get('del_api_key_builtin'):
 
            user = User.get(user_id)
 
            if user:
 
                user.api_key = generate_api_key(user.username)
 
                user.api_key = generate_api_key()
 
                Session().add(user)
 
                Session().commit()
 
                h.flash(_("API key successfully reset"), category='success')
 
        elif api_key:
 
            ApiKeyModel().delete(api_key, self.authuser.user_id)
 
            Session().commit()
 
            h.flash(_("API key successfully deleted"), category='success')
 

	
 
        return redirect(url('my_account_api_keys'))
kallithea/controllers/admin/users.py
Show inline comments
 
@@ -308,25 +308,25 @@ class UsersController(BaseController):
 
        ApiKeyModel().create(c.user.user_id, description, lifetime)
 
        Session().commit()
 
        h.flash(_("API key successfully created"), category='success')
 
        return redirect(url('edit_user_api_keys', id=c.user.user_id))
 

	
 
    def delete_api_key(self, id):
 
        c.user = self._get_user_or_raise_if_default(id)
 

	
 
        api_key = request.POST.get('del_api_key')
 
        if request.POST.get('del_api_key_builtin'):
 
            user = User.get(c.user.user_id)
 
            if user:
 
                user.api_key = generate_api_key(user.username)
 
                user.api_key = generate_api_key()
 
                Session().add(user)
 
                Session().commit()
 
                h.flash(_("API key successfully reset"), category='success')
 
        elif api_key:
 
            ApiKeyModel().delete(api_key, c.user.user_id)
 
            Session().commit()
 
            h.flash(_("API key successfully deleted"), category='success')
 

	
 
        return redirect(url('edit_user_api_keys', id=c.user.user_id))
 

	
 
    def update_account(self, id):
 
        pass
kallithea/controllers/api/api.py
Show inline comments
 
@@ -1547,24 +1547,35 @@ class ApiController(JSONRPCController):
 
        :param landing_rev:
 
        :param enable_statistics:
 
        :param enable_locking:
 
        :param enable_downloads:
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasPermissionAnyApi('hg.admin')(user=apiuser):
 
            # check if we have admin permission for this repo !
 
            if not HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
 
                                                               repo_name=repo.repo_name):
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
            if (name != repo.repo_name and
 
                not HasPermissionAnyApi('hg.create.repository')(user=apiuser)
 
                ):
 
                raise JSONRPCError('no permission to create (or move) repositories')
 

	
 
            if not isinstance(owner, Optional):
 
                #forbid setting owner for non-admins
 
                raise JSONRPCError(
 
                    'Only Kallithea admin can specify `owner` param'
 
                )
 

	
 
        updates = {
 
            # update function requires this.
 
            'repo_name': repo.repo_name
 
        }
 
        repo_group = group
 
        if not isinstance(repo_group, Optional):
 
            repo_group = get_repo_group_or_error(repo_group)
 
            repo_group = repo_group.group_id
 
        try:
 
            store_update(updates, name, 'repo_name')
 
            store_update(updates, repo_group, 'repo_group')
 
            store_update(updates, owner, 'user')
 
@@ -1644,24 +1655,27 @@ class ApiController(JSONRPCController):
 

	
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser):
 
            pass
 
        elif HasRepoPermissionAnyApi('repository.admin',
 
                                     'repository.write',
 
                                     'repository.read')(user=apiuser,
 
                                                        repo_name=repo.repo_name):
 
            if not isinstance(owner, Optional):
 
                #forbid setting owner for non-admins
 
                raise JSONRPCError(
 
                    'Only Kallithea admin can specify `owner` param'
 
                )
 

	
 
            if not HasPermissionAnyApi('hg.create.repository')(user=apiuser):
 
                raise JSONRPCError('no permission to create repositories')
 
        else:
 
            raise JSONRPCError('repository `%s` does not exist' % (repoid,))
 

	
 
        if isinstance(owner, Optional):
 
            owner = apiuser.user_id
 

	
 
        owner = get_user_or_error(owner)
 

	
 
        try:
 
            # create structure of groups and return the last group
 
            group = map_groups(fork_name)
 

	
kallithea/i18n/be/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -998,33 +998,33 @@ msgstr "Адбылася памылка пры выдаленні карыстача"
 
#: kallithea/controllers/admin/users.py:259
 
#: kallithea/controllers/admin/users.py:282
 
#: kallithea/controllers/admin/users.py:307
 
#: kallithea/controllers/admin/users.py:320
 
#: kallithea/controllers/admin/users.py:344
 
#: kallithea/controllers/admin/users.py:407
 
#: kallithea/controllers/admin/users.py:454
 
msgid "You can't edit this user"
 
msgstr "Вы не можаце рэдагаваць дадзенага карыстача"
 

	
 
#: kallithea/controllers/admin/users.py:482
 
#, python-format
 
msgid "Added IP address %s to user whitelist"
 
msgid "Added ip %s to user whitelist"
 
msgstr "Дададзены IP %s у белы спіс карыстача"
 

	
 
#: kallithea/controllers/admin/users.py:488
 
msgid "An error occurred during ip saving"
 
msgstr "Адбылася памылка пры захаванні IP"
 

	
 
#: kallithea/controllers/admin/users.py:502
 
msgid "Removed IP address from user whitelist"
 
msgid "Removed ip address from user whitelist"
 
msgstr "Выдалены IP %s з белага спісу карыстача"
 

	
 
#: kallithea/lib/auth.py:745
 
#, python-format
 
msgid "IP %s not allowed"
 
msgstr "IP %s заблакаваны"
 

	
 
#: kallithea/lib/auth.py:806
 
msgid "You need to be a registered user to perform this action"
 
msgstr "Вы павінны быць зарэгістраваным карыстачом, каб выканаць гэта дзеянне"
 

	
 
#: kallithea/lib/auth.py:843
 
@@ -2032,25 +2032,25 @@ msgid ""
 
"The LDAP Login attribute of the CN must be specified - this is the name of "
 
"the attribute that is equivalent to \"username\""
 
msgstr ""
 
"Для ўваходу па LDAP павінна быць паказана значэнне атрыбута CN - гэта "
 
"эквівалент імя карыстача"
 

	
 
#: kallithea/model/validators.py:785
 
#, python-format
 
msgid "Revisions %(revs)s are already part of pull request or have set status"
 
msgstr "Рэвізіі %(revs)s ужо ўключаны ў pull-request ці маюць усталяваны статус"
 

	
 
#: kallithea/model/validators.py:817
 
msgid "Please enter a valid IPv4 or IPv6 address"
 
msgid "Please enter a valid IPv4 or IpV6 address"
 
msgstr "Калі ласка, увядзіце існы IPv4 ці IPv6 адрас"
 

	
 
#: kallithea/model/validators.py:818
 
#, python-format
 
msgid "The network size (bits) must be within the range of 0-32 (not %(bits)r)"
 
msgstr ""
 
"Значэнне маскі падсеткі павінна быць у межах ад 0 да 32 (%(bits)r - няслушна)"
 

	
 
#: kallithea/model/validators.py:851
 
msgid "Key name can only consist of letters, underscore, dash or numbers"
 
msgstr ""
 
"Ключавое імя можа толькі складацца з літар, знака падкрэслення, працяжнік ці "
kallithea/i18n/kallithea.pot
Show inline comments
 
# Translations template for Kallithea.
 
# Copyright (C) 2015 Various authors, licensing as GPLv3
 
# This file is distributed under the same license as the Kallithea project.
 
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
 
##, fuzzy
 
msgid ""
 
msgstr ""
 
"Project-Id-Version: Kallithea 0.1\n"
 
"Project-Id-Version: Kallithea 0.2.2\n"
 
"Report-Msgid-Bugs-To: translations@kallithea-scm.org\n"
 
"POT-Creation-Date: 2015-04-01 03:17+0200\n"
 
"POT-Creation-Date: 2015-07-12 18:32+0200\n"
 
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 
"Language-Team: LANGUAGE <LL@li.org>\n"
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=UTF-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 

	
 
#: kallithea/controllers/changelog.py:86
 
#: kallithea/controllers/pullrequests.py:247 kallithea/lib/base.py:449
 
msgid "There are no changesets yet"
 
msgstr ""
 

	
 
@@ -38,25 +38,25 @@ msgstr ""
 

	
 
#: kallithea/controllers/changeset.py:96 kallithea/controllers/changeset.py:103
 
#: kallithea/templates/files/diff_2way.html:55
 
msgid "Ignore whitespace"
 
msgstr ""
 

	
 
#: kallithea/controllers/changeset.py:169
 
#, python-format
 
msgid "increase diff context to %(num)s lines"
 
msgstr ""
 

	
 
#: kallithea/controllers/changeset.py:212 kallithea/controllers/files.py:97
 
#: kallithea/controllers/files.py:117 kallithea/controllers/files.py:746
 
#: kallithea/controllers/files.py:117 kallithea/controllers/files.py:745
 
msgid "Such revision does not exist for this repository"
 
msgstr ""
 

	
 
#: kallithea/controllers/changeset.py:352
 
#: kallithea/controllers/pullrequests.py:699
 
msgid "No comments."
 
msgstr ""
 

	
 
#: kallithea/controllers/changeset.py:382
 
msgid "Changing status on a changeset associated with a closed pull request is not allowed"
 
msgstr ""
 

	
 
@@ -194,64 +194,64 @@ msgstr ""
 
#, python-format
 
msgid "Unknown revision %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/files.py:541
 
msgid "Empty repository"
 
msgstr ""
 

	
 
#: kallithea/controllers/files.py:543
 
msgid "Unknown archive type"
 
msgstr ""
 

	
 
#: kallithea/controllers/files.py:775
 
#: kallithea/controllers/files.py:774
 
#: kallithea/templates/changeset/changeset_range.html:9
 
#: kallithea/templates/email_templates/pull_request.html:15
 
#: kallithea/templates/pullrequests/pullrequest.html:116
 
msgid "Changesets"
 
msgstr ""
 

	
 
#: kallithea/controllers/files.py:776 kallithea/controllers/pullrequests.py:182
 
#: kallithea/controllers/files.py:775 kallithea/controllers/pullrequests.py:182
 
#: kallithea/controllers/summary.py:74 kallithea/model/scm.py:816
 
#: kallithea/templates/switch_to_list.html:3
 
#: kallithea/templates/branches/branches.html:10
 
msgid "Branches"
 
msgstr ""
 

	
 
#: kallithea/controllers/files.py:777 kallithea/controllers/pullrequests.py:183
 
#: kallithea/controllers/files.py:776 kallithea/controllers/pullrequests.py:183
 
#: kallithea/controllers/summary.py:75 kallithea/model/scm.py:827
 
#: kallithea/templates/switch_to_list.html:25
 
#: kallithea/templates/tags/tags.html:10
 
msgid "Tags"
 
msgstr ""
 

	
 
#: kallithea/controllers/forks.py:187
 
#, python-format
 
msgid "An error occurred during repository forking %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/home.py:84
 
msgid "Groups"
 
msgstr ""
 

	
 
#: kallithea/controllers/home.py:89
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:106
 
#: kallithea/templates/admin/repos/repo_add.html:12
 
#: kallithea/templates/admin/repos/repo_add.html:16
 
#: kallithea/templates/admin/repos/repos.html:9
 
#: kallithea/templates/admin/users/user_edit_advanced.html:6
 
#: kallithea/templates/base/base.html:60 kallithea/templates/base/base.html:77
 
#: kallithea/templates/base/base.html:127
 
#: kallithea/templates/base/base.html:390
 
#: kallithea/templates/base/base.html:562
 
#: kallithea/templates/base/base.html:131
 
#: kallithea/templates/base/base.html:394
 
#: kallithea/templates/base/base.html:566
 
msgid "Repositories"
 
msgstr ""
 

	
 
#: kallithea/controllers/home.py:130
 
#: kallithea/templates/files/files_add.html:32
 
#: kallithea/templates/files/files_delete.html:23
 
#: kallithea/templates/files/files_edit.html:32
 
msgid "Branch"
 
msgstr ""
 

	
 
#: kallithea/controllers/home.py:136
 
msgid "Tag"
 
@@ -404,30 +404,30 @@ msgstr ""
 
msgid "Invalid search query. Try quoting it."
 
msgstr ""
 

	
 
#: kallithea/controllers/search.py:140
 
msgid "There is no index to search in. Please run whoosh indexer"
 
msgstr ""
 

	
 
#: kallithea/controllers/search.py:144
 
msgid "An error occurred during search operation."
 
msgstr ""
 

	
 
#: kallithea/controllers/summary.py:199
 
#: kallithea/templates/summary/summary.html:387
 
#: kallithea/templates/summary/summary.html:388
 
msgid "No data ready yet"
 
msgstr ""
 

	
 
#: kallithea/controllers/summary.py:202
 
#: kallithea/templates/summary/summary.html:101
 
#: kallithea/templates/summary/summary.html:102
 
msgid "Statistics are disabled for this repository"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/auth_settings.py:125
 
msgid "Auth settings updated successfully"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/auth_settings.py:136
 
msgid "error occurred during update of auth settings"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/defaults.py:97
 
@@ -577,28 +577,28 @@ msgstr ""
 
#: kallithea/templates/admin/repos/repo_add.html:10
 
#: kallithea/templates/admin/repos/repo_add.html:14
 
#: kallithea/templates/admin/repos/repos.html:9
 
#: kallithea/templates/admin/settings/settings.html:9
 
#: kallithea/templates/admin/user_groups/user_group_add.html:8
 
#: kallithea/templates/admin/user_groups/user_group_edit.html:9
 
#: kallithea/templates/admin/user_groups/user_groups.html:10
 
#: kallithea/templates/admin/users/user_add.html:8
 
#: kallithea/templates/admin/users/user_edit.html:9
 
#: kallithea/templates/admin/users/user_edit_profile.html:114
 
#: kallithea/templates/admin/users/users.html:10
 
#: kallithea/templates/admin/users/users.html:55
 
#: kallithea/templates/base/base.html:255
 
#: kallithea/templates/base/base.html:256
 
#: kallithea/templates/base/base.html:262
 
#: kallithea/templates/base/base.html:263
 
#: kallithea/templates/base/base.html:259
 
#: kallithea/templates/base/base.html:260
 
#: kallithea/templates/base/base.html:266
 
#: kallithea/templates/base/base.html:267
 
msgid "Admin"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/permissions.py:76
 
#: kallithea/controllers/admin/permissions.py:87
 
#: kallithea/controllers/admin/permissions.py:92
 
#: kallithea/controllers/admin/permissions.py:95
 
#: kallithea/controllers/admin/permissions.py:98
 
#: kallithea/controllers/admin/permissions.py:101
 
msgid "Disabled"
 
msgstr ""
 

	
 
@@ -692,168 +692,164 @@ msgstr ""
 

	
 
#: kallithea/controllers/admin/repo_groups.py:420
 
#: kallithea/controllers/admin/repo_groups.py:455
 
#: kallithea/controllers/admin/user_groups.py:340
 
msgid "Cannot revoke permission for yourself as admin"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repo_groups.py:435
 
msgid "Repository Group permissions updated"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repo_groups.py:472
 
#: kallithea/controllers/admin/repos.py:430
 
#: kallithea/controllers/admin/repos.py:429
 
#: kallithea/controllers/admin/user_groups.py:352
 
msgid "An error occurred during revoking of permission"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:163
 
#: kallithea/controllers/admin/repos.py:162
 
#, python-format
 
msgid "Error creating repository %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:238
 
#: kallithea/controllers/admin/repos.py:237
 
#, python-format
 
msgid "Created repository %s from %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:247
 
#: kallithea/controllers/admin/repos.py:246
 
#, python-format
 
msgid "Forked repository %s as %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:250
 
#: kallithea/controllers/admin/repos.py:249
 
#, python-format
 
msgid "Created repository %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:290
 
#: kallithea/controllers/admin/repos.py:289
 
#, python-format
 
msgid "Repository %s updated successfully"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:309
 
#: kallithea/controllers/admin/repos.py:308
 
#, python-format
 
msgid "Error occurred during update of repository %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:336
 
#: kallithea/controllers/admin/repos.py:335
 
#, python-format
 
msgid "Detached %s forks"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:339
 
#: kallithea/controllers/admin/repos.py:338
 
#, python-format
 
msgid "Deleted %s forks"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:344
 
#: kallithea/controllers/admin/repos.py:343
 
#, python-format
 
msgid "Deleted repository %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:347
 
#: kallithea/controllers/admin/repos.py:346
 
#, python-format
 
msgid "Cannot delete %s it still contains attached forks"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:352
 
#: kallithea/controllers/admin/repos.py:351
 
#, python-format
 
msgid "An error occurred during deletion of %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:406
 
#: kallithea/controllers/admin/repos.py:405
 
msgid "Repository permissions updated"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:462
 
#: kallithea/controllers/admin/repos.py:461
 
msgid "An error occurred during creation of field"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:476
 
#: kallithea/controllers/admin/repos.py:475
 
msgid "An error occurred during removal of field"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:492
 
#: kallithea/controllers/admin/repos.py:491
 
msgid "-- Not a fork --"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:522
 
msgid "Updated repository visibility in public journal"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:526
 
msgid "Updated repository visibility in public journal"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:530
 
msgid "An error occurred during setting this repository in public journal"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:535 kallithea/model/validators.py:340
 
msgid "Token mismatch"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:550
 
#: kallithea/controllers/admin/repos.py:543
 
msgid "Nothing"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:545
 
#, python-format
 
msgid "Marked repo %s as fork of %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:552
 
#, python-format
 
msgid "Marked repo %s as fork of %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:559
 
msgid "An error occurred during this operation"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:575
 
#: kallithea/controllers/admin/repos.py:568
 
msgid "Locked repository"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:578
 
#: kallithea/controllers/admin/repos.py:571
 
msgid "Unlocked repository"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:581
 
#: kallithea/controllers/admin/repos.py:608
 
#: kallithea/controllers/admin/repos.py:574
 
#: kallithea/controllers/admin/repos.py:601
 
msgid "An error occurred during unlocking"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:599
 
#: kallithea/controllers/admin/repos.py:592
 
msgid "Unlocked"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:602
 
#: kallithea/controllers/admin/repos.py:595
 
msgid "Locked"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:604
 
#: kallithea/controllers/admin/repos.py:597
 
#, python-format
 
msgid "Repository has been %s"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:622
 
#: kallithea/controllers/admin/repos.py:615
 
msgid "Cache invalidation successful"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:626
 
#: kallithea/controllers/admin/repos.py:619
 
msgid "An error occurred during cache invalidation"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:641
 
#: kallithea/controllers/admin/repos.py:634
 
msgid "Pulled from remote location"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:644
 
#: kallithea/controllers/admin/repos.py:637
 
msgid "An error occurred during pull from remote location"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/repos.py:677
 
#: kallithea/controllers/admin/repos.py:670
 
msgid "An error occurred during deletion of repository stats"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/settings.py:170
 
msgid "Updated VCS settings"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/settings.py:174
 
msgid "Unable to activate hgsubversion support. The \"hgsubversion\" library is missing"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/settings.py:180
 
@@ -985,209 +981,209 @@ msgstr ""
 
#, python-format
 
msgid "Added IP address %s to user whitelist"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/users.py:488
 
msgid "An error occurred during ip saving"
 
msgstr ""
 

	
 
#: kallithea/controllers/admin/users.py:502
 
msgid "Removed IP address from user whitelist"
 
msgstr ""
 

	
 
#: kallithea/lib/auth.py:745
 
#: kallithea/lib/auth.py:746
 
#, python-format
 
msgid "IP %s not allowed"
 
msgstr ""
 

	
 
#: kallithea/lib/auth.py:806
 
#: kallithea/lib/auth.py:814
 
msgid "You need to be a registered user to perform this action"
 
msgstr ""
 

	
 
#: kallithea/lib/auth.py:843
 
#: kallithea/lib/auth.py:851
 
msgid "You need to be signed in to view this page"
 
msgstr ""
 

	
 
#: kallithea/lib/base.py:427
 
msgid "Repository not found in the filesystem"
 
msgstr ""
 

	
 
#: kallithea/lib/base.py:453 kallithea/lib/helpers.py:643
 
#: kallithea/lib/base.py:453 kallithea/lib/helpers.py:626
 
msgid "Changeset not found"
 
msgstr ""
 

	
 
#: kallithea/lib/diffs.py:66
 
msgid "Binary file"
 
msgstr ""
 

	
 
#: kallithea/lib/diffs.py:82
 
msgid "Changeset was too big and was cut off, use diff menu to display this diff"
 
msgstr ""
 

	
 
#: kallithea/lib/diffs.py:92
 
msgid "No changes detected"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:627
 
#: kallithea/lib/helpers.py:610
 
#, python-format
 
msgid "Deleted branch: %s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:630
 
#: kallithea/lib/helpers.py:613
 
#, python-format
 
msgid "Created tag: %s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:693
 
#: kallithea/lib/helpers.py:676
 
#, python-format
 
msgid "Show all combined changesets %s->%s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:699
 
#: kallithea/lib/helpers.py:682
 
msgid "compare view"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:718
 
#: kallithea/lib/helpers.py:701
 
msgid "and"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:719
 
#: kallithea/lib/helpers.py:702
 
#, python-format
 
msgid "%s more"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:720 kallithea/templates/changelog/changelog.html:44
 
#: kallithea/lib/helpers.py:703 kallithea/templates/changelog/changelog.html:44
 
msgid "revisions"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:727
 
#, python-format
 
msgid "fork name %s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:744
 
#, python-format
 
msgid "fork name %s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:761
 
#, python-format
 
msgid "Pull request #%s"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:771
 
#: kallithea/lib/helpers.py:754
 
msgid "[deleted] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:773 kallithea/lib/helpers.py:785
 
#: kallithea/lib/helpers.py:756 kallithea/lib/helpers.py:768
 
msgid "[created] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:775
 
#: kallithea/lib/helpers.py:758
 
msgid "[created] repository as fork"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:777 kallithea/lib/helpers.py:787
 
#: kallithea/lib/helpers.py:760 kallithea/lib/helpers.py:770
 
msgid "[forked] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:779 kallithea/lib/helpers.py:789
 
#: kallithea/lib/helpers.py:762 kallithea/lib/helpers.py:772
 
msgid "[updated] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:781
 
#: kallithea/lib/helpers.py:764
 
msgid "[downloaded] archive from repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:783
 
#: kallithea/lib/helpers.py:766
 
msgid "[delete] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:791
 
#: kallithea/lib/helpers.py:774
 
msgid "[created] user"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:793
 
#: kallithea/lib/helpers.py:776
 
msgid "[updated] user"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:795
 
#: kallithea/lib/helpers.py:778
 
msgid "[created] user group"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:797
 
#: kallithea/lib/helpers.py:780
 
msgid "[updated] user group"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:799
 
#: kallithea/lib/helpers.py:782
 
msgid "[commented] on revision in repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:801
 
#: kallithea/lib/helpers.py:784
 
msgid "[commented] on pull request for"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:803
 
#: kallithea/lib/helpers.py:786
 
msgid "[closed] pull request for"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:805
 
#: kallithea/lib/helpers.py:788
 
msgid "[pushed] into"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:807
 
#: kallithea/lib/helpers.py:790
 
msgid "[committed via Kallithea] into repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:809
 
#: kallithea/lib/helpers.py:792
 
msgid "[pulled from remote] into repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:811
 
#: kallithea/lib/helpers.py:794
 
msgid "[pulled] from"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:813
 
#: kallithea/lib/helpers.py:796
 
msgid "[started following] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:815
 
#: kallithea/lib/helpers.py:798
 
msgid "[stopped following] repository"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1144
 
#: kallithea/lib/helpers.py:1127
 
#, python-format
 
msgid " and %s more"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1148
 
#: kallithea/lib/helpers.py:1131
 
msgid "No Files"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1214
 
#: kallithea/lib/helpers.py:1197
 
msgid "new file"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1217
 
#: kallithea/lib/helpers.py:1200
 
msgid "mod"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1220
 
#: kallithea/lib/helpers.py:1203
 
msgid "del"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1223
 
#: kallithea/lib/helpers.py:1206
 
msgid "rename"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1228
 
#: kallithea/lib/helpers.py:1211
 
msgid "chmod"
 
msgstr ""
 

	
 
#: kallithea/lib/helpers.py:1460
 
#: kallithea/lib/helpers.py:1443
 
#, python-format
 
msgid "%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"
 
msgstr ""
 

	
 
#: kallithea/lib/utils2.py:425
 
#, python-format
 
msgid "%d year"
 
msgid_plural "%d years"
 
msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/lib/utils2.py:426
 
@@ -1676,25 +1672,25 @@ msgid "Repository creation enabled with 
 
msgstr ""
 

	
 
#: kallithea/lib/dbmigrate/schema/db_2_2_0.py:1646
 
#: kallithea/lib/dbmigrate/schema/db_2_2_3.py:1673 kallithea/model/db.py:1675
 
msgid "Repository creation disabled with write permission to a repository group"
 
msgstr ""
 

	
 
#: kallithea/model/comment.py:76
 
#, python-format
 
msgid "on line %s"
 
msgstr ""
 

	
 
#: kallithea/model/comment.py:231 kallithea/model/pull_request.py:164
 
#: kallithea/model/comment.py:231 kallithea/model/pull_request.py:165
 
msgid "[Mention]"
 
msgstr ""
 

	
 
#: kallithea/model/forms.py:57
 
msgid "Please enter a login"
 
msgstr ""
 

	
 
#: kallithea/model/forms.py:58
 
#, python-format
 
msgid "Enter a value %(min)i characters long or more"
 
msgstr ""
 

	
 
@@ -1756,25 +1752,25 @@ msgstr ""
 
msgid "Review request on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(pr_username)s"
 
msgstr ""
 

	
 
#: kallithea/model/notification.py:302
 
#, python-format
 
msgid "Comment on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(comment_username)s"
 
msgstr ""
 

	
 
#: kallithea/model/notification.py:315
 
msgid "Closing"
 
msgstr ""
 

	
 
#: kallithea/model/pull_request.py:132
 
#: kallithea/model/pull_request.py:133
 
#, python-format
 
msgid "%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s"
 
msgstr ""
 

	
 
#: kallithea/model/scm.py:808
 
msgid "latest tip"
 
msgstr ""
 

	
 
#: kallithea/model/user.py:194
 
msgid "New user registration"
 
msgstr ""
 

	
 
@@ -1883,24 +1879,28 @@ msgstr ""
 
#: kallithea/model/validators.py:308
 
msgid "invalid password"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:309
 
msgid "invalid user name"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:310
 
msgid "Your account is disabled"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:340
 
msgid "Token mismatch"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:354
 
#, python-format
 
msgid "Repository name %(repo)s is disallowed"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:356
 
#, python-format
 
msgid "Repository named %(repo)s already exists"
 
msgstr ""
 

	
 
#: kallithea/model/validators.py:357
 
#, python-format
 
@@ -2050,25 +2050,25 @@ msgstr ""
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:72
 
#: kallithea/templates/admin/repos/repos.html:48
 
#: kallithea/templates/admin/user_groups/user_group_add.html:40
 
#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:15
 
#: kallithea/templates/admin/user_groups/user_groups.html:47
 
#: kallithea/templates/admin/users/user_edit_api_keys.html:64
 
#: kallithea/templates/email_templates/changeset_comment.html:18
 
#: kallithea/templates/email_templates/pull_request.html:12
 
#: kallithea/templates/forks/fork.html:38
 
#: kallithea/templates/pullrequests/pullrequest.html:40
 
#: kallithea/templates/pullrequests/pullrequest_show.html:38
 
#: kallithea/templates/pullrequests/pullrequest_show.html:63
 
#: kallithea/templates/summary/summary.html:84
 
#: kallithea/templates/summary/summary.html:85
 
msgid "Description"
 
msgstr ""
 

	
 
#: kallithea/templates/index_base.html:129
 
#: kallithea/templates/admin/my_account/my_account_repos.html:46
 
#: kallithea/templates/admin/my_account/my_account_watched.html:46
 
#: kallithea/templates/admin/repo_groups/repo_groups.html:46
 
#: kallithea/templates/admin/repos/repo_add_base.html:9
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:7
 
#: kallithea/templates/admin/repos/repos.html:47
 
#: kallithea/templates/admin/user_groups/user_groups.html:46
 
#: kallithea/templates/base/perms_summary.html:53
 
@@ -2095,25 +2095,25 @@ msgstr ""
 
#: kallithea/templates/journal/journal.html:189
 
#: kallithea/templates/journal/journal.html:280
 
msgid "Tip"
 
msgstr ""
 

	
 
#: kallithea/templates/index_base.html:136
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:10
 
#: kallithea/templates/admin/repo_groups/repo_groups.html:49
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:60
 
#: kallithea/templates/admin/repos/repos.html:50
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:8
 
#: kallithea/templates/admin/user_groups/user_groups.html:50
 
#: kallithea/templates/summary/summary.html:137
 
#: kallithea/templates/summary/summary.html:138
 
msgid "Owner"
 
msgstr ""
 

	
 
#: kallithea/templates/index_base.html:144
 
#: kallithea/templates/admin/my_account/my_account_repos.html:57
 
#: kallithea/templates/admin/my_account/my_account_watched.html:57
 
#: kallithea/templates/base/root.html:44
 
#: kallithea/templates/bookmarks/bookmarks.html:79
 
#: kallithea/templates/branches/branches.html:79
 
#: kallithea/templates/journal/journal.html:198
 
#: kallithea/templates/journal/journal.html:289
 
#: kallithea/templates/tags/tags.html:79
 
@@ -2142,73 +2142,73 @@ msgstr ""
 
#: kallithea/templates/base/root.html:47
 
#: kallithea/templates/bookmarks/bookmarks.html:82
 
#: kallithea/templates/branches/branches.html:82
 
#: kallithea/templates/journal/journal.html:201
 
#: kallithea/templates/journal/journal.html:292
 
#: kallithea/templates/tags/tags.html:82
 
msgid "Data error."
 
msgstr ""
 

	
 
#: kallithea/templates/index_base.html:148
 
#: kallithea/templates/admin/my_account/my_account_repos.html:61
 
#: kallithea/templates/admin/my_account/my_account_watched.html:61
 
#: kallithea/templates/base/base.html:143 kallithea/templates/base/root.html:48
 
#: kallithea/templates/base/base.html:147 kallithea/templates/base/root.html:48
 
#: kallithea/templates/bookmarks/bookmarks.html:83
 
#: kallithea/templates/branches/branches.html:83
 
#: kallithea/templates/journal/journal.html:202
 
#: kallithea/templates/journal/journal.html:293
 
#: kallithea/templates/tags/tags.html:83
 
msgid "Loading..."
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:5 kallithea/templates/login.html:15
 
#: kallithea/templates/base/base.html:329
 
#: kallithea/templates/base/base.html:333
 
msgid "Log In"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:13
 
#, python-format
 
msgid "Log In to %s"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:27 kallithea/templates/register.html:24
 
#: kallithea/templates/admin/admin_log.html:5
 
#: kallithea/templates/admin/my_account/my_account_profile.html:32
 
#: kallithea/templates/admin/users/user_add.html:32
 
#: kallithea/templates/admin/users/user_edit_profile.html:33
 
#: kallithea/templates/admin/users/users.html:50
 
#: kallithea/templates/base/base.html:305
 
#: kallithea/templates/base/base.html:309
 
msgid "Username"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:36 kallithea/templates/register.html:33
 
#: kallithea/templates/admin/my_account/my_account.html:36
 
#: kallithea/templates/admin/users/user_add.html:41
 
#: kallithea/templates/base/base.html:314
 
#: kallithea/templates/base/base.html:318
 
msgid "Password"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:46
 
msgid "Remember me"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:50
 
msgid "Sign In"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:56
 
msgid "Forgot your password ?"
 
msgstr ""
 

	
 
#: kallithea/templates/login.html:59 kallithea/templates/base/base.html:325
 
#: kallithea/templates/login.html:59 kallithea/templates/base/base.html:329
 
msgid "Don't have an account ?"
 
msgstr ""
 

	
 
#: kallithea/templates/password_reset.html:5
 
msgid "Password Reset"
 
msgstr ""
 

	
 
#: kallithea/templates/password_reset.html:12
 
#, python-format
 
msgid "Reset Your Password to %s"
 
msgstr ""
 

	
 
@@ -2388,100 +2388,99 @@ msgid "enabled"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/auth/auth_settings.html:40
 
#: kallithea/templates/base/root.html:41
 
msgid "disabled"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/auth/auth_settings.html:51
 
msgid "Plugin"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/auth/auth_settings.html:101
 
#: kallithea/templates/admin/defaults/defaults.html:84
 
#: kallithea/templates/admin/defaults/defaults.html:82
 
#: kallithea/templates/admin/my_account/my_account_password.html:33
 
#: kallithea/templates/admin/my_account/my_account_profile.html:70
 
#: kallithea/templates/admin/permissions/permissions_globals.html:108
 
#: kallithea/templates/admin/repo_groups/repo_group_add.html:69
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:114
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:42
 
#: kallithea/templates/admin/repos/repo_edit_permissions.html:101
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:134
 
#: kallithea/templates/admin/settings/settings_hooks.html:53
 
#: kallithea/templates/admin/user_groups/user_group_add.html:57
 
#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:104
 
#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:60
 
#: kallithea/templates/admin/users/user_add.html:96
 
#: kallithea/templates/admin/users/user_edit_profile.html:122
 
#: kallithea/templates/base/default_perms_box.html:64
 
msgid "Save"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:5
 
#: kallithea/templates/admin/defaults/defaults.html:25
 
msgid "Repository Defaults"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:11
 
#: kallithea/templates/base/base.html:66
 
msgid "Defaults"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:35
 
#: kallithea/templates/admin/defaults/defaults.html:33
 
#: kallithea/templates/admin/repos/repo_add_base.html:59
 
#: kallithea/templates/admin/repos/repo_edit_fields.html:7
 
msgid "Type"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:44
 
#: kallithea/templates/admin/defaults/defaults.html:42
 
#: kallithea/templates/admin/repos/repo_add_base.html:77
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:82
 
#: kallithea/templates/data_table/_dt_elements.html:74
 
#: kallithea/templates/data_table/_dt_elements.html:72
 
msgid "Private repository"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:48
 
#: kallithea/templates/admin/defaults/defaults.html:46
 
#: kallithea/templates/admin/repos/repo_add_base.html:81
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:86
 
#: kallithea/templates/forks/fork.html:72
 
msgid "Private repositories are only visible to people explicitly added as collaborators."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:55
 
#: kallithea/templates/admin/defaults/defaults.html:53
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:91
 
msgid "Enable statistics"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:59
 
#: kallithea/templates/admin/defaults/defaults.html:57
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:95
 
msgid "Enable statistics window on summary page."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:65
 
#: kallithea/templates/admin/defaults/defaults.html:63
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:100
 
msgid "Enable downloads"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:69
 
#: kallithea/templates/admin/defaults/defaults.html:67
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:104
 
msgid "Enable download menu on summary page."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:75
 
#: kallithea/templates/admin/defaults/defaults.html:73
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:34
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:109
 
msgid "Enable locking"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/defaults/defaults.html:79
 
#: kallithea/templates/admin/defaults/defaults.html:77
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:113
 
msgid "Enable lock-by-pulling on repository."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/edit.html:5
 
#: kallithea/templates/admin/gists/edit.html:18
 
msgid "Edit Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/edit.html:36
 
#, python-format
 
msgid "Gist was update since you started editing. Copy your changes and click %(here)s to reload new version."
 
@@ -2535,30 +2534,30 @@ msgstr ""
 
#: kallithea/templates/admin/gists/index.html:18
 
#, python-format
 
msgid "Public Gists for User %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/index.html:10
 
#: kallithea/templates/admin/gists/index.html:20
 
msgid "Public Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/index.html:37
 
#: kallithea/templates/admin/gists/show.html:25
 
#: kallithea/templates/base/base.html:240
 
#: kallithea/templates/base/base.html:244
 
msgid "Create New Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/index.html:54
 
#: kallithea/templates/data_table/_dt_elements.html:143
 
#: kallithea/templates/data_table/_dt_elements.html:141
 
msgid "Created"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/index.html:74
 
msgid "There are no gists yet"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/new.html:5
 
#: kallithea/templates/admin/gists/new.html:18
 
msgid "New Gist"
 
msgstr ""
 

	
 
@@ -2571,25 +2570,25 @@ msgid "Create Private Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/new.html:57
 
msgid "Create Public Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/new.html:58
 
#: kallithea/templates/admin/my_account/my_account_api_keys.html:70
 
#: kallithea/templates/admin/my_account/my_account_emails.html:46
 
#: kallithea/templates/admin/my_account/my_account_password.html:34
 
#: kallithea/templates/admin/my_account/my_account_profile.html:71
 
#: kallithea/templates/admin/permissions/permissions_globals.html:109
 
#: kallithea/templates/admin/permissions/permissions_ips.html:41
 
#: kallithea/templates/admin/permissions/permissions_ips.html:39
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:115
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:43
 
#: kallithea/templates/admin/repos/repo_edit_fields.html:59
 
#: kallithea/templates/admin/repos/repo_edit_permissions.html:102
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:135
 
#: kallithea/templates/admin/settings/settings_global.html:57
 
#: kallithea/templates/admin/settings/settings_vcs.html:81
 
#: kallithea/templates/admin/settings/settings_visual.html:117
 
#: kallithea/templates/admin/user_groups/user_group_edit_perms.html:105
 
#: kallithea/templates/admin/users/user_edit_api_keys.html:70
 
#: kallithea/templates/admin/users/user_edit_emails.html:46
 
#: kallithea/templates/admin/users/user_edit_ips.html:50
 
@@ -2614,66 +2613,66 @@ msgstr ""
 
msgid "URL"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:37
 
msgid "Public Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:39
 
msgid "Private Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:56
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:76
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:75
 
#: kallithea/templates/changeset/changeset_file_comment.html:50
 
#: kallithea/templates/files/files_source.html:39
 
#: kallithea/templates/files/files_source.html:42
 
#: kallithea/templates/files/files_source.html:45
 
msgid "Delete"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:56
 
msgid "Confirm to delete this Gist"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:63
 
#: kallithea/templates/changeset/changeset_file_comment.html:91
 
#: kallithea/templates/changeset/changeset_file_comment.html:207
 
#: kallithea/templates/data_table/_dt_elements.html:167
 
#: kallithea/templates/data_table/_dt_elements.html:183
 
#: kallithea/templates/data_table/_dt_elements.html:165
 
#: kallithea/templates/data_table/_dt_elements.html:181
 
#: kallithea/templates/files/diff_2way.html:56
 
#: kallithea/templates/files/files_source.html:41
 
#: kallithea/templates/files/files_source.html:44
 
#: kallithea/templates/pullrequests/pullrequest_show.html:41
 
msgid "Edit"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:65
 
#: kallithea/templates/files/files_edit.html:49
 
#: kallithea/templates/files/files_source.html:34
 
msgid "Show as Raw"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:73
 
msgid "created"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/gists/show.html:86
 
#: kallithea/templates/files/files_source.html:73
 
msgid "Show as raw"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account.html:5
 
#: kallithea/templates/admin/my_account/my_account.html:9
 
#: kallithea/templates/base/base.html:346
 
#: kallithea/templates/base/base.html:350
 
msgid "My Account"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account.html:35
 
#: kallithea/templates/admin/users/user_edit.html:29
 
msgid "Profile"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account.html:37
 
#: kallithea/templates/admin/users/user_edit.html:30
 
msgid "API Keys"
 
msgstr ""
 
@@ -2739,48 +2738,48 @@ msgstr ""
 
#: kallithea/templates/admin/my_account/my_account_api_keys.html:49
 
#: kallithea/templates/admin/users/user_edit_api_keys.html:49
 
msgid "No additional api keys specified"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_api_keys.html:61
 
#: kallithea/templates/admin/users/user_edit_api_keys.html:61
 
msgid "New api key"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_api_keys.html:69
 
#: kallithea/templates/admin/my_account/my_account_emails.html:45
 
#: kallithea/templates/admin/permissions/permissions_ips.html:40
 
#: kallithea/templates/admin/permissions/permissions_ips.html:38
 
#: kallithea/templates/admin/repos/repo_add_base.html:85
 
#: kallithea/templates/admin/repos/repo_edit_fields.html:58
 
#: kallithea/templates/admin/users/user_edit_api_keys.html:69
 
#: kallithea/templates/admin/users/user_edit_emails.html:45
 
#: kallithea/templates/admin/users/user_edit_ips.html:49
 
msgid "Add"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_emails.html:7
 
#: kallithea/templates/admin/users/user_edit_emails.html:7
 
msgid "Primary"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_emails.html:19
 
#: kallithea/templates/admin/permissions/permissions_ips.html:14
 
#: kallithea/templates/admin/permissions/permissions_ips.html:12
 
#: kallithea/templates/admin/repos/repo_edit_fields.html:18
 
#: kallithea/templates/admin/settings/settings_hooks.html:36
 
#: kallithea/templates/admin/users/user_edit_emails.html:19
 
#: kallithea/templates/admin/users/user_edit_ips.html:22
 
#: kallithea/templates/data_table/_dt_elements.html:131
 
#: kallithea/templates/data_table/_dt_elements.html:159
 
#: kallithea/templates/data_table/_dt_elements.html:175
 
#: kallithea/templates/data_table/_dt_elements.html:191
 
#: kallithea/templates/data_table/_dt_elements.html:129
 
#: kallithea/templates/data_table/_dt_elements.html:157
 
#: kallithea/templates/data_table/_dt_elements.html:173
 
#: kallithea/templates/data_table/_dt_elements.html:189
 
msgid "delete"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_emails.html:20
 
#: kallithea/templates/admin/users/user_edit_emails.html:20
 
#, python-format
 
msgid "Confirm to delete this email: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/my_account/my_account_emails.html:26
 
#: kallithea/templates/admin/users/user_edit_emails.html:26
 
msgid "No additional emails specified."
 
@@ -2859,43 +2858,43 @@ msgstr ""
 
msgid "My Notifications"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/notifications.html:24
 
msgid "All"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/notifications.html:25
 
msgid "Comments"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/notifications.html:26
 
#: kallithea/templates/base/base.html:186
 
#: kallithea/templates/base/base.html:190
 
msgid "Pull Requests"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/notifications.html:30
 
msgid "Mark All Read"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/notifications_data.html:40
 
msgid "No notifications here yet"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/show_notification.html:5
 
#: kallithea/templates/admin/notifications/show_notification.html:11
 
msgid "Show Notification"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/notifications/show_notification.html:9
 
#: kallithea/templates/base/base.html:345
 
#: kallithea/templates/base/base.html:349
 
msgid "Notifications"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions.html:5
 
msgid "Permissions Administration"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions.html:11
 
#: kallithea/templates/admin/repo_groups/repo_group_edit.html:42
 
#: kallithea/templates/admin/repos/repo_edit.html:43
 
#: kallithea/templates/admin/user_groups/user_group_edit.html:32
 
#: kallithea/templates/base/base.html:64
 
@@ -2929,35 +2928,35 @@ msgstr ""
 
msgid "All default permissions on each repository will be reset to chosen permission, note that all custom default permission on repositories will be lost"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:27
 
#: kallithea/templates/admin/permissions/permissions_globals.html:40
 
#: kallithea/templates/admin/permissions/permissions_globals.html:54
 
msgid "Overwrite existing settings"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:32
 
#: kallithea/templates/admin/repos/repo_add_base.html:41
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:42
 
#: kallithea/templates/data_table/_dt_elements.html:204
 
#: kallithea/templates/data_table/_dt_elements.html:202
 
#: kallithea/templates/forks/fork.html:48
 
msgid "Repository group"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:39
 
msgid "All default permissions on each repository group will be reset to chosen permission, note that all custom default permission on repository groups will be lost"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:46
 
#: kallithea/templates/data_table/_dt_elements.html:211
 
#: kallithea/templates/data_table/_dt_elements.html:209
 
msgid "User group"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:53
 
msgid "All default permissions on each user group will be reset to chosen permission, note that all custom default permission on repository groups will be lost"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:60
 
msgid "Repository creation"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:68
 
@@ -2975,48 +2974,40 @@ msgstr ""
 
#: kallithea/templates/admin/permissions/permissions_globals.html:85
 
msgid "Repository forking"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:93
 
msgid "Registration"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_globals.html:101
 
msgid "External auth account activation"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_ips.html:1
 
msgid "Default IP Whitelist for All Users"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_ips.html:15
 
#: kallithea/templates/admin/permissions/permissions_ips.html:13
 
#: kallithea/templates/admin/users/user_edit_ips.html:23
 
#, python-format
 
msgid "Confirm to delete this ip: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_ips.html:21
 
#: kallithea/templates/admin/permissions/permissions_ips.html:19
 
#: kallithea/templates/admin/users/user_edit_ips.html:30
 
msgid "All IP addresses are allowed."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_ips.html:32
 
#: kallithea/templates/admin/permissions/permissions_ips.html:30
 
#: kallithea/templates/admin/users/user_edit_ips.html:42
 
msgid "New IP address"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/permissions/permissions_perms.html:1
 
msgid "Default User Permissions Overview"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_add.html:11
 
#: kallithea/templates/admin/repo_groups/repo_group_edit.html:11
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:105
 
#: kallithea/templates/admin/repo_groups/repo_groups.html:10
 
#: kallithea/templates/base/base.html:61 kallithea/templates/base/base.html:80
 
msgid "Repository Groups"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_add.html:33
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_settings.html:8
 
#: kallithea/templates/admin/user_groups/user_group_add.html:32
 
#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:7
 
@@ -3043,27 +3034,27 @@ msgstr ""
 
msgid "%s Repository Group Settings"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit.html:21
 
msgid "Add Child Group"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit.html:40
 
#: kallithea/templates/admin/repos/repo_edit.html:12
 
#: kallithea/templates/admin/repos/repo_edit.html:40
 
#: kallithea/templates/admin/settings/settings.html:11
 
#: kallithea/templates/admin/user_groups/user_group_edit.html:29
 
#: kallithea/templates/base/base.html:67 kallithea/templates/base/base.html:154
 
#: kallithea/templates/data_table/_dt_elements.html:43
 
#: kallithea/templates/data_table/_dt_elements.html:47
 
#: kallithea/templates/base/base.html:67 kallithea/templates/base/base.html:158
 
#: kallithea/templates/data_table/_dt_elements.html:45
 
#: kallithea/templates/data_table/_dt_elements.html:49
 
msgid "Settings"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit.html:41
 
#: kallithea/templates/admin/repos/repo_edit.html:46
 
#: kallithea/templates/admin/user_groups/user_group_edit.html:30
 
#: kallithea/templates/admin/users/user_edit.html:31
 
msgid "Advanced"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:1
 
#, python-format
 
@@ -3081,25 +3072,25 @@ msgstr ""
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:8
 
msgid "Children groups"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:9
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:7
 
#: kallithea/templates/admin/users/user_edit_advanced.html:8
 
#: kallithea/templates/pullrequests/pullrequest_show.html:147
 
msgid "Created on"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:21
 
#: kallithea/templates/data_table/_dt_elements.html:192
 
#: kallithea/templates/data_table/_dt_elements.html:190
 
#, python-format
 
msgid "Confirm to delete this group: %s with %s repository"
 
msgid_plural "Confirm to delete this group: %s with %s repositories"
 
msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_advanced.html:25
 
msgid "Delete this repository group"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repo_groups/repo_group_edit_perms.html:7
 
#: kallithea/templates/admin/repos/repo_edit_permissions.html:8
 
@@ -3276,113 +3267,113 @@ msgid "Extra Fields"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit.html:52
 
msgid "Caches"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit.html:55
 
msgid "Remote"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit.html:58
 
#: kallithea/templates/summary/statistics.html:8
 
#: kallithea/templates/summary/summary.html:174
 
#: kallithea/templates/summary/summary.html:175
 
#: kallithea/templates/summary/summary.html:176
 
msgid "Statistics"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:1
 
msgid "Parent"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:5
 
#: kallithea/templates/admin/repos/repo_edit_fork.html:5
 
msgid "Set"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:8
 
#: kallithea/templates/admin/repos/repo_edit_fork.html:9
 
msgid "Manually set this repository as a fork of another from the list."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:22
 
msgid "Public Journal Visibility"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:30
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:29
 
msgid "Remove from public journal"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:35
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:34
 
msgid "Add to Public Journal"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:41
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:40
 
msgid "All actions done in this repository will be visible to everyone in the public journal."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:47
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:46
 
msgid "Change Locking"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:53
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:52
 
msgid "Confirm to unlock repository."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:55
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:54
 
msgid "Unlock Repository"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:61
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:60
 
msgid "Confirm to lock repository."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:63
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:62
 
msgid "Lock Repository"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:65
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:64
 
msgid "Repository is not locked"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:69
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:68
 
msgid "Force locking on the repository. Works only when anonymous access is disabled. Triggering a pull locks the repository.  The user who is pulling locks the repository; only the user who pulled and locked it can unlock it by doing a push."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:80
 
#: kallithea/templates/data_table/_dt_elements.html:132
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:79
 
#: kallithea/templates/data_table/_dt_elements.html:130
 
#, python-format
 
msgid "Confirm to delete this repository: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:82
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:81
 
msgid "Delete this Repository"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:85
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:84
 
#, python-format
 
msgid "This repository has %s fork"
 
msgid_plural "This repository has %s forks"
 
msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:86
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:85
 
msgid "Detach forks"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:87
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:86
 
msgid "Delete forks"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:91
 
#: kallithea/templates/admin/repos/repo_edit_advanced.html:90
 
msgid "The deleted repository will be moved away and hidden until the administrator expires it. The administrator can both permanently delete it or restore it."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_caches.html:4
 
msgid "Invalidate Repository Cache"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_caches.html:4
 
msgid "Confirm to invalidate repository cache."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_caches.html:7
 
@@ -3457,57 +3448,57 @@ msgstr ""
 
msgid "Pull Changes from Remote Location"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_remote.html:8
 
msgid "Confirm to pull changes from remote side."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_remote.html:14
 
msgid "This repository does not have a remote URL set."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:11
 
msgid "Non-changeable id"
 
msgid "Permanent Repository ID"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:11
 
msgid "What is that?"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:13
 
msgid "URL by id"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:14
 
msgid ""
 
"In case this repository is renamed or moved into another group the repository URL changes.\n"
 
"                               Using the above URL guarantees that this repository will always be accessible under such URL.\n"
 
"                               Useful for CI systems, or any other cases that you need to hardcode the URL into 3rd party service."
 
"                               Using the above permanent URL guarantees that this repository always will be accessible on that URL.\n"
 
"                               This is useful for CI systems, or any other cases that you need to hardcode the URL into a 3rd party service."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:21
 
#: kallithea/templates/summary/summary.html:72
 
msgid "Clone URL"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:27
 
#: kallithea/templates/base/perms_summary.html:43
 
#: kallithea/templates/base/perms_summary.html:79
 
#: kallithea/templates/base/perms_summary.html:81
 
#: kallithea/templates/data_table/_dt_elements.html:124
 
#: kallithea/templates/data_table/_dt_elements.html:125
 
#: kallithea/templates/data_table/_dt_elements.html:152
 
#: kallithea/templates/data_table/_dt_elements.html:153
 
#: kallithea/templates/data_table/_dt_elements.html:169
 
#: kallithea/templates/data_table/_dt_elements.html:185
 
#: kallithea/templates/data_table/_dt_elements.html:122
 
#: kallithea/templates/data_table/_dt_elements.html:123
 
#: kallithea/templates/data_table/_dt_elements.html:150
 
#: kallithea/templates/data_table/_dt_elements.html:151
 
#: kallithea/templates/data_table/_dt_elements.html:167
 
#: kallithea/templates/data_table/_dt_elements.html:183
 
msgid "edit"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:30
 
msgid "new value"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:37
 
msgid "URL used for doing remote pulls."
 
msgstr ""
 

	
 
#: kallithea/templates/admin/repos/repo_edit_settings.html:55
 
@@ -3948,25 +3939,25 @@ msgstr ""
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:6
 
#: kallithea/templates/admin/user_groups/user_group_edit_settings.html:32
 
#: kallithea/templates/admin/user_groups/user_groups.html:48
 
msgid "Members"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:1
 
#, python-format
 
msgid "User Group: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:19
 
#: kallithea/templates/data_table/_dt_elements.html:176
 
#: kallithea/templates/data_table/_dt_elements.html:174
 
#, python-format
 
msgid "Confirm to delete this user group: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/user_groups/user_group_edit_advanced.html:21
 
msgid "Delete this user group"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/user_groups/user_group_edit_members.html:17
 
msgid "No members yet"
 
msgstr ""
 

	
 
@@ -4030,25 +4021,25 @@ msgid "Source of Record"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/users/user_edit_advanced.html:9
 
#: kallithea/templates/admin/users/users.html:53
 
msgid "Last Login"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/users/user_edit_advanced.html:10
 
msgid "Member of User groups"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/users/user_edit_advanced.html:21
 
#: kallithea/templates/data_table/_dt_elements.html:160
 
#: kallithea/templates/data_table/_dt_elements.html:158
 
#, python-format
 
msgid "Confirm to delete this user: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/users/user_edit_advanced.html:23
 
msgid "Delete this user"
 
msgstr ""
 

	
 
#: kallithea/templates/admin/users/user_edit_ips.html:8
 
#, python-format
 
msgid "Inherited from %s"
 
msgstr ""
 
@@ -4082,185 +4073,193 @@ msgstr ""
 
msgid "Auth Type"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:18
 
#, python-format
 
msgid "Server instance: %s"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:30
 
msgid "Support"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:122
 
#: kallithea/templates/base/base.html:90
 
msgid "Mercurial repository"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:93
 
msgid "Git repository"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:126
 
msgid "Create Fork"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:133
 
#: kallithea/templates/data_table/_dt_elements.html:11
 
#: kallithea/templates/data_table/_dt_elements.html:15
 
#: kallithea/templates/base/base.html:137
 
#: kallithea/templates/data_table/_dt_elements.html:13
 
#: kallithea/templates/data_table/_dt_elements.html:17
 
#: kallithea/templates/summary/summary.html:8
 
msgid "Summary"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:135
 
#: kallithea/templates/base/base.html:137
 
#: kallithea/templates/changelog/changelog.html:14
 
#: kallithea/templates/data_table/_dt_elements.html:19
 
#: kallithea/templates/data_table/_dt_elements.html:23
 
msgid "Changelog"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:139
 
#: kallithea/templates/data_table/_dt_elements.html:27
 
#: kallithea/templates/data_table/_dt_elements.html:31
 
#: kallithea/templates/base/base.html:141
 
#: kallithea/templates/changelog/changelog.html:14
 
#: kallithea/templates/data_table/_dt_elements.html:21
 
#: kallithea/templates/data_table/_dt_elements.html:25
 
msgid "Changelog"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:143
 
#: kallithea/templates/data_table/_dt_elements.html:29
 
#: kallithea/templates/data_table/_dt_elements.html:33
 
#: kallithea/templates/files/files.html:11
 
msgid "Files"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:141
 
#: kallithea/templates/base/base.html:145
 
msgid "Switch To"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:148
 
#: kallithea/templates/base/base.html:150
 
#: kallithea/templates/base/base.html:152
 
#: kallithea/templates/base/base.html:154
 
msgid "Options"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:158
 
#: kallithea/templates/base/base.html:162
 
#: kallithea/templates/forks/forks_data.html:21
 
msgid "Compare Fork"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:160
 
#: kallithea/templates/base/base.html:164
 
#: kallithea/templates/bookmarks/bookmarks.html:56
 
#: kallithea/templates/bookmarks/bookmarks_data.html:13
 
#: kallithea/templates/branches/branches.html:56
 
#: kallithea/templates/branches/branches_data.html:13
 
#: kallithea/templates/tags/tags.html:56
 
#: kallithea/templates/tags/tags_data.html:13
 
msgid "Compare"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:162
 
#: kallithea/templates/base/base.html:250
 
#: kallithea/templates/base/base.html:166
 
#: kallithea/templates/base/base.html:254
 
#: kallithea/templates/search/search.html:14
 
#: kallithea/templates/search/search.html:54
 
msgid "Search"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:166
 
#: kallithea/templates/base/base.html:170
 
msgid "Unlock"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:168
 
#: kallithea/templates/base/base.html:172
 
msgid "Lock"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:176
 
msgid "Follow"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:177
 
msgid "Unfollow"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:180
 
#: kallithea/templates/data_table/_dt_elements.html:35
 
#: kallithea/templates/data_table/_dt_elements.html:39
 
#: kallithea/templates/forks/fork.html:9
 
msgid "Fork"
 
msgid "Follow"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:181
 
msgid "Unfollow"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:184
 
#: kallithea/templates/data_table/_dt_elements.html:37
 
#: kallithea/templates/data_table/_dt_elements.html:41
 
#: kallithea/templates/forks/fork.html:9
 
msgid "Fork"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:185
 
#: kallithea/templates/pullrequests/pullrequest.html:88
 
msgid "Create Pull Request"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:186
 
#: kallithea/templates/base/base.html:190
 
#, python-format
 
msgid "Show Pull Requests for %s"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:224
 
#: kallithea/templates/base/base.html:228
 
msgid "Show recent activity"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:225
 
#: kallithea/templates/base/base.html:229
 
#: kallithea/templates/journal/journal.html:4
 
#: kallithea/templates/journal/journal.html:12
 
msgid "Journal"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:230
 
#: kallithea/templates/base/base.html:231
 
#: kallithea/templates/base/base.html:234
 
#: kallithea/templates/base/base.html:235
 
msgid "Public journal"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:236
 
#: kallithea/templates/base/base.html:240
 
msgid "Show public gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:237
 
msgid "Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:241
 
msgid "Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:245
 
msgid "All Public Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:243
 
#: kallithea/templates/base/base.html:247
 
msgid "My Public Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:244
 
#: kallithea/templates/base/base.html:248
 
msgid "My Private Gists"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:249
 
#: kallithea/templates/base/base.html:253
 
msgid "Search in repositories"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:272
 
#: kallithea/templates/base/base.html:273
 
#: kallithea/templates/base/base.html:276
 
#: kallithea/templates/base/base.html:277
 
#: kallithea/templates/pullrequests/pullrequest_show_my.html:4
 
#: kallithea/templates/pullrequests/pullrequest_show_my.html:8
 
msgid "My Pull Requests"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:292
 
#: kallithea/templates/base/base.html:296
 
msgid "Not Logged In"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:299
 
#: kallithea/templates/base/base.html:303
 
msgid "Login to Your Account"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:322
 
#: kallithea/templates/base/base.html:326
 
msgid "Forgot password ?"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:347
 
#: kallithea/templates/base/base.html:351
 
msgid "Log Out"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:395
 
#: kallithea/templates/base/base.html:399
 
msgid "No matches found"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:524
 
#: kallithea/templates/base/base.html:528
 
msgid "Keyboard shortcuts"
 
msgstr ""
 

	
 
#: kallithea/templates/base/base.html:533
 
#: kallithea/templates/base/base.html:537
 
msgid "Site-wide shortcuts"
 
msgstr ""
 

	
 
#: kallithea/templates/base/default_perms_box.html:14
 
msgid "Inherit from defaults"
 
msgstr ""
 

	
 
#: kallithea/templates/base/default_perms_box.html:19
 
#, python-format
 
msgid "Select to inherit permissions from %s permissions settings, and default IP address whitelist."
 
msgstr ""
 

	
 
@@ -4306,25 +4305,25 @@ msgstr ""
 
msgid "Edit Permission"
 
msgstr ""
 

	
 
#: kallithea/templates/base/perms_summary.html:90
 
msgid "No permission defined"
 
msgstr ""
 

	
 
#: kallithea/templates/base/root.html:22
 
msgid "Add Another Comment"
 
msgstr ""
 

	
 
#: kallithea/templates/base/root.html:23
 
#: kallithea/templates/data_table/_dt_elements.html:216
 
#: kallithea/templates/data_table/_dt_elements.html:214
 
msgid "Stop following this repository"
 
msgstr ""
 

	
 
#: kallithea/templates/base/root.html:24
 
msgid "Start following this repository"
 
msgstr ""
 

	
 
#: kallithea/templates/base/root.html:25
 
msgid "Group"
 
msgstr ""
 

	
 
#: kallithea/templates/base/root.html:26
 
@@ -4555,39 +4554,39 @@ msgstr ""
 
msgid "Commit Message"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:9
 
#: kallithea/templates/pullrequests/pullrequest_data.html:17
 
msgid "Age"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:11
 
msgid "Refs"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:91
 
#: kallithea/templates/changelog/changelog_summary_data.html:81
 
msgid "Add or upload files directly via Kallithea"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:94
 
#: kallithea/templates/changelog/changelog_summary_data.html:84
 
#: kallithea/templates/files/files_add.html:21
 
#: kallithea/templates/files/files_ypjax.html:9
 
msgid "Add New File"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:100
 
#: kallithea/templates/changelog/changelog_summary_data.html:90
 
msgid "Push new repo"
 
msgstr ""
 

	
 
#: kallithea/templates/changelog/changelog_summary_data.html:108
 
#: kallithea/templates/changelog/changelog_summary_data.html:98
 
msgid "Existing repository?"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset.html:8
 
#, python-format
 
msgid "%s Changeset"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset.html:36
 
msgid "parent rev."
 
msgstr ""
 

	
 
@@ -4687,25 +4686,24 @@ msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:67
 
msgid "Commenting on line {1}."
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:68
 
#: kallithea/templates/changeset/changeset_file_comment.html:163
 
#, python-format
 
msgid "Comments parsed using %s syntax with %s support."
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:70
 
#: kallithea/templates/changeset/changeset_file_comment.html:165
 
msgid "Use @username inside this text to notify another user"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:80
 
#: kallithea/templates/changeset/changeset_file_comment.html:199
 
msgid "Comment preview"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:85
 
msgid "Submitting ..."
 
msgstr ""
 

	
 
@@ -4743,24 +4741,28 @@ msgstr[1] ""
 
msgid "%d inline"
 
msgid_plural "%d inline"
 
msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:116
 
#, python-format
 
msgid "%d general"
 
msgid_plural "%d general"
 
msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:165
 
msgid "Use @username inside this text to notify another user."
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:172
 
msgid "Vote for pull request status"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:174
 
msgid "Set changeset status"
 
msgstr ""
 

	
 
#: kallithea/templates/changeset/changeset_file_comment.html:178
 
msgid "No change"
 
msgstr ""
 

	
 
@@ -4862,57 +4864,49 @@ msgstr[0] ""
 
msgstr[1] ""
 

	
 
#: kallithea/templates/compare/compare_diff.html:65
 
#: kallithea/templates/pullrequests/pullrequest_show.html:315
 
msgid "No files"
 
msgstr ""
 

	
 
#: kallithea/templates/compare/compare_diff.html:78
 
#: kallithea/templates/compare/compare_diff.html:89
 
msgid "Show full diff"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:67
 
msgid "Mercurial repository"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:69
 
msgid "Git repository"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:76
 
#: kallithea/templates/data_table/_dt_elements.html:74
 
msgid "Public repository"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:86
 
#: kallithea/templates/data_table/_dt_elements.html:84
 
msgid "Repository creation in progress..."
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:100
 
#: kallithea/templates/data_table/_dt_elements.html:98
 
msgid "No changesets yet"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:105
 
#: kallithea/templates/data_table/_dt_elements.html:107
 
#: kallithea/templates/data_table/_dt_elements.html:109
 
#, python-format
 
msgid "Subscribe to %s rss feed"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:113
 
#: kallithea/templates/data_table/_dt_elements.html:115
 
#: kallithea/templates/data_table/_dt_elements.html:117
 
#, python-format
 
msgid "Subscribe to %s atom feed"
 
msgstr ""
 

	
 
#: kallithea/templates/data_table/_dt_elements.html:141
 
#: kallithea/templates/data_table/_dt_elements.html:139
 
msgid "Creating"
 
msgstr ""
 

	
 
#: kallithea/templates/email_templates/changeset_comment.html:5
 
#, python-format
 
msgid "Comment from %s on %s changeset %s mentioned you"
 
msgstr ""
 

	
 
#: kallithea/templates/email_templates/changeset_comment.html:7
 
#, python-format
 
msgid "Comment from %s on %s changeset %s"
 
msgstr ""
 
@@ -5171,26 +5165,26 @@ msgid "Go Back"
 
msgstr ""
 

	
 
#: kallithea/templates/files/files_ypjax.html:24
 
msgid "No files at given path"
 
msgstr ""
 

	
 
#: kallithea/templates/followers/followers.html:5
 
#, python-format
 
msgid "%s Followers"
 
msgstr ""
 

	
 
#: kallithea/templates/followers/followers.html:9
 
#: kallithea/templates/summary/summary.html:145
 
#: kallithea/templates/summary/summary.html:146
 
#: kallithea/templates/summary/summary.html:147
 
msgid "Followers"
 
msgstr ""
 

	
 
#: kallithea/templates/followers/followers_data.html:12
 
msgid "Started following -"
 
msgstr ""
 

	
 
#: kallithea/templates/forks/fork.html:5
 
#, python-format
 
msgid "Fork repository %s"
 
msgstr ""
 

	
 
@@ -5223,50 +5217,50 @@ msgid "Checkout source after making a cl
 
msgstr ""
 

	
 
#: kallithea/templates/forks/fork.html:96
 
msgid "Fork this Repository"
 
msgstr ""
 

	
 
#: kallithea/templates/forks/forks.html:5
 
#, python-format
 
msgid "%s Forks"
 
msgstr ""
 

	
 
#: kallithea/templates/forks/forks.html:9
 
#: kallithea/templates/summary/summary.html:151
 
#: kallithea/templates/summary/summary.html:152
 
#: kallithea/templates/summary/summary.html:153
 
msgid "Forks"
 
msgstr ""
 

	
 
#: kallithea/templates/forks/forks_data.html:17
 
msgid "Forked"
 
msgstr ""
 

	
 
#: kallithea/templates/forks/forks_data.html:43
 
#: kallithea/templates/forks/forks_data.html:30
 
msgid "There are no forks yet"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/journal.html:21
 
msgid "ATOM journal feed"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/journal.html:22
 
msgid "RSS journal feed"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/journal.html:56
 
msgid "My Repos"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/journal_data.html:61
 
#: kallithea/templates/journal/journal_data.html:43
 
msgid "No entries yet"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/public_journal.html:4
 
#: kallithea/templates/journal/public_journal.html:21
 
msgid "Public Journal"
 
msgstr ""
 

	
 
#: kallithea/templates/journal/public_journal.html:13
 
msgid "ATOM public journal feed"
 
msgstr ""
 

	
 
@@ -5559,152 +5553,152 @@ msgstr ""
 
#: kallithea/templates/summary/summary.html:39
 
#, python-format
 
msgid "%s ATOM feed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:17
 
#: kallithea/templates/summary/summary.html:40
 
#, python-format
 
msgid "%s RSS feed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:36
 
#: kallithea/templates/summary/summary.html:103
 
#: kallithea/templates/summary/summary.html:119
 
#: kallithea/templates/summary/summary.html:104
 
#: kallithea/templates/summary/summary.html:120
 
msgid "Enable"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:39
 
msgid "Stats gathered: "
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:88
 
#: kallithea/templates/summary/summary.html:352
 
#: kallithea/templates/summary/statistics.html:89
 
#: kallithea/templates/summary/summary.html:353
 
msgid "files"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:112
 
#: kallithea/templates/summary/summary.html:376
 
#: kallithea/templates/summary/statistics.html:113
 
#: kallithea/templates/summary/summary.html:377
 
msgid "Show more"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:389
 
msgid "commits"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:390
 
msgid "files added"
 
msgid "commits"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:391
 
msgid "files changed"
 
msgid "files added"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:392
 
msgid "files changed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:393
 
msgid "files removed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:394
 
msgid "commit"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:395
 
msgid "file added"
 
msgid "commit"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:396
 
msgid "file changed"
 
msgid "file added"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:397
 
msgid "file changed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/statistics.html:398
 
msgid "file removed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:4
 
#, python-format
 
msgid "%s Summary"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:13
 
#, python-format
 
msgid "Repository locked by %s"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:15
 
msgid "Repository unlocked"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:22
 
msgid "Fork of"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:77
 
#: kallithea/templates/summary/summary.html:78
 
msgid "Show by Name"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:78
 
#: kallithea/templates/summary/summary.html:79
 
msgid "Show by ID"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:95
 
#: kallithea/templates/summary/summary.html:96
 
msgid "Trending files"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:111
 
#: kallithea/templates/summary/summary.html:112
 
msgid "Download"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:115
 
#: kallithea/templates/summary/summary.html:116
 
msgid "There are no downloads yet"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:117
 
#: kallithea/templates/summary/summary.html:118
 
msgid "Downloads are disabled for this repository"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:123
 
#: kallithea/templates/summary/summary.html:124
 
msgid "Download as zip"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:128
 
#: kallithea/templates/summary/summary.html:129
 
msgid "Check this to download archive with subrepos"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:128
 
#: kallithea/templates/summary/summary.html:129
 
msgid "with subrepos"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:159
 
#: kallithea/templates/summary/summary.html:160
 
msgid "Repository Size"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:166
 
#: kallithea/templates/summary/summary.html:168
 
#: kallithea/templates/summary/summary.html:167
 
#: kallithea/templates/summary/summary.html:169
 
msgid "Feed"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:189
 
#: kallithea/templates/summary/summary.html:190
 
msgid "Latest Changes"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:191
 
#: kallithea/templates/summary/summary.html:192
 
msgid "Quick Start"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:205
 
#: kallithea/templates/summary/summary.html:206
 
#, python-format
 
msgid "Readme file from revision %s:%s"
 
msgstr ""
 

	
 
#: kallithea/templates/summary/summary.html:296
 
#: kallithea/templates/summary/summary.html:297
 
#, python-format
 
msgid "Download %s as %s"
 
msgstr ""
 

	
 
#: kallithea/templates/tags/tags.html:5
 
#, python-format
 
msgid "%s Tags"
 
msgstr ""
 

	
 
#: kallithea/templates/tags/tags.html:26
 
msgid "Compare Tags"
 
msgstr ""
kallithea/lib/auth.py
Show inline comments
 
@@ -17,25 +17,25 @@ kallithea.lib.auth
 

	
 
authentication and permission libraries
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Apr 4, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 
from __future__ import with_statement
 
import time
 
import random
 
import os
 
import logging
 
import traceback
 
import hashlib
 
import itertools
 
import collections
 

	
 
from tempfile import _RandomNameSequence
 
from decorator import decorator
 

	
 
from pylons import url, request
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 
@@ -76,32 +76,32 @@ class PasswordGenerator(object):
 
    """
 
    ALPHABETS_NUM = r'''1234567890'''
 
    ALPHABETS_SMALL = r'''qwertyuiopasdfghjklzxcvbnm'''
 
    ALPHABETS_BIG = r'''QWERTYUIOPASDFGHJKLZXCVBNM'''
 
    ALPHABETS_SPECIAL = r'''`-=[]\;',./~!@#$%^&*()_+{}|:"<>?'''
 
    ALPHABETS_FULL = ALPHABETS_BIG + ALPHABETS_SMALL \
 
        + ALPHABETS_NUM + ALPHABETS_SPECIAL
 
    ALPHABETS_ALPHANUM = ALPHABETS_BIG + ALPHABETS_SMALL + ALPHABETS_NUM
 
    ALPHABETS_BIG_SMALL = ALPHABETS_BIG + ALPHABETS_SMALL
 
    ALPHABETS_ALPHANUM_BIG = ALPHABETS_BIG + ALPHABETS_NUM
 
    ALPHABETS_ALPHANUM_SMALL = ALPHABETS_SMALL + ALPHABETS_NUM
 

	
 
    def __init__(self, passwd=''):
 
        self.passwd = passwd
 

	
 
    def gen_password(self, length, type_=None):
 
        if type_ is None:
 
            type_ = self.ALPHABETS_FULL
 
        self.passwd = ''.join([random.choice(type_) for _ in xrange(length)])
 
        return self.passwd
 
    def gen_password(self, length, alphabet=ALPHABETS_FULL):
 
        assert len(alphabet) <= 256, alphabet
 
        l = []
 
        while len(l) < length:
 
            i = ord(os.urandom(1))
 
            if i < len(alphabet):
 
                l.append(alphabet[i])
 
        return ''.join(l)
 

	
 

	
 
class KallitheaCrypto(object):
 

	
 
    @classmethod
 
    def hash_string(cls, str_):
 
        """
 
        Cryptographic function used for password hashing based on pybcrypt
 
        or pycrypto in windows
 

	
 
        :param password: password to hash
 
        """
 
@@ -134,24 +134,25 @@ class KallitheaCrypto(object):
 
        else:
 
            raise Exception('Unknown or unsupported platform %s' \
 
                            % __platform__)
 

	
 

	
 
def get_crypt_password(password):
 
    return KallitheaCrypto.hash_string(password)
 

	
 

	
 
def check_password(password, hashed):
 
    return KallitheaCrypto.hash_check(password, hashed)
 

	
 

	
 
class CookieStoreWrapper(object):
 

	
 
    def __init__(self, cookie_store):
 
        self.cookie_store = cookie_store
 

	
 
    def __repr__(self):
 
        return 'CookieStore<%s>' % (self.cookie_store)
 

	
 
    def get(self, key, other=None):
 
        if isinstance(self.cookie_store, dict):
 
            return self.cookie_store.get(key, other)
 
        elif isinstance(self.cookie_store, AuthUser):
 
@@ -266,24 +267,27 @@ def _cached_perms_data(user_id, user_is_
 
        'hg.fork.none', 'hg.fork.repository',
 
        'hg.create.none', 'hg.create.repository',
 
        'hg.usergroup.create.false', 'hg.usergroup.create.true'
 
    ])
 

	
 
    # USER GROUPS comes first
 
    # user group global permissions
 
    user_perms_from_users_groups = Session().query(UserGroupToPerm)\
 
        .options(joinedload(UserGroupToPerm.permission))\
 
        .join((UserGroupMember, UserGroupToPerm.users_group_id ==
 
               UserGroupMember.users_group_id))\
 
        .filter(UserGroupMember.user_id == uid)\
 
        .join((UserGroup, UserGroupMember.users_group_id ==
 
               UserGroup.users_group_id))\
 
        .filter(UserGroup.users_group_active == True)\
 
        .order_by(UserGroupToPerm.users_group_id)\
 
        .all()
 
    # need to group here by groups since user can be in more than
 
    # one group
 
    _grouped = [[x, list(y)] for x, y in
 
                itertools.groupby(user_perms_from_users_groups,
 
                                  lambda x:x.users_group)]
 
    for gr, perms in _grouped:
 
        # since user can be in multiple groups iterate over them and
 
        # select the lowest permissions first (more explicit)
 
        ##TODO: do this^^
 
        if not gr.inherit_default_permissions:
 
@@ -316,24 +320,27 @@ def _cached_perms_data(user_id, user_is_
 
    # check if user is part of user groups for this repository and
 
    # fill in his permission from it. _choose_perm decides of which
 
    # permission should be selected based on selected method
 
    #======================================================================
 

	
 
    # user group for repositories permissions
 
    user_repo_perms_from_users_groups = \
 
     Session().query(UserGroupRepoToPerm, Permission, Repository,)\
 
        .join((Repository, UserGroupRepoToPerm.repository_id ==
 
               Repository.repo_id))\
 
        .join((Permission, UserGroupRepoToPerm.permission_id ==
 
               Permission.permission_id))\
 
        .join((UserGroup, UserGroupRepoToPerm.users_group_id ==
 
               UserGroup.users_group_id))\
 
        .filter(UserGroup.users_group_active == True)\
 
        .join((UserGroupMember, UserGroupRepoToPerm.users_group_id ==
 
               UserGroupMember.users_group_id))\
 
        .filter(UserGroupMember.user_id == uid)\
 
        .all()
 

	
 
    multiple_counter = collections.defaultdict(int)
 
    for perm in user_repo_perms_from_users_groups:
 
        r_k = perm.UserGroupRepoToPerm.repository.repo_name
 
        multiple_counter[r_k] += 1
 
        p = perm.Permission.permission_name
 
        cur_perm = permissions[RK][r_k]
 

	
 
@@ -365,24 +372,27 @@ def _cached_perms_data(user_id, user_is_
 
    #======================================================================
 
    #======================================================================
 
    # check if user is part of user groups for this repository groups and
 
    # fill in his permission from it. _choose_perm decides of which
 
    # permission should be selected based on selected method
 
    #======================================================================
 
    # user group for repo groups permissions
 
    user_repo_group_perms_from_users_groups = \
 
     Session().query(UserGroupRepoGroupToPerm, Permission, RepoGroup)\
 
     .join((RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
 
     .join((Permission, UserGroupRepoGroupToPerm.permission_id
 
            == Permission.permission_id))\
 
     .join((UserGroup, UserGroupRepoGroupToPerm.users_group_id ==
 
            UserGroup.users_group_id))\
 
     .filter(UserGroup.users_group_active == True)\
 
     .join((UserGroupMember, UserGroupRepoGroupToPerm.users_group_id
 
            == UserGroupMember.users_group_id))\
 
     .filter(UserGroupMember.user_id == uid)\
 
     .all()
 

	
 
    multiple_counter = collections.defaultdict(int)
 
    for perm in user_repo_group_perms_from_users_groups:
 
        g_k = perm.UserGroupRepoGroupToPerm.group.group_name
 
        multiple_counter[g_k] += 1
 
        p = perm.Permission.permission_name
 
        cur_perm = permissions[GK][g_k]
 
        if multiple_counter[g_k] > 1:
 
@@ -403,24 +413,27 @@ def _cached_perms_data(user_id, user_is_
 
    # !! PERMISSIONS FOR USER GROUPS !!
 
    #======================================================================
 
    # user group for user group permissions
 
    user_group_user_groups_perms = \
 
     Session().query(UserGroupUserGroupToPerm, Permission, UserGroup)\
 
     .join((UserGroup, UserGroupUserGroupToPerm.target_user_group_id
 
            == UserGroup.users_group_id))\
 
     .join((Permission, UserGroupUserGroupToPerm.permission_id
 
            == Permission.permission_id))\
 
     .join((UserGroupMember, UserGroupUserGroupToPerm.user_group_id
 
            == UserGroupMember.users_group_id))\
 
     .filter(UserGroupMember.user_id == uid)\
 
     .join((UserGroup, UserGroupMember.users_group_id ==
 
            UserGroup.users_group_id), aliased=True, from_joinpoint=True)\
 
     .filter(UserGroup.users_group_active == True)\
 
     .all()
 

	
 
    multiple_counter = collections.defaultdict(int)
 
    for perm in user_group_user_groups_perms:
 
        g_k = perm.UserGroupUserGroupToPerm.target_user_group.users_group_name
 
        multiple_counter[g_k] += 1
 
        p = perm.Permission.permission_name
 
        cur_perm = permissions[UK][g_k]
 
        if multiple_counter[g_k] > 1:
 
            p = _choose_perm(p, cur_perm)
 
        permissions[UK][g_k] = p
 

	
kallithea/lib/dbmigrate/schema/db_1_2_0.py
Show inline comments
 
@@ -327,25 +327,25 @@ class User(Base, BaseModel):
 

	
 
    @classmethod
 
    def create(cls, form_data):
 
        from kallithea.lib.auth import get_crypt_password
 

	
 
        try:
 
            new_user = cls()
 
            for k, v in form_data.items():
 
                if k == 'password':
 
                    v = get_crypt_password(v)
 
                setattr(new_user, k, v)
 

	
 
            new_user.api_key = generate_api_key(form_data['username'])
 
            new_user.api_key = generate_api_key()
 
            Session.add(new_user)
 
            Session.commit()
 
            return new_user
 
        except:
 
            log.error(traceback.format_exc())
 
            Session.rollback()
 
            raise
 

	
 
class UserLog(Base, BaseModel):
 
    __tablename__ = 'user_logs'
 
    __table_args__ = {'extend_existing':True}
 
    user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
kallithea/lib/helpers.py
Show inline comments
 
@@ -342,40 +342,40 @@ def pygmentize_annotation(repo_name, fil
 
    cgenerator = gen_color()
 

	
 
    def get_color_string(cs):
 
        if cs in color_dict:
 
            col = color_dict[cs]
 
        else:
 
            col = color_dict[cs] = cgenerator.next()
 
        return "color: rgb(%s)! important;" % (', '.join(col))
 

	
 
    def url_func(repo_name):
 

	
 
        def _url_func(changeset):
 
            author = changeset.author
 
            author = escape(changeset.author)
 
            date = changeset.date
 
            message = tooltip(changeset.message)
 
            message = escape(changeset.message)
 

	
 
            tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
 
                            " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
 
                            "</b> %s<br/></div>")
 

	
 
            tooltip_html = tooltip_html % (author, date, message)
 
            lnk_format = show_id(changeset)
 
            uri = link_to(
 
                    lnk_format,
 
                    url('changeset_home', repo_name=repo_name,
 
                        revision=changeset.raw_id),
 
                    style=get_color_string(changeset.raw_id),
 
                    class_='tooltip',
 
                    class_='tooltip safe-html-title',
 
                    title=tooltip_html
 
                  )
 

	
 
            uri += '\n'
 
            return uri
 
        return _url_func
 

	
 
    return literal(markup_whitespace(annotate_highlight(filenode, url_func(repo_name), **kwargs)))
 

	
 

	
 
def is_following_repo(repo_name, user_id):
 
    from kallithea.model.scm import ScmModel
kallithea/lib/utils2.py
Show inline comments
 
@@ -23,26 +23,28 @@ Original author and date, and relevant c
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 

	
 
import os
 
import re
 
import sys
 
import time
 
import uuid
 
import datetime
 
import urllib
 
import binascii
 

	
 
import webob
 
import urllib
 
import urlobject
 

	
 
from pylons.i18n.translation import _, ungettext
 
from kallithea.lib.vcs.utils.lazy import LazyProperty
 
from kallithea.lib.compat import json
 

	
 

	
 
def __get_lem():
 
    """
 
    Get language extension map based on what's inside pygments lexers
 
    """
 
    from pygments import lexers
 
@@ -152,41 +154,29 @@ def detect_mode(line, default):
 
    :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
 
    """
 
    if line.endswith('\r\n'):
 
        return 2
 
    elif line.endswith('\n'):
 
        return 0
 
    elif line.endswith('\r'):
 
        return 1
 
    else:
 
        return default
 

	
 

	
 
def generate_api_key(username, salt=None):
 
def generate_api_key():
 
    """
 
    Generates unique API key for given username, if salt is not given
 
    it'll be generated from some random string
 

	
 
    :param username: username as string
 
    :param salt: salt to hash generate KEY
 
    :rtype: str
 
    :returns: sha1 hash from username+salt
 
    Generates a random (presumably unique) API key.
 
    """
 
    from tempfile import _RandomNameSequence
 
    import hashlib
 

	
 
    if salt is None:
 
        salt = _RandomNameSequence().next()
 

	
 
    return hashlib.sha1(username + salt).hexdigest()
 
    return binascii.hexlify(os.urandom(20))
 

	
 

	
 
def safe_int(val, default=None):
 
    """
 
    Returns int() of val if val is not convertable to int use default
 
    instead
 

	
 
    :param val:
 
    :param default:
 
    """
 

	
 
    try:
kallithea/model/api_key.py
Show inline comments
 
@@ -41,25 +41,25 @@ log = logging.getLogger(__name__)
 
class ApiKeyModel(BaseModel):
 
    cls = UserApiKeys
 

	
 
    def create(self, user, description, lifetime=-1):
 
        """
 
        :param user: user or user_id
 
        :param description: description of ApiKey
 
        :param lifetime: expiration time in seconds
 
        """
 
        user = self._get_user(user)
 

	
 
        new_api_key = UserApiKeys()
 
        new_api_key.api_key = generate_api_key(user.username)
 
        new_api_key.api_key = generate_api_key()
 
        new_api_key.user_id = user.user_id
 
        new_api_key.description = description
 
        new_api_key.expires = time.time() + (lifetime * 60) if lifetime != -1 else -1
 
        Session().add(new_api_key)
 

	
 
        return new_api_key
 

	
 
    def delete(self, api_key, user=None):
 
        """
 
        Deletes given api_key, if user is set it also filters the object for
 
        deletion by given user.
 
        """
kallithea/model/db.py
Show inline comments
 
@@ -546,24 +546,27 @@ class User(Base, BaseModel):
 
            q = cls.query().filter(cls.username == username)
 

	
 
        if cache:
 
            q = q.options(FromCache(
 
                            "sql_cache_short",
 
                            "get_user_%s" % _hash_key(username)
 
                          )
 
            )
 
        return q.scalar()
 

	
 
    @classmethod
 
    def get_by_api_key(cls, api_key, cache=False, fallback=True):
 
        if len(api_key) != 40 or not api_key.isalnum():
 
            return None
 

	
 
        q = cls.query().filter(cls.api_key == api_key)
 

	
 
        if cache:
 
            q = q.options(FromCache("sql_cache_short",
 
                                    "get_api_key_%s" % api_key))
 
        res = q.scalar()
 

	
 
        if fallback and not res:
 
            #fallback to additional keys
 
            _res = UserApiKeys.query()\
 
                .filter(UserApiKeys.api_key == api_key)\
 
                .filter(or_(UserApiKeys.expires == -1,
 
@@ -1653,60 +1656,60 @@ class RepoGroup(Base, BaseModel):
 

	
 

	
 
class Permission(Base, BaseModel):
 
    __tablename__ = 'permissions'
 
    __table_args__ = (
 
        Index('p_perm_name_idx', 'permission_name'),
 
        {'extend_existing': True, 'mysql_engine': 'InnoDB',
 
         'mysql_charset': 'utf8', 'sqlite_autoincrement': True},
 
    )
 
    PERMS = [
 
        ('hg.admin', _('Kallithea Administrator')),
 

	
 
        ('repository.none', _('Repository no access')),
 
        ('repository.read', _('Repository read access')),
 
        ('repository.write', _('Repository write access')),
 
        ('repository.admin', _('Repository admin access')),
 

	
 
        ('group.none', _('Repository group no access')),
 
        ('group.read', _('Repository group read access')),
 
        ('group.write', _('Repository group write access')),
 
        ('group.admin', _('Repository group admin access')),
 

	
 
        ('usergroup.none', _('User group no access')),
 
        ('usergroup.read', _('User group read access')),
 
        ('usergroup.write', _('User group write access')),
 
        ('usergroup.admin', _('User group admin access')),
 

	
 
        ('hg.repogroup.create.false', _('Repository Group creation disabled')),
 
        ('hg.repogroup.create.true', _('Repository Group creation enabled')),
 

	
 
        ('hg.usergroup.create.false', _('User Group creation disabled')),
 
        ('hg.usergroup.create.true', _('User Group creation enabled')),
 

	
 
        ('hg.create.none', _('Repository creation disabled')),
 
        ('hg.create.repository', _('Repository creation enabled')),
 
        ('repository.none', _('Default user has no access to new Repositories')),
 
        ('repository.read', _('Default user has read access to new Repositories')),
 
        ('repository.write', _('Default user has write access to new Repositories')),
 
        ('repository.admin', _('Default user has admin access to new Repositories')),
 

	
 
        ('group.none', _('Default user has no access to new Repository Groups')),
 
        ('group.read', _('Default user has read access to new Repository Groups')),
 
        ('group.write', _('Default user has write access to new Repository Groups')),
 
        ('group.admin', _('Default user has admin access to new Repository Groups')),
 

	
 
        ('usergroup.none', _('Default user has no access to new User Groups')),
 
        ('usergroup.read', _('Default user has read access to new User Groups')),
 
        ('usergroup.write', _('Default user has write access to new User Groups')),
 
        ('usergroup.admin', _('Default user has admin access to new User Groups')),
 

	
 
        ('hg.repogroup.create.false', _('Only admins can create Repository Groups')),
 
        ('hg.repogroup.create.true', _('Non-admins can create Repository Groups')),
 

	
 
        ('hg.usergroup.create.false', _('Only admins can create User Groups')),
 
        ('hg.usergroup.create.true', _('Non-admins can create User Groups')),
 

	
 
        ('hg.create.none', _('Only admins can create top level Repositories')),
 
        ('hg.create.repository', _('Non-admins can create top level Repositories')),
 

	
 
        ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')),
 
        ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')),
 

	
 
        ('hg.fork.none', _('Repository forking disabled')),
 
        ('hg.fork.repository', _('Repository forking enabled')),
 
        ('hg.fork.none', _('Only admins can fork repositories')),
 
        ('hg.fork.repository', _('Non-admins can can fork repositories')),
 

	
 
        ('hg.register.none', _('Registration disabled')),
 
        ('hg.register.manual_activate', _('User Registration with manual account activation')),
 
        ('hg.register.auto_activate', _('User Registration with automatic account activation')),
 

	
 
        ('hg.extern_activate.manual', _('Manual activation of external account')),
 
        ('hg.extern_activate.auto', _('Automatic activation of external account')),
 

	
 
    ]
 

	
 
    #definition of system default permissions for DEFAULT user
 
    DEFAULT_USER_PERMISSIONS = [
 
        'repository.read',
 
        'group.read',
 
        'usergroup.read',
 
        'hg.create.repository',
 
        'hg.create.write_on_repogroup.true',
 
        'hg.fork.repository',
 
        'hg.register.manual_activate',
 
        'hg.extern_activate.auto',
kallithea/model/user.py
Show inline comments
 
@@ -87,25 +87,25 @@ class UserModel(BaseModel):
 
        # raises UserCreationError if it's not allowed
 
        check_allowed_create_user(user_data, cur_user)
 
        from kallithea.lib.auth import get_crypt_password
 

	
 
        new_user = User()
 
        for k, v in form_data.items():
 
            if k == 'password':
 
                v = get_crypt_password(v)
 
            if k == 'firstname':
 
                k = 'name'
 
            setattr(new_user, k, v)
 

	
 
        new_user.api_key = generate_api_key(form_data['username'])
 
        new_user.api_key = generate_api_key()
 
        self.sa.add(new_user)
 

	
 
        log_create_user(new_user.get_dict(), cur_user)
 
        return new_user
 

	
 
    def create_or_update(self, username, password, email, firstname='',
 
                         lastname='', active=True, admin=False,
 
                         extern_type=None, extern_name=None, cur_user=None):
 
        """
 
        Creates a new instance if not found, or updates current one
 

	
 
        :param username:
 
@@ -149,25 +149,25 @@ class UserModel(BaseModel):
 
            new_user.username = username
 
            new_user.admin = admin
 
            new_user.email = email
 
            new_user.active = active
 
            new_user.extern_name = safe_unicode(extern_name) \
 
                if extern_name else None
 
            new_user.extern_type = safe_unicode(extern_type) \
 
                if extern_type else None
 
            new_user.name = firstname
 
            new_user.lastname = lastname
 

	
 
            if not edit:
 
                new_user.api_key = generate_api_key(username)
 
                new_user.api_key = generate_api_key()
 

	
 
            # set password only if creating an user or password is changed
 
            password_change = new_user.password and \
 
                not check_password(password, new_user.password)
 
            if not edit or password_change:
 
                reason = 'new password' if edit else 'new user'
 
                log.debug('Updating password reason=>%s' % (reason,))
 
                new_user.password = get_crypt_password(password) \
 
                    if password else None
 

	
 
            self.sa.add(new_user)
 

	
kallithea/model/user_group.py
Show inline comments
 
@@ -237,25 +237,25 @@ class UserGroupModel(BaseModel):
 
            .filter(UserGroupToPerm.users_group == user_group)\
 
            .filter(UserGroupToPerm.permission == perm)\
 
            .scalar()
 
        if _perm:
 
            return
 

	
 
        new = UserGroupToPerm()
 
        new.users_group = user_group
 
        new.permission = perm
 
        self.sa.add(new)
 
        return new
 

	
 
    def revokehas_permrevoke_permgrant_perm_perm(self, user_group, perm):
 
    def revoke_perm(self, user_group, perm):
 
        user_group = self._get_user_group(user_group)
 
        perm = self._get_perm(perm)
 

	
 
        obj = UserGroupToPerm.query()\
 
            .filter(UserGroupToPerm.users_group == user_group)\
 
            .filter(UserGroupToPerm.permission == perm).scalar()
 
        if obj:
 
            self.sa.delete(obj)
 

	
 
    def grant_user_permission(self, user_group, user, perm):
 
        """
 
        Grant permission for user on given user group, or update
kallithea/public/js/base.js
Show inline comments
 
@@ -500,43 +500,49 @@ var _init_tooltip = function(){
 
    if(!$tipBox.length){
 
        $tipBox = $('<div id="tip-box"></div>')
 
        $(document.body).append($tipBox);
 
    }
 

	
 
    $tipBox.hide();
 
    $tipBox.css('position', 'absolute');
 
    $tipBox.css('max-width', '600px');
 

	
 
    _activate_tooltip($('.tooltip'));
 
};
 

	
 
var _show_tooltip = function(e, tipText){
 
var _show_tooltip = function(e, tipText, safe){
 
    e.stopImmediatePropagation();
 
    var el = e.currentTarget;
 
    var $el = $(el);
 
    if(tipText){
 
        // just use it
 
    } else if(el.tagName.toLowerCase() === 'img'){
 
        tipText = el.alt ? el.alt : '';
 
    } else {
 
        tipText = el.title ? el.title : '';
 
        safe = safe || $el.hasClass("safe-html-title");
 
    }
 

	
 
    if(tipText !== ''){
 
        // save org title
 
        $(el).attr('tt_title', tipText);
 
        $el.attr('tt_title', tipText);
 
        // reset title to not show org tooltips
 
        $(el).attr('title', '');
 
        $el.attr('title', '');
 

	
 
        var $tipBox = $('#tip-box');
 
        $tipBox.html(tipText);
 
        if (safe) {
 
            $tipBox.html(tipText);
 
        } else {
 
            $tipBox.text(tipText);
 
        }
 
        $tipBox.css('display', 'block');
 
    }
 
};
 

	
 
var _move_tooltip = function(e){
 
    e.stopImmediatePropagation();
 
    var $tipBox = $('#tip-box');
 
    $tipBox.css('top', (e.pageY + 15) + 'px');
 
    $tipBox.css('left', (e.pageX + 15) + 'px');
 
};
 

	
 
var _close_tooltip = function(e){
kallithea/templates/admin/permissions/permissions_globals.html
Show inline comments
 
@@ -10,91 +10,95 @@ ${h.form(url('admin_permissions'), metho
 
                    <div class="checkbox">
 
                        ${h.checkbox('anonymous',True)}
 
                    </div>
 
                     <span class="help-block">${h.literal(_('Allow access to Kallithea without needing to log in. Anonymous users use %s user permissions.' % (h.link_to('*default*',h.url('admin_permissions_perms')))))}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="default_repo_perm">${_('Repository')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_repo_perm','',c.repo_perms_choices)}
 

	
 
                    ${h.checkbox('overwrite_default_repo','true')}
 
                    <label for="overwrite_default_repo">
 
                    <span class="tooltip"
 
                    title="${h.tooltip(_('All default permissions on each repository will be reset to chosen permission, note that all custom default permission on repositories will be lost'))}">
 
                    ${_('Overwrite existing settings')}</span> </label>
 
                    ${_('Apply to all existing repositories')}</span> </label>
 
                    <span class="help-block">${_('Permissions for the Default user on new repositories.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="default_group_perm">${_('Repository group')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_group_perm','',c.group_perms_choices)}
 
                    ${h.checkbox('overwrite_default_group','true')}
 
                    <label for="overwrite_default_group">
 
                    <span class="tooltip"
 
                    title="${h.tooltip(_('All default permissions on each repository group will be reset to chosen permission, note that all custom default permission on repository groups will be lost'))}">
 
                    ${_('Overwrite existing settings')}</span> </label>
 

	
 
                    ${_('Apply to all existing repository groups')}</span> </label>
 
                    <span class="help-block">${_('Permissions for the Default user on new repository groups.')}</span>
 
                </div>
 
            </div>
 
            <div class="field">
 
                <div class="label">
 
                    <label for="default_group_perm">${_('User group')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_user_group_perm','',c.user_group_perms_choices)}
 
                    ${h.checkbox('overwrite_default_user_group','true')}
 
                    <label for="overwrite_default_user_group">
 
                    <span class="tooltip"
 
                    title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on user groups will be lost'))}">
 
                    ${_('Overwrite existing settings')}</span> </label>
 

	
 
                    ${_('Apply to all existing user groups')}</span></label>
 
                    <span class="help-block">${_('Permissions for the Default user on new user groups.')}</span>
 
                </div>
 
            </div>
 
             <div class="field">
 
                <div class="label">
 
                    <label for="default_repo_create">${_('Repository creation')}:</label>
 
                    <label for="default_repo_create">${_('Top level repository creation')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_repo_create','',c.repo_create_choices)}
 
                    <span class="help-block">${_('Enable this to allow non-admins to create repositories at the top level.')}</span>
 
                    <span class="help-block">${_('Note: This will also give all users API access to create repositories everywhere. That might change in future versions.')}</span>
 
                </div>
 
             </div>
 
            <div class="field">
 
                <div class="label label-checkbox">
 
                    <label for="create_on_write">${_('Repository creation with group write access')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('create_on_write','',c.repo_create_on_write_choices)}
 
                    <span class="help-block">${_('Write permission to a repository group allows creating repositories inside that group.')}</span>
 
                    <span class="help-block">${_('With this, write permission to a repository group allows creating repositories inside that group. Without this, group write permissions mean nothing.')}</span>
 
                </div>
 
            </div>
 
             <div class="field">
 
                <div class="label">
 
                    <label for="default_user_group_create">${_('User group creation')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_user_group_create','',c.user_group_create_choices)}
 
                    <span class="help-block">${_('Enable this to allow non-admins to create user groups.')}</span>
 
                </div>
 
             </div>
 
             <div class="field">
 
                <div class="label">
 
                    <label for="default_fork">${_('Repository forking')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_fork','',c.fork_choices)}
 
                    <span class="help-block">${_('Enable this to allow non-admins to fork repositories.')}</span>
 
                </div>
 
             </div>
 
             <div class="field">
 
                <div class="label">
 
                    <label for="default_register">${_('Registration')}:</label>
 
                </div>
 
                <div class="select">
 
                    ${h.select('default_register','',c.register_choices)}
 
                </div>
 
             </div>
 
             <div class="field">
 
                <div class="label">
kallithea/templates/data_table/_dt_elements.html
Show inline comments
 
@@ -84,25 +84,25 @@
 
      <i class="icon-wrench" title="${_('Repository creation in progress...')}"></i>
 
    %endif
 
  </div>
 
</%def>
 

	
 
<%def name="last_change(last_change)">
 
  <span class="tooltip" date="${last_change}" title="${h.tooltip(h.fmt_date(last_change))}">${h.age(last_change)}</span>
 
</%def>
 

	
 
<%def name="revision(name,rev,tip,author,last_msg)">
 
  <div>
 
  %if rev >= 0:
 
      <a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip revision-link" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a>
 
      <a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip revision-link safe-html-title" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a>
 
  %else:
 
      ${_('No changesets yet')}
 
  %endif
 
  </div>
 
</%def>
 

	
 
<%def name="rss(name)">
 
  %if c.authuser.username != 'default':
 
    <a title="${_('Subscribe to %s rss feed')% name}" href="${h.url('rss_feed_home',repo_name=name,api_key=c.authuser.api_key)}"><i class="icon-rss-squared"></i></a>
 
  %else:
 
    <a title="${_('Subscribe to %s rss feed')% name}" href="${h.url('rss_feed_home',repo_name=name)}"><i class="icon-rss-squared"></i></a>
 
  %endif
kallithea/tests/api/api_base.py
Show inline comments
 
@@ -1169,24 +1169,83 @@ class _BaseTestApi(object):
 
    def test_api_update_repo_exception_occurred(self):
 
        repo_name = 'api_update_me'
 
        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
        id_, params = _build_data(self.apikey, 'update_repo',
 
                                  repoid=repo_name, owner=TEST_USER_ADMIN_LOGIN,)
 
        response = api_call(self, params)
 
        try:
 
            expected = 'failed to update repo `%s`' % repo_name
 
            self._compare_error(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_repo(repo_name)
 

	
 
    def test_api_update_repo_regular_user_change_repo_name(self):
 
        repo_name = 'admin_owned'
 
        new_repo_name = 'new_repo_name'
 
        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
        RepoModel().grant_user_permission(repo=repo_name,
 
                                          user=self.TEST_USER_LOGIN,
 
                                          perm='repository.admin')
 
        UserModel().revoke_perm('default', 'hg.create.repository')
 
        UserModel().grant_perm('default', 'hg.create.none')
 
        updates = {'name': new_repo_name}
 
        id_, params = _build_data(self.apikey_regular, 'update_repo',
 
                                  repoid=repo_name, **updates)
 
        response = api_call(self, params)
 
        try:
 
            expected = 'no permission to create (or move) repositories'
 
            self._compare_error(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_repo(repo_name)
 
            fixture.destroy_repo(new_repo_name)
 

	
 
    def test_api_update_repo_regular_user_change_repo_name_allowed(self):
 
        repo_name = 'admin_owned'
 
        new_repo_name = 'new_repo_name'
 
        repo = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
        RepoModel().grant_user_permission(repo=repo_name,
 
                                          user=self.TEST_USER_LOGIN,
 
                                          perm='repository.admin')
 
        UserModel().revoke_perm('default', 'hg.create.none')
 
        UserModel().grant_perm('default', 'hg.create.repository')
 
        updates = {'name': new_repo_name}
 
        id_, params = _build_data(self.apikey_regular, 'update_repo',
 
                                  repoid=repo_name, **updates)
 
        response = api_call(self, params)
 
        try:
 
            expected = {
 
                'msg': 'updated repo ID:%s %s' % (repo.repo_id, new_repo_name),
 
                'repository': repo.get_api_data()
 
            }
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_repo(repo_name)
 
            fixture.destroy_repo(new_repo_name)
 

	
 
    def test_api_update_repo_regular_user_change_owner(self):
 
        repo_name = 'admin_owned'
 
        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
        RepoModel().grant_user_permission(repo=repo_name,
 
                                          user=self.TEST_USER_LOGIN,
 
                                          perm='repository.admin')
 
        updates = {'owner': TEST_USER_ADMIN_LOGIN}
 
        id_, params = _build_data(self.apikey_regular, 'update_repo',
 
                                  repoid=repo_name, **updates)
 
        response = api_call(self, params)
 
        try:
 
            expected = 'Only Kallithea admin can specify `owner` param'
 
            self._compare_error(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_repo(repo_name)
 

	
 
    def test_api_delete_repo(self):
 
        repo_name = 'api_delete_me'
 
        fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 

	
 
        id_, params = _build_data(self.apikey, 'delete_repo',
 
                                  repoid=repo_name, )
 
        response = api_call(self, params)
 

	
 
        ret = {
 
            'msg': 'Deleted repository `%s`' % repo_name,
 
            'success': True
 
        }
 
@@ -1294,24 +1353,45 @@ class _BaseTestApi(object):
 
                                          user=self.TEST_USER_LOGIN,
 
                                          perm='repository.none')
 
        fork_name = 'api-repo-fork'
 
        id_, params = _build_data(self.apikey_regular, 'fork_repo',
 
                                  repoid=self.REPO,
 
                                  fork_name=fork_name,
 
        )
 
        response = api_call(self, params)
 
        expected = 'repository `%s` does not exist' % (self.REPO)
 
        self._compare_error(id_, expected, given=response.body)
 
        fixture.destroy_repo(fork_name)
 

	
 
    @parameterized.expand([('read', 'repository.read'),
 
                           ('write', 'repository.write'),
 
                           ('admin', 'repository.admin')])
 
    def test_api_fork_repo_non_admin_no_create_repo_permission(self, name, perm):
 
        fork_name = 'api-repo-fork'
 
        # regardless of base repository permission, forking is disallowed
 
        # when repository creation is disabled
 
        RepoModel().grant_user_permission(repo=self.REPO,
 
                                          user=self.TEST_USER_LOGIN,
 
                                          perm=perm)
 
        UserModel().revoke_perm('default', 'hg.create.repository')
 
        UserModel().grant_perm('default', 'hg.create.none')
 
        id_, params = _build_data(self.apikey_regular, 'fork_repo',
 
                                  repoid=self.REPO,
 
                                  fork_name=fork_name,
 
        )
 
        response = api_call(self, params)
 
        expected = 'no permission to create repositories'
 
        self._compare_error(id_, expected, given=response.body)
 
        fixture.destroy_repo(fork_name)
 

	
 
    def test_api_fork_repo_unknown_owner(self):
 
        fork_name = 'api-repo-fork'
 
        owner = 'i-dont-exist'
 
        id_, params = _build_data(self.apikey, 'fork_repo',
 
                                  repoid=self.REPO,
 
                                  fork_name=fork_name,
 
                                  owner=owner,
 
        )
 
        response = api_call(self, params)
 
        expected = 'user `%s` does not exist' % owner
 
        self._compare_error(id_, expected, given=response.body)
 

	
kallithea/tests/functional/test_login.py
Show inline comments
 
@@ -321,25 +321,25 @@ class TestLoginController(TestController
 
        username = 'test_password_reset_1'
 
        password = 'qweqwe'
 
        email = 'username@python-works.com'
 
        name = 'passwd'
 
        lastname = 'reset'
 

	
 
        new = User()
 
        new.username = username
 
        new.password = password
 
        new.email = email
 
        new.name = name
 
        new.lastname = lastname
 
        new.api_key = generate_api_key(username)
 
        new.api_key = generate_api_key()
 
        Session().add(new)
 
        Session().commit()
 

	
 
        response = self.app.post(url(controller='login',
 
                                     action='password_reset'),
 
                                 {'email': email, })
 

	
 
        self.checkSessionFlash(response, 'Your password reset link was sent')
 

	
 
        response = response.follow()
 

	
 
        # BAD KEY
 
@@ -386,24 +386,26 @@ class TestLoginController(TestController
 
                api_key = User.get_first_admin().api_key
 

	
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
 
                                 action='changeset_raw',
 
                                 repo_name=HG_REPO, revision='tip', api_key=api_key),
 
                             status=403)
 

	
 
    @parameterized.expand([
 
        ('none', None, 302),
 
        ('empty_string', '', 302),
 
        ('fake_number', '123456', 302),
 
        ('fake_not_alnum', 'a-z', 302),
 
        ('fake_api_key', '0123456789abcdef0123456789ABCDEF01234567', 302),
 
        ('proper_api_key', None, 200)
 
    ])
 
    def test_access_whitelisted_page_via_api_key(self, test_name, api_key, code):
 
        whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw'])
 
        with mock.patch('kallithea.CONFIG', whitelist):
 
            self.assertEqual(['ChangesetController:changeset_raw'],
 
                             whitelist['api_access_controllers_whitelist'])
 
            if test_name == 'proper_api_key':
 
                api_key = User.get_first_admin().api_key
 

	
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
kallithea/tests/models/test_permissions.py
Show inline comments
 
@@ -52,24 +52,26 @@ class TestPermissions(BaseTestCase):
 

	
 
        UserModel().delete(self.u1)
 
        UserModel().delete(self.u2)
 
        UserModel().delete(self.u3)
 
        UserModel().delete(self.a1)
 
        if hasattr(self, 'g1'):
 
            RepoGroupModel().delete(self.g1.group_id)
 
        if hasattr(self, 'g2'):
 
            RepoGroupModel().delete(self.g2.group_id)
 

	
 
        if hasattr(self, 'ug1'):
 
            UserGroupModel().delete(self.ug1, force=True)
 
        if hasattr(self, 'ug2'):
 
            UserGroupModel().delete(self.ug2, force=True)
 

	
 
        Session().commit()
 

	
 
    def test_default_perms_set(self):
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        perms = {
 
            'repositories_groups': {},
 
            'global': set([u'hg.create.repository', u'repository.read',
 
                           u'hg.register.manual_activate']),
 
            'repositories': {HG_REPO: u'repository.read'}
 
        }
 
        self.assertEqual(u1_auth.permissions['repositories'][HG_REPO],
 
@@ -425,24 +427,236 @@ class TestPermissions(BaseTestCase):
 
        self.u1.inherit_default_permissions = False
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        # this user will have non inherited permissions from he's
 
        # explicitly set permissions
 
        self.assertEqual(u1_auth.permissions['global'],
 
                         set(['hg.create.repository', 'hg.fork.repository',
 
                              'hg.register.manual_activate',
 
                              'hg.extern_activate.auto',
 
                              'repository.read', 'group.read',
 
                              'usergroup.read', 'hg.create.write_on_repogroup.true']))
 

	
 
    def test_inactive_user_group_does_not_affect_global_permissions(self):
 
        # Issue #138: Inactive User Groups affecting permissions
 
        # Add user to inactive user group, set specific permissions on user
 
        # group and disable inherit-from-default. User permissions should still
 
        # inherit from default.
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        # enable fork and create on user group
 
        user_group_model.revoke_perm(self.ug1, perm='hg.create.none')
 
        user_group_model.grant_perm(self.ug1, perm='hg.create.repository')
 
        user_group_model.revoke_perm(self.ug1, perm='hg.fork.none')
 
        user_group_model.grant_perm(self.ug1, perm='hg.fork.repository')
 

	
 
        user_model = UserModel()
 
        # disable fork and create on default user
 
        usr = 'default'
 
        user_model.revoke_perm(usr, 'hg.create.repository')
 
        user_model.grant_perm(usr, 'hg.create.none')
 
        user_model.revoke_perm(usr, 'hg.fork.repository')
 
        user_model.grant_perm(usr, 'hg.fork.none')
 

	
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 

	
 
        self.assertEqual(u1_auth.permissions['global'],
 
                         set(['hg.create.none', 'hg.fork.none',
 
                              'hg.register.manual_activate',
 
                              'hg.extern_activate.auto',
 
                              'repository.read', 'group.read',
 
                              'usergroup.read',
 
                              'hg.create.write_on_repogroup.true']))
 

	
 
    def test_inactive_user_group_does_not_affect_global_permissions_inverse(self):
 
        # Issue #138: Inactive User Groups affecting permissions
 
        # Add user to inactive user group, set specific permissions on user
 
        # group and disable inherit-from-default. User permissions should still
 
        # inherit from default.
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        # disable fork and create on user group
 
        user_group_model.revoke_perm(self.ug1, perm='hg.create.repository')
 
        user_group_model.grant_perm(self.ug1, perm='hg.create.none')
 
        user_group_model.revoke_perm(self.ug1, perm='hg.fork.repository')
 
        user_group_model.grant_perm(self.ug1, perm='hg.fork.none')
 

	
 
        user_model = UserModel()
 
        # enable fork and create on default user
 
        usr = 'default'
 
        user_model.revoke_perm(usr, 'hg.create.none')
 
        user_model.grant_perm(usr, 'hg.create.repository')
 
        user_model.revoke_perm(usr, 'hg.fork.none')
 
        user_model.grant_perm(usr, 'hg.fork.repository')
 

	
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 

	
 
        self.assertEqual(u1_auth.permissions['global'],
 
                         set(['hg.create.repository', 'hg.fork.repository',
 
                              'hg.register.manual_activate',
 
                              'hg.extern_activate.auto',
 
                              'repository.read', 'group.read',
 
                              'usergroup.read',
 
                              'hg.create.write_on_repogroup.true']))
 

	
 
    def test_inactive_user_group_does_not_affect_repo_permissions(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        # note: make u2 repo owner rather than u1, because the owner always has
 
        # admin permissions
 
        self.test_repo = fixture.create_repo(name='myownrepo',
 
                                             repo_type='hg',
 
                                             cur_user=self.u2)
 

	
 
        # enable admin access for user group on repo
 
        RepoModel().grant_user_group_permission(self.test_repo,
 
                                                group_name=self.ug1,
 
                                                perm='repository.admin')
 
        # enable only write access for default user on repo
 
        RepoModel().grant_user_permission(self.test_repo,
 
                                          user='default',
 
                                          perm='repository.write')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['repositories']['myownrepo'],
 
                         'repository.write')
 

	
 
    def test_inactive_user_group_does_not_affect_repo_permissions_inverse(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        # note: make u2 repo owner rather than u1, because the owner always has
 
        # admin permissions
 
        self.test_repo = fixture.create_repo(name='myownrepo',
 
                                             repo_type='hg',
 
                                             cur_user=self.u2)
 

	
 
        # enable only write access for user group on repo
 
        RepoModel().grant_user_group_permission(self.test_repo,
 
                                                group_name=self.ug1,
 
                                                perm='repository.write')
 
        # enable admin access for default user on repo
 
        RepoModel().grant_user_permission(self.test_repo,
 
                                          user='default',
 
                                          perm='repository.admin')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['repositories']['myownrepo'],
 
                         'repository.admin')
 

	
 
    def test_inactive_user_group_does_not_affect_repo_group_permissions(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
 

	
 
        # enable admin access for user group on repo group
 
        RepoGroupModel().grant_user_group_permission(self.g1,
 
                                                     group_name=self.ug1,
 
                                                     perm='group.admin')
 
        # enable only write access for default user on repo group
 
        RepoGroupModel().grant_user_permission(self.g1,
 
                                               user='default',
 
                                               perm='group.write')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['repositories_groups'],
 
                         {u'group1': u'group.write'})
 

	
 
    def test_inactive_user_group_does_not_affect_repo_group_permissions_inverse(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        self.g1 = fixture.create_repo_group('group1', skip_if_exists=True)
 

	
 
        # enable only write access for user group on repo group
 
        RepoGroupModel().grant_user_group_permission(self.g1,
 
                                                     group_name=self.ug1,
 
                                                     perm='group.write')
 
        # enable admin access for default user on repo group
 
        RepoGroupModel().grant_user_permission(self.g1,
 
                                               user='default',
 
                                               perm='group.admin')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['repositories_groups'],
 
                         {u'group1': u'group.admin'})
 

	
 
    def test_inactive_user_group_does_not_affect_user_group_permissions(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        self.ug2 = fixture.create_user_group('G2')
 

	
 
        # enable admin access for user group on user group
 
        UserGroupModel().grant_user_group_permission(self.ug2,
 
                                                     user_group=self.ug1,
 
                                                     perm='usergroup.admin')
 
        # enable only write access for default user on user group
 
        UserGroupModel().grant_user_permission(self.ug2,
 
                                               user='default',
 
                                               perm='usergroup.write')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['user_groups'][u'G1'], u'usergroup.read')
 
        self.assertEqual(u1_auth.permissions['user_groups'][u'G2'], u'usergroup.write')
 

	
 
    def test_inactive_user_group_does_not_affect_user_group_permissions_inverse(self):
 
        self.ug1 = fixture.create_user_group('G1')
 
        self.ug1.inherit_default_permissions = False
 
        user_group_model = UserGroupModel()
 
        user_group_model.add_user_to_group(self.ug1, self.u1)
 
        user_group_model.update(self.ug1, {'users_group_active': False})
 

	
 
        self.ug2 = fixture.create_user_group('G2')
 

	
 
        # enable only write access for user group on user group
 
        UserGroupModel().grant_user_group_permission(self.ug2,
 
                                                     user_group=self.ug1,
 
                                                     perm='usergroup.write')
 
        # enable admin access for default user on user group
 
        UserGroupModel().grant_user_permission(self.ug2,
 
                                               user='default',
 
                                               perm='usergroup.admin')
 
        Session().commit()
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['user_groups'][u'G1'], u'usergroup.read')
 
        self.assertEqual(u1_auth.permissions['user_groups'][u'G2'], u'usergroup.admin')
 

	
 
    def test_owner_permissions_doesnot_get_overwritten_by_group(self):
 
        #create repo as USER,
 
        self.test_repo = fixture.create_repo(name='myownrepo',
 
                                             repo_type='hg',
 
                                             cur_user=self.u1)
 

	
 
        #he has permissions of admin as owner
 
        u1_auth = AuthUser(user_id=self.u1.user_id)
 
        self.assertEqual(u1_auth.permissions['repositories']['myownrepo'],
 
                         'repository.admin')
 
        #set his permission as user group, he should still be admin
 
        self.ug1 = fixture.create_user_group('G1')
0 comments (0 inline, 0 general)