Changeset - b2c3d4568a5f
[Not reviewed]
Merge default
0 36 0
Mads Kiilerich - 3 years ago 2023-03-31 21:29:14
mads@kiilerich.com
Merge stable
36 files changed with 892 insertions and 991 deletions:
0 comments (0 inline, 0 general)
CONTRIBUTORS
Show inline comments
 
List of contributors to Kallithea project:
 

	
 
    Mads Kiilerich <mads@kiilerich.com> 2016-2023
 
    Manuel Jacob <me@manueljacob.de> 2019-2020 2022-2023
 
    Mathias De Mare <mathias.de_mare@nokia.com> 2023
 
    Asterios Dimitriou <steve@pci.gr> 2016-2017 2020 2022
 
    Jaime Marquínez Ferrándiz <weblate@jregistros.fastmail.net> 2022
 
    Louis Bertrand <louis.bertrand@durhamcollege.ca> 2022
 
    toras9000 <toras9000@gmail.com> 2022
 
    yzqzss <yzqzss@othing.xyz> 2022
 
    МАН69К <weblate@mah69k.net> 2022
 
    Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> 2014-2021
 
    Mads Kiilerich <mads@kiilerich.com> 2016-2021
 
    ssantos <ssantos@web.de> 2018-2021
 
    Private <adamantine.sword@gmail.com> 2019-2021
 
    Étienne Gilli <etienne@gilli.io> 2020-2021
 
@@ -11,10 +19,8 @@ List of contributors to Kallithea projec
 
    Michalis <michalisntovas@yahoo.gr> 2021
 
    vs <vsuhachev@yandex.ru> 2021
 
    Александр <akonn7@mail.ru> 2021
 
    Asterios Dimitriou <steve@pci.gr> 2016-2017 2020
 
    Allan Nordhøy <epost@anotheragency.no> 2017-2020
 
    Anton Schur <tonich.sh@gmail.com> 2017 2020
 
    Manuel Jacob <me@manueljacob.de> 2019-2020
 
    Artem <kovalevartem.ru@gmail.com> 2020
 
    David Ignjić <ignjic@gmail.com> 2020
 
    Dennis Fink <dennis.fink@c3l.lu> 2020
docs/api/api.rst
Show inline comments
 
@@ -23,7 +23,7 @@ API access
 
Clients must send JSON encoded JSON-RPC requests::
 

	
 
    {
 
        "id: "<id>",
 
        "id": "<id>",
 
        "api_key": "<api_key>",
 
        "method": "<method_name>",
 
        "args": {"<arg_key>": "<arg_val>"}
 
@@ -175,23 +175,22 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "get_ip"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
                 "ip_addr_server": <ip_from_clien>",
 
                 "ip_addr_server" : <ip_from_client>",
 
                 "user_ips": [
 
                                {
 
                                   "ip_addr": "<ip_with_mask>",
 
                                   "ip_range": ["<start_ip>", "<end_ip>"],
 
                                   "ip_range" : ["<start_ip>", "<end_ip>"]
 
                                },
 
                                ...
 
                             ]
 
             }
 

	
 
    error :  null
 

	
 
get_user
 
@@ -225,7 +224,7 @@ OUTPUT::
 
                "emails":       "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login":   "<last_login>",
 
                "permissions": {
 
@@ -234,7 +233,7 @@ OUTPUT::
 
                               "hg.register.manual_activate"],
 
                    "repositories": {"repo1": "repository.none"},
 
                    "repositories_groups": {"Group1": "group.read"}
 
                 },
 
                 }
 
            }
 
    error:  null
 

	
 
@@ -265,9 +264,9 @@ OUTPUT::
 
                "emails":       "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login":   "<last_login>",
 
                "last_login" :  "<last_login>"
 
              },
 
 
            ]
 
@@ -310,10 +309,10 @@ OUTPUT::
 
                "email" :    "<email>",
 
                "emails":    "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
              },
 
                "last_login": "<last_login>"
 
              }
 
            }
 
    error:  null
 

	
 
@@ -358,10 +357,10 @@ OUTPUT::
 
                "email" :    "<email>",
 
                "emails":    "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
              },
 
                "last_login": "<last_login>"
 
              }
 
            }
 
    error:  null
 

	
 
@@ -377,7 +376,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "delete_user"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 
@@ -422,9 +421,9 @@ OUTPUT::
 
                                "email" :    "<email>",
 
                                "emails":    "<list_of_all_additional_emails>",
 
                                "active" :   "<bool>",
 
                                "admin" :    "<bool>",
 
                                "admin" :    "<bool>",
 
                                "ldap_dn" :  "<ldap_dn>",
 
                                "last_login": "<last_login>",
 
                                "last_login": "<last_login>"
 
                              },
 
 
                            ]
 
@@ -451,7 +450,7 @@ OUTPUT::
 
               {
 
               "users_group_id" : "<id>",
 
               "group_name" :     "<groupname>",
 
               "active":          "<bool>",
 
               "active" :         "<bool>"
 
               },
 
 
              ]
 
@@ -482,15 +481,15 @@ OUTPUT::
 
              "users_group": {
 
                     "users_group_id" : "<id>",
 
                     "group_name" :     "<groupname>",
 
                     "active":          "<bool>",
 
               },
 
                     "active" :         "<bool>"
 
               }
 
            }
 
    error:  null
 

	
 
add_user_to_user_group
 
^^^^^^^^^^^^^^^^^^^^^^
 

	
 
Adds a user to a user group. If the user already is in that group, success will be
 
Add a user to a user group. If the user already is in that group, success will be
 
``false``.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
@@ -501,14 +500,14 @@ INPUT::
 
    method :  "add_user_user_group"
 
    args:     {
 
                "usersgroupid" : "<user group id or name>",
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: {
 
              "success": True|False # depends on if member is in group
 
              "success" : True|False,  # depends on if member is in group
 
              "msg": "added member `<username>` to a user group `<groupname>` |
 
                      User is already in that group"
 
            }
 
@@ -528,7 +527,7 @@ INPUT::
 
    method :  "remove_user_from_user_group"
 
    args:     {
 
                "usersgroupid" : "<user group id or name>",
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username>"
 
              }
 

	
 
OUTPUT::
 
@@ -541,6 +540,167 @@ OUTPUT::
 
            }
 
    error:  null
 

	
 
get_repo_group
 
^^^^^^^^^^^^^^
 

	
 
Get an existing repository group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repo_group"
 
    args :    {
 
                "repogroupid" : "<repo group id or name>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result :
 
               {
 
               "group_id" :          "<id>",
 
               "group_name" :        "<groupname>",
 
               "group_description" : "<groupdescription>",
 
               "parent_group" :      "<groupid>"|null,
 
               "repositories" :      "<list_of_all_repo_names_in_group>",
 
               "owner" :             "<owner>",
 
               "members" :           [
 
                                       {
 
                                         "name" : "<name>",
 
                                         "type" : "user",
 
                                         "permission" : "group.(none|read|write|admin)"
 
                                       },
 
                                       {
 
                                         "name" : "<name>",
 
                                         "type" : "user_group",
 
                                         "permission" : "group.(none|read|write|admin)"
 
                                       },
 
 
                                     ]
 

	
 
               },
 
    error : null
 

	
 
get_repo_groups
 
^^^^^^^^^^^^^^^
 

	
 
List all existing repository groups.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repo_groups"
 
    args :    { }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : [
 
               {
 
               "group_id" :          "<id>",
 
               "group_name" :        "<groupname>",
 
               "group_description" : "<groupdescription>",
 
               "parent_group" :      "<groupid>"|null,
 
               "repositories" :      "<list_of_all_repo_names_in_group>",
 
               "owner" :             "<owner>"
 
               },
 
 
              ]
 
    error : null
 

	
 
create_repo_group
 
^^^^^^^^^^^^^^^^^
 

	
 
Create a new repository group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "create_repo_group"
 
    args :    {
 
                "group_name" :       "<group_name>",
 
                "description" :      "<description> = Optional("")",
 
                "owner" :            "<username or user_id> = Optional(None)",
 
                "parent" :           "<reponame or id> = Optional(None)",
 
                "copy_permissions" : "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
                "msg" : "created new repo group `<group_name>`",
 
                "repo_group" : {
 
                                 "group_id" :          <id>,
 
                                 "group_name" :        "<parent_group>/<group_name>",
 
                                 "group_description" : "<description>",
 
                                 "parent_group" :      <id>|null,
 
                                 "repositories" :      <list of repositories>,
 
                                 "owner" :             "<user_name>"
 
                                }
 

	
 
update_repo_group
 
^^^^^^^^^^^^^^^^^
 

	
 
Update a repository group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "update_repo_group"
 
    args :    {
 
                "repogroupid" :         "<id>",
 
                "group_name" :       "<group_name> = Optional(None)",
 
                "description" :      "<description> = Optional(None)",
 
                "owner" :            "<username or user_id> = Optional(None)",
 
                "parent" :           "<reponame or id> = Optional(None)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
                "msg" : "updated repository group ID:<id> <group_name>",
 
                "repo_group" : {
 
                                 "group_id" :          <id>,
 
                                 "group_name" :        "<parent_group>/<group_name>",
 
                                 "group_description" : "<description>",
 
                                 "parent_group" :      <id>|null,
 
                                 "repositories" :      <list of repositories>,
 
                                 "owner" :             "<user_name>"
 
                                }
 

	
 
delete_repo_group
 
^^^^^^^^^^^^^^^^^
 

	
 
Delete a repository group.
 
This command can only be executed using the api_key of a user with admin rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "delete_repo_group"
 
    args :    {
 
                "repogroupid" : "<id>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : {
 
                "msg" : "deleted repo group ID:<id> <group_name>",
 
                "repo_group" : null
 
              }
 

	
 
get_repo
 
^^^^^^^^
 

	
 
@@ -557,7 +717,7 @@ INPUT::
 
    args:     {
 
                "repoid" : "<reponame or repo_id>",
 
                "with_revision_names": "<bool> = Optional(False)",
 
                "with_pullrequests": "<bool> = Optional(False)",
 
                "with_pullrequests" : "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 
@@ -566,7 +726,7 @@ OUTPUT::
 
    result: None if repository does not exist or
 
            {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "enable_downloads":  "<bool>",
 
@@ -596,7 +756,7 @@ OUTPUT::
 
                                    "email" :      "<email>",
 
                                    "emails":      "<list_of_all_additional_emails>",
 
                                    "active" :     "<bool>",
 
                                    "admin" :      "<bool>",
 
                                    "admin" :      "<bool>",
 
                                    "ldap_dn" :    "<ldap_dn>",
 
                                    "last_login":  "<last_login>",
 
                                    "permission" : "repository.(read|write|admin)"
 
@@ -622,9 +782,9 @@ OUTPUT::
 
                                    "emails":       "<list_of_all_additional_emails>",
 
                                    "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                                    "active" :      "<bool>",
 
                                    "admin" :       "<bool>",
 
                                    "admin" :       "<bool>",
 
                                    "ldap_dn" :     "<ldap_dn>",
 
                                    "last_login":   "<last_login>",
 
                                    "last_login" :  "<last_login>"
 
                                  },
 
 
                                ],
 
@@ -651,7 +811,7 @@ OUTPUT::
 
                    "url": "<pull_request_url>",
 
                    "reviewers": [
 
                      {
 
                        "username": "<user_id>",
 
                        "username" : "<user_id>"
 
                      },
 
                      ...
 
                    ],
 
@@ -670,7 +830,7 @@ OUTPUT::
 
                      {
 
                        "username": "<user_id>",
 
                        "text": "<comment text>",
 
                        "comment_id": "<comment_id>",
 
                        "comment_id" : "<comment_id>"
 
                      },
 
                      ...
 
                    ],
 
@@ -713,7 +873,7 @@ OUTPUT::
 
    result: [
 
              {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private" :          "<bool>",
 
@@ -723,7 +883,7 @@ OUTPUT::
 
                "owner":             "<repo_owner>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "enable_downloads":  "<bool>",
 
                "enable_statistics": "<bool>",
 
                "enable_statistics": "<bool>"
 
              },
 
 
            ]
 
@@ -742,7 +902,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "get_repo_nodes"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "revision"  : "<revision>",
 
                "root_path" : "<root_path>",
 
                "ret_type"  : "<ret_type> = Optional('all')"
 
@@ -753,8 +913,8 @@ OUTPUT::
 
    id : <id_given_in_input>
 
    result: [
 
              {
 
                "name" :        "<name>"
 
                "type" :        "<type>",
 
                "name" :        "<name>",
 
                "type" :        "<type>"
 
              },
 
 
            ]
 
@@ -787,7 +947,7 @@ INPUT::
 
                "clone_uri" :        "<clone_uri> = Optional(None)",
 
                "landing_rev" :      "<landing_rev> = Optional('tip')",
 
                "enable_downloads":  "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 
@@ -797,7 +957,7 @@ OUTPUT::
 
              "msg": "Created new repository `<reponame>`",
 
              "repo": {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private" :          "<bool>",
 
@@ -807,8 +967,8 @@ OUTPUT::
 
                "owner":             "<username or user_id>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "enable_downloads":  "<bool>",
 
                "enable_statistics": "<bool>",
 
              },
 
                "enable_statistics": "<bool>"
 
              }
 
            }
 
    error:  null
 

	
 
@@ -826,7 +986,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "update_repo"
 
    args:     {
 
                "repoid" :           "<reponame or repo_id>"
 
                "repoid" :           "<reponame or repo_id>",
 
                "name" :             "<reponame> = Optional('')",
 
                "group" :            "<group_id> = Optional(None)",
 
                "owner" :            "<owner_name_or_id = Optional(=apiuser)>",
 
@@ -835,7 +995,7 @@ INPUT::
 
                "clone_uri" :        "<clone_uri> = Optional(None)",
 
                "landing_rev" :      "<landing_rev> = Optional('tip')",
 
                "enable_downloads":  "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)"
 
              }
 

	
 
OUTPUT::
 
@@ -845,7 +1005,7 @@ OUTPUT::
 
              "msg": "updated repo ID:repo_id `<reponame>`",
 
              "repository": {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private":           "<bool>",
 
@@ -864,7 +1024,7 @@ OUTPUT::
 
                                       "revision": "<numeric_revision>",
 
                                       "short_id": "<short_id>"
 
                                     }
 
              },
 
              }
 
            }
 
    error:  null
 

	
 
@@ -892,7 +1052,6 @@ INPUT::
 
                "copy_permissions": "<bool>",
 
                "private":          "<bool>",
 
                "landing_rev":      "<landing_rev>"
 

	
 
              }
 

	
 
OUTPUT::
 
@@ -943,9 +1102,9 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "grant_user_permission"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
                "userid" : "<username or user_id>"
 
                "perm" :       "(repository.(none|read|write|admin))",
 
                "repoid" : "<reponame or repo_id>",
 
                "userid" : "<username or user_id>",
 
                "perm" :       "(repository.(none|read|write|admin))"
 
              }
 

	
 
OUTPUT::
 
@@ -969,7 +1128,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method  : "revoke_user_permission"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "userid" : "<username or user_id>"
 
              }
 

	
 
@@ -995,9 +1154,9 @@ INPUT::
 
    api_key : "<api_key>"
 
    method :  "grant_user_group_permission"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
                "usersgroupid" : "<user group id or name>"
 
                "perm" : "(repository.(none|read|write|admin))",
 
                "repoid" : "<reponame or repo_id>",
 
                "usersgroupid" : "<user group id or name>",
 
                "perm" : "(repository.(none|read|write|admin))"
 
              }
 

	
 
OUTPUT::
 
@@ -1021,7 +1180,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method  : "revoke_user_group_permission"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
                "repoid" : "<reponame or repo_id>",
 
                "usersgroupid" : "<user group id or name>"
 
              }
 

	
 
@@ -1062,7 +1221,7 @@ OUTPUT::
 
    result: [
 
    {
 
      "raw_id": "<raw_id>",
 
      "short_id": "short_id": "<short_id>",
 
      "short_id" : "<short_id>",
 
      "author": "<full_author>",
 
      "date": "<date_time_of_commit>",
 
      "message": "<commit_message>",
 
@@ -1157,7 +1316,7 @@ INPUT::
 
    api_key : "<api_key>"
 
    method  : "get_pullrequest"
 
    args:     {
 
                "pullrequest_id" : "<pullrequest_id>",
 
                "pullrequest_id" : "<pullrequest_id>"
 
              }
 

	
 
OUTPUT::
 
@@ -1171,7 +1330,7 @@ OUTPUT::
 
        "url": "<pull_request_url>",
 
        "reviewers": [
 
          {
 
            "username": "<user_name>",
 
            "username" : "<user_name>"
 
          },
 
          ...
 
        ],
 
@@ -1190,7 +1349,7 @@ OUTPUT::
 
          {
 
            "username": "<user_name>",
 
            "text": "<comment text>",
 
            "comment_id": "<comment_id>",
 
            "comment_id" : "<comment_id>"
 
          },
 
          ...
 
        ],
 
@@ -1225,7 +1384,7 @@ INPUT::
 
                "pull_request_id":  "<pull_request_id>",
 
                "comment_msg":      Optional(''),
 
                "status":           Optional(None),     # "under_review", "approved" or "rejected"
 
                "close_pr":         Optional(False)",
 
                "close_pr" :        Optional(False)"
 
              }
 

	
 
OUTPUT::
docs/conf.py
Show inline comments
 
@@ -47,7 +47,7 @@ master_doc = 'index'
 

	
 
# General information about the project.
 
project = 'Kallithea'
 
copyright = '2010-2022 by various authors, licensed as GPLv3.'
 
copyright = '2010-2023 by various authors, licensed as GPLv3.'
 

	
 
# The version info for the project you're documenting, acts as replacement for
 
# |version| and |release|, also used in various other places throughout the
kallithea/controllers/admin/repo_groups.py
Show inline comments
 
@@ -76,6 +76,7 @@ class RepoGroupsController(base.BaseCont
 
        repo_group = db.RepoGroup.get_or_404(group_id)
 
        data = repo_group.get_dict()
 
        data['group_name'] = repo_group.name
 
        data['owner'] = repo_group.owner.username
 

	
 
        # fill repository group users
 
        for p in repo_group.repo_group_to_perm:
 
@@ -146,7 +147,7 @@ class RepoGroupsController(base.BaseCont
 
                group_name=form_result['group_name'],
 
                group_description=form_result['group_description'],
 
                parent=form_result['parent_group_id'],
 
                owner=request.authuser.user_id, # TODO: make editable
 
                owner=request.authuser.user_id,
 
                copy_permissions=form_result['group_copy_permissions']
 
            )
 
            meta.Session().commit()
kallithea/controllers/api/api.py
Show inline comments
 
@@ -65,8 +65,6 @@ def store_update(updates, attr, name):
 
def get_user_or_error(userid):
 
    """
 
    Get user by id or name or return JsonRPCError if not found
 

	
 
    :param userid:
 
    """
 
    user = UserModel().get_user(userid)
 
    if user is None:
 
@@ -77,8 +75,6 @@ def get_user_or_error(userid):
 
def get_repo_or_error(repoid):
 
    """
 
    Get repo by id or name or return JsonRPCError if not found
 

	
 
    :param repoid:
 
    """
 
    repo = RepoModel().get_repo(repoid)
 
    if repo is None:
 
@@ -89,8 +85,6 @@ def get_repo_or_error(repoid):
 
def get_repo_group_or_error(repogroupid):
 
    """
 
    Get repo group by id or name or return JsonRPCError if not found
 

	
 
    :param repogroupid:
 
    """
 
    repo_group = db.RepoGroup.guess_instance(repogroupid)
 
    if repo_group is None:
 
@@ -102,8 +96,6 @@ def get_repo_group_or_error(repogroupid)
 
def get_user_group_or_error(usergroupid):
 
    """
 
    Get user group by id or name or return JsonRPCError if not found
 

	
 
    :param usergroupid:
 
    """
 
    user_group = UserGroupModel().get_group(usergroupid)
 
    if user_group is None:
 
@@ -114,8 +106,6 @@ def get_user_group_or_error(usergroupid)
 
def get_perm_or_error(permid, prefix=None):
 
    """
 
    Get permission by id or name or return JsonRPCError if not found
 

	
 
    :param permid:
 
    """
 
    perm = db.Permission.get_by_key(permid)
 
    if perm is None:
 
@@ -130,8 +120,6 @@ def get_perm_or_error(permid, prefix=Non
 
def get_gist_or_error(gistid):
 
    """
 
    Get gist by id or gist_access_id or return JsonRPCError if not found
 

	
 
    :param gistid:
 
    """
 
    gist = GistModel().get_gist(gistid)
 
    if gist is None:
 
@@ -165,30 +153,15 @@ class ApiController(JSONRPCController):
 
        automatically keep remote repos up to date. This command can be executed
 
        only using api_key belonging to user with admin rights
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param clone_uri: repository URI to pull from (optional)
 
        :type clone_uri: str
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            "msg": "Pulled from `<repository name>`"
 
                "msg" : "Pulled from `<repository name>`",
 
            "repository": "<repository name>"
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "Unable to pull changes from `<reponame>`"
 
          }
 

	
 
        """
 

	
 
        repo = get_repo_or_error(repoid)
 

	
 
        try:
 
@@ -214,10 +187,6 @@ class ApiController(JSONRPCController):
 
        aka "clean zombies". This command can be executed only using api_key
 
        belonging to user with admin rights.
 

	
 
        :param remove_obsolete: deletes repositories from
 
            database that are not found on the filesystem
 
        :type remove_obsolete: Optional(bool)
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
@@ -226,17 +195,7 @@ class ApiController(JSONRPCController):
 
            'removed': [<removed repository name>,...]
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            'Error occurred during rescan repositories action'
 
          }
 

	
 
        """
 

	
 
        try:
 
            rm_obsolete = remove_obsolete
 
            added, removed = repo2db_mapper(ScmModel().repo_scan(),
 
@@ -254,9 +213,6 @@ class ApiController(JSONRPCController):
 
        This command can be executed only using api_key belonging to user with admin
 
        rights or regular user that have write or admin or write access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
@@ -265,15 +221,6 @@ class ApiController(JSONRPCController):
 
            'repository': <repository name>
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            'Error occurred during cache invalidation action'
 
          }
 

	
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -301,23 +248,20 @@ class ApiController(JSONRPCController):
 
        This command can be executed only using api_key belonging to user with
 
        admin rights.
 

	
 
        :param userid: username to show ips for
 
        :type userid: Optional(str or int)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : {
 
                         "server_ip_addr": "<ip_from_clien>",
 
                         "server_ip_addr" : "<ip_from_client>",
 
                         "user_ips": [
 
                                        {
 
                                           "ip_addr": "<ip_with_mask>",
 
                                           "ip_range": ["<start_ip>", "<end_ip>"],
 
                                           "ip_range" : ["<start_ip>", "<end_ip>"]
 
                                        },
 
                                        ...
 
                                     ]
 
            }
 

	
 
            error : null
 
        """
 
        if userid is None:
 
            userid = request.authuser.user_id
 
@@ -336,15 +280,16 @@ class ApiController(JSONRPCController):
 
        """
 
        return server info, including Kallithea version and installed packages
 

	
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            'modules': [<module name>,...]
 
                'modules' : [ [<module name>, <module version>], ...]
 
            'py_version': <python version>,
 
            'platform': <platform type>,
 
            'kallithea_version': <kallithea version>
 
                'kallithea_version' : <kallithea version>,
 
                'git_version' : '<git version>',
 
                'git_path' : '<git path>'
 
          }
 
          error :  null
 
        """
 
@@ -358,39 +303,29 @@ class ApiController(JSONRPCController):
 
        belonging to user with admin rights, or regular users that cannot
 
        specify different userid than theirs
 

	
 
        :param userid: user to get data for
 
        :type userid: Optional(str or int)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: None if user does not exist or
 
                    {
 
                        "user_id" :     "<user_id>",
 
                        "api_key" :     "<api_key>",
 
                        "api_keys":     "[<list of all API keys including additional ones>]"
 
                        "username" :    "<username>",
 
                        "firstname":    "<firstname>",
 
                        "lastname" :    "<lastname>",
 
                        "email" :       "<email>",
 
                        "emails":       "[<list of all emails including additional ones>]",
 
                        "ip_addresses": "[<ip_address_for_user>,...]",
 
                        "active" :      "<bool: user active>",
 
                        "admin" :       "<bool: user is admin>",
 
                        "extern_name" : "<extern_name>",
 
                        "extern_type" : "<extern type>
 
                        "last_login":   "<last_login>",
 
                        "admin" :       "<bool: user is admin>",
 
                        "permissions": {
 
                            "global": ["hg.create.repository",
 
                                       "repository.read",
 
                                       "hg.register.manual_activate"],
 
                            "repositories": {"repo1": "repository.none"},
 
                            "repositories_groups": {"Group1": "group.read"}
 
                         },
 
                            "repositories_groups" : {"Group1" : "group.read"},
 
                            "user_groups" : { "usrgrp1" : "usergroup.admin" }
 
                    }
 

	
 
                     }
 
            error:  null
 

	
 
        """
 
        if not HasPermissionAny('hg.admin')():
 
            # make sure normal user does not pass someone else userid,
 
@@ -414,14 +349,12 @@ class ApiController(JSONRPCController):
 
        Lists all existing users. This command can be executed only using api_key
 
        belonging to user with admin rights.
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: [<user_object>, ...]
 
            error:  null
 
        """
 

	
 
        return [
 
            user.get_api_data()
 
            for user in db.User.query()
 
@@ -439,26 +372,6 @@ class ApiController(JSONRPCController):
 
        Creates new user. Returns new user object. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param username: new username
 
        :type username: str or int
 
        :param email: email
 
        :type email: str
 
        :param password: password
 
        :type password: Optional(str)
 
        :param firstname: firstname
 
        :type firstname: Optional(str)
 
        :param lastname: lastname
 
        :type lastname: Optional(str)
 
        :param active: active
 
        :type active: Optional(bool)
 
        :param admin: admin
 
        :type admin: Optional(bool)
 
        :param extern_name: name of extern
 
        :type extern_name: Optional(str)
 
        :param extern_type: extern_type
 
        :type extern_type: Optional(str)
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -467,21 +380,7 @@ class ApiController(JSONRPCController):
 
                      "user": <user_obj>
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "user `<username>` already exist"
 
            or
 
            "email `<email>` already exist"
 
            or
 
            "failed to create user `<username>`"
 
          }
 

	
 
        """
 

	
 
        if db.User.get_by_username(username):
 
            raise JSONRPCError("user `%s` already exist" % (username,))
 

	
 
@@ -519,47 +418,15 @@ class ApiController(JSONRPCController):
 
        updates given user if such user exists. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param userid: userid to update
 
        :type userid: str or int
 
        :param username: new username
 
        :type username: str or int
 
        :param email: email
 
        :type email: str
 
        :param password: password
 
        :type password: Optional(str)
 
        :param firstname: firstname
 
        :type firstname: Optional(str)
 
        :param lastname: lastname
 
        :type lastname: Optional(str)
 
        :param active: active
 
        :type active: Optional(bool)
 
        :param admin: admin
 
        :type admin: Optional(bool)
 
        :param extern_name:
 
        :type extern_name: Optional(str)
 
        :param extern_type:
 
        :type extern_type: Optional(str)
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: {
 
                      "msg" : "updated user ID:<userid> <username>",
 
                      "user": <user_object>,
 
                      "user" : <user_object>
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to update user `<username>`"
 
          }
 

	
 
        """
 

	
 
        user = get_user_or_error(userid)
 

	
 
        # only non optional arguments will be stored in updates
 
@@ -596,9 +463,6 @@ class ApiController(JSONRPCController):
 
        deletes given user if such user exists. This command can
 
        be executed only using api_key belonging to user with admin rights.
 

	
 
        :param userid: user to delete
 
        :type userid: str or int
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -607,15 +471,6 @@ class ApiController(JSONRPCController):
 
                      "user": null
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to delete user ID:<userid> <username>"
 
          }
 

	
 
        """
 
        user = get_user_or_error(userid)
 

	
 
@@ -639,9 +494,6 @@ class ApiController(JSONRPCController):
 
        belonging to user with admin rights or user who has at least
 
        read access to user group.
 

	
 
        :param usergroupid: id of user_group to edit
 
        :type usergroupid: str or int
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -649,11 +501,12 @@ class ApiController(JSONRPCController):
 
                     {
 
                       "users_group_id" : "<id>",
 
                       "group_name" :     "<groupname>",
 
                       "group_description" : "<description>",
 
                       "active":          "<bool>",
 
                       "owner" :          "<username>",
 
                       "members" :  [<user_obj>,...]
 
                     }
 
            error : null
 

	
 
        """
 
        user_group = get_user_group_or_error(usergroupid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -670,14 +523,12 @@ class ApiController(JSONRPCController):
 
        api_key belonging to user with admin rights or user who has at least
 
        read access to user group.
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result : [<user_group_obj>,...]
 
            error : null
 
        """
 

	
 
        return [
 
            user_group.get_api_data()
 
            for user_group in UserGroupList(db.UserGroup.query().all(), perm_level='read')
 
@@ -691,15 +542,6 @@ class ApiController(JSONRPCController):
 
        belonging to user with admin rights or an user who has create user group
 
        permission
 

	
 
        :param group_name: name of new user group
 
        :type group_name: str
 
        :param description: group description
 
        :type description: str
 
        :param owner: owner of group. If not passed apiuser is the owner
 
        :type owner: Optional(str or int)
 
        :param active: group is active
 
        :type active: Optional(bool)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -708,19 +550,7 @@ class ApiController(JSONRPCController):
 
                      "user_group": <user_group_object>
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "user group `<group name>` already exist"
 
            or
 
            "failed to create group `<group name>`"
 
          }
 

	
 
        """
 

	
 
        if UserGroupModel().get_by_name(group_name):
 
            raise JSONRPCError("user group `%s` already exist" % (group_name,))
 

	
 
@@ -748,17 +578,6 @@ class ApiController(JSONRPCController):
 
        Updates given usergroup.  This command can be executed only using api_key
 
        belonging to user with admin rights or an admin of given user group
 

	
 
        :param usergroupid: id of user group to update
 
        :type usergroupid: str or int
 
        :param group_name: name of new user group
 
        :type group_name: str
 
        :param description: group description
 
        :type description: str
 
        :param owner: owner of group.
 
        :type owner: Optional(str or int)
 
        :param active: group is active
 
        :type active: Optional(bool)
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
@@ -767,15 +586,6 @@ class ApiController(JSONRPCController):
 
            "user_group": <user_group_object>
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to update user group `<user group name>`"
 
          }
 

	
 
        """
 
        user_group = get_user_group_or_error(usergroupid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -809,9 +619,6 @@ class ApiController(JSONRPCController):
 
        This command can be executed only using api_key
 
        belonging to user with admin rights or an admin of given user group
 

	
 
        :param usergroupid:
 
        :type usergroupid: int
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
@@ -819,17 +626,6 @@ class ApiController(JSONRPCController):
 
            "msg": "deleted user group ID:<user_group_id> <user_group_name>"
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to delete user group ID:<user_group_id> <user_group_name>"
 
            or
 
            "RepoGroup assigned to <repo_groups_list>"
 
          }
 

	
 
        """
 
        user_group = get_user_group_or_error(usergroupid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -859,32 +655,17 @@ class ApiController(JSONRPCController):
 
        """
 
        Adds a user to a user group. If user exists in that group success will be
 
        `false`. This command can be executed only using api_key
 
        belonging to user with admin rights  or an admin of given user group
 

	
 
        :param usergroupid:
 
        :type usergroupid: int
 
        :param userid:
 
        :type userid: int
 
        belonging to user with admin rights or an admin of a given user group
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
              "success": True|False # depends on if member is in group
 
              "msg": "added member `<username>` to user group `<groupname>` |
 
                "msg" : "added member `<username>` to a user group `<groupname>` |
 
                      User is already in that group"
 

	
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to add member to user group `<user_group_name>`"
 
          }
 

	
 
        """
 
        user = get_user_or_error(userid)
 
        user_group = get_user_group_or_error(usergroupid)
 
@@ -920,10 +701,6 @@ class ApiController(JSONRPCController):
 
        be `false`. This command can be executed only
 
        using api_key belonging to user with admin rights or an admin of given user group
 

	
 
        :param usergroupid:
 
        :param userid:
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -933,7 +710,6 @@ class ApiController(JSONRPCController):
 
                              User wasn't in group"
 
                    }
 
            error:  null
 

	
 
        """
 
        user = get_user_or_error(userid)
 
        user_group = get_user_group_or_error(usergroupid)
 
@@ -967,16 +743,12 @@ class ApiController(JSONRPCController):
 
        executed only using api_key belonging to user with admin
 
        rights or regular user that have at least read access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            {
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                        "repo_name" :        "<reponame>",
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "enable_downloads":  "<bool>",
 
@@ -992,7 +764,7 @@ class ApiController(JSONRPCController):
 
                                       "raw_id":   "<raw_id>",
 
                                       "revision": "<numeric_revision>",
 
                                       "short_id": "<short_id>"
 
                                     }
 
                                             },
 
                "owner":             "<repo_owner>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "members" :     [
 
@@ -1008,7 +780,7 @@ class ApiController(JSONRPCController):
 
                                    "permission" : "usergroup.(read|write|admin)"
 
                                  },
 
 
                                ]
 
                                        ],
 
                 "followers":   [<user_obj>, ...],
 
                 <if with_revision_names == True>
 
                 "tags": {
 
@@ -1022,11 +794,9 @@ class ApiController(JSONRPCController):
 
                 "bookmarks": {
 
                            "<bookmarkname>": "<raw_id>",
 
                            ...
 
                         },
 
            }
 
          }
 
          error :  null
 

	
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
@@ -1073,24 +843,23 @@ class ApiController(JSONRPCController):
 
        api_key belonging to user with admin rights or regular user that have
 
        admin, write or read access to repository.
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: [
 
                      {
 
                        "repo_id" :          "<repo_id>",
 
                        "repo_name" :        "<reponame>"
 
                        "repo_name" :        "<reponame>",
 
                        "repo_type" :        "<repo_type>",
 
                        "clone_uri" :        "<clone_uri>",
 
                        "private": :         "<bool>",
 
                        "private" :          "<bool>",
 
                        "created_on" :       "<datetimecreated>",
 
                        "description" :      "<description>",
 
                        "landing_rev":       "<landing_rev>",
 
                        "owner":             "<repo_owner>",
 
                        "fork_of":           "<name_of_fork_parent>",
 
                        "enable_downloads":  "<bool>",
 
                        "enable_statistics": "<bool>",
 
                        "enable_statistics": "<bool>"
 
                      },
 
 
                    ]
 
@@ -1115,23 +884,13 @@ class ApiController(JSONRPCController):
 
        `dirs`.  This command can be executed only using api_key belonging to
 
        user with admin rights or regular user that have at least read access to repository.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param revision: revision for which listing should be done
 
        :type revision: str
 
        :param root_path: path from which start displaying
 
        :type root_path: str
 
        :param ret_type: return type 'all|files|dirs' nodes
 
        :type ret_type: Optional(str)
 

	
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: [
 
                      {
 
                        "name" :        "<name>"
 
                        "type" :        "<type>",
 
                        "name" :        "<name>",
 
                        "type" :        "<type>"
 
                      },
 
 
                    ]
 
@@ -1178,46 +937,14 @@ class ApiController(JSONRPCController):
 
        belonging to user with admin rights or regular user that have create
 
        repository permission. Regular users cannot specify owner parameter
 

	
 
        :param repo_name: repository name
 
        :type repo_name: str
 
        :param owner: user_id or username
 
        :type owner: Optional(str)
 
        :param repo_type: 'hg' or 'git'
 
        :type repo_type: Optional(str)
 
        :param description: repository description
 
        :type description: Optional(str)
 
        :param private:
 
        :type private: bool
 
        :param clone_uri:
 
        :type clone_uri: str
 
        :param landing_rev: <rev_type>:<rev>
 
        :type landing_rev: str
 
        :param enable_downloads:
 
        :type enable_downloads: bool
 
        :param enable_statistics:
 
        :type enable_statistics: bool
 
        :param copy_permissions: Copy permission from group that repository is
 
            being created.
 
        :type copy_permissions: bool
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
            result: {
 
                      "msg": "Created new repository `<reponame>`",
 
                      "success": true,
 
                      "task": "<celery task id or None if done sync>"
 
                      "success" : true
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
             'failed to create repository `<repo_name>`
 
          }
 

	
 
        """
 
        group_name = None
 
        repo_name_parts = repo_name.split('/')
 
@@ -1266,8 +993,8 @@ class ApiController(JSONRPCController):
 
                clone_uri=clone_uri,
 
                repo_group=group_name,
 
                repo_landing_rev=landing_rev,
 
                enable_statistics=enable_statistics,
 
                enable_downloads=enable_downloads,
 
                repo_enable_statistics=enable_statistics,
 
                repo_enable_downloads=enable_downloads,
 
                repo_copy_permissions=copy_permissions,
 
            )
 

	
 
@@ -1291,21 +1018,8 @@ class ApiController(JSONRPCController):
 
                    clone_uri=None, landing_rev=None,
 
                    enable_statistics=None,
 
                    enable_downloads=None):
 

	
 
        """
 
        Updates repo
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param name:
 
        :param owner:
 
        :param group:
 
        :param description:
 
        :param private:
 
        :param clone_uri:
 
        :param landing_rev:
 
        :param enable_statistics:
 
        :param enable_downloads:
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -1365,19 +1079,11 @@ class ApiController(JSONRPCController):
 
        user with admin rights or regular user that have fork permission, and at least
 
        read access to forking repository. Regular users cannot specify owner parameter.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param fork_name:
 
        :param owner:
 
        :param description:
 
        :param copy_permissions:
 
        :param private:
 
        :param landing_rev:
 

	
 
        INPUT::
 

	
 
            id : <id_for_response>
 
            api_key : "<api_key>"
 
            method :  "fork_repo"
 
            args:     {
 
                        "repoid" :          "<reponame or repo_id>",
 
                        "fork_name":        "<forkname>",
 
@@ -1393,11 +1099,9 @@ class ApiController(JSONRPCController):
 
            id : <id_given_in_input>
 
            result: {
 
                      "msg": "Created fork of `<reponame>` as `<forkname>`",
 
                      "success": true,
 
                      "task": "<celery task id or None if done sync>"
 
                      "success" : true
 
                    }
 
            error:  null
 

	
 
        """
 
        repo = get_repo_or_error(repoid)
 
        repo_name = repo.repo_name
 
@@ -1472,11 +1176,6 @@ class ApiController(JSONRPCController):
 
        When `forks` param is set it's possible to detach or delete forks of deleting
 
        repository
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param forks: `detach` or `delete`, what do do with attached forks for repo
 
        :type forks: Optional(str)
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1485,7 +1184,6 @@ class ApiController(JSONRPCController):
 
                      "success": true
 
                    }
 
            error:  null
 

	
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
@@ -1526,12 +1224,6 @@ class ApiController(JSONRPCController):
 
        if found. This command can be executed only using api_key belonging to user
 
        with admin rights.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param userid:
 
        :param perm: (repository.(none|read|write|admin))
 
        :type perm: str
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1570,10 +1262,6 @@ class ApiController(JSONRPCController):
 
        Revoke permission for user on given repository. This command can be executed
 
        only using api_key belonging to user with admin rights.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param userid:
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1582,9 +1270,7 @@ class ApiController(JSONRPCController):
 
                      "success": true
 
                    }
 
            error:  null
 

	
 
        """
 

	
 
        repo = get_repo_or_error(repoid)
 
        user = get_user_or_error(userid)
 
        try:
 
@@ -1611,31 +1297,14 @@ class ApiController(JSONRPCController):
 
        existing one if found. This command can be executed only using
 
        api_key belonging to user with admin rights.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param usergroupid: id of usergroup
 
        :type usergroupid: str or int
 
        :param perm: (repository.(none|read|write|admin))
 
        :type perm: str
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
 
            "success": true
 

	
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to edit permission for user group: `<usergroup>` in repo `<repo>`'
 
          }
 

	
 
        """
 
        repo = get_repo_or_error(repoid)
 
        perm = get_perm_or_error(perm)
 
@@ -1675,10 +1344,6 @@ class ApiController(JSONRPCController):
 
        Revoke permission for user group on given repository. This command can be
 
        executed only using api_key belonging to user with admin rights.
 

	
 
        :param repoid: repository name or repository id
 
        :type repoid: str or int
 
        :param usergroupid:
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1722,9 +1387,6 @@ class ApiController(JSONRPCController):
 
        """
 
        Returns given repo group together with permissions, and repositories
 
        inside the group
 

	
 
        :param repogroupid: id/name of repository group
 
        :type repogroupid: str or int
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
@@ -1757,7 +1419,6 @@ class ApiController(JSONRPCController):
 
    def get_repo_groups(self):
 
        """
 
        Returns all repository groups
 

	
 
        """
 
        return [
 
            repo_group.get_api_data()
 
@@ -1773,34 +1434,14 @@ class ApiController(JSONRPCController):
 
        Creates a repository group. This command can be executed only using
 
        api_key belonging to user with admin rights.
 

	
 
        :param group_name:
 
        :type group_name:
 
        :param description:
 
        :type description:
 
        :param owner:
 
        :type owner:
 
        :param parent:
 
        :type parent:
 
        :param copy_permissions:
 
        :type copy_permissions:
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
              "msg": "created new repo group `<repo_group_name>`"
 
              "msg" : "created new repo group `<repo_group_name>`",
 
              "repo_group": <repogroup_object>
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            failed to create repo group `<repogroupid>`
 
          }
 

	
 
        """
 
        if db.RepoGroup.get_by_group_name(group_name):
 
            raise JSONRPCError("repo group `%s` already exist" % (group_name,))
 
@@ -1835,14 +1476,18 @@ class ApiController(JSONRPCController):
 
                          description=None,
 
                          owner=None,
 
                          parent=None):
 
        """
 
        TODO
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 
        parent_repo_group_id = None if parent is None else get_repo_group_or_error(parent).group_id
 

	
 
        updates = {}
 
        try:
 
            store_update(updates, group_name, 'group_name')
 
            store_update(updates, description, 'group_description')
 
            store_update(updates, owner, 'owner')
 
            store_update(updates, parent, 'parent_group')
 
            store_update(updates, parent_repo_group_id, 'parent_group_id')
 
            repo_group = RepoGroupModel().update(repo_group, updates)
 
            meta.Session().commit()
 
            return dict(
 
@@ -1858,10 +1503,6 @@ class ApiController(JSONRPCController):
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def delete_repo_group(self, repogroupid):
 
        """
 

	
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
@@ -1870,15 +1511,6 @@ class ApiController(JSONRPCController):
 
            'repo_group': null
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to delete repo group ID:<repogroupid> <repogroupname>"
 
          }
 

	
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
@@ -1905,14 +1537,6 @@ class ApiController(JSONRPCController):
 
        to user with admin rights, or user who has admin right to given repository
 
        group.
 

	
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 
        :param userid:
 
        :param perm: (group.(none|read|write|admin))
 
        :type perm: str
 
        :param apply_to_children: 'none', 'repos', 'groups', 'all'
 
        :type apply_to_children: str
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1921,17 +1545,7 @@ class ApiController(JSONRPCController):
 
                      "success": true
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
 
          }
 

	
 
        """
 

	
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
        if not HasPermissionAny('hg.admin')():
 
@@ -1968,13 +1582,6 @@ class ApiController(JSONRPCController):
 
        be executed only using api_key belonging to user with admin rights, or
 
        user who has admin right to given repository group.
 

	
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 
        :param userid:
 
        :type userid:
 
        :param apply_to_children: 'none', 'repos', 'groups', 'all'
 
        :type apply_to_children: str
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -1983,17 +1590,7 @@ class ApiController(JSONRPCController):
 
                      "success": true
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
 
          }
 

	
 
        """
 

	
 
        repo_group = get_repo_group_or_error(repogroupid)
 

	
 
        if not HasPermissionAny('hg.admin')():
 
@@ -2031,33 +1628,14 @@ class ApiController(JSONRPCController):
 
        api_key belonging to user with admin rights, or user who has admin
 
        right to given repository group.
 

	
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 
        :param usergroupid: id of usergroup
 
        :type usergroupid: str or int
 
        :param perm: (group.(none|read|write|admin))
 
        :type perm: str
 
        :param apply_to_children: 'none', 'repos', 'groups', 'all'
 
        :type apply_to_children: str
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
 
            "success": true
 

	
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
 
          }
 

	
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 
        perm = get_perm_or_error(perm, prefix='group.')
 
@@ -2103,12 +1681,6 @@ class ApiController(JSONRPCController):
 
        executed only using api_key belonging to user with admin rights, or
 
        user who has admin right to given repository group.
 

	
 
        :param repogroupid: name or id of repository group
 
        :type repogroupid: str or int
 
        :param usergroupid:
 
        :param apply_to_children: 'none', 'repos', 'groups', 'all'
 
        :type apply_to_children: str
 

	
 
        OUTPUT::
 

	
 
            id : <id_given_in_input>
 
@@ -2117,16 +1689,6 @@ class ApiController(JSONRPCController):
 
                      "success": true
 
                    }
 
            error:  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
 
          }
 

	
 

	
 
        """
 
        repo_group = get_repo_group_or_error(repogroupid)
 
        user_group = get_user_group_or_error(usergroupid)
 
@@ -2162,9 +1724,6 @@ class ApiController(JSONRPCController):
 
    def get_gist(self, gistid):
 
        """
 
        Get given gist by id
 

	
 
        :param gistid: id of private or public gist
 
        :type gistid: str
 
        """
 
        gist = get_gist_or_error(gistid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -2176,9 +1735,6 @@ class ApiController(JSONRPCController):
 
        """
 
        Get all gists for given user. If userid is empty returned gists
 
        are for user who called the api
 

	
 
        :param userid: user to get gists for
 
        :type userid: Optional(str or int)
 
        """
 
        if not HasPermissionAny('hg.admin')():
 
            # make sure normal user does not pass someone else userid,
 
@@ -2204,40 +1760,17 @@ class ApiController(JSONRPCController):
 
    def create_gist(self, files, owner=None,
 
                    gist_type=db.Gist.GIST_PUBLIC, lifetime=-1,
 
                    description=''):
 

	
 
        """
 
        Creates new Gist
 

	
 
        :param files: files to be added to gist
 
            {'filename': {'content':'...', 'lexer': null},
 
             'filename2': {'content':'...', 'lexer': null}}
 
        :type files: dict
 
        :param owner: gist owner, defaults to api method caller
 
        :type owner: Optional(str or int)
 
        :param gist_type: type of gist 'public' or 'private'
 
        :type gist_type: Optional(str)
 
        :param lifetime: time in minutes of gist lifetime
 
        :type lifetime: Optional(int)
 
        :param description: gist description
 
        :type description: Optional(str)
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            "msg": "created new gist",
 
            "gist": {}
 
            "gist" : <gist_object>
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to create gist"
 
          }
 

	
 
        """
 
        try:
 
            if owner is None:
 
@@ -2265,26 +1798,14 @@ class ApiController(JSONRPCController):
 
        """
 
        Deletes existing gist
 

	
 
        :param gistid: id of gist to delete
 
        :type gistid: str
 

	
 
        OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : {
 
            "deleted gist ID: <gist_id>",
 
            "msg" : "deleted gist ID: <gist_id>",
 
            "gist": null
 
          }
 
          error :  null
 

	
 
        ERROR OUTPUT::
 

	
 
          id : <id_given_in_input>
 
          result : null
 
          error :  {
 
            "failed to delete gist ID:<gist_id>"
 
          }
 

	
 
        """
 
        gist = get_gist_or_error(gistid)
 
        if not HasPermissionAny('hg.admin')():
 
@@ -2306,6 +1827,9 @@ class ApiController(JSONRPCController):
 
    # permission check inside
 
    def get_changesets(self, repoid, start=None, end=None, start_date=None,
 
                       end_date=None, branch_name=None, reverse=False, with_file_list=False, max_revisions=None):
 
        """
 
        TODO
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasRepoPermissionLevel('read')(repo.repo_name):
 
            raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
 
@@ -2323,7 +1847,10 @@ class ApiController(JSONRPCController):
 
            raise JSONRPCError('Repository is empty')
 

	
 
    # permission check inside
 
    def get_changeset(self, repoid, raw_id, with_reviews=False):
 
    def get_changeset(self, repoid, raw_id, with_reviews=False, with_comments=False, with_inline_comments=False):
 
        """
 
        TODO
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if not HasRepoPermissionLevel('read')(repo.repo_name):
 
            raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
 
@@ -2335,9 +1862,19 @@ class ApiController(JSONRPCController):
 

	
 
        if with_reviews:
 
            reviews = ChangesetStatusModel().get_statuses(
 
                                repo.repo_name, raw_id)
 
                                repo.repo_name, changeset.raw_id)
 
            info["reviews"] = reviews
 

	
 
        if with_comments:
 
            comments = ChangesetCommentsModel().get_comments(
 
                                repo.repo_id, changeset.raw_id)
 
            info["comments"] = comments
 

	
 
        if with_inline_comments:
 
            inline_comments = ChangesetCommentsModel().get_inline_comments(
 
                                repo.repo_id, changeset.raw_id)
 
            info["inline_comments"] = inline_comments
 

	
 
        return info
 

	
 
    # permission check inside
kallithea/controllers/pullrequests.py
Show inline comments
 
@@ -35,6 +35,7 @@ from tg import tmpl_context as c
 
from tg.i18n import ugettext as _
 
from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPFound, HTTPNotFound
 

	
 
import kallithea
 
import kallithea.lib.helpers as h
 
from kallithea.controllers import base
 
from kallithea.controllers.changeset import create_cs_pr_comment, delete_cs_pr_comment
 
@@ -494,6 +495,8 @@ class PullrequestsController(base.BaseRe
 
        except IndexError: # probably because c.cs_ranges is empty, probably because revisions are missing
 
            pass
 

	
 
        rev_limit = safe_int(kallithea.CONFIG.get('next_iteration_rev_limit'), 0)
 

	
 
        avail_revs = set()
 
        avail_show = []
 
        c.cs_branch_name = c.cs_ref_name
 
@@ -563,6 +566,14 @@ class PullrequestsController(base.BaseRe
 
        except ChangesetDoesNotExistError:
 
            c.update_msg = _('Error: some changesets not found when displaying pull request from %s.') % c.cs_rev
 

	
 
        if rev_limit:
 
            if len(avail_revs) - 1 > rev_limit:
 
                c.update_msg = _('%d additional changesets are not shown.') % (len(avail_revs) - 1)
 
                avail_show = []
 
            elif len(avail_show) - 1 > rev_limit:
 
                c.update_msg = _('%d changesets available for merging are not shown.') % (len(avail_show) - len(avail_revs))
 
                avail_show = sorted(avail_revs, reverse=True)
 

	
 
        c.avail_revs = avail_revs
 
        c.avail_cs = [org_scm_instance.get_changeset(r) for r in avail_show]
 
        c.avail_jsdata = graph_data(org_scm_instance, avail_show)
kallithea/i18n/be/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -8,8 +8,8 @@ msgstr ""
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=UTF-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
 
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 

	
 
msgid "Repository not found in the filesystem"
 
msgstr "Рэпазітар не знойдзены на файлавай сістэме"
 
@@ -1414,6 +1414,12 @@ msgstr "Адміністраванне груп рэпазітароў"
 
msgid "Number of Top-level Repositories"
 
msgstr "Лік рэпазітароў верхняга ўзроўня"
 

	
 
msgid "Type of repository to create."
 
msgstr "Тып стваранага рэпазітара."
 

	
 
msgid "Repository URL"
 
msgstr "URL рэпазітара"
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr ""
 
@@ -1423,9 +1429,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Апцыянальна абраць групу, у якую змясціць дадзены рэпазітар."
 

	
 
msgid "Type of repository to create."
 
msgstr "Тып стваранага рэпазітара."
 

	
 
msgid "Landing revision"
 
msgstr "Рэвізія для выгрузкі"
 

	
 
@@ -1529,13 +1532,6 @@ msgstr "Пацвердзіце спампоўку змен з аддаленага рэпазітара."
 
msgid "Remote repository"
 
msgstr "Аддалены рэпазітар"
 

	
 
msgid "Repository URL"
 
msgstr "URL рэпазітара"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"Рэвізія па змоўчанні, з якой будзе рабіцца выгрузка файлаў пры спампоўцы"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Змяніць уладальніка рэпазітара."
 

	
 
@@ -1891,11 +1887,11 @@ msgstr "Няма супадзенняў"
 
msgid "Open New Pull Request from {0}"
 
msgstr "Стварыць новы pull-запыт з {0}"
 

	
 
msgid "Open New Pull Request for {0} &rarr; {1}"
 
msgstr "Стварыць новы pull-запыт для {0} &rarr; {1}"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "Паказаць выбраныя наборы змен: {0} &rarr; {1}"
 
msgid "Open New Pull Request for {0}"
 
msgstr "Стварыць новы pull-запыт для {0}"
 

	
 
msgid "Show Selected Changesets {0}"
 
msgstr "Паказаць выбраныя наборы змен {0}"
 

	
 
msgid "Selection Link"
 
msgstr "Спасылка выбару"
kallithea/i18n/de/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -958,8 +958,8 @@ msgstr "Es gibt bereits ein Repository m
 

	
 
msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
 
msgstr ""
 
"Es gibt bereits ein Repository mit \"%(repo)s\" in der Gruppe \"%(group)s"
 
"\""
 
"Es gibt bereits ein Repository mit \"%(repo)s\" in der Gruppe "
 
"\"%(group)s\""
 

	
 
msgid "Repository group with name \"%(repo)s\" already exists"
 
msgstr "Eine Repositorygruppe mit dem Namen \"%(repo)s\" existiert bereits"
 
@@ -1615,6 +1615,9 @@ msgstr ""
 
"untergeordneten Elemente, einschließlich nicht-privater Repositories und "
 
"anderer Gruppen, falls ausgewählt."
 

	
 
msgid "Type name of user"
 
msgstr "Typname des Benutzers"
 

	
 
msgid "Remove this group"
 
msgstr "Diese Gruppe löschen"
 

	
 
@@ -1630,9 +1633,15 @@ msgstr "Repositorygruppenverwaltung"
 
msgid "Number of Top-level Repositories"
 
msgstr "Anzahl der Repositories oberster Ebene"
 

	
 
msgid "Type of repository to create."
 
msgstr "Repository Typ der erstellt werden soll."
 

	
 
msgid "Clone remote repository"
 
msgstr "Entferntes Repository clonen"
 

	
 
msgid "Repository URL"
 
msgstr "Repository URL"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository will be "
 
"created as a clone from this URL."
 
@@ -1651,9 +1660,6 @@ msgstr ""
 
"Wähle bei Bedarf eine Gruppe, der dieses Repository zugeordnet werden "
 
"soll."
 

	
 
msgid "Type of repository to create."
 
msgstr "Repository Typ der erstellt werden soll."
 

	
 
msgid "Landing revision"
 
msgstr "Start Revision"
 

	
 
@@ -1794,27 +1800,9 @@ msgstr "Bestätige die Abholung von Änderungen vom entfernten Repository."
 
msgid "This repository does not have a remote repository URL."
 
msgstr "Für dieses Repository ist keine nicht-lokale URL angegeben."
 

	
 
msgid ""
 
"In case this repository is renamed or moved into another group the "
 
"repository URL changes.\n"
 
"                               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 ""
 
"Falls dieses Repository umbenannt oder in eine andere Gruppe verschoben "
 
"wird, ändert sich seine URL.\n"
 
"Die Verwendung der permanenten URL garantiert, dass dieses Repository "
 
"immer über diese URL erreichbar sein wird.\n"
 
"Dies ist insbesondere für CI-Systeme oder in Fällen nützlich, in denen "
 
"die URL des Repositories bei Dritten dauerhaft eingetragen wird."
 

	
 
msgid "Remote repository"
 
msgstr "Entferntes Repository"
 

	
 
msgid "Repository URL"
 
msgstr "Repository URL"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -1822,12 +1810,6 @@ msgstr ""
 
"Optional: URL eines entfernten Repositories. Falls gesetzt, dann kann das "
 
"Repository von dieser URL bezogen werden."
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr "Standardrevision für Dateiseite, Downloads, Whoosh und Readme"
 

	
 
msgid "Type name of user"
 
msgstr "Typname des Benutzers"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Besitzer des Repositorys ändern."
 

	
 
@@ -2496,8 +2478,5 @@ msgstr "Schnelleinstieg"
 
msgid "Add or upload files directly via Kallithea"
 
msgstr "Dateien direkt über Kallithea hinzufügen oder hochladen"
 

	
 
msgid "Readme file from revision %s:%s"
 
msgstr "Liesmich-Datei von Revision %s:%s"
 

	
 
msgid "Download %s as %s"
 
msgstr "%s als %s herunterladen"
kallithea/i18n/el/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -577,6 +577,13 @@ msgstr "Δημιουργήθηκε η εργασία της αποστολής ηλεκτρονικού ταχυδρομείου"
 
msgid "Hook already exists"
 
msgstr "Το άγκιστρο υπάρχει ήδη"
 

	
 
msgid ""
 
"Hook names with \".kallithea_\" are reserved for internal use. Please use "
 
"another hook name."
 
msgstr ""
 
"Άγκιστρα με το όνομα \".kallithea_\" είναι δεσμευμένα για εσωτερική "
 
"χρήση. Παρακαλώ δώστε άλλο όνομα στο άγκιστρο."
 

	
 
msgid "Added new hook"
 
msgstr "Προσθήκη νέου άγκιστρου"
 

	
 
@@ -665,6 +672,12 @@ msgstr ""
 
msgid "No changes detected"
 
msgstr "Δεν εντοπίστηκαν αλλαγές"
 

	
 
msgid "Show whitespace changes"
 
msgstr "Εμφάνιση αλλαγής κενού"
 

	
 
msgid "Ignore whitespace changes"
 
msgstr "Αγνόηση αλλαγής κενού"
 

	
 
msgid "Increase diff context to %(num)s lines"
 
msgstr "Αύξηση του diff πλαισίου σε %(num)s γραμμές"
 

	
 
@@ -782,6 +795,54 @@ msgstr "chmod"
 
msgid "SSH key is missing"
 
msgstr "Το κλειδί SSH λείπει"
 

	
 
msgid ""
 
"Invalid SSH key - it must have both a key type and a base64 part, like "
 
"'ssh-rsa ASRNeaZu4FA...xlJp='"
 
msgstr ""
 
"Άκυρο κλειδί SSH - πρέπει να έχει έναν τύπο κλειδιού καθώς και ένα τμήμα "
 
"base64, όπως \"ssh-rsa ASRNeaZu4FA ... xlJp =\""
 

	
 
msgid ""
 
"Invalid SSH key - it must start with key type 'ssh-rsa', 'ssh-dss', 'ssh-"
 
"ed448', or 'ssh-ed25519'"
 
msgstr ""
 
"Άκυρο κλειδί SSH - πρέπει να ξεκινά με τύπο κλειδιού 'ssh-rsa',ssh-"
 
"dss','ssh-ed448' ή 'ssh-ed25519'"
 

	
 
msgid "Invalid SSH key - unexpected characters in base64 part %r"
 
msgstr "Άκυρο κλειδί SSH - μη αναμενόμενοι χαρακτήρες στο τμήμα base64 %r"
 

	
 
msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it can't be decoded)"
 
msgstr ""
 
"Άκυρο κλειδί SSH - το base64 μέρος %r φαίνεται κομμένο (δεν μπορεί να "
 
"αποκωδικοποιηθεί)"
 

	
 
msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it contains a partial "
 
"string length)"
 
msgstr ""
 
"Άκυρο κλειδί SSH - το base64 μέρος %r φαίνεται κομμένο (περιέχει ένα "
 
"μερικό μήκος συμβολοσειράς)"
 

	
 
msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it is too short for "
 
"declared string length %s)"
 
msgstr ""
 
"Άκυρο κλειδί SSH - το τμήμα base64 %r φαίνεται να είναι κομμένο (είναι "
 
"πολύ μικρό για το δηλωμένο μήκος συμβολοσειράς %s)"
 

	
 
msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it contains too few "
 
"strings for a %s key)"
 
msgstr ""
 
"Άκυρο κλειδί SSH - το base64 τμήμα %r φαίνεται να είναι περικομμένο "
 
"(περιέχει πολύ λίγες συμβολοσειρές για ένα κλειδί %s)"
 

	
 
msgid "Invalid SSH key - it is a %s key but the base64 part contains %r"
 
msgstr ""
 
"Άκυρο κλειδί SSH - είναι ένα κλειδί %s αλλά το base64 μέρος περιέχει %r"
 

	
 
msgid "%d year"
 
msgid_plural "%d years"
 
msgstr[0] "%d έτος"
 
@@ -935,9 +996,30 @@ msgstr "Εισαγάγετε %(min)i χαρακτήρες ή περισσότερους"
 
msgid "Name must not contain only digits"
 
msgstr "Το όνομα δεν πρέπει να περιέχει μόνο ψηφία"
 

	
 
msgid ""
 
"[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
 
"%(branch)s by %(cs_author_username)s"
 
msgstr ""
 
"[Σχόλιο] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" στο "
 
"%(branch)s από %(cs_author_username)s"
 

	
 
msgid "New user %(new_username)s registered"
 
msgstr "Καταχωρήθηκε νέος χρήστης %(new_username)s"
 

	
 
msgid ""
 
"[Review] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
 
"%(pr_source_branch)s by %(pr_owner_username)s"
 
msgstr ""
 
"[Κριτική] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" στο "
 
"%(pr_source_branch)s από %(pr_owner_username)s"
 

	
 
msgid ""
 
"[Comment] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
 
"%(pr_source_branch)s by %(pr_owner_username)s"
 
msgstr ""
 
"[Σχόλιο] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" στο "
 
"%(pr_source_branch)s από %(pr_owner_username)s"
 

	
 
msgid "Closing"
 
msgstr "Κλείσιμο"
 

	
 
@@ -1103,6 +1185,11 @@ msgstr "Η ομάδα αποθετηρίου με το όνομα \"%(repo)s\" υπάρχει ήδη"
 
msgid "Invalid repository URL"
 
msgstr "Μη έγκυρη διεύθυνση URL αποθετηρίου"
 

	
 
msgid "Invalid repository URL. It must be a valid http, https, or ssh URL"
 
msgstr ""
 
"Μη έγκυρο αποθετήριο URL. Πρέπει να είναι μια έγκυρη http, https ή ssh "
 
"διεύθυνση URL"
 

	
 
msgid "Fork has to be the same type as parent"
 
msgstr "Ο κλώνος πρέπει να έχει τον ίδιο τύπο με τον γονέα του"
 

	
 
@@ -1823,6 +1910,9 @@ msgstr ""
 
"συμπεριλαμβανομένων των μη ιδιωτικών αποθετηρίων και άλλων ομάδων, εάν "
 
"επιλεγεί."
 

	
 
msgid "Type name of user"
 
msgstr "Πληκτρολογήστε το όνομα του χρήστη"
 

	
 
msgid "Remove this group"
 
msgstr "Κατάργηση αυτής της ομάδας"
 

	
 
@@ -1838,9 +1928,15 @@ msgstr "Διαχείριση Ομάδων Αποθετηρίου"
 
msgid "Number of Top-level Repositories"
 
msgstr "Αριθμός αποθετηρίων ανώτατου επιπέδου"
 

	
 
msgid "Type of repository to create."
 
msgstr "Τύπος αποθετηρίου προς δημιουργία."
 

	
 
msgid "Clone remote repository"
 
msgstr "Κλωνοποίηση απομακρυσμένου αποθετηρίου"
 

	
 
msgid "Repository URL"
 
msgstr "URL Αποθετηρίου"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository will be "
 
"created as a clone from this URL."
 
@@ -1858,9 +1954,6 @@ msgid "Optionally select a group to put 
 
msgstr ""
 
"Προαιρετικά, επιλέξτε μια ομάδα για να τοποθετήσετε αυτό το αποθετήριο."
 

	
 
msgid "Type of repository to create."
 
msgstr "Τύπος αποθετηρίου προς δημιουργία."
 

	
 
msgid "Landing revision"
 
msgstr "Αναθεώρηση εκφόρτωσης"
 

	
 
@@ -2008,29 +2101,9 @@ msgstr ""
 
msgid "Permanent URL"
 
msgstr "Μόνιμη διεύθυνση URL"
 

	
 
msgid ""
 
"In case this repository is renamed or moved into another group the "
 
"repository URL changes.\n"
 
"                               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 ""
 
"Η διεύθυνση URL του αποθετηρίου αλλάζει όταν αυτό μετονομαστεί ή "
 
"μετακινηθεί σε άλλη ομάδα.\n"
 
"                               Η χρήση της παραπάνω μόνιμης διεύθυνσης "
 
"URL εγγυάται ότι αυτό το αποθετήριο θα είναι πάντα προσβάσιμο σε αυτήν τη "
 
"διεύθυνση URL.\n"
 
"                               Αυτό είναι χρήσιμο για συστήματα CI ή για "
 
"άλλες περιπτώσεις που χρειάζεστε να κωδικοποιήσετε τη διεύθυνση URL σε "
 
"κάποια υπηρεσία τρίτου μέρους."
 

	
 
msgid "Remote repository"
 
msgstr "Απομακρυσμένο αποθετήριο"
 

	
 
msgid "Repository URL"
 
msgstr "URL Αποθετηρίου"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -2038,13 +2111,6 @@ msgstr ""
 
"Προαιρετικό: Διεύθυνση URL ενός απομακρυσμένου αποθετηρίου. Εάν οριστεί, "
 
"το αποθετήριο μπορεί να τραβηχτεί από αυτήν τη διεύθυνση URL."
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"Προεπιλεγμένη αναθεώρηση για τη σελίδα αρχείων, λήψεων, Whoosh και readme"
 

	
 
msgid "Type name of user"
 
msgstr "Πληκτρολογήστε το όνομα του χρήστη"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Αλλάξτε τον κάτοχο αυτού του αποθετηρίου."
 

	
 
@@ -2136,6 +2202,9 @@ msgstr ""
 
msgid "Save Settings"
 
msgstr "Αποθήκευση Ρυθμίσεων"
 

	
 
msgid "Custom Hooks are not enabled"
 
msgstr "Τα προσαρμοσμένα άγκιστρα δεν είναι ενεργά"
 

	
 
msgid "Failed to remove hook"
 
msgstr "Απέτυχε η αφαίρεση γάντζου"
 

	
 
@@ -2164,6 +2233,18 @@ msgstr ""
 
msgid "Install Git hooks"
 
msgstr "Εγκατάσταση Git hooks"
 

	
 
msgid "Install and overwrite Git hooks"
 
msgstr "Εγκατάσταση και επανεγγραφή Git hooks"
 

	
 
msgid ""
 
"Install Kallithea's internal hooks for all Git repositories. Existing "
 
"hooks that don't seem to come from Kallithea will be disabled by renaming "
 
"to .bak extension."
 
msgstr ""
 
"Εγκαταστήστε τα εσωτερικά hooks της Kallithea για όλα τα αποθετήρια Git. "
 
"Τα υπάρχοντα hooks που δεν φαίνεται να προέρχονται από την Kallithea θα "
 
"απενεργοποιηθούν με τη μετονομασία σε επέκταση .bak."
 

	
 
msgid "Rescan Repositories"
 
msgstr "Επανασάρωση αποθετηρίων"
 

	
 
@@ -2665,11 +2746,11 @@ msgstr "Δεν υπάρχουν αρχεία που να ταιριάζουν"
 
msgid "Open New Pull Request from {0}"
 
msgstr "Άνοιγμα νέας αίτησης έλξης από {0}"
 

	
 
msgid "Open New Pull Request for {0} &rarr; {1}"
 
msgstr "Άνοιγμα νέου αιτήματος έλξης για {0} &rarr; {1}"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "Εμφάνιση Επιλεγμένων Σετ Αλλαγών {0} &rarr; {1}"
 
msgid "Open New Pull Request for {0}"
 
msgstr "Άνοιγμα νέου αιτήματος έλξης για {0}"
 

	
 
msgid "Show Selected Changesets {0}"
 
msgstr "Εμφάνιση Επιλεγμένων Σετ Αλλαγών {0}"
 

	
 
msgid "Selection Link"
 
msgstr "Σύνδεσμος Επιλογής"
 
@@ -2772,6 +2853,9 @@ msgstr ""
 
msgid "Changeset status: %s by %s"
 
msgstr "Κατάσταση σετ αλλαγών: %s από %s"
 

	
 
msgid "(No commit message)"
 
msgstr "(Χωρίς κείμενο commit)"
 

	
 
msgid "Expand commit message"
 
msgstr "Ανάπτυξη μηνύματος commit"
 

	
 
@@ -2934,6 +3018,12 @@ msgstr "Εμφάνιση πλήρους διαφοράς για αυτό το αρχείο"
 
msgid "Show full side-by-side diff for this file"
 
msgstr "Εμφάνιση πλήρους διαφοράς δίπλα-δίπλα για αυτό το αρχείο"
 

	
 
msgid "Raw diff for this file"
 
msgstr "Διαφορές για αυτό το αρχείο"
 

	
 
msgid "Download diff for this file"
 
msgstr "Μεταφόρτωση διαφοράς για αυτό το αρχείο"
 

	
 
msgid "Show inline comments"
 
msgstr "Εμφάνιση ενσωματωμένων σχολίων"
 

	
 
@@ -3620,8 +3710,5 @@ msgstr "Ώθηση νέου αποθετηρίου"
 
msgid "Existing repository?"
 
msgstr "Υπάρχον αποθετήριο;"
 

	
 
msgid "Readme file from revision %s:%s"
 
msgstr "Αρχείο Readme από την αναθεώρηση %s:%s"
 

	
 
msgid "Download %s as %s"
 
msgstr "Λήψη %s ως %s"
kallithea/i18n/es/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -13,6 +13,9 @@ msgstr ""
 
msgid "There are no changesets yet"
 
msgstr "Aún no hay cambios"
 

	
 
msgid "SSH access is disabled."
 
msgstr "El acceso mediante SSH está desactivado."
 

	
 
msgid "None"
 
msgstr "Ninguno"
 

	
 
@@ -77,6 +80,9 @@ msgstr "%s%s canal"
 
msgid "Click here to add new file"
 
msgstr "Haga clic aquí para añadir un archivo nuevo"
 

	
 
msgid "There are no files yet."
 
msgstr "Aún no hay archivos."
 

	
 
msgid "%s at %s"
 
msgstr "%s en %s"
 

	
 
@@ -211,6 +217,9 @@ msgstr "Petición pull actualizada"
 
msgid "Successfully deleted pull request"
 
msgstr "Petición pull eliminada correctamente"
 

	
 
msgid "Revision %s not found in %s"
 
msgstr "No se ha encontrado la revisión %s en %s"
 

	
 
msgid "This pull request has already been merged to %s."
 
msgstr "La petición pull ya ha sido incluida a %s."
 

	
kallithea/i18n/fr/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -238,7 +238,7 @@ msgid "Bookmarks"
 
msgstr "Signets"
 

	
 
msgid "Error creating pull request: %s"
 
msgstr "Erreur de création de la demande de pull : %s"
 
msgstr "Erreur de création de la demande de pull : %s"
 

	
 
msgid "Error occurred while creating pull request"
 
msgstr "Une erreur est survenue durant la création de la pull request"
 
@@ -286,7 +286,7 @@ msgid "No additional changesets found fo
 
msgstr "Pas de changeset additionnel trouvé pour cette requête de pull."
 

	
 
msgid "Note: Branch %s has another head: %s."
 
msgstr "Note : La branche %s a une autre tête : %s."
 
msgstr "Note : La branche %s a une autre tête : %s."
 

	
 
msgid "Git pull requests don't support iterating yet."
 
msgstr ""
 
@@ -371,7 +371,7 @@ msgstr "Une erreur est survenue durant la mise à jour du gist %s"
 

	
 
msgid "You can't edit this user since it's crucial for entire application"
 
msgstr ""
 
"Vous ne pouvez pas éditer cet utilisateur ; il est nécessaire pour le bon "
 
"Vous ne pouvez pas éditer cet utilisateur ; il est nécessaire pour le bon "
 
"fonctionnement de l’application"
 

	
 
msgid "Your account was updated successfully"
 
@@ -386,7 +386,7 @@ msgstr ""
 
"l'utilisateur"
 

	
 
msgid "Added email %s to user"
 
msgstr "L’e-mail « %s » a été ajouté à l’utilisateur"
 
msgstr "L’e-mail « %s » a été ajouté à l’utilisateur"
 

	
 
msgid "An error occurred during email saving"
 
msgstr "Une erreur est survenue durant l’enregistrement de l’e-mail"
 
@@ -561,7 +561,7 @@ msgstr ""
 
"l'application"
 

	
 
msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
 
msgstr "Dépôts ré-analysés avec succès. Ajouté: %s. Supprimé: %s."
 
msgstr "Dépôts ré-analysés avec succès. Ajouté : %s. Supprimé : %s."
 

	
 
msgid "Invalidated %s repositories"
 
msgstr "%s dépôts invalidés"
 
@@ -590,8 +590,8 @@ msgid ""
 
"Hook names with \".kallithea_\" are reserved for internal use. Please use "
 
"another hook name."
 
msgstr ""
 
"Les noms de hook avec \".kallithea_\" sont réservés pour un usage interne. "
 
"Merci de choisir un autre nom pour le hook."
 
"Les noms de hook avec \".kallithea_\" sont réservés pour un usage "
 
"interne. Merci de choisir un autre nom pour le hook."
 

	
 
msgid "Added new hook"
 
msgstr "Le nouveau hook a été ajouté"
 
@@ -679,7 +679,7 @@ msgid ""
 
"Changeset was too big and was cut off, use diff menu to display this diff"
 
msgstr ""
 
"Cet ensemble de changements était trop gros pour être affiché et a été "
 
"découpé, utilisez le menu « diff » pour afficher les différences"
 
"découpé, utilisez le menu « diff » pour afficher les différences"
 

	
 
msgid "No changes detected"
 
msgstr "Aucun changement détecté"
 
@@ -694,10 +694,10 @@ msgid "Increase diff context to %(num)s 
 
msgstr "Augmenter le contexte du diff à %(num)s lignes"
 

	
 
msgid "Deleted branch: %s"
 
msgstr "Branche supprimée: %s"
 
msgstr "Branche supprimée : %s"
 

	
 
msgid "Created tag: %s"
 
msgstr "Étiquette créée: %s"
 
msgstr "Étiquette créée : %s"
 

	
 
msgid "Changeset %s not found"
 
msgstr "Ensemble de changements %s non trouvé"
 
@@ -841,18 +841,19 @@ msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it is too short for "
 
"declared string length %s)"
 
msgstr ""
 
"Clé SSH invalide – la partie base64 %r semble tronquée (elle est trop court "
 
"pour la taille déclarée %s)"
 
"Clé SSH invalide – la partie base64 %r semble tronquée (elle est trop "
 
"court pour la taille déclarée %s)"
 

	
 
msgid ""
 
"Invalid SSH key - base64 part %r seems truncated (it contains too few "
 
"strings for a %s key)"
 
msgstr ""
 
"Clé SSH invalide – la partie base64 %r semble tronquée (elle ne contient pas "
 
"assez de parties pour une clé %s)"
 
"Clé SSH invalide – la partie base64 %r semble tronquée (elle ne contient "
 
"pas assez de parties pour une clé %s)"
 

	
 
msgid "Invalid SSH key - it is a %s key but the base64 part contains %r"
 
msgstr "Clé SSH invalide – c'est une clé %s mais la partie base64 contient %r"
 
msgstr ""
 
"Clé SSH invalide – c'est une clé %s mais la partie base64 contient %r"
 

	
 
msgid "%d year"
 
msgid_plural "%d years"
 
@@ -1019,8 +1020,8 @@ msgid ""
 
"[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
 
"%(branch)s by %(cs_author_username)s"
 
msgstr ""
 
"[Commentaire] Changeset %(short_id)s « %(message_short)s » de %(repo_name)s "
 
"dans %(branch)s par %(cs_author_username)s"
 
"[Commentaire] Changeset %(short_id)s « %(message_short)s » de "
 
"%(repo_name)s dans %(branch)s par %(cs_author_username)s"
 

	
 
msgid "New user %(new_username)s registered"
 
msgstr "Nouvel utilisateur %(new_username)s enregistré"
 
@@ -1029,14 +1030,14 @@ msgid ""
 
"[Review] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
 
"%(pr_source_branch)s by %(pr_owner_username)s"
 
msgstr ""
 
"[Revue] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » depuis "
 
"[Revue] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » depuis "
 
"%(pr_source_branch)s par %(pr_owner_username)s"
 

	
 
msgid ""
 
"[Comment] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
 
"%(pr_source_branch)s by %(pr_owner_username)s"
 
msgstr ""
 
"[Commentaire] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » "
 
"[Commentaire] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » "
 
"depuis %(pr_source_branch)s par %(pr_owner_username)s"
 

	
 
msgid "Closing"
 
@@ -1056,10 +1057,10 @@ msgid "You are not authorized to create 
 
msgstr "Vous n'êtes pas autorisé à créer cette requête de pull"
 

	
 
msgid "Missing changesets since the previous iteration:"
 
msgstr "Changeset manquant depuis la précédente itération :"
 
msgstr "Changeset manquant depuis la précédente itération :"
 

	
 
msgid "New changesets on %s %s since the previous iteration:"
 
msgstr "Nouveau changeset sur %s %s depuis la précédente itération :"
 
msgstr "Nouveau changeset sur %s %s depuis la précédente itération :"
 

	
 
msgid "Ancestor didn't change - diff since previous iteration:"
 
msgstr "L'ancêtre n'a pas changé - diff depuis l'itération précédente :"
 
@@ -1081,7 +1082,7 @@ msgid "latest tip"
 
msgstr "Dernier sommet"
 

	
 
msgid "SSH key %r is invalid: %s"
 
msgstr "La clé SSH %r est invalide : %s"
 
msgstr "La clé SSH %r est invalide : %s"
 

	
 
msgid "SSH key %s is already used by %s"
 
msgstr "La clé SSH %s est déjà utilisée par %s"
 
@@ -1092,7 +1093,7 @@ msgstr "Clé SSH avec l'empreinte %r trouvée"
 
msgid ""
 
"You can't remove this user since it is crucial for the entire application"
 
msgstr ""
 
"Vous ne pouvez pas supprimer cet utilisateur ; il est nécessaire pour le "
 
"Vous ne pouvez pas supprimer cet utilisateur ; il est nécessaire pour le "
 
"bon fonctionnement de l’application"
 

	
 
msgid ""
 
@@ -1100,20 +1101,20 @@ msgid ""
 
"owners or remove those repositories: %s"
 
msgstr ""
 
"L’utilisateur \"%s\" possède %s dépôts et ne peut être supprimé. Changez "
 
"les propriétaires ou supprimez ces dépôts : %s"
 
"les propriétaires ou supprimez ces dépôts : %s"
 

	
 
msgid ""
 
"User \"%s\" still owns %s repository groups and cannot be removed. Switch "
 
"owners or remove those repository groups: %s"
 
msgstr ""
 
"L’utilisateur \"%s\" possède %s groupes de dépôt et ne peut être "
 
"supprimé. Changez les propriétaires ou supprimez ces dépôts : %s"
 
"supprimé. Changez les propriétaires ou supprimez ces dépôts : %s"
 

	
 
msgid ""
 
"User \"%s\" still owns %s user groups and cannot be removed. Switch "
 
"owners or remove those user groups: %s"
 
msgstr ""
 
"L’utilisateur « %s » possède %s groupes d'utilisateurs et ne peut pas "
 
"L’utilisateur « %s » possède %s groupes d'utilisateurs et ne peut pas "
 
"être supprimé. Changez les propriétaires de ces groupes d'utilisateurs ou "
 
"supprimez-les : %s"
 

	
 
@@ -1134,10 +1135,10 @@ msgid "Value cannot be an empty list"
 
msgstr "Cette valeur ne peut être une liste vide"
 

	
 
msgid "Username \"%(username)s\" already exists"
 
msgstr "Le nom d’utilisateur « %(username)s » existe déjà"
 
msgstr "Le nom d’utilisateur « %(username)s » existe déjà"
 

	
 
msgid "Username \"%(username)s\" cannot be used"
 
msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
 
msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
 

	
 
msgid ""
 
"Username may only contain alphanumeric characters underscores, periods or "
 
@@ -1151,13 +1152,13 @@ msgid "The input is not valid"
 
msgstr "L'entrée n'est pas valide"
 

	
 
msgid "Username %(username)s is not valid"
 
msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
 
msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
 

	
 
msgid "Invalid user group name"
 
msgstr "Nom de groupe d'utilisateurs invalide"
 

	
 
msgid "User group \"%(usergroup)s\" already exists"
 
msgstr "Le groupe d'utilisateurs «%(usergroup)s» existe déjà"
 
msgstr "Le groupe d'utilisateurs « %(usergroup)s » existe déjà"
 

	
 
msgid ""
 
"user group name may only contain alphanumeric characters underscores, "
 
@@ -1171,10 +1172,10 @@ msgid "Cannot assign this group as paren
 
msgstr "Impossible d’assigner ce groupe en tant que parent"
 

	
 
msgid "Group \"%(group_name)s\" already exists"
 
msgstr "Le groupe « %(group_name)s » existe déjà"
 
msgstr "Le groupe « %(group_name)s » existe déjà"
 

	
 
msgid "Repository with name \"%(group_name)s\" already exists"
 
msgstr "Un dépôt portant le nom « %(group_name)s » existe déjà"
 
msgstr "Un dépôt portant le nom « %(group_name)s » existe déjà"
 

	
 
msgid "Invalid characters (non-ascii) in password"
 
msgstr "Caractères incorrects (non-ASCII) dans le mot de passe"
 
@@ -1189,23 +1190,24 @@ msgid "Invalid username or password"
 
msgstr "Nom d'utilisateur ou mot de passe invalide"
 

	
 
msgid "Repository name %(repo)s is not allowed"
 
msgstr "Le nom de dépôt « %(repo)s » n’est pas autorisé"
 
msgstr "Le nom de dépôt « %(repo)s » n’est pas autorisé"
 

	
 
msgid "Repository named %(repo)s already exists"
 
msgstr "Un dépôt portant le nom « %(repo)s » existe déjà"
 
msgstr "Un dépôt portant le nom « %(repo)s » existe déjà"
 

	
 
msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
 
msgstr "Le dépôt « %(repo)s » existe déjà dans le groupe « %(group)s »"
 
msgstr "Le dépôt « %(repo)s » existe déjà dans le groupe « %(group)s »"
 

	
 
msgid "Repository group with name \"%(repo)s\" already exists"
 
msgstr "Un groupe de dépôts avec le nom «%(repo)s» existe déjà"
 
msgstr "Un groupe de dépôts avec le nom « %(repo)s » existe déjà"
 

	
 
msgid "Invalid repository URL"
 
msgstr "URL de dépôt invalide"
 

	
 
msgid "Invalid repository URL. It must be a valid http, https, or ssh URL"
 
msgstr ""
 
"URL de dépôt invalide. Ce doit être une URL valide de type http, https ou ssh"
 
"URL de dépôt invalide. Ce doit être une URL valide de type http, https ou "
 
"ssh"
 

	
 
msgid "Fork has to be the same type as parent"
 
msgstr "Le fork doit être du même type que le parent"
 
@@ -1231,7 +1233,7 @@ msgid "This email address is already in 
 
msgstr "Cette adresse e-mail est déjà enregistrée"
 

	
 
msgid "Email address \"%(email)s\" not found"
 
msgstr "L’adresse e-mail « %(email)s » n’existe pas"
 
msgstr "L’adresse e-mail « %(email)s » n’existe pas"
 

	
 
msgid ""
 
"The LDAP Login attribute of the CN must be specified - this is the name "
 
@@ -1308,10 +1310,10 @@ msgid "Stay logged in after browser rest
 
msgstr "Rester connecté après un redémarrage du navigateur"
 

	
 
msgid "Forgot your password?"
 
msgstr "Mot de passe oublié?"
 
msgstr "Mot de passe oublié ?"
 

	
 
msgid "Don't have an account?"
 
msgstr "Vous n’avez pas de compte?"
 
msgstr "Vous n’avez pas de compte ?"
 

	
 
msgid "Sign In"
 
msgstr "Connexion"
 
@@ -1596,13 +1598,13 @@ msgid "Built-in"
 
msgstr "Inclus"
 

	
 
msgid "Confirm to reset this API key: %s"
 
msgstr "Confirmer la remise à zéro de cette clé d'API: %s"
 
msgstr "Confirmer la remise à zéro de cette clé d'API : %s"
 

	
 
msgid "Expired"
 
msgstr "a expiré"
 

	
 
msgid "Confirm to remove this API key: %s"
 
msgstr "Confirmer la suppression de cette clé d'API: %s"
 
msgstr "Confirmer la suppression de cette clé d'API : %s"
 

	
 
msgid "Remove"
 
msgstr "Supprimer"
 
@@ -1645,7 +1647,7 @@ msgid "Primary"
 
msgstr "Primaire"
 

	
 
msgid "Confirm to delete this email: %s"
 
msgstr "Veuillez confirmer la suppression de l’e-mail : %s"
 
msgstr "Veuillez confirmer la suppression de l’e-mail : %s"
 

	
 
msgid "No additional emails specified."
 
msgstr "Pas d'adresse e-mail supplémentaires spécifiées."
 
@@ -1695,7 +1697,7 @@ msgid "Last Used"
 
msgstr "Dernière utilisation"
 

	
 
msgid "Confirm to remove this SSH key: %s"
 
msgstr "Confirmer la suppression de cette clé SSH: %s"
 
msgstr "Confirmer la suppression de cette clé SSH : %s"
 

	
 
msgid "No SSH keys have been added"
 
msgstr "Aucune clé SSH n'a été ajoutée"
 
@@ -1821,7 +1823,7 @@ msgid "External auth account activation"
 
msgstr "Activation de l'authentification externe"
 

	
 
msgid "Confirm to delete this IP address: %s"
 
msgstr "Confirmer la suppression de cette adresse IP: %s"
 
msgstr "Confirmer la suppression de cette adresse IP : %s"
 

	
 
msgid "All IP addresses are allowed."
 
msgstr "Toutes les adresses IP sont autorisées."
 
@@ -1860,7 +1862,7 @@ msgid "Permissions"
 
msgstr "Permissions"
 

	
 
msgid "Repository Group: %s"
 
msgstr "Groupe de dépôts: %s"
 
msgstr "Groupe de dépôts : %s"
 

	
 
msgid "Top level repositories"
 
msgstr "Dépôts de niveau supérieur"
 
@@ -1876,8 +1878,8 @@ msgstr "Créé le"
 

	
 
msgid "Confirm to delete this group: %s with %s repository"
 
msgid_plural "Confirm to delete this group: %s with %s repositories"
 
msgstr[0] "Confirmer la suppression de ce groupe : %s avec %s dépôt"
 
msgstr[1] "Confirmer la suppression de ce groupe : %s avec %s dépôts"
 
msgstr[0] "Confirmer la suppression de ce groupe : %s avec %s dépôt"
 
msgstr[1] "Confirmer la suppression de ce groupe : %s avec %s dépôts"
 

	
 
msgid "Delete this repository group"
 
msgstr "Supprimer ce groupe de dépôts"
 
@@ -1919,6 +1921,9 @@ msgstr ""
 
"Ajouter ou révoquer la permission pour tous les enfants de ce groupe, y "
 
"compris les dépôts non-privés et les autres groupes si sélectionné."
 

	
 
msgid "Type name of user"
 
msgstr "Saisir le nom de l'utilisateur"
 

	
 
msgid "Remove this group"
 
msgstr "Supprimer ce groupe"
 

	
 
@@ -1934,9 +1939,15 @@ msgstr "Administration des groupes de dépôts"
 
msgid "Number of Top-level Repositories"
 
msgstr "Nombre de dépôts de niveau supérieur"
 

	
 
msgid "Type of repository to create."
 
msgstr "Type de dépôt à créer."
 

	
 
msgid "Clone remote repository"
 
msgstr "Cloner le dépôt distant"
 

	
 
msgid "Repository URL"
 
msgstr "URL du dépôt"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository will be "
 
"created as a clone from this URL."
 
@@ -1953,9 +1964,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Sélectionnez un groupe (optionel) dans lequel sera placé le dépôt."
 

	
 
msgid "Type of repository to create."
 
msgstr "Type de dépôt à créer."
 

	
 
msgid "Landing revision"
 
msgstr "Révision d’arrivée"
 

	
 
@@ -1977,7 +1985,7 @@ msgid ""
 
"Repository \"%(repo_name)s\" is being created, you will be redirected "
 
"when this process is finished.repo_name"
 
msgstr ""
 
"Le dépôt « %(repo_name)s » est en cours de création, vous allez être "
 
"Le dépôt « %(repo_name)s » est en cours de création, vous allez être "
 
"redirigé quand cette opération sera terminée."
 

	
 
msgid ""
 
@@ -2100,28 +2108,9 @@ msgstr "Ce dépôt n'a pas d'URL de dépôt distant."
 
msgid "Permanent URL"
 
msgstr "URL permanente"
 

	
 
msgid ""
 
"In case this repository is renamed or moved into another group the "
 
"repository URL changes.\n"
 
"                               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 ""
 
"Si ce dépôt est renommé ou déplacé dans un autre groupe, l'URL du dépôt "
 
"change.\n"
 
"                               L'utilisation de l'URL permanente ci-"
 
"dessus garantit que ce dépôt sera toujours accessible via cette URL.\n"
 
"                               Cela peut être utile pour les systèmes "
 
"d'intégration continue, ou dans tous les cas où vous devez saisir l'URL "
 
"« en dur » dans un service tiers."
 

	
 
msgid "Remote repository"
 
msgstr "Dépôt distant"
 

	
 
msgid "Repository URL"
 
msgstr "URL du dépôt"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -2129,14 +2118,6 @@ msgstr ""
 
"Optionel : URL d'un dépôt distant. Si renseigné, le dépôt sera pullé à "
 
"partir de cette URL."
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"Révision par défaut pour les pages de fichiers, de téléchargements, de "
 
"recherche et de documentation"
 

	
 
msgid "Type name of user"
 
msgstr "Saisir le nom de l'utilisateur"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Changer le propriétaire de ce dépôt."
 

	
 
@@ -2248,9 +2229,9 @@ msgid ""
 
"post-receive hooks internally. Installation of these hooks is managed in "
 
"%s."
 
msgstr ""
 
"Kallithea ne supporte pas les hooks Git personnalisés. Kallithea utilise des "
 
"hooks Git de post-réception en interne. L'installation de ces hooks est "
 
"gérée dans %s."
 
"Kallithea ne supporte pas les hooks Git personnalisés. Kallithea utilise "
 
"des hooks Git de post-réception en interne. L'installation de ces hooks "
 
"est gérée dans %s."
 

	
 
msgid "Custom Hooks are not enabled"
 
msgstr "Les Hooks personnalisés ne sont pas activés"
 
@@ -2299,9 +2280,9 @@ msgid ""
 
"hooks that don't seem to come from Kallithea will be disabled by renaming "
 
"to .bak extension."
 
msgstr ""
 
"Installe les hooks internes de Kallithea pour tous les dépôts Git. Les hooks "
 
"existants qui ne semblent pas être livrés avec Kallithea seront désactivés "
 
"en les renommant avec l'extension .bak."
 
"Installe les hooks internes de Kallithea pour tous les dépôts Git. Les "
 
"hooks existants qui ne semblent pas être livrés avec Kallithea seront "
 
"désactivés en les renommant avec l'extension .bak."
 

	
 
msgid "Rescan Repositories"
 
msgstr "Relancer le scan des dépôts"
 
@@ -2452,12 +2433,13 @@ msgid ""
 
"hostname\n"
 
"                                                    "
 
msgstr ""
 
"Modèle de construction d'URL de clone. Par exemple : "
 
"'{scheme}://{user}@{netloc}/{repo}'.\n"
 
"Modèle de construction d'URL de clone. Par exemple : '{scheme}://{user}"
 
"@{netloc}/{repo}'.\n"
 
"                                                       Les variables "
 
"suivantes sont disponibles :\n"
 
"                                                        {scheme}    'http' "
 
"ou 'https' envoyé à partir du serveur Kallithea en cours d'utilisation,\n"
 
"                                                        {scheme}    "
 
"'http' ou 'https' envoyé à partir du serveur Kallithea en cours "
 
"d'utilisation,\n"
 
"                                                        {user}     nom de "
 
"l'utilisateur courant,\n"
 
"                                                        {netloc}    "
 
@@ -2466,8 +2448,8 @@ msgstr ""
 
"complet du dépôt,\n"
 
"                                                        {repoid}    ID du "
 
"dépôt, peut être utilisé pour cloner par ID,\n"
 
"                                                        {system_user}  nom "
 
"de l'utilisateur système Kallithea,\n"
 
"                                                        {system_user}  "
 
"nom de l'utilisateur système Kallithea,\n"
 
"                                                        {hostname}  nom "
 
"d'hôte du serveur\n"
 
"                                                    "
 
@@ -2509,7 +2491,7 @@ msgid "Show private repository icon on r
 
msgstr "Afficher l’icône de dépôt privé sur les dépôts"
 

	
 
msgid "Show public/private icons next to repository names."
 
msgstr "Afficher l’icône « public/privé » à côté du nom des dépôts."
 
msgstr "Afficher l’icône « public/privé » à côté du nom des dépôts."
 

	
 
msgid "Meta Tagging"
 
msgstr "Meta-tagging"
 
@@ -2600,7 +2582,7 @@ msgid "Member of User Groups"
 
msgstr "Membre des groupes d'utilisateurs"
 

	
 
msgid "Confirm to delete this user: %s"
 
msgstr "Voulez-vous vraiment supprimer l’utilisateur « %s » ?"
 
msgstr "Voulez-vous vraiment supprimer l’utilisateur « %s » ?"
 

	
 
msgid "Delete this user"
 
msgstr "Supprimer cet utilisateur"
 
@@ -2714,7 +2696,7 @@ msgid "Login to Your Account"
 
msgstr "Connexion à votre compte"
 

	
 
msgid "Forgot password?"
 
msgstr "Mot de passe oublié?"
 
msgstr "Mot de passe oublié ?"
 

	
 
msgid "Log Out"
 
msgstr "Se déconnecter"
 
@@ -2800,11 +2782,11 @@ msgstr "Aucun fichier correspondant"
 
msgid "Open New Pull Request from {0}"
 
msgstr "Ouvrir une nouvelle requête de pull à partir de {0}"
 

	
 
msgid "Open New Pull Request for {0} &rarr; {1}"
 
msgstr "Ouvrir une nouvelle requête de pull pour {0} &rarr; {1}"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "Afficher les changesets sélectionnés {0} &rarr; {1}"
 
msgid "Open New Pull Request for {0}"
 
msgstr "Ouvrir une nouvelle requête de pull pour {0}"
 

	
 
msgid "Show Selected Changesets {0}"
 
msgstr "Afficher les changesets sélectionnés {0}"
 

	
 
msgid "Selection Link"
 
msgstr "Lien vers la sélection"
 
@@ -3147,10 +3129,10 @@ msgid "Creating"
 
msgstr "En cours de création"
 

	
 
msgid "Mention in Comment on Changeset \"%s\""
 
msgstr "Mention dans le commentaire sur le changeset « %s »"
 
msgstr "Mention dans le commentaire sur le changeset « %s »"
 

	
 
msgid "Comment on Changeset \"%s\""
 
msgstr "Commentaire sur le changeset « %s »"
 
msgstr "Commentaire sur le changeset « %s »"
 

	
 
msgid "Changeset on"
 
msgstr "Changeset sur"
 
@@ -3209,10 +3191,10 @@ msgstr ""
 
"tenez pas compte de ce message."
 

	
 
msgid "Mention on Pull Request %s \"%s\" by %s"
 
msgstr "Mention sur la requête de pull %s « %s » par %s"
 
msgstr "Mention sur la requête de pull %s « %s » par %s"
 

	
 
msgid "Added as Reviewer of Pull Request %s \"%s\" by %s"
 
msgstr "Ajouté comme relecteur de la requête de pull %s « %s » par %s"
 
msgstr "Ajouté comme relecteur de la requête de pull %s « %s » par %s"
 

	
 
msgid "Pull request"
 
msgstr "Requête de pull"
 
@@ -3227,13 +3209,13 @@ msgid "View Pull Request"
 
msgstr "Afficher la requête de pull"
 

	
 
msgid "Mention in Comment on Pull Request %s \"%s\""
 
msgstr "Mention dans le commentaire sur la requête de pull %s « %s »"
 
msgstr "Mention dans le commentaire sur la requête de pull %s « %s »"
 

	
 
msgid "Pull Request %s \"%s\" Closed"
 
msgstr "Requête de pull %s « %s » fermée"
 
msgstr "Requête de pull %s « %s » fermée"
 

	
 
msgid "Comment on Pull Request %s \"%s\""
 
msgstr "Commentaire sur la requête de pull %s « %s »"
 
msgstr "Commentaire sur la requête de pull %s « %s »"
 

	
 
msgid "New User Registration"
 
msgstr "Nouvel enregistrement d'utilisateur"
 
@@ -3763,8 +3745,5 @@ msgstr "Pusher le nouveau dépôt"
 
msgid "Existing repository?"
 
msgstr "Le dépôt existe déjà ?"
 

	
 
msgid "Readme file from revision %s:%s"
 
msgstr "Fichier Lisez-moi de la revision %s:%s"
 

	
 
msgid "Download %s as %s"
 
msgstr "Télécharge %s comme %s"
kallithea/i18n/ja/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -1412,9 +1412,15 @@ msgstr "リポジトリグループ管理"
 
msgid "Number of Top-level Repositories"
 
msgstr "トップレベルリポジトリ数"
 

	
 
msgid "Type of repository to create."
 
msgstr "作成するリポジトリの種別を指定します"
 

	
 
msgid "Clone remote repository"
 
msgstr "リモートリポジトリをクローン"
 

	
 
msgid "Repository URL"
 
msgstr "リポジトリURL"
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr ""
 
@@ -1423,9 +1429,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "オプション:このリポジトリが属するグループを選択します"
 

	
 
msgid "Type of repository to create."
 
msgstr "作成するリポジトリの種別を指定します"
 

	
 
msgid "Landing revision"
 
msgstr "ランディングリビジョン"
 

	
 
@@ -1547,26 +1550,9 @@ msgstr "リモートリポジトリから変更を取り込んでもよろしいですか?"
 
msgid "This repository does not have a remote repository URL."
 
msgstr "このリポジトリにリモートURLは設定されていません"
 

	
 
msgid ""
 
"In case this repository is renamed or moved into another group the "
 
"repository URL changes.\n"
 
"                               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 ""
 
"通常、リポジトリの名前を変更したり、別のグループに移動すると、リポジトリの"
 
"URLが変わります。\n"
 
"上のURLを使えば、常にリポジトリにアクセスできます。\n"
 
"この機能は、CIを使っている場合や、3rd pirtyのサービス向けにURLを固定化した"
 
"いときに便利です。"
 

	
 
msgid "Remote repository"
 
msgstr "リモートリポジトリ"
 

	
 
msgid "Repository URL"
 
msgstr "リポジトリURL"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -1574,11 +1560,6 @@ msgstr ""
 
"オプション: リモートリポジトリのURLです。設定した場合、このURLから変更を取"
 
"得することができます。"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"ファイルページ、ダウンロード、検索、READMEのデフォルトのリビジョンを指定し"
 
"ます"
 

	
 
msgid "Change owner of this repository."
 
msgstr "リポジトリの所有者を変更"
 

	
 
@@ -2057,10 +2038,10 @@ msgstr "マッチするファイルはありません"
 
msgid "Open New Pull Request from {0}"
 
msgstr "新しいプルリクエストを{0}から作成"
 

	
 
msgid "Open New Pull Request for {0} &rarr; {1}"
 
msgid "Open New Pull Request for {0}"
 
msgstr "{0} &rarr; {1}から新しいプルリクエストを作成する"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgid "Show Selected Changesets {0}"
 
msgstr "選択したチェンジセット{0} &rarr; {0}を表示"
 

	
 
msgid "Collapse Diff"
 
@@ -2757,8 +2738,5 @@ msgstr "新しいリポジトリをプッシュ"
 
msgid "Existing repository?"
 
msgstr "存在するリポジトリをプッシュ"
 

	
 
msgid "Readme file from revision %s:%s"
 
msgstr "リビジョン %s:%s の README ファイル"
 

	
 
msgid "Download %s as %s"
 
msgstr "%s を %s でダウンロード"
kallithea/i18n/nb_NO/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -896,6 +896,9 @@ msgstr "Legg til ny"
 
msgid "Both"
 
msgstr "Begge"
 

	
 
msgid "Type name of user"
 
msgstr "Skriv inn brukerens navn"
 

	
 
msgid "Remove this group"
 
msgstr "Fjern denne gruppen"
 

	
 
@@ -955,9 +958,6 @@ msgstr "Privat pakkebrønn"
 
msgid "Fork of repository"
 
msgstr "Forgrening av pakkebrønn"
 

	
 
msgid "Type name of user"
 
msgstr "Skriv inn brukerens navn"
 

	
 
msgid "Processed commits"
 
msgstr "Behandlede innsendelser"
 

	
kallithea/i18n/nl_BE/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -215,8 +215,8 @@ msgstr "Repository paginagrootte"
 
msgid "Open New Pull Request from {0}"
 
msgstr "Open nieuwe pull request vanaf {0}"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "Toon geselecteerde changesets {0} &rarr; {1}"
 
msgid "Show Selected Changesets {0}"
 
msgstr "Toon geselecteerde changesets {0}"
 

	
 
msgid "Select changeset"
 
msgstr "Selecteer een changeset"
kallithea/i18n/pl/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -8,8 +8,8 @@ msgstr ""
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=UTF-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n"
 
"%100<10 || n%100>=20) ? 1 : 2;\n"
 
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && "
 
"(n%100<10 || n%100>=20) ? 1 : 2;\n"
 

	
 
msgid ""
 
"CSRF token leak has been detected - all form tokens have been expired"
 
@@ -176,6 +176,9 @@ msgstr "Nieprawidłowy token resetowania hasła"
 
msgid "Successfully updated password"
 
msgstr "Pomyślnie zaktualizowano hasło"
 

	
 
msgid "Invalid reviewer \"%s\" specified"
 
msgstr "Podano nieprawidłowego recenzenta \"%s\""
 

	
 
msgid "%s (closed)"
 
msgstr "%s (zamknięty)"
 

	
 
@@ -1506,6 +1509,9 @@ msgstr "Dodaj nowe"
 
msgid "Both"
 
msgstr "Oba"
 

	
 
msgid "Type of repository to create."
 
msgstr "Rodzaj repozytorium do stworzenia."
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr ""
 
@@ -1514,9 +1520,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Opcjonalnie wybierz grupę do wprowadzenia tego repozytorium."
 

	
 
msgid "Type of repository to create."
 
msgstr "Rodzaj repozytorium do stworzenia."
 

	
 
msgid "Landing revision"
 
msgstr "Docelowa rewizja"
 

	
 
@@ -1562,9 +1565,6 @@ msgstr "Nowy opis pola"
 
msgid "Enter description of a field"
 
msgstr "Wprowadź opis pola"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr "Wersja domyślna dla plików stronicowania, pobierania plików, readme"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Zmiana właściciela tego repozytorium."
 

	
kallithea/i18n/pt/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -889,6 +889,9 @@ msgstr[1] "Confirme para apagar este grupo: %s com %s repositórios"
 
msgid "Add new"
 
msgstr "Adicionar novo"
 

	
 
msgid "Type of repository to create."
 
msgstr "Tipo de repositório a criar."
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr ""
 
@@ -898,9 +901,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Opcionalmente selecione um grupo no qual pôr esse repositório."
 

	
 
msgid "Type of repository to create."
 
msgstr "Tipo de repositório a criar."
 

	
 
msgid "Landing revision"
 
msgstr "Revisão de pouso"
 

	
 
@@ -943,11 +943,6 @@ msgstr "Nova descrição de campo"
 
msgid "Enter description of a field"
 
msgstr "Entre com a descrição de um campo"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"Revisão predefinida para página de ficheiros, descarregamentos, whoosh e "
 
"readme"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Mudar o dono desse repositório."
 

	
kallithea/i18n/pt_BR/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -889,6 +889,9 @@ msgstr[1] "Confirme para excluir este grupo: %s com %s repositórios"
 
msgid "Add new"
 
msgstr "Adicionar novo"
 

	
 
msgid "Type of repository to create."
 
msgstr "Tipo de repositório a criar."
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr ""
 
@@ -898,9 +901,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Opcionalmente selecione um grupo no qual colocar esse repositório."
 

	
 
msgid "Type of repository to create."
 
msgstr "Tipo de repositório a criar."
 

	
 
msgid "Landing revision"
 
msgstr "Revisão de pouso"
 

	
 
@@ -943,9 +943,6 @@ msgstr "Nova descrição de campo"
 
msgid "Enter description of a field"
 
msgstr "Entre com a descrição de um campo"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr "Revisão padrão para página de arquivos, downloads, whoosh e readme"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Mudar o dono desse repositório."
 

	
kallithea/i18n/ru/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -8,8 +8,8 @@ msgstr ""
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=UTF-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
 
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 

	
 
msgid ""
 
"CSRF token leak has been detected - all form tokens have been expired"
 
@@ -934,6 +934,13 @@ msgstr "Введите не менее %(min)i символов"
 
msgid "Name must not contain only digits"
 
msgstr "Имя не может состоять только из цифр"
 

	
 
msgid ""
 
"[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
 
"%(branch)s by %(cs_author_username)s"
 
msgstr ""
 
"[Комментарий] к набору изменений %(short_id)s «%(message_short)s» "
 
"репозитория %(repo_name)s в %(branch)s от %(cs_author_username)s"
 

	
 
msgid "New user %(new_username)s registered"
 
msgstr "Новый пользователь \"%(new_username)s\" зарегистрирован"
 

	
 
@@ -1811,6 +1818,9 @@ msgstr ""
 
"Установить или отозвать права всех дочерних элементов этой группы, "
 
"включая публичные репозитории и другие группы, если они выбраны."
 

	
 
msgid "Type name of user"
 
msgstr "Введите имя пользователя"
 

	
 
msgid "Remove this group"
 
msgstr "Удалить группу"
 

	
 
@@ -1826,9 +1836,15 @@ msgstr "Администрирование групп репозиториев"
 
msgid "Number of Top-level Repositories"
 
msgstr "Число репозиториев верхнего уровня"
 

	
 
msgid "Type of repository to create."
 
msgstr "Тип создаваемого репозитория."
 

	
 
msgid "Clone remote repository"
 
msgstr "Клонировать удалённый репозиторий"
 

	
 
msgid "Repository URL"
 
msgstr "URL репозитория"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository will be "
 
"created as a clone from this URL."
 
@@ -1844,9 +1860,6 @@ msgstr ""
 
msgid "Optionally select a group to put this repository into."
 
msgstr "Опционально выбрать группу, в которую поместить данный репозиторий."
 

	
 
msgid "Type of repository to create."
 
msgstr "Тип создаваемого репозитория."
 

	
 
msgid "Landing revision"
 
msgstr "Ревизия для выгрузки"
 

	
 
@@ -1989,27 +2002,9 @@ msgstr "Данный репозиторий не имеет URL удалённого репозитория."
 
msgid "Permanent URL"
 
msgstr "Постоянный URL"
 

	
 
msgid ""
 
"In case this repository is renamed or moved into another group the "
 
"repository URL changes.\n"
 
"                               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 ""
 
"В случае, когда репозиторий переименовывается или перемещается в другую "
 
"группу, URL репозитория изменяется.\n"
 
"                               Использование постоянного URL гарантирует, "
 
"что данный репозиторий всегда будет доступен по этому URL.\n"
 
"                               Это может быть полезно в CI-системах, или "
 
"в любом другом случае, требующем встраивания URL в код ПО."
 

	
 
msgid "Remote repository"
 
msgstr "Удалённый репозиторий"
 

	
 
msgid "Repository URL"
 
msgstr "URL репозитория"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -2017,14 +2012,6 @@ msgstr ""
 
"Опционально: URL удалённого репозитория. Если задан, то репозиторий можно "
 
"получить по заданному адресу."
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr ""
 
"Ревизия по умолчанию, из которой будет производиться выгрузка файлов при "
 
"скачивании"
 

	
 
msgid "Type name of user"
 
msgstr "Введите имя пользователя"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Изменить владельца репозитория."
 

	
 
@@ -2645,11 +2632,11 @@ msgstr "Нет совпадений"
 
msgid "Open New Pull Request from {0}"
 
msgstr "Открыть новый pull-запрос от {0}"
 

	
 
msgid "Open New Pull Request for {0} &rarr; {1}"
 
msgstr "Открыть новый pull-запрос для {0} &rarr; {1}"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "Показать выбранные наборы изменений: {0} &rarr; {1}"
 
msgid "Open New Pull Request for {0}"
 
msgstr "Открыть новый pull-запрос для {0}"
 

	
 
msgid "Show Selected Changesets {0}"
 
msgstr "Показать выбранные наборы изменений: {0}"
 

	
 
msgid "Selection Link"
 
msgstr "Ссылка выбора"
 
@@ -3598,8 +3585,5 @@ msgstr "Отправить новый репозиторий"
 
msgid "Existing repository?"
 
msgstr "Существующий репозиторий?"
 

	
 
msgid "Readme file from revision %s:%s"
 
msgstr "Файл readme из ревизии %s:%s"
 

	
 
msgid "Download %s as %s"
 
msgstr "Скачать %s как %s"
kallithea/i18n/uk/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -8,8 +8,8 @@ msgstr ""
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=UTF-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
 
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
 
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
 

	
 
msgid ""
 
"CSRF token leak has been detected - all form tokens have been expired"
 
@@ -1054,6 +1054,9 @@ msgstr ""
 
"Встановіть або скасуйте дозвіл для всіх дітей цієї групи, включно з "
 
"неприватними репозиторіями та іншими групами, якщо вони вибрані."
 

	
 
msgid "Type name of user"
 
msgstr "Введіть ім'я користувача"
 

	
 
msgid "Remove this group"
 
msgstr "Видалити цю групу"
 

	
 
@@ -1069,15 +1072,18 @@ msgstr "Адміністрування Груп Репозиторіїв"
 
msgid "Number of Top-level Repositories"
 
msgstr "Кількість репозиторіїв верхнього рівня"
 

	
 
msgid "Type of repository to create."
 
msgstr "Тип сховища для створення."
 

	
 
msgid "Clone remote repository"
 
msgstr "Клонувати віддалений репозиторій"
 

	
 
msgid "Repository URL"
 
msgstr "URL репозиторію"
 

	
 
msgid "Optionally select a group to put this repository into."
 
msgstr "За бажанням виберіть групу, в яку буде розміщено цей репозиторій."
 

	
 
msgid "Type of repository to create."
 
msgstr "Тип сховища для створення."
 

	
 
msgid "Landing revision"
 
msgstr "Цільова редакція"
 

	
 
@@ -1205,9 +1211,6 @@ msgstr "У цьому сховищі немає URL-адреси віддаленого сховища."
 
msgid "Remote repository"
 
msgstr "Віддалений репозиторій"
 

	
 
msgid "Repository URL"
 
msgstr "URL репозиторію"
 

	
 
msgid ""
 
"Optional: URL of a remote repository. If set, the repository can be "
 
"pulled from this URL."
 
@@ -1215,9 +1218,6 @@ msgstr ""
 
"Опціонально: URL-адреса віддаленого сховища. Якщо встановлено, сховище "
 
"можна витягнути з цієї URL-адреси."
 

	
 
msgid "Type name of user"
 
msgstr "Введіть ім'я користувача"
 

	
 
msgid "Change owner of this repository."
 
msgstr "Змінити власника цього сховища."
 

	
kallithea/i18n/zh_CN/LC_MESSAGES/kallithea.po
Show inline comments
 
@@ -569,7 +569,7 @@ msgstr "不是一个合法的路径"
 
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 必须指定 - 这个名字作为用户名"
 
msgstr "LDAP 登录属性的 CN 必须指定 - 这个名字作为用户名"
 

	
 
msgid "Repository"
 
msgstr "版本库"
 
@@ -715,6 +715,9 @@ msgid "Confirm to delete this group: %s 
 
msgid_plural "Confirm to delete this group: %s with %s repositories"
 
msgstr[0] "确认删除这个版本库组:%s包含%s个版本库"
 

	
 
msgid "Type of repository to create."
 
msgstr "要创建的版本库类型。"
 

	
 
msgid ""
 
"Keep it short and to the point. Use a README file for longer descriptions."
 
msgstr "保持简短。用README文件来写更长的描述。"
 
@@ -722,9 +725,6 @@ msgstr "保持简短。用README文件来写更长的描述。"
 
msgid "Optionally select a group to put this repository into."
 
msgstr "可选的选择一个组将版本库放到其中。"
 

	
 
msgid "Type of repository to create."
 
msgstr "要创建的版本库类型。"
 

	
 
msgid "Landing revision"
 
msgstr "默认修订"
 

	
 
@@ -743,9 +743,6 @@ msgstr "确认删除版本库:%s"
 
msgid "Key"
 
msgstr "键"
 

	
 
msgid "Default revision for files page, downloads, whoosh and readme"
 
msgstr "文件浏览、下载、whoosh和README的默认修订版本"
 

	
 
msgid "Change owner of this repository."
 
msgstr "修改这个版本库的所有者。"
 

	
 
@@ -863,8 +860,8 @@ msgstr "开始关注该版本库"
 
msgid "Group"
 
msgstr "组"
 

	
 
msgid "Show Selected Changesets {0} &rarr; {1}"
 
msgstr "显示选中的修订集 {0} &rarr; {1}"
 
msgid "Show Selected Changesets {0}"
 
msgstr "显示选中的修订集 {0}"
 

	
 
msgid "Select changeset"
 
msgstr "选择修订集"
 
@@ -946,7 +943,7 @@ msgid "You need to be logged in to comme
 
msgstr "您必须登录才能评论。"
 

	
 
msgid "Login now"
 
msgstr "现在登陆"
 
msgstr "现在登录"
 

	
 
msgid "Hide"
 
msgstr "隐藏"
kallithea/model/db.py
Show inline comments
 
@@ -913,7 +913,7 @@ class Repository(meta.Base, BaseDbModel)
 
    STATE_ERROR = 'repo_state_error'
 

	
 
    repo_id = Column(Integer(), primary_key=True)
 
    repo_name = Column(Unicode(255), nullable=False, unique=True)
 
    repo_name = Column(Unicode(255), nullable=False, unique=True)  # full path, must be updated (based on get_new_name) when name or path changes
 
    repo_state = Column(String(255), nullable=False)
 

	
 
    clone_uri = Column(String(255), nullable=True) # FIXME: not nullable?
 
@@ -1337,7 +1337,7 @@ class RepoGroup(meta.Base, BaseDbModel):
 
    SEP = ' &raquo; '
 

	
 
    group_id = Column(Integer(), primary_key=True)
 
    group_name = Column(Unicode(255), nullable=False, unique=True) # full path
 
    group_name = Column(Unicode(255), nullable=False, unique=True)  # full path, must be updated (based on get_new_name) when name or path changes
 
    parent_group_id = Column('group_parent_id', Integer(), ForeignKey('groups.group_id'), nullable=True)
 
    group_description = Column(Unicode(10000), nullable=False)
 
    owner_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
 
@@ -1914,6 +1914,7 @@ class ChangesetComment(meta.Base, BaseDb
 
        return dict(
 
            comment_id=self.comment_id,
 
            username=self.author.username,
 
            created_on=self.created_on.replace(microsecond=0),
 
            text=self.text,
 
        )
 

	
kallithea/model/forms.py
Show inline comments
 
@@ -173,6 +173,7 @@ def RepoGroupForm(edit=False, old_data=N
 
        group_copy_permissions = v.StringBoolean(if_missing=False)
 

	
 
        if edit:
 
            owner = All(v.UnicodeString(not_empty=True), v.ValidRepoUser())
 
            # FIXME: do a special check that we cannot move a group to one of
 
            # its children
 
            pass
kallithea/model/repo.py
Show inline comments
 
@@ -711,13 +711,10 @@ def create_repo(form_data, cur_user):
 
    copy_fork_permissions = form_data.get('copy_permissions')
 
    copy_group_permissions = form_data.get('repo_copy_permissions')
 
    fork_of = form_data.get('fork_parent_id')
 
    enable_statistics = form_data['repo_enable_statistics']
 
    enable_downloads = form_data['repo_enable_downloads']
 
    state = form_data.get('repo_state', db.Repository.STATE_PENDING)
 

	
 
    # repo creation defaults, private and repo_type are filled in form
 
    defs = db.Setting.get_default_repo_settings(strip_prefix=True)
 
    enable_statistics = defs.get('repo_enable_statistics')
 
    enable_downloads = defs.get('repo_enable_downloads')
 

	
 
    try:
 
        db_repo = RepoModel()._create_repo(
 
            repo_name=repo_name_full,
kallithea/model/repo_group.py
Show inline comments
 
@@ -278,45 +278,46 @@ class RepoGroupModel(object):
 
    def update(self, repo_group, repo_group_args):
 
        try:
 
            repo_group = db.RepoGroup.guess_instance(repo_group)
 
            old_path = repo_group.full_path
 
            old_path = repo_group.full_path  # aka .group_name
 

	
 
            # change properties
 
            if 'owner' in repo_group_args:
 
                repo_group.owner = db.User.get_by_username(repo_group_args['owner'])
 
            if 'group_description' in repo_group_args:
 
                repo_group.group_description = repo_group_args['group_description']
 
            if 'parent_group_id' in repo_group_args:
 
                repo_group.parent_group_id = repo_group_args['parent_group_id']
 

	
 
            if 'parent_group_id' in repo_group_args:
 
                assert repo_group_args['parent_group_id'] != '-1', repo_group_args  # RepoGroupForm should have converted to None
 
                repo_group.parent_group = db.RepoGroup.get(repo_group_args['parent_group_id'])
 
                new_parent_group = db.RepoGroup.get(repo_group_args['parent_group_id'])
 
                if new_parent_group is not repo_group.parent_group:
 
                    repo_group.parent_group = new_parent_group
 
                    repo_group.group_name = repo_group.get_new_name(repo_group.name)
 
                    log.debug('Moving repo group %s to %s', old_path, repo_group.group_name)
 
            if 'group_name' in repo_group_args:
 
                group_name = repo_group_args['group_name']
 
                if kallithea.lib.utils2.repo_name_slug(group_name) != group_name:
 
                    raise Exception('invalid repo group name %s' % group_name)
 
                if repo_group.name != group_name:
 
                repo_group.group_name = repo_group.get_new_name(group_name)
 
                    log.debug('Renaming repo group %s to %s', old_path, repo_group.group_name)
 
            new_path = repo_group.full_path
 
            meta.Session().add(repo_group)
 

	
 
            # iterate over all members of this groups and do fixes
 
            # if obj is a repoGroup also fix the name of the group according
 
            # to the parent
 
            # if obj is a Repo fix it's name
 
            # this can be potentially heavy operation
 
            # Iterate over all members of this repo group and update the full
 
            # path (repo_name and group_name) based on the (already updated)
 
            # full path of the parent.
 
            # This can potentially be a heavy operation.
 
            for obj in repo_group.recursive_groups_and_repos():
 
                # set the value from it's parent
 
                if obj is repo_group:
 
                    continue  # already updated and logged
 
                if isinstance(obj, db.RepoGroup):
 
                    new_name = obj.get_new_name(obj.name)
 
                    log.debug('Fixing group %s to new name %s'
 
                                % (obj.group_name, new_name))
 
                    log.debug('Fixing repo group %s to new name %s', obj.group_name, new_name)
 
                    obj.group_name = new_name
 
                elif isinstance(obj, db.Repository):
 
                    # we need to get all repositories from this new group and
 
                    # rename them accordingly to new group path
 
                    new_name = obj.get_new_name(obj.just_name)
 
                    log.debug('Fixing repo %s to new name %s'
 
                                % (obj.repo_name, new_name))
 
                    log.debug('Fixing repo %s to new name %s', obj.repo_name, new_name)
 
                    obj.repo_name = new_name
 

	
 
            # Rename in file system
 
            self._rename_group(old_path, new_path)
 

	
 
            return repo_group
kallithea/templates/about.html
Show inline comments
 
@@ -24,7 +24,15 @@
 
  necessarily limited to the following:</p>
 
  <ul>
 

	
 
  <li>Copyright &copy; 2012&ndash;2021, Mads Kiilerich</li>
 
  <li>Copyright &copy; 2012&ndash;2023, Mads Kiilerich</li>
 
  <li>Copyright &copy; 2019&ndash;2020, 2022&ndash;2023, Manuel Jacob</li>
 
  <li>Copyright &copy; 2023, Mathias De Mare</li>
 
  <li>Copyright &copy; 2016&ndash;2017, 2020, 2022, Asterios Dimitriou</li>
 
  <li>Copyright &copy; 2022, Jaime Marquínez Ferrándiz</li>
 
  <li>Copyright &copy; 2022, Louis Bertrand</li>
 
  <li>Copyright &copy; 2022, toras9000</li>
 
  <li>Copyright &copy; 2022, yzqzss</li>
 
  <li>Copyright &copy; 2022, МАН69К</li>
 
  <li>Copyright &copy; 2014&ndash;2021, Thomas De Schampheleire</li>
 
  <li>Copyright &copy; 2015&ndash;2017, 2019&ndash;2021, Étienne Gilli</li>
 
  <li>Copyright &copy; 2018&ndash;2021, ssantos</li>
 
@@ -35,10 +43,8 @@
 
  <li>Copyright &copy; 2021, Michalis</li>
 
  <li>Copyright &copy; 2021, vs</li>
 
  <li>Copyright &copy; 2021, Александр</li>
 
  <li>Copyright &copy; 2016&ndash;2017, 2020, Asterios Dimitriou</li>
 
  <li>Copyright &copy; 2017&ndash;2020, Allan Nordhøy</li>
 
  <li>Copyright &copy; 2017, 2020, Anton Schur</li>
 
  <li>Copyright &copy; 2019&ndash;2020, Manuel Jacob</li>
 
  <li>Copyright &copy; 2020, Artem</li>
 
  <li>Copyright &copy; 2020, David Ignjić</li>
 
  <li>Copyright &copy; 2020, Dennis Fink</li>
kallithea/templates/admin/repo_groups/repo_group_edit_settings.html
Show inline comments
 
@@ -9,6 +9,13 @@ ${h.form(url('update_repos_group',group_
 
        </div>
 

	
 
        <div class="form-group">
 
            <label class="control-label" for="owner">${_('Owner')}:</label>
 
            <div>
 
               ${h.text('owner',class_='form-control', placeholder=_('Type name of user'))}
 
            </div>
 
        </div>
 

	
 
        <div class="form-group">
 
            <label class="control-label" for="group_description">${_('Description')}:</label>
 
            <div>
 
                ${h.textarea('group_description',cols=23,rows=5,class_='form-control')}
 
@@ -47,5 +54,6 @@ ${h.end_form()}
 
        $("#parent_group_id").select2({
 
            'dropdownAutoWidth': true
 
        });
 
        SimpleUserAutoComplete($('#owner'));
 
    });
 
</script>
kallithea/templates/admin/repos/repo_add_base.html
Show inline comments
 
## -*- coding: utf-8 -*-
 

	
 
${h.form(url('repos'))}
 
<div class="form">
 
        <div class="form-group">
 
@@ -8,10 +6,17 @@ ${h.form(url('repos'))}
 
                ${h.text('repo_name',class_='form-control')}
 
            </div>
 
        </div>
 
        <div id="remote_clone" class="form-group">
 
        <div class="form-group">
 
            <label class="control-label" for="repo_type">${_('Type')}:</label>
 
            <div>
 
                ${h.select('repo_type','hg',c.backends,class_='form-control')}
 
                <span class="help-block">${_('Type of repository to create.')}</span>
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <label class="control-label" for="clone_uri">${_('Clone remote repository')}:</label>
 
            <div>
 
                ${h.text('clone_uri',class_='form-control')}
 
                ${h.text('clone_uri',class_='form-control', placeholder=_('Repository URL'))}
 
                <span class="help-block">
 
                    ${_('Optional: URL of a remote repository. If set, the repository will be created as a clone from this URL.')}
 
                </span>
 
@@ -39,16 +44,9 @@ ${h.form(url('repos'))}
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <label class="control-label" for="repo_type">${_('Type')}:</label>
 
            <div>
 
                ${h.select('repo_type','hg',c.backends,class_='form-control')}
 
                <span class="help-block">${_('Type of repository to create.')}</span>
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
 
            <div>
 
                ${h.select('repo_landing_rev','',c.landing_revs,class_='form-control')}
 
                ${h.select('repo_landing_rev',None,c.landing_revs,class_='form-control')}
 
                <span class="help-block">${_('Default revision for files page, downloads, full text search index and readme generation')}</span>
 
            </div>
 
        </div>
 
@@ -60,14 +58,37 @@ ${h.form(url('repos'))}
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <label class="control-label" for="repo_enable_statistics">${_('Enable statistics')}:</label>
 
            <div>
 
                ${h.checkbox('repo_enable_statistics',value="True")}
 
                <span class="help-block">${_('Enable statistics window on summary page.')}</span>
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <label class="control-label" for="repo_enable_downloads">${_('Enable downloads')}:</label>
 
            <div>
 
                ${h.checkbox('repo_enable_downloads',value="True")}
 
                <span class="help-block">${_('Enable download menu on summary page.')}</span>
 
            </div>
 
        </div>
 
        <div class="form-group">
 
            <div class="buttons">
 
                ${h.submit('add',_('Add'),class_="btn btn-default")}
 
            </div>
 
        </div>
 
</div>
 
${h.end_form()}
 

	
 
<script>
 
    'use strict';
 
    $(document).ready(function(){
 
        $('#repo_type').select2({
 
            'minimumResultsForSearch': -1
 
        });
 
        $('#repo_group').select2({
 
            'dropdownAutoWidth': true
 
        });
 

	
 
        function setCopyPermsOption(group_val){
 
            if(group_val != "-1"){
 
                $('#copy_perms').show();
 
@@ -77,22 +98,14 @@ ${h.form(url('repos'))}
 
            }
 
        }
 

	
 
        $("#repo_group").select2({
 
            'dropdownAutoWidth': true
 
        });
 

	
 
        setCopyPermsOption($('#repo_group').val());
 
        $("#repo_group").on("change", function(e) {
 
        $('#repo_group').on("change", function(e) {
 
            setCopyPermsOption(e.val);
 
        });
 

	
 
        $("#repo_type").select2({
 
            'minimumResultsForSearch': -1
 
        });
 
        $("#repo_landing_rev").select2({
 
        $('#repo_landing_rev').select2({
 
            'minimumResultsForSearch': -1
 
        });
 
        $('#repo_name').focus();
 
    });
 
</script>
 
${h.end_form()}
kallithea/templates/admin/repos/repo_edit_settings.html
Show inline comments
 
@@ -20,27 +20,32 @@ ${h.form(url('update_repo', repo_name=c.
 
            <div class="form-group">
 
                <label class="control-label" for="clone_uri">${_('Remote repository')}:</label>
 
                <div>
 
                  <div id="alter_clone_uri">
 
                        ${h.text('clone_uri',class_='form-control', placeholder=_('Repository URL'))}
 
                        ${h.hidden('clone_uri_hidden', c.repo_info.clone_uri_hidden)}
 
                  </div>
 
                  <span id="alter_clone_uri_help_block" class="help-block">
 
                <span class="help-block">
 
                    ${_('Optional: URL of a remote repository. If set, the repository can be pulled from this URL.')}
 
                  </span>
 
                </div>
 
            </div>
 
            <div class="form-group">
 
            <label class="control-label" for="repo_description">${_('Description')}:</label>
 
            <div>
 
                ${h.textarea('repo_description',class_='form-control')}
 
                <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
 
            </div>
 
        </div>
 
        <div class="form-group">
 
                <label class="control-label" for="repo_group">${_('Repository group')}:</label>
 
                <div>
 
                    ${h.select('repo_group','',c.repo_groups,class_='form-control')}
 
                ${h.select('repo_group',None,c.repo_groups,class_='form-control')}
 
                    <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
 
                </div>
 
            </div>
 
            <div class="form-group">
 
                <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
 
                <div>
 
                    ${h.select('repo_landing_rev','',c.landing_revs,class_='form-control')}
 
                    <span class="help-block">${_('Default revision for files page, downloads, whoosh and readme')}</span>
 
                ${h.select('repo_landing_rev',None,c.landing_revs,class_='form-control')}
 
                <span class="help-block">${_('Default revision for files page, downloads, full text search index and readme generation')}</span>
 
                </div>
 
            </div>
 
            <div class="form-group">
 
@@ -51,14 +56,6 @@ ${h.form(url('update_repo', repo_name=c.
 
                </div>
 
            </div>
 
            <div class="form-group">
 
                <label class="control-label" for="repo_description">${_('Description')}:</label>
 
                <div>
 
                    ${h.textarea('repo_description',class_='form-control')}
 
                    <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
 
                </div>
 
            </div>
 

	
 
            <div class="form-group">
 
                <label class="control-label" for="repo_private">${_('Private repository')}:</label>
 
                <div>
 
                    ${h.checkbox('repo_private',value="True")}
 
@@ -106,10 +103,10 @@ ${h.form(url('update_repo', repo_name=c.
 
<script>
 
    'use strict';
 
    $(document).ready(function(){
 
        $('#repo_landing_rev').select2({
 
        $('#repo_group').select2({
 
            'dropdownAutoWidth': true
 
        });
 
        $('#repo_group').select2({
 
        $('#repo_landing_rev').select2({
 
            'dropdownAutoWidth': true
 
        });
 

	
kallithea/templates/base/base.html
Show inline comments
 
@@ -23,7 +23,7 @@
 
            <a class="navbar-link" href="${h.url('kallithea_project_url')}" target="_blank">Kallithea</a>,
 
        %endif
 
        which is
 
        <a class="navbar-link" href="${h.canonical_url('about')}#copyright">&copy; 2010&ndash;2022 by various authors &amp; licensed under GPLv3</a>.
 
        <a class="navbar-link" href="${h.canonical_url('about')}#copyright">&copy; 2010&ndash;2023 by various authors &amp; licensed under GPLv3</a>.
 
        %if c.issues_url:
 
            &ndash; <a class="navbar-link" href="${c.issues_url}" target="_blank">${_('Support')}</a>
 
        %endif
kallithea/templates/base/root.html
Show inline comments
 
@@ -38,8 +38,8 @@
 
                'Search truncated': ${h.jshtml(_('Search truncated'))},
 
                'No matching files': ${h.jshtml(_('No matching files'))},
 
                'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
 
                'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
 
                'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
 
                'Open New Pull Request for {0}': ${h.js(_('Open New Pull Request for {0}'))},
 
                'Show Selected Changesets {0}': ${h.js(_('Show Selected Changesets {0}'))},
 
                'Selection Link': ${h.jshtml(_('Selection Link'))},
 
                'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
 
                'Expand Diff': ${h.jshtml(_('Expand Diff'))},
kallithea/templates/changelog/changelog.html
Show inline comments
 
@@ -109,13 +109,13 @@ ${self.repo_context_bar('changelog', c.f
 
                                pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},
 
                                                                'revision': rev_start + '...' + rev_end}));
 
                            $('#rev_range_container').html(
 
                                 _TM['Show Selected Changesets {0} &rarr; {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12)));
 
                                 _TM['Show Selected Changesets {0}'].format(rev_start.substr(0, 12) + ' &rarr; ' + rev_end.substr(0, 12)));
 
                            $('#rev_range_container').show();
 
                            $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
 
                                                                        {'repo_name': ${h.js(c.repo_name)},
 
                                                                         'rev_start': rev_start,
 
                                                                         'rev_end': rev_end}));
 
                            $('#open_new_pr').html(_TM['Open New Pull Request for {0} &rarr; {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12)));
 
                            $('#open_new_pr').html(_TM['Open New Pull Request for {0}'].format(rev_start.substr(0, 12) + ' &rarr; ' + rev_end.substr(0, 12)));
 
                        } else {
 
                            $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
 
                                                                        {'repo_name': ${h.js(c.repo_name)},
kallithea/templates/summary/summary.html
Show inline comments
 
@@ -224,7 +224,7 @@ hg push ${c.clone_repo_url}
 
<div id="readme" class="anchor">
 
</div>
 
<div class="panel panel-primary">
 
    <div class="panel-heading" title="${_('Readme file from revision %s:%s') % (c.db_repo.landing_rev[0], c.db_repo.landing_rev[1])}">
 
    <div class="panel-heading" title="${_('Readme file from %s') % (c.db_repo.landing_rev[1])}">
 
        <div class="panel-title">
 
            <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
 
        </div>
kallithea/tests/api/api_base.py
Show inline comments
 
@@ -16,6 +16,7 @@
 
Tests for the JSON-RPC web api.
 
"""
 

	
 
import datetime
 
import os
 
import random
 
import re
 
@@ -260,7 +261,7 @@ class _BaseTestApi(object):
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    def test_api_pull_remote(self):
 
        # Note: pulling from local repos is a mis-feature - it will bypass access control
 
        # Note: pulling from local repos is a misfeature - it will bypass access control
 
        # ... but ok, if the path already has been set in the database
 
        repo_name = 'test_pull'
 
        r = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
 
@@ -784,24 +785,73 @@ class _BaseTestApi(object):
 
        finally:
 
            RepoModel().revoke_user_permission(self.REPO, self.TEST_USER_LOGIN)
 

	
 
    def test_api_create_repo(self):
 
        repo_name = 'api-repo'
 
    @base.parametrize('changing_attr,updates', [
 
        ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
 
        ('description', {'description': 'new description'}),
 
        ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
 
        ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
 
        ('clone_uri', {'clone_uri': None}),
 
        ('landing_rev', {'landing_rev': 'branch:master'}),
 
        ('private', {'private': True}),
 
        ('enable_statistics', {'enable_statistics': True}),
 
        ('enable_downloads', {'enable_downloads': True}),
 
        ('repo_group', {'group': 'test_group_for_update'}),
 
    ])
 
    def test_api_create_repo(self, changing_attr, updates):
 
        repo_name = repo_name_full = 'new_repo'
 

	
 
        if changing_attr == 'repo_group':
 
            group_name = updates['group']
 
            fixture.create_repo_group(group_name)
 
            repo_name_full = '/'.join([group_name, repo_name])
 
            updates = {}
 

	
 
        id_, params = _build_data(self.apikey, 'create_repo',
 
                                  repo_name=repo_name,
 
                                  owner=base.TEST_USER_ADMIN_LOGIN,
 
                                  repo_type=self.REPO_TYPE,
 
        )
 
                                  repo_type=self.REPO_TYPE, repo_name=repo_name_full, **updates)
 
        response = api_call(self, params)
 

	
 
        repo = RepoModel().get_by_repo_name(repo_name)
 
        try:
 
            expected = {
 
                'msg': 'Created new repository `%s`' % repo_name_full,
 
                'success': True}
 
            if changing_attr == 'clone_uri' and updates['clone_uri']:
 
                expected = 'failed to create repository `%s`' % repo_name
 
                self._compare_error(id_, expected, given=response.body)
 
                return
 
            else:
 
                self._compare_ok(id_, expected, given=response.body)
 

	
 
            repo = db.Repository.get_by_repo_name(repo_name_full)
 
        assert repo is not None
 
        ret = {
 
            'msg': 'Created new repository `%s`' % repo_name,
 
            'success': True,
 

	
 
            expected_data = {
 
                    'clone_uri': None,
 
                    'created_on': repo.created_on,
 
                    'description': repo_name,
 
                    'enable_downloads': False,
 
                    'enable_statistics': False,
 
                    'fork_of': None,
 
                    'landing_rev': ['rev', 'tip'],
 
                    'last_changeset': {'author': '',
 
                                       'date': datetime.datetime(1970, 1, 1, 0, 0),
 
                                       'message': '',
 
                                       'raw_id': '0000000000000000000000000000000000000000',
 
                                       'revision': -1,
 
                                       'short_id': '000000000000'},
 
                    'owner': 'test_admin',
 
                    'private': False,
 
                    'repo_id': repo.repo_id,
 
                    'repo_name': repo_name_full,
 
                    'repo_type': self.REPO_TYPE,
 
        }
 
        expected = ret
 
        self._compare_ok(id_, expected, given=response.body)
 
        fixture.destroy_repo(repo_name)
 
            expected_data.update(updates)
 
            if changing_attr == 'landing_rev':
 
                expected_data['landing_rev'] = expected_data['landing_rev'].split(':', 1)
 
            assert repo.get_api_data() == expected_data
 
        finally:
 
            fixture.destroy_repo(repo_name_full)
 
            if changing_attr == 'repo_group':
 
                fixture.destroy_repo_group(group_name)
 

	
 
    @base.parametrize('repo_name', [
 
        '',
 
@@ -827,7 +877,7 @@ class _BaseTestApi(object):
 
        fixture.destroy_repo(repo_name)
 

	
 
    def test_api_create_repo_clone_uri_local(self):
 
        # cloning from local repos was a mis-feature - it would bypass access control
 
        # cloning from local repos was a misfeature - it would bypass access control
 
        # TODO: introduce other test coverage of actual remote cloning
 
        clone_uri = os.path.join(base.TESTS_TMP_PATH, self.REPO)
 
        repo_name = 'api-repo'
 
@@ -1004,9 +1054,10 @@ class _BaseTestApi(object):
 
        ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
 
        ('description', {'description': 'new description'}),
 
        ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
 
        ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a mis-feature - it would bypass access control
 
        ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
 
        ('clone_uri', {'clone_uri': None}),
 
        ('landing_rev', {'landing_rev': 'branch:master'}),
 
        ('private', {'private': True}),
 
        ('enable_statistics', {'enable_statistics': True}),
 
        ('enable_downloads', {'enable_downloads': True}),
 
        ('name', {'name': 'new_repo_name'}),
 
@@ -1020,20 +1071,32 @@ class _BaseTestApi(object):
 

	
 
        id_, params = _build_data(self.apikey, 'update_repo',
 
                                  repoid=repo_name, **updates)
 
        response = api_call(self, params)
 

	
 
        if changing_attr == 'name':
 
            repo_name = updates['name']
 
        if changing_attr == 'repo_group':
 
            repo_name = '/'.join([updates['group'], repo_name])
 
        expected = {
 
            'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name),
 
            'repository': repo.get_api_data()
 
        }
 
        expected['repository'].update(updates)
 
        if changing_attr == 'clone_uri' and updates['clone_uri'] is None:
 
            expected['repository']['clone_uri'] = ''
 
        if changing_attr == 'landing_rev':
 
            expected['repository']['landing_rev'] = expected['repository']['landing_rev'].split(':', 1)
 
        if changing_attr == 'name':
 
            expected['repository']['repo_name'] = expected['repository'].pop('name')
 
        if changing_attr == 'repo_group':
 
            expected['repository']['repo_name'] = expected['repository'].pop('group') + '/' + repo.repo_name
 

	
 
        response = api_call(self, params)
 

	
 
        try:
 
            if changing_attr == 'clone_uri' and updates['clone_uri']:
 
                expected = 'failed to update repo `%s`' % repo_name
 
                self._compare_error(id_, expected, given=response.body)
 
            else:
 
                expected = {
 
                    'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name),
 
                    'repository': repo.get_api_data()
 
                }
 
                self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            fixture.destroy_repo(repo_name)
 
@@ -1044,7 +1107,7 @@ class _BaseTestApi(object):
 
        ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
 
        ('description', {'description': 'new description'}),
 
        ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
 
        ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a mis-feature - it would bypass access control
 
        ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
 
        ('clone_uri', {'clone_uri': None}),
 
        ('landing_rev', {'landing_rev': 'branch:master'}),
 
        ('enable_statistics', {'enable_statistics': True}),
 
@@ -1788,6 +1851,47 @@ class _BaseTestApi(object):
 
        )
 
        self._compare_error(id_, expected, given=response.body)
 

	
 
    @base.parametrize('changing_attr,updates', [
 
        ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
 
        ('description', {'description': 'new description'}),
 
        ('group_name', {'group_name': 'new_repo_name'}),
 
        ('parent', {'parent': 'test_group_for_update'}),
 
    ])
 
    def test_api_update_repo_group(self, changing_attr, updates):
 
        group_name = 'lololo'
 
        repo_group = fixture.create_repo_group(group_name)
 

	
 
        new_group_name = group_name
 
        if changing_attr == 'group_name':
 
            assert repo_group.parent_group_id is None  # lazy assumption for this test
 
            new_group_name = updates['group_name']
 
        if changing_attr == 'parent':
 
            new_group_name = '/'.join([updates['parent'], group_name.rsplit('/', 1)[-1]])
 

	
 
        expected = {
 
            'msg': 'updated repository group ID:%s %s' % (repo_group.group_id, new_group_name),
 
            'repo_group': repo_group.get_api_data()
 
        }
 
        expected['repo_group'].update(updates)
 
        if 'description' in updates:
 
            expected['repo_group']['group_description'] = expected['repo_group'].pop('description')
 

	
 
        if changing_attr == 'parent':
 
            new_parent = fixture.create_repo_group(updates['parent'])
 
            expected['repo_group']['parent_group'] = expected['repo_group'].pop('parent')
 
            expected['repo_group']['group_name'] = new_group_name
 

	
 
        id_, params = _build_data(self.apikey, 'update_repo_group',
 
                                  repogroupid=group_name, **updates)
 
        response = api_call(self, params)
 

	
 
        try:
 
            self._compare_ok(id_, expected, given=response.body)
 
        finally:
 
            if changing_attr == 'parent':
 
                fixture.destroy_repo_group(new_parent.group_id)
 
            fixture.destroy_repo_group(new_group_name)
 

	
 
    @base.parametrize('name,perm,apply_to_children', [
 
        ('none', 'group.none', 'none'),
 
        ('read', 'group.read', 'none'),
 
@@ -2375,6 +2479,8 @@ class _BaseTestApi(object):
 
        result = ext_json.loads(response.body)["result"]
 
        assert result["raw_id"] == self.TEST_REVISION
 
        assert "reviews" not in result
 
        assert "comments" not in result
 
        assert "inline_comments" not in result
 

	
 
    def test_api_get_changeset_with_reviews(self):
 
        reviewobjs = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved")
 
@@ -2385,6 +2491,8 @@ class _BaseTestApi(object):
 
        result = ext_json.loads(response.body)["result"]
 
        assert result["raw_id"] == self.TEST_REVISION
 
        assert "reviews" in result
 
        assert "comments" not in result
 
        assert "inline_comments" not in result
 
        assert len(result["reviews"]) == 1
 
        review = result["reviews"][0]
 
        expected = {
 
@@ -2394,6 +2502,49 @@ class _BaseTestApi(object):
 
        }
 
        assert review == expected
 

	
 
    def test_api_get_changeset_with_comments(self):
 
        commentobj = fixture.add_changeset_comment(self.REPO, self.TEST_REVISION, "example changeset comment")
 
        id_, params = _build_data(self.apikey, 'get_changeset',
 
                                  repoid=self.REPO, raw_id=self.TEST_REVISION,
 
                                  with_comments=True)
 
        response = api_call(self, params)
 
        result = ext_json.loads(response.body)["result"]
 
        assert result["raw_id"] == self.TEST_REVISION
 
        assert "reviews" not in result
 
        assert "comments" in result
 
        assert "inline_comments" not in result
 
        comment = result["comments"][-1]
 
        expected = {
 
            'comment_id': commentobj.comment_id,
 
            'text': 'example changeset comment',
 
            'username': 'test_admin',
 
            'created_on': commentobj.created_on.replace(microsecond=0).isoformat(),
 
        }
 
        assert comment == expected
 

	
 
    def test_api_get_changeset_with_inline_comments(self):
 
        commentobj = fixture.add_changeset_comment(self.REPO, self.TEST_REVISION, "example inline comment", f_path='vcs/__init__.py', line_no="n3")
 
        id_, params = _build_data(self.apikey, 'get_changeset',
 
                                  repoid=self.REPO, raw_id=self.TEST_REVISION,
 
                                  with_inline_comments=True)
 
        response = api_call(self, params)
 
        result = ext_json.loads(response.body)["result"]
 
        assert result["raw_id"] == self.TEST_REVISION
 
        assert "reviews" not in result
 
        assert "comments" not in result
 
        assert "inline_comments" in result
 
        expected = [
 
            ['vcs/__init__.py', {
 
                'n3': [{
 
                    'comment_id': commentobj.comment_id,
 
                    'text': 'example inline comment',
 
                    'username': 'test_admin',
 
                    'created_on': commentobj.created_on.replace(microsecond=0).isoformat(),
 
                }]
 
            }]
 
        ]
 
        assert result["inline_comments"] == expected
 

	
 
    def test_api_get_changeset_that_does_not_exist(self):
 
        """ Fetch changeset status for non-existant changeset.
 
        revision id is the above git hash used in the test above with the
 
@@ -2436,7 +2587,8 @@ class _BaseTestApi(object):
 
            "org_ref_parts": ["branch", "stable", self.TEST_PR_SRC],
 
            "other_ref_parts": ["branch", "default", self.TEST_PR_DST],
 
            "comments": [{"username": base.TEST_USER_ADMIN_LOGIN, "text": "",
 
                         "comment_id": pullrequest.comments[0].comment_id}],
 
                          "comment_id": pullrequest.comments[0].comment_id,
 
                          "created_on": "2000-01-01T00:00:00"}],
 
            "owner": base.TEST_USER_ADMIN_LOGIN,
 
            "statuses": [{"status": "under_review", "reviewer": base.TEST_USER_ADMIN_LOGIN, "modified_at": "2000-01-01T00:00:00"} for i in range(0, len(self.TEST_PR_REVISIONS))],
 
            "title": "get test",
kallithea/tests/fixture.py
Show inline comments
 
@@ -95,6 +95,8 @@ class Fixture(object):
 
            repo_group='-1',
 
            repo_description='DESC',
 
            repo_private=False,
 
            repo_enable_statistics=False,
 
            repo_enable_downloads=False,
 
            repo_landing_rev='rev:tip',
 
            repo_copy_permissions=False,
 
            repo_state=db.Repository.STATE_CREATED,
 
@@ -327,6 +329,11 @@ class Fixture(object):
 
        meta.Session().commit()
 
        return csm
 

	
 
    def add_changeset_comment(self, repo, revision, text, author=TEST_USER_ADMIN_LOGIN, f_path=None, line_no=None):
 
        comment = ChangesetCommentsModel().create(text, repo, author, revision=revision, f_path=f_path, line_no=line_no, send_email=False)
 
        meta.Session().commit()
 
        return comment
 

	
 
    def create_pullrequest(self, testcontroller, repo_name, pr_src_rev, pr_dst_rev, title='title'):
 
        org_ref = 'branch:stable:%s' % pr_src_rev
 
        other_ref = 'branch:default:%s' % pr_dst_rev
kallithea/tests/functional/test_admin_repo_groups.py
Show inline comments
 
@@ -53,6 +53,7 @@ class TestRepoGroupsController(base.Test
 
        # edit
 
        response = self.app.post(base.url('update_repos_group', group_name=group_name),
 
                                         {'group_name': group_name,
 
                                         'owner': base.TEST_USER_REGULAR2_LOGIN,
 
                                         'group_description': 'lolo',
 
                                          '_session_csrf_secret_token': self.session_csrf_secret_token()})
 
        self.checkSessionFlash(response, 'Updated repository group %s' % group_name)
setup.py
Show inline comments
 
@@ -75,6 +75,8 @@ requirements = [
 
    "pip >= 20.0, < 999",
 
    "chardet >= 3",
 
]
 
if sys.version_info < (3, 8):
 
    requirements.append("importlib-metadata < 5")
 

	
 
dependency_links = [
 
]
0 comments (0 inline, 0 general)