##// END OF EJS Templates
Merge stable
Mads Kiilerich -
r8765:b2c3d456 merge default
parent child Browse files
Show More
@@ -1,7 +1,15 b''
1 List of contributors to Kallithea project:
1 List of contributors to Kallithea project:
2
2
3 Mads Kiilerich <mads@kiilerich.com> 2016-2023
4 Manuel Jacob <me@manueljacob.de> 2019-2020 2022-2023
5 Mathias De Mare <mathias.de_mare@nokia.com> 2023
6 Asterios Dimitriou <steve@pci.gr> 2016-2017 2020 2022
7 Jaime Marquínez Ferrándiz <weblate@jregistros.fastmail.net> 2022
8 Louis Bertrand <louis.bertrand@durhamcollege.ca> 2022
9 toras9000 <toras9000@gmail.com> 2022
10 yzqzss <yzqzss@othing.xyz> 2022
11 МАН69К <weblate@mah69k.net> 2022
3 Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> 2014-2021
12 Thomas De Schampheleire <thomas.de_schampheleire@nokia.com> 2014-2021
4 Mads Kiilerich <mads@kiilerich.com> 2016-2021
5 ssantos <ssantos@web.de> 2018-2021
13 ssantos <ssantos@web.de> 2018-2021
6 Private <adamantine.sword@gmail.com> 2019-2021
14 Private <adamantine.sword@gmail.com> 2019-2021
7 Étienne Gilli <etienne@gilli.io> 2020-2021
15 Étienne Gilli <etienne@gilli.io> 2020-2021
@@ -11,10 +19,8 b' List of contributors to Kallithea projec'
11 Michalis <michalisntovas@yahoo.gr> 2021
19 Michalis <michalisntovas@yahoo.gr> 2021
12 vs <vsuhachev@yandex.ru> 2021
20 vs <vsuhachev@yandex.ru> 2021
13 Александр <akonn7@mail.ru> 2021
21 Александр <akonn7@mail.ru> 2021
14 Asterios Dimitriou <steve@pci.gr> 2016-2017 2020
15 Allan Nordhøy <epost@anotheragency.no> 2017-2020
22 Allan Nordhøy <epost@anotheragency.no> 2017-2020
16 Anton Schur <tonich.sh@gmail.com> 2017 2020
23 Anton Schur <tonich.sh@gmail.com> 2017 2020
17 Manuel Jacob <me@manueljacob.de> 2019-2020
18 Artem <kovalevartem.ru@gmail.com> 2020
24 Artem <kovalevartem.ru@gmail.com> 2020
19 David Ignjić <ignjic@gmail.com> 2020
25 David Ignjić <ignjic@gmail.com> 2020
20 Dennis Fink <dennis.fink@c3l.lu> 2020
26 Dennis Fink <dennis.fink@c3l.lu> 2020
This diff has been collapsed as it changes many lines, (797 lines changed) Show them Hide them
@@ -23,7 +23,7 b' API access'
23 Clients must send JSON encoded JSON-RPC requests::
23 Clients must send JSON encoded JSON-RPC requests::
24
24
25 {
25 {
26 "id: "<id>",
26 "id": "<id>",
27 "api_key": "<api_key>",
27 "api_key": "<api_key>",
28 "method": "<method_name>",
28 "method": "<method_name>",
29 "args": {"<arg_key>": "<arg_val>"}
29 "args": {"<arg_key>": "<arg_val>"}
@@ -115,7 +115,7 b' OUTPUT::'
115
115
116 id : <id_given_in_input>
116 id : <id_given_in_input>
117 result : "Pulled from `<reponame>`"
117 result : "Pulled from `<reponame>`"
118 error : null
118 error : null
119
119
120 rescan_repos
120 rescan_repos
121 ^^^^^^^^^^^^
121 ^^^^^^^^^^^^
@@ -138,7 +138,7 b' OUTPUT::'
138 id : <id_given_in_input>
138 id : <id_given_in_input>
139 result : "{'added': [<list of names of added repos>],
139 result : "{'added': [<list of names of added repos>],
140 'removed': [<list of names of removed repos>]}"
140 'removed': [<list of names of removed repos>]}"
141 error : null
141 error : null
142
142
143 invalidate_cache
143 invalidate_cache
144 ^^^^^^^^^^^^^^^^
144 ^^^^^^^^^^^^^^^^
@@ -160,7 +160,7 b' OUTPUT::'
160
160
161 id : <id_given_in_input>
161 id : <id_given_in_input>
162 result : "Caches of repository `<reponame>`"
162 result : "Caches of repository `<reponame>`"
163 error : null
163 error : null
164
164
165 get_ip
165 get_ip
166 ^^^^^^
166 ^^^^^^
@@ -175,24 +175,23 b' INPUT::'
175 api_key : "<api_key>"
175 api_key : "<api_key>"
176 method : "get_ip"
176 method : "get_ip"
177 args : {
177 args : {
178 "userid" : "<user_id or username>",
178 "userid" : "<user_id or username>"
179 }
179 }
180
180
181 OUTPUT::
181 OUTPUT::
182
182
183 id : <id_given_in_input>
183 id : <id_given_in_input>
184 result : {
184 result : {
185 "ip_addr_server": <ip_from_clien>",
185 "ip_addr_server" : <ip_from_client>",
186 "user_ips": [
186 "user_ips" : [
187 {
187 {
188 "ip_addr": "<ip_with_mask>",
188 "ip_addr" : "<ip_with_mask>",
189 "ip_range": ["<start_ip>", "<end_ip>"],
189 "ip_range" : ["<start_ip>", "<end_ip>"]
190 },
190 },
191 ...
191 ...
192 ]
192 ]
193 }
193 }
194
194 error : null
195 error : null
196
195
197 get_user
196 get_user
198 ^^^^^^^^
197 ^^^^^^^^
@@ -214,29 +213,29 b' INPUT::'
214 OUTPUT::
213 OUTPUT::
215
214
216 id : <id_given_in_input>
215 id : <id_given_in_input>
217 result: None if user does not exist or
216 result : None if user does not exist or
218 {
217 {
219 "user_id" : "<user_id>",
218 "user_id" : "<user_id>",
220 "api_key" : "<api_key>",
219 "api_key" : "<api_key>",
221 "username" : "<username>",
220 "username" : "<username>",
222 "firstname": "<firstname>",
221 "firstname" : "<firstname>",
223 "lastname" : "<lastname>",
222 "lastname" : "<lastname>",
224 "email" : "<email>",
223 "email" : "<email>",
225 "emails": "<list_of_all_additional_emails>",
224 "emails" : "<list_of_all_additional_emails>",
226 "ip_addresses": "<list_of_ip_addresses_for_user>",
225 "ip_addresses": "<list_of_ip_addresses_for_user>",
227 "active" : "<bool>",
226 "active" : "<bool>",
228 "admin" :  "<bool>",
227 "admin" : "<bool>",
229 "ldap_dn" : "<ldap_dn>",
228 "ldap_dn" : "<ldap_dn>",
230 "last_login": "<last_login>",
229 "last_login" : "<last_login>",
231 "permissions": {
230 "permissions": {
232 "global": ["hg.create.repository",
231 "global": ["hg.create.repository",
233 "repository.read",
232 "repository.read",
234 "hg.register.manual_activate"],
233 "hg.register.manual_activate"],
235 "repositories": {"repo1": "repository.none"},
234 "repositories" : {"repo1" : "repository.none"},
236 "repositories_groups": {"Group1": "group.read"}
235 "repositories_groups" : {"Group1" : "group.read"}
237 },
236 }
238 }
237 }
239 error: null
238 error : null
240
239
241 get_users
240 get_users
242 ^^^^^^^^^
241 ^^^^^^^^^
@@ -254,24 +253,24 b' INPUT::'
254 OUTPUT::
253 OUTPUT::
255
254
256 id : <id_given_in_input>
255 id : <id_given_in_input>
257 result: [
256 result : [
258 {
257 {
259 "user_id" : "<user_id>",
258 "user_id" : "<user_id>",
260 "api_key" : "<api_key>",
259 "api_key" : "<api_key>",
261 "username" : "<username>",
260 "username" : "<username>",
262 "firstname": "<firstname>",
261 "firstname" : "<firstname>",
263 "lastname" : "<lastname>",
262 "lastname" : "<lastname>",
264 "email" : "<email>",
263 "email" : "<email>",
265 "emails": "<list_of_all_additional_emails>",
264 "emails" : "<list_of_all_additional_emails>",
266 "ip_addresses": "<list_of_ip_addresses_for_user>",
265 "ip_addresses": "<list_of_ip_addresses_for_user>",
267 "active" : "<bool>",
266 "active" : "<bool>",
268 "admin" :  "<bool>",
267 "admin" : "<bool>",
269 "ldap_dn" : "<ldap_dn>",
268 "ldap_dn" : "<ldap_dn>",
270 "last_login": "<last_login>",
269 "last_login" : "<last_login>"
271 },
270 },
272
271
273 ]
272 ]
274 error: null
273 error : null
275
274
276 .. _create-user:
275 .. _create-user:
277
276
@@ -300,22 +299,22 b' INPUT::'
300 OUTPUT::
299 OUTPUT::
301
300
302 id : <id_given_in_input>
301 id : <id_given_in_input>
303 result: {
302 result : {
304 "msg" : "created new user `<username>`",
303 "msg" : "created new user `<username>`",
305 "user": {
304 "user" : {
306 "user_id" : "<user_id>",
305 "user_id" : "<user_id>",
307 "username" : "<username>",
306 "username" : "<username>",
308 "firstname": "<firstname>",
307 "firstname": "<firstname>",
309 "lastname" : "<lastname>",
308 "lastname" : "<lastname>",
310 "email" : "<email>",
309 "email" : "<email>",
311 "emails": "<list_of_all_additional_emails>",
310 "emails" : "<list_of_all_additional_emails>",
312 "active" : "<bool>",
311 "active" : "<bool>",
313 "admin" :  "<bool>",
312 "admin" : "<bool>",
314 "ldap_dn" : "<ldap_dn>",
313 "ldap_dn" : "<ldap_dn>",
315 "last_login": "<last_login>",
314 "last_login": "<last_login>"
316 },
315 }
317 }
316 }
318 error: null
317 error : null
319
318
320 Example::
319 Example::
321
320
@@ -347,23 +346,23 b' INPUT::'
347 OUTPUT::
346 OUTPUT::
348
347
349 id : <id_given_in_input>
348 id : <id_given_in_input>
350 result: {
349 result : {
351 "msg" : "updated user ID:<userid> <username>",
350 "msg" : "updated user ID:<userid> <username>",
352 "user": {
351 "user" : {
353 "user_id" : "<user_id>",
352 "user_id" : "<user_id>",
354 "api_key" : "<api_key>",
353 "api_key" : "<api_key>",
355 "username" : "<username>",
354 "username" : "<username>",
356 "firstname": "<firstname>",
355 "firstname": "<firstname>",
357 "lastname" : "<lastname>",
356 "lastname" : "<lastname>",
358 "email" : "<email>",
357 "email" : "<email>",
359 "emails": "<list_of_all_additional_emails>",
358 "emails" : "<list_of_all_additional_emails>",
360 "active" : "<bool>",
359 "active" : "<bool>",
361 "admin" :  "<bool>",
360 "admin" : "<bool>",
362 "ldap_dn" : "<ldap_dn>",
361 "ldap_dn" : "<ldap_dn>",
363 "last_login": "<last_login>",
362 "last_login": "<last_login>"
364 },
363 }
365 }
364 }
366 error: null
365 error : null
367
366
368 delete_user
367 delete_user
369 ^^^^^^^^^^^
368 ^^^^^^^^^^^
@@ -377,17 +376,17 b' INPUT::'
377 api_key : "<api_key>"
376 api_key : "<api_key>"
378 method : "delete_user"
377 method : "delete_user"
379 args : {
378 args : {
380 "userid" : "<user_id or username>",
379 "userid" : "<user_id or username>"
381 }
380 }
382
381
383 OUTPUT::
382 OUTPUT::
384
383
385 id : <id_given_in_input>
384 id : <id_given_in_input>
386 result: {
385 result : {
387 "msg" : "deleted user ID:<userid> <username>",
386 "msg" : "deleted user ID:<userid> <username>",
388 "user": null
387 "user" : null
389 }
388 }
390 error: null
389 error : null
391
390
392 get_user_group
391 get_user_group
393 ^^^^^^^^^^^^^^
392 ^^^^^^^^^^^^^^
@@ -411,7 +410,7 b' OUTPUT::'
411 {
410 {
412 "users_group_id" : "<id>",
411 "users_group_id" : "<id>",
413 "group_name" : "<groupname>",
412 "group_name" : "<groupname>",
414 "active": "<bool>",
413 "active" : "<bool>",
415 "members" : [
414 "members" : [
416 {
415 {
417 "user_id" : "<user_id>",
416 "user_id" : "<user_id>",
@@ -420,11 +419,11 b' OUTPUT::'
420 "firstname": "<firstname>",
419 "firstname": "<firstname>",
421 "lastname" : "<lastname>",
420 "lastname" : "<lastname>",
422 "email" : "<email>",
421 "email" : "<email>",
423 "emails": "<list_of_all_additional_emails>",
422 "emails" : "<list_of_all_additional_emails>",
424 "active" : "<bool>",
423 "active" : "<bool>",
425 "admin" :  "<bool>",
424 "admin" : "<bool>",
426 "ldap_dn" : "<ldap_dn>",
425 "ldap_dn" : "<ldap_dn>",
427 "last_login": "<last_login>",
426 "last_login": "<last_login>"
428 },
427 },
429
428
430 ]
429 ]
@@ -451,7 +450,7 b' OUTPUT::'
451 {
450 {
452 "users_group_id" : "<id>",
451 "users_group_id" : "<id>",
453 "group_name" : "<groupname>",
452 "group_name" : "<groupname>",
454 "active": "<bool>",
453 "active" : "<bool>"
455 },
454 },
456
455
457 ]
456 ]
@@ -468,29 +467,29 b' INPUT::'
468 id : <id_for_response>
467 id : <id_for_response>
469 api_key : "<api_key>"
468 api_key : "<api_key>"
470 method : "create_user_group"
469 method : "create_user_group"
471 args: {
470 args : {
472 "group_name": "<groupname>",
471 "group_name": "<groupname>",
473 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
472 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
474 "active": "<bool> = Optional(True)"
473 "active" : "<bool> = Optional(True)"
475 }
474 }
476
475
477 OUTPUT::
476 OUTPUT::
478
477
479 id : <id_given_in_input>
478 id : <id_given_in_input>
480 result: {
479 result : {
481 "msg": "created new user group `<groupname>`",
480 "msg" : "created new user group `<groupname>`",
482 "users_group": {
481 "users_group" : {
483 "users_group_id" : "<id>",
482 "users_group_id" : "<id>",
484 "group_name" : "<groupname>",
483 "group_name" : "<groupname>",
485 "active": "<bool>",
484 "active" : "<bool>"
486 },
485 }
487 }
486 }
488 error: null
487 error : null
489
488
490 add_user_to_user_group
489 add_user_to_user_group
491 ^^^^^^^^^^^^^^^^^^^^^^
490 ^^^^^^^^^^^^^^^^^^^^^^
492
491
493 Adds a user to a user group. If the user already is in that group, success will be
492 Add a user to a user group. If the user already is in that group, success will be
494 ``false``.
493 ``false``.
495 This command can only be executed using the api_key of a user with admin rights.
494 This command can only be executed using the api_key of a user with admin rights.
496
495
@@ -499,20 +498,20 b' INPUT::'
499 id : <id_for_response>
498 id : <id_for_response>
500 api_key : "<api_key>"
499 api_key : "<api_key>"
501 method : "add_user_user_group"
500 method : "add_user_user_group"
502 args: {
501 args : {
503 "usersgroupid" : "<user group id or name>",
502 "usersgroupid" : "<user group id or name>",
504 "userid" : "<user_id or username>",
503 "userid" : "<user_id or username>"
505 }
504 }
506
505
507 OUTPUT::
506 OUTPUT::
508
507
509 id : <id_given_in_input>
508 id : <id_given_in_input>
510 result: {
509 result : {
511 "success": True|False # depends on if member is in group
510 "success" : True|False, # depends on if member is in group
512 "msg": "added member `<username>` to a user group `<groupname>` |
511 "msg" : "added member `<username>` to a user group `<groupname>` |
513 User is already in that group"
512 User is already in that group"
514 }
513 }
515 error: null
514 error : null
516
515
517 remove_user_from_user_group
516 remove_user_from_user_group
518 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
517 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -526,20 +525,181 b' INPUT::'
526 id : <id_for_response>
525 id : <id_for_response>
527 api_key : "<api_key>"
526 api_key : "<api_key>"
528 method : "remove_user_from_user_group"
527 method : "remove_user_from_user_group"
529 args: {
528 args : {
530 "usersgroupid" : "<user group id or name>",
529 "usersgroupid" : "<user group id or name>",
531 "userid" : "<user_id or username>",
530 "userid" : "<user_id or username>"
531 }
532
533 OUTPUT::
534
535 id : <id_given_in_input>
536 result : {
537 "success" : True|False, # depends on if member is in group
538 "msg" : "removed member <username> from user group <groupname> |
539 User wasn't in group"
540 }
541 error : null
542
543 get_repo_group
544 ^^^^^^^^^^^^^^
545
546 Get an existing repository group.
547 This command can only be executed using the api_key of a user with admin rights.
548
549 INPUT::
550
551 id : <id_for_response>
552 api_key : "<api_key>"
553 method : "get_repo_group"
554 args : {
555 "repogroupid" : "<repo group id or name>"
532 }
556 }
533
557
534 OUTPUT::
558 OUTPUT::
535
559
536 id : <id_given_in_input>
560 id : <id_given_in_input>
537 result: {
561 result :
538 "success": True|False, # depends on if member is in group
562 {
539 "msg": "removed member <username> from user group <groupname> |
563 "group_id" : "<id>",
540 User wasn't in group"
564 "group_name" : "<groupname>",
541 }
565 "group_description" : "<groupdescription>",
542 error: null
566 "parent_group" : "<groupid>"|null,
567 "repositories" : "<list_of_all_repo_names_in_group>",
568 "owner" : "<owner>",
569 "members" : [
570 {
571 "name" : "<name>",
572 "type" : "user",
573 "permission" : "group.(none|read|write|admin)"
574 },
575 {
576 "name" : "<name>",
577 "type" : "user_group",
578 "permission" : "group.(none|read|write|admin)"
579 },
580
581 ]
582
583 },
584 error : null
585
586 get_repo_groups
587 ^^^^^^^^^^^^^^^
588
589 List all existing repository groups.
590 This command can only be executed using the api_key of a user with admin rights.
591
592 INPUT::
593
594 id : <id_for_response>
595 api_key : "<api_key>"
596 method : "get_repo_groups"
597 args : { }
598
599 OUTPUT::
600
601 id : <id_given_in_input>
602 result : [
603 {
604 "group_id" : "<id>",
605 "group_name" : "<groupname>",
606 "group_description" : "<groupdescription>",
607 "parent_group" : "<groupid>"|null,
608 "repositories" : "<list_of_all_repo_names_in_group>",
609 "owner" : "<owner>"
610 },
611
612 ]
613 error : null
614
615 create_repo_group
616 ^^^^^^^^^^^^^^^^^
617
618 Create a new repository group.
619 This command can only be executed using the api_key of a user with admin rights.
620
621 INPUT::
622
623 id : <id_for_response>
624 api_key : "<api_key>"
625 method : "create_repo_group"
626 args : {
627 "group_name" : "<group_name>",
628 "description" : "<description> = Optional("")",
629 "owner" : "<username or user_id> = Optional(None)",
630 "parent" : "<reponame or id> = Optional(None)",
631 "copy_permissions" : "<bool> = Optional(False)"
632 }
633
634 OUTPUT::
635
636 id : <id_given_in_input>
637 result : {
638 "msg" : "created new repo group `<group_name>`",
639 "repo_group" : {
640 "group_id" : <id>,
641 "group_name" : "<parent_group>/<group_name>",
642 "group_description" : "<description>",
643 "parent_group" : <id>|null,
644 "repositories" : <list of repositories>,
645 "owner" : "<user_name>"
646 }
647
648 update_repo_group
649 ^^^^^^^^^^^^^^^^^
650
651 Update a repository group.
652 This command can only be executed using the api_key of a user with admin rights.
653
654 INPUT::
655
656 id : <id_for_response>
657 api_key : "<api_key>"
658 method : "update_repo_group"
659 args : {
660 "repogroupid" : "<id>",
661 "group_name" : "<group_name> = Optional(None)",
662 "description" : "<description> = Optional(None)",
663 "owner" : "<username or user_id> = Optional(None)",
664 "parent" : "<reponame or id> = Optional(None)"
665 }
666
667 OUTPUT::
668
669 id : <id_given_in_input>
670 result : {
671 "msg" : "updated repository group ID:<id> <group_name>",
672 "repo_group" : {
673 "group_id" : <id>,
674 "group_name" : "<parent_group>/<group_name>",
675 "group_description" : "<description>",
676 "parent_group" : <id>|null,
677 "repositories" : <list of repositories>,
678 "owner" : "<user_name>"
679 }
680
681 delete_repo_group
682 ^^^^^^^^^^^^^^^^^
683
684 Delete a repository group.
685 This command can only be executed using the api_key of a user with admin rights.
686
687 INPUT::
688
689 id : <id_for_response>
690 api_key : "<api_key>"
691 method : "delete_repo_group"
692 args : {
693 "repogroupid" : "<id>"
694 }
695
696 OUTPUT::
697
698 id : <id_given_in_input>
699 result : {
700 "msg" : "deleted repo group ID:<id> <group_name>",
701 "repo_group" : null
702 }
543
703
544 get_repo
704 get_repo
545 ^^^^^^^^
705 ^^^^^^^^
@@ -554,144 +714,144 b' INPUT::'
554 id : <id_for_response>
714 id : <id_for_response>
555 api_key : "<api_key>"
715 api_key : "<api_key>"
556 method : "get_repo"
716 method : "get_repo"
557 args: {
717 args : {
558 "repoid" : "<reponame or repo_id>",
718 "repoid" : "<reponame or repo_id>",
559 "with_revision_names": "<bool> = Optional(False)",
719 "with_revision_names" : "<bool> = Optional(False)",
560 "with_pullrequests": "<bool> = Optional(False)",
720 "with_pullrequests" : "<bool> = Optional(False)"
561 }
721 }
562
722
563 OUTPUT::
723 OUTPUT::
564
724
565 id : <id_given_in_input>
725 id : <id_given_in_input>
566 result: None if repository does not exist or
726 result : None if repository does not exist or
567 {
727 {
568 "repo_id" : "<repo_id>",
728 "repo_id" : "<repo_id>",
569 "repo_name" : "<reponame>"
729 "repo_name" : "<reponame>",
570 "repo_type" : "<repo_type>",
730 "repo_type" : "<repo_type>",
571 "clone_uri" : "<clone_uri>",
731 "clone_uri" : "<clone_uri>",
572 "enable_downloads": "<bool>",
732 "enable_downloads" : "<bool>",
573 "enable_statistics": "<bool>",
733 "enable_statistics": "<bool>",
574 "private": "<bool>",
734 "private" : "<bool>",
575 "created_on" : "<date_time_created>",
735 "created_on" : "<date_time_created>",
576 "description" : "<description>",
736 "description" : "<description>",
577 "landing_rev": "<landing_rev>",
737 "landing_rev" : "<landing_rev>",
578 "last_changeset": {
738 "last_changeset" : {
579 "author": "<full_author>",
739 "author" : "<full_author>",
580 "date": "<date_time_of_commit>",
740 "date" : "<date_time_of_commit>",
581 "message": "<commit_message>",
741 "message" : "<commit_message>",
582 "raw_id": "<raw_id>",
742 "raw_id" : "<raw_id>",
583 "revision": "<numeric_revision>",
743 "revision": "<numeric_revision>",
584 "short_id": "<short_id>"
744 "short_id": "<short_id>"
585 },
745 },
586 "owner": "<repo_owner>",
746 "owner" : "<repo_owner>",
587 "fork_of": "<name_of_fork_parent>",
747 "fork_of" : "<name_of_fork_parent>",
588 "members" : [
748 "members" : [
589 {
749 {
590 "type": "user",
750 "type" : "user",
591 "user_id" : "<user_id>",
751 "user_id" : "<user_id>",
592 "api_key" : "<api_key>",
752 "api_key" : "<api_key>",
593 "username" : "<username>",
753 "username" : "<username>",
594 "firstname": "<firstname>",
754 "firstname" : "<firstname>",
595 "lastname" : "<lastname>",
755 "lastname" : "<lastname>",
596 "email" : "<email>",
756 "email" : "<email>",
597 "emails": "<list_of_all_additional_emails>",
757 "emails" : "<list_of_all_additional_emails>",
598 "active" : "<bool>",
758 "active" : "<bool>",
599 "admin" :  "<bool>",
759 "admin" : "<bool>",
600 "ldap_dn" : "<ldap_dn>",
760 "ldap_dn" : "<ldap_dn>",
601 "last_login": "<last_login>",
761 "last_login" : "<last_login>",
602 "permission" : "repository.(read|write|admin)"
762 "permission" : "repository.(read|write|admin)"
603 },
763 },
604
764
605 {
765 {
606 "type": "users_group",
766 "type" : "users_group",
607 "id" : "<usersgroupid>",
767 "id" : "<usersgroupid>",
608 "name" : "<usersgroupname>",
768 "name" : "<usersgroupname>",
609 "active": "<bool>",
769 "active" : "<bool>",
610 "permission" : "repository.(read|write|admin)"
770 "permission" : "repository.(read|write|admin)"
611 },
771 },
612
772
613 ],
773 ],
614 "followers": [
774 "followers" : [
615 {
775 {
616 "user_id" : "<user_id>",
776 "user_id" : "<user_id>",
617 "username" : "<username>",
777 "username" : "<username>",
618 "api_key" : "<api_key>",
778 "api_key" : "<api_key>",
619 "firstname": "<firstname>",
779 "firstname" : "<firstname>",
620 "lastname" : "<lastname>",
780 "lastname" : "<lastname>",
621 "email" : "<email>",
781 "email" : "<email>",
622 "emails": "<list_of_all_additional_emails>",
782 "emails" : "<list_of_all_additional_emails>",
623 "ip_addresses": "<list_of_ip_addresses_for_user>",
783 "ip_addresses": "<list_of_ip_addresses_for_user>",
624 "active" : "<bool>",
784 "active" : "<bool>",
625 "admin" :  "<bool>",
785 "admin" : "<bool>",
626 "ldap_dn" : "<ldap_dn>",
786 "ldap_dn" : "<ldap_dn>",
627 "last_login": "<last_login>",
787 "last_login" : "<last_login>"
628 },
788 },
629
789
630 ],
790 ],
631 <if with_revision_names == True>
791 <if with_revision_names == True>
632 "tags": {
792 "tags" : {
633 "<tagname>": "<raw_id>",
793 "<tagname>" : "<raw_id>",
634 ...
794 ...
635 },
795 },
636 "branches": {
796 "branches" : {
637 "<branchname>": "<raw_id>",
797 "<branchname>" : "<raw_id>",
638 ...
798 ...
639 },
799 },
640 "bookmarks": {
800 "bookmarks" : {
641 "<bookmarkname>": "<raw_id>",
801 "<bookmarkname>" : "<raw_id>",
642 ...
802 ...
643 },
803 },
644 <if with_pullrequests == True>
804 <if with_pullrequests == True>
645 "pull_requests": [
805 "pull_requests" : [
646 {
806 {
647 "status": "<pull_request_status>",
807 "status" : "<pull_request_status>",
648 "pull_request_id": <pull_request_id>,
808 "pull_request_id" : <pull_request_id>,
649 "description": "<pull_request_description>",
809 "description" : "<pull_request_description>",
650 "title": "<pull_request_title>",
810 "title" : "<pull_request_title>",
651 "url": "<pull_request_url>",
811 "url" : "<pull_request_url>",
652 "reviewers": [
812 "reviewers" : [
653 {
813 {
654 "username": "<user_id>",
814 "username" : "<user_id>"
655 },
815 },
656 ...
816 ...
657 ],
817 ],
658 "org_repo_url": "<repo_url>",
818 "org_repo_url" : "<repo_url>",
659 "org_ref_parts": [
819 "org_ref_parts" : [
660 "<ref_type>",
820 "<ref_type>",
661 "<ref_name>",
821 "<ref_name>",
662 "<raw_id>"
822 "<raw_id>"
663 ],
823 ],
664 "other_ref_parts": [
824 "other_ref_parts" : [
665 "<ref_type>",
825 "<ref_type>",
666 "<ref_name>",
826 "<ref_name>",
667 "<raw_id>"
827 "<raw_id>"
668 ],
828 ],
669 "comments": [
829 "comments" : [
670 {
830 {
671 "username": "<user_id>",
831 "username" : "<user_id>",
672 "text": "<comment text>",
832 "text" : "<comment text>",
673 "comment_id": "<comment_id>",
833 "comment_id" : "<comment_id>"
674 },
834 },
675 ...
835 ...
676 ],
836 ],
677 "owner": "<username>",
837 "owner" : "<username>",
678 "statuses": [
838 "statuses" : [
679 {
839 {
680 "status": "<status_of_review>", # "under_review", "approved" or "rejected"
840 "status" : "<status_of_review>", # "under_review", "approved" or "rejected"
681 "reviewer": "<user_id>",
841 "reviewer" : "<user_id>",
682 "modified_at": "<date_time_of_review>" # iso 8601 date, server's timezone
842 "modified_at" : "<date_time_of_review>" # iso 8601 date, server's timezone
683 },
843 },
684 ...
844 ...
685 ],
845 ],
686 "revisions": [
846 "revisions" : [
687 "<raw_id>",
847 "<raw_id>",
688 ...
848 ...
689 ]
849 ]
690 },
850 },
691 ...
851 ...
692 ]
852 ]
693 }
853 }
694 error: null
854 error : null
695
855
696 get_repos
856 get_repos
697 ^^^^^^^^^
857 ^^^^^^^^^
@@ -705,29 +865,29 b' INPUT::'
705 id : <id_for_response>
865 id : <id_for_response>
706 api_key : "<api_key>"
866 api_key : "<api_key>"
707 method : "get_repos"
867 method : "get_repos"
708 args: { }
868 args : { }
709
869
710 OUTPUT::
870 OUTPUT::
711
871
712 id : <id_given_in_input>
872 id : <id_given_in_input>
713 result: [
873 result : [
714 {
874 {
715 "repo_id" : "<repo_id>",
875 "repo_id" : "<repo_id>",
716 "repo_name" : "<reponame>"
876 "repo_name" : "<reponame>",
717 "repo_type" : "<repo_type>",
877 "repo_type" : "<repo_type>",
718 "clone_uri" : "<clone_uri>",
878 "clone_uri" : "<clone_uri>",
719 "private" : "<bool>",
879 "private" : "<bool>",
720 "created_on" : "<datetimecreated>",
880 "created_on" : "<datetimecreated>",
721 "description" : "<description>",
881 "description" : "<description>",
722 "landing_rev": "<landing_rev>",
882 "landing_rev" : "<landing_rev>",
723 "owner": "<repo_owner>",
883 "owner" : "<repo_owner>",
724 "fork_of": "<name_of_fork_parent>",
884 "fork_of" : "<name_of_fork_parent>",
725 "enable_downloads": "<bool>",
885 "enable_downloads" : "<bool>",
726 "enable_statistics": "<bool>",
886 "enable_statistics": "<bool>"
727 },
887 },
728
888
729 ]
889 ]
730 error: null
890 error : null
731
891
732 get_repo_nodes
892 get_repo_nodes
733 ^^^^^^^^^^^^^^
893 ^^^^^^^^^^^^^^
@@ -741,24 +901,24 b' INPUT::'
741 id : <id_for_response>
901 id : <id_for_response>
742 api_key : "<api_key>"
902 api_key : "<api_key>"
743 method : "get_repo_nodes"
903 method : "get_repo_nodes"
744 args: {
904 args : {
745 "repoid" : "<reponame or repo_id>"
905 "repoid" : "<reponame or repo_id>",
746 "revision" : "<revision>",
906 "revision" : "<revision>",
747 "root_path" : "<root_path>",
907 "root_path" : "<root_path>",
748 "ret_type" : "<ret_type> = Optional('all')"
908 "ret_type" : "<ret_type> = Optional('all')"
749 }
909 }
750
910
751 OUTPUT::
911 OUTPUT::
752
912
753 id : <id_given_in_input>
913 id : <id_given_in_input>
754 result: [
914 result : [
755 {
915 {
756 "name" : "<name>"
916 "name" : "<name>",
757 "type" : "<type>",
917 "type" : "<type>"
758 },
918 },
759
919
760 ]
920 ]
761 error: null
921 error : null
762
922
763 create_repo
923 create_repo
764 ^^^^^^^^^^^
924 ^^^^^^^^^^^
@@ -778,7 +938,7 b' INPUT::'
778 id : <id_for_response>
938 id : <id_for_response>
779 api_key : "<api_key>"
939 api_key : "<api_key>"
780 method : "create_repo"
940 method : "create_repo"
781 args: {
941 args : {
782 "repo_name" : "<reponame>",
942 "repo_name" : "<reponame>",
783 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
943 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
784 "repo_type" : "<repo_type> = Optional('hg')",
944 "repo_type" : "<repo_type> = Optional('hg')",
@@ -786,31 +946,31 b' INPUT::'
786 "private" : "<bool> = Optional(False)",
946 "private" : "<bool> = Optional(False)",
787 "clone_uri" : "<clone_uri> = Optional(None)",
947 "clone_uri" : "<clone_uri> = Optional(None)",
788 "landing_rev" : "<landing_rev> = Optional('tip')",
948 "landing_rev" : "<landing_rev> = Optional('tip')",
789 "enable_downloads": "<bool> = Optional(False)",
949 "enable_downloads" : "<bool> = Optional(False)",
790 "enable_statistics": "<bool> = Optional(False)",
950 "enable_statistics": "<bool> = Optional(False)"
791 }
951 }
792
952
793 OUTPUT::
953 OUTPUT::
794
954
795 id : <id_given_in_input>
955 id : <id_given_in_input>
796 result: {
956 result : {
797 "msg": "Created new repository `<reponame>`",
957 "msg" : "Created new repository `<reponame>`",
798 "repo": {
958 "repo" : {
799 "repo_id" : "<repo_id>",
959 "repo_id" : "<repo_id>",
800 "repo_name" : "<reponame>"
960 "repo_name" : "<reponame>",
801 "repo_type" : "<repo_type>",
961 "repo_type" : "<repo_type>",
802 "clone_uri" : "<clone_uri>",
962 "clone_uri" : "<clone_uri>",
803 "private" : "<bool>",
963 "private" : "<bool>",
804 "created_on" : "<datetimecreated>",
964 "created_on" : "<datetimecreated>",
805 "description" : "<description>",
965 "description" : "<description>",
806 "landing_rev": "<landing_rev>",
966 "landing_rev" : "<landing_rev>",
807 "owner": "<username or user_id>",
967 "owner" : "<username or user_id>",
808 "fork_of": "<name_of_fork_parent>",
968 "fork_of" : "<name_of_fork_parent>",
809 "enable_downloads": "<bool>",
969 "enable_downloads" : "<bool>",
810 "enable_statistics": "<bool>",
970 "enable_statistics": "<bool>"
811 },
971 }
812 }
972 }
813 error: null
973 error : null
814
974
815 update_repo
975 update_repo
816 ^^^^^^^^^^^
976 ^^^^^^^^^^^
@@ -825,8 +985,8 b' INPUT::'
825 id : <id_for_response>
985 id : <id_for_response>
826 api_key : "<api_key>"
986 api_key : "<api_key>"
827 method : "update_repo"
987 method : "update_repo"
828 args: {
988 args : {
829 "repoid" : "<reponame or repo_id>"
989 "repoid" : "<reponame or repo_id>",
830 "name" : "<reponame> = Optional('')",
990 "name" : "<reponame> = Optional('')",
831 "group" : "<group_id> = Optional(None)",
991 "group" : "<group_id> = Optional(None)",
832 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
992 "owner" : "<owner_name_or_id = Optional(=apiuser)>",
@@ -834,39 +994,39 b' INPUT::'
834 "private" : "<bool> = Optional(False)",
994 "private" : "<bool> = Optional(False)",
835 "clone_uri" : "<clone_uri> = Optional(None)",
995 "clone_uri" : "<clone_uri> = Optional(None)",
836 "landing_rev" : "<landing_rev> = Optional('tip')",
996 "landing_rev" : "<landing_rev> = Optional('tip')",
837 "enable_downloads": "<bool> = Optional(False)",
997 "enable_downloads" : "<bool> = Optional(False)",
838 "enable_statistics": "<bool> = Optional(False)",
998 "enable_statistics": "<bool> = Optional(False)"
839 }
999 }
840
1000
841 OUTPUT::
1001 OUTPUT::
842
1002
843 id : <id_given_in_input>
1003 id : <id_given_in_input>
844 result: {
1004 result : {
845 "msg": "updated repo ID:repo_id `<reponame>`",
1005 "msg" : "updated repo ID:repo_id `<reponame>`",
846 "repository": {
1006 "repository" : {
847 "repo_id" : "<repo_id>",
1007 "repo_id" : "<repo_id>",
848 "repo_name" : "<reponame>"
1008 "repo_name" : "<reponame>",
849 "repo_type" : "<repo_type>",
1009 "repo_type" : "<repo_type>",
850 "clone_uri" : "<clone_uri>",
1010 "clone_uri" : "<clone_uri>",
851 "private": "<bool>",
1011 "private" : "<bool>",
852 "created_on" : "<datetimecreated>",
1012 "created_on" : "<datetimecreated>",
853 "description" : "<description>",
1013 "description" : "<description>",
854 "landing_rev": "<landing_rev>",
1014 "landing_rev" : "<landing_rev>",
855 "owner": "<username or user_id>",
1015 "owner" : "<username or user_id>",
856 "fork_of": "<name_of_fork_parent>",
1016 "fork_of" : "<name_of_fork_parent>",
857 "enable_downloads": "<bool>",
1017 "enable_downloads" : "<bool>",
858 "enable_statistics": "<bool>",
1018 "enable_statistics": "<bool>",
859 "last_changeset": {
1019 "last_changeset" : {
860 "author": "<full_author>",
1020 "author" : "<full_author>",
861 "date": "<date_time_of_commit>",
1021 "date" : "<date_time_of_commit>",
862 "message": "<commit_message>",
1022 "message" : "<commit_message>",
863 "raw_id": "<raw_id>",
1023 "raw_id" : "<raw_id>",
864 "revision": "<numeric_revision>",
1024 "revision": "<numeric_revision>",
865 "short_id": "<short_id>"
1025 "short_id": "<short_id>"
866 }
1026 }
867 },
1027 }
868 }
1028 }
869 error: null
1029 error : null
870
1030
871 fork_repo
1031 fork_repo
872 ^^^^^^^^^
1032 ^^^^^^^^^
@@ -884,25 +1044,24 b' INPUT::'
884 id : <id_for_response>
1044 id : <id_for_response>
885 api_key : "<api_key>"
1045 api_key : "<api_key>"
886 method : "fork_repo"
1046 method : "fork_repo"
887 args: {
1047 args : {
888 "repoid" : "<reponame or repo_id>",
1048 "repoid" : "<reponame or repo_id>",
889 "fork_name": "<forkname>",
1049 "fork_name" : "<forkname>",
890 "owner": "<username or user_id = Optional(=apiuser)>",
1050 "owner" : "<username or user_id = Optional(=apiuser)>",
891 "description": "<description>",
1051 "description" : "<description>",
892 "copy_permissions": "<bool>",
1052 "copy_permissions": "<bool>",
893 "private": "<bool>",
1053 "private" : "<bool>",
894 "landing_rev": "<landing_rev>"
1054 "landing_rev" : "<landing_rev>"
895
896 }
1055 }
897
1056
898 OUTPUT::
1057 OUTPUT::
899
1058
900 id : <id_given_in_input>
1059 id : <id_given_in_input>
901 result: {
1060 result : {
902 "msg": "Created fork of `<reponame>` as `<forkname>`",
1061 "msg" : "Created fork of `<reponame>` as `<forkname>`",
903 "success": true
1062 "success" : true
904 }
1063 }
905 error: null
1064 error : null
906
1065
907 delete_repo
1066 delete_repo
908 ^^^^^^^^^^^
1067 ^^^^^^^^^^^
@@ -917,19 +1076,19 b' INPUT::'
917 id : <id_for_response>
1076 id : <id_for_response>
918 api_key : "<api_key>"
1077 api_key : "<api_key>"
919 method : "delete_repo"
1078 method : "delete_repo"
920 args: {
1079 args : {
921 "repoid" : "<reponame or repo_id>",
1080 "repoid" : "<reponame or repo_id>",
922 "forks" : "`delete` or `detach` = Optional(None)"
1081 "forks" : "`delete` or `detach` = Optional(None)"
923 }
1082 }
924
1083
925 OUTPUT::
1084 OUTPUT::
926
1085
927 id : <id_given_in_input>
1086 id : <id_given_in_input>
928 result: {
1087 result : {
929 "msg": "Deleted repository `<reponame>`",
1088 "msg" : "Deleted repository `<reponame>`",
930 "success": true
1089 "success" : true
931 }
1090 }
932 error: null
1091 error : null
933
1092
934 grant_user_permission
1093 grant_user_permission
935 ^^^^^^^^^^^^^^^^^^^^^
1094 ^^^^^^^^^^^^^^^^^^^^^
@@ -942,20 +1101,20 b' INPUT::'
942 id : <id_for_response>
1101 id : <id_for_response>
943 api_key : "<api_key>"
1102 api_key : "<api_key>"
944 method : "grant_user_permission"
1103 method : "grant_user_permission"
945 args: {
1104 args : {
946 "repoid" : "<reponame or repo_id>"
1105 "repoid" : "<reponame or repo_id>",
947 "userid" : "<username or user_id>"
1106 "userid" : "<username or user_id>",
948 "perm" : "(repository.(none|read|write|admin))",
1107 "perm" : "(repository.(none|read|write|admin))"
949 }
1108 }
950
1109
951 OUTPUT::
1110 OUTPUT::
952
1111
953 id : <id_given_in_input>
1112 id : <id_given_in_input>
954 result: {
1113 result : {
955 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
1114 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
956 "success": true
1115 "success" : true
957 }
1116 }
958 error: null
1117 error : null
959
1118
960 revoke_user_permission
1119 revoke_user_permission
961 ^^^^^^^^^^^^^^^^^^^^^^
1120 ^^^^^^^^^^^^^^^^^^^^^^
@@ -967,20 +1126,20 b' INPUT::'
967
1126
968 id : <id_for_response>
1127 id : <id_for_response>
969 api_key : "<api_key>"
1128 api_key : "<api_key>"
970 method : "revoke_user_permission"
1129 method : "revoke_user_permission"
971 args: {
1130 args : {
972 "repoid" : "<reponame or repo_id>"
1131 "repoid" : "<reponame or repo_id>",
973 "userid" : "<username or user_id>"
1132 "userid" : "<username or user_id>"
974 }
1133 }
975
1134
976 OUTPUT::
1135 OUTPUT::
977
1136
978 id : <id_given_in_input>
1137 id : <id_given_in_input>
979 result: {
1138 result : {
980 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
1139 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
981 "success": true
1140 "success" : true
982 }
1141 }
983 error: null
1142 error : null
984
1143
985 grant_user_group_permission
1144 grant_user_group_permission
986 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1145 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -994,20 +1153,20 b' INPUT::'
994 id : <id_for_response>
1153 id : <id_for_response>
995 api_key : "<api_key>"
1154 api_key : "<api_key>"
996 method : "grant_user_group_permission"
1155 method : "grant_user_group_permission"
997 args: {
1156 args : {
998 "repoid" : "<reponame or repo_id>"
1157 "repoid" : "<reponame or repo_id>",
999 "usersgroupid" : "<user group id or name>"
1158 "usersgroupid" : "<user group id or name>",
1000 "perm" : "(repository.(none|read|write|admin))",
1159 "perm" : "(repository.(none|read|write|admin))"
1001 }
1160 }
1002
1161
1003 OUTPUT::
1162 OUTPUT::
1004
1163
1005 id : <id_given_in_input>
1164 id : <id_given_in_input>
1006 result: {
1165 result : {
1007 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
1166 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
1008 "success": true
1167 "success" : true
1009 }
1168 }
1010 error: null
1169 error : null
1011
1170
1012 revoke_user_group_permission
1171 revoke_user_group_permission
1013 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1172 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1019,20 +1178,20 b' INPUT::'
1019
1178
1020 id : <id_for_response>
1179 id : <id_for_response>
1021 api_key : "<api_key>"
1180 api_key : "<api_key>"
1022 method : "revoke_user_group_permission"
1181 method : "revoke_user_group_permission"
1023 args: {
1182 args : {
1024 "repoid" : "<reponame or repo_id>"
1183 "repoid" : "<reponame or repo_id>",
1025 "usersgroupid" : "<user group id or name>"
1184 "usersgroupid" : "<user group id or name>"
1026 }
1185 }
1027
1186
1028 OUTPUT::
1187 OUTPUT::
1029
1188
1030 id : <id_given_in_input>
1189 id : <id_given_in_input>
1031 result: {
1190 result : {
1032 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
1191 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
1033 "success": true
1192 "success" : true
1034 }
1193 }
1035 error: null
1194 error : null
1036
1195
1037 get_changesets
1196 get_changesets
1038 ^^^^^^^^^^^^^^
1197 ^^^^^^^^^^^^^^
@@ -1044,37 +1203,37 b' INPUT::'
1044
1203
1045 id : <id_for_response>
1204 id : <id_for_response>
1046 api_key : "<api_key>"
1205 api_key : "<api_key>"
1047 method : "get_changesets"
1206 method : "get_changesets"
1048 args: {
1207 args : {
1049 "repoid" : "<reponame or repo_id>",
1208 "repoid" : "<reponame or repo_id>",
1050 "start": "<revision number> = Optional(None)",
1209 "start" : "<revision number> = Optional(None)",
1051 "end": "<revision number> = Optional(None)",
1210 "end" : "<revision number> = Optional(None)",
1052 "start_date": "<date> = Optional(None)", # in "%Y-%m-%dT%H:%M:%S" format
1211 "start_date" : "<date> = Optional(None)", # in "%Y-%m-%dT%H:%M:%S" format
1053 "end_date": "<date> = Optional(None)", # in "%Y-%m-%dT%H:%M:%S" format
1212 "end_date" : "<date> = Optional(None)", # in "%Y-%m-%dT%H:%M:%S" format
1054 "branch_name": "<branch name filter> = Optional(None)",
1213 "branch_name" : "<branch name filter> = Optional(None)",
1055 "reverse": "<bool> = Optional(False)",
1214 "reverse" : "<bool> = Optional(False)",
1056 "with_file_list": "<bool> = Optional(False)"
1215 "with_file_list" : "<bool> = Optional(False)"
1057 }
1216 }
1058
1217
1059 OUTPUT::
1218 OUTPUT::
1060
1219
1061 id : <id_given_in_input>
1220 id : <id_given_in_input>
1062 result: [
1221 result : [
1063 {
1222 {
1064 "raw_id": "<raw_id>",
1223 "raw_id" : "<raw_id>",
1065 "short_id": "short_id": "<short_id>",
1224 "short_id" : "<short_id>",
1066 "author": "<full_author>",
1225 "author" : "<full_author>",
1067 "date": "<date_time_of_commit>",
1226 "date" : "<date_time_of_commit>",
1068 "message": "<commit_message>",
1227 "message" : "<commit_message>",
1069 "revision": "<numeric_revision>",
1228 "revision" : "<numeric_revision>",
1070 <if with_file_list == True>
1229 <if with_file_list == True>
1071 "added": [<list of added files>],
1230 "added" : [<list of added files>],
1072 "changed": [<list of changed files>],
1231 "changed" : [<list of changed files>],
1073 "removed": [<list of removed files>]
1232 "removed" : [<list of removed files>]
1074 },
1233 },
1075 ...
1234 ...
1076 ]
1235 ]
1077 error: null
1236 error : null
1078
1237
1079 get_changeset
1238 get_changeset
1080 ^^^^^^^^^^^^^
1239 ^^^^^^^^^^^^^
@@ -1087,32 +1246,32 b' INPUT::'
1087
1246
1088 id : <id_for_response>
1247 id : <id_for_response>
1089 api_key : "<api_key>"
1248 api_key : "<api_key>"
1090 method : "get_changeset"
1249 method : "get_changeset"
1091 args: {
1250 args : {
1092 "repoid" : "<reponame or repo_id>",
1251 "repoid" : "<reponame or repo_id>",
1093 "raw_id" : "<raw_id>",
1252 "raw_id" : "<raw_id>",
1094 "with_reviews": "<bool> = Optional(False)"
1253 "with_reviews" : "<bool> = Optional(False)"
1095 }
1254 }
1096
1255
1097 OUTPUT::
1256 OUTPUT::
1098
1257
1099 id : <id_given_in_input>
1258 id : <id_given_in_input>
1100 result: {
1259 result : {
1101 "author": "<full_author>",
1260 "author" : "<full_author>",
1102 "date": "<date_time_of_commit>",
1261 "date" : "<date_time_of_commit>",
1103 "message": "<commit_message>",
1262 "message" : "<commit_message>",
1104 "raw_id": "<raw_id>",
1263 "raw_id" : "<raw_id>",
1105 "revision": "<numeric_revision>",
1264 "revision": "<numeric_revision>",
1106 "short_id": "<short_id>",
1265 "short_id": "<short_id>",
1107 "reviews": [{
1266 "reviews" : [{
1108 "reviewer": "<username>",
1267 "reviewer" : "<username>",
1109 "modified_at": "<date_time_of_review>", # iso 8601 date, server's timezone
1268 "modified_at" : "<date_time_of_review>", # iso 8601 date, server's timezone
1110 "status": "<status_of_review>", # "under_review", "approved" or "rejected"
1269 "status" : "<status_of_review>", # "under_review", "approved" or "rejected"
1111 },
1270 },
1112 ...
1271 ...
1113 ]
1272 ]
1114 }
1273 }
1115 error: null
1274 error : null
1116
1275
1117 Example output::
1276 Example output::
1118
1277
@@ -1155,60 +1314,60 b' INPUT::'
1155
1314
1156 id : <id_for_response>
1315 id : <id_for_response>
1157 api_key : "<api_key>"
1316 api_key : "<api_key>"
1158 method : "get_pullrequest"
1317 method : "get_pullrequest"
1159 args: {
1318 args : {
1160 "pullrequest_id" : "<pullrequest_id>",
1319 "pullrequest_id" : "<pullrequest_id>"
1161 }
1320 }
1162
1321
1163 OUTPUT::
1322 OUTPUT::
1164
1323
1165 id : <id_given_in_input>
1324 id : <id_given_in_input>
1166 result: {
1325 result : {
1167 "status": "<pull_request_status>",
1326 "status" : "<pull_request_status>",
1168 "pull_request_id": <pull_request_id>,
1327 "pull_request_id" : <pull_request_id>,
1169 "description": "<pull_request_description>",
1328 "description" : "<pull_request_description>",
1170 "title": "<pull_request_title>",
1329 "title" : "<pull_request_title>",
1171 "url": "<pull_request_url>",
1330 "url" : "<pull_request_url>",
1172 "reviewers": [
1331 "reviewers" : [
1173 {
1332 {
1174 "username": "<user_name>",
1333 "username" : "<user_name>"
1175 },
1334 },
1176 ...
1335 ...
1177 ],
1336 ],
1178 "org_repo_url": "<repo_url>",
1337 "org_repo_url" : "<repo_url>",
1179 "org_ref_parts": [
1338 "org_ref_parts" : [
1180 "<ref_type>",
1339 "<ref_type>",
1181 "<ref_name>",
1340 "<ref_name>",
1182 "<raw_id>"
1341 "<raw_id>"
1183 ],
1342 ],
1184 "other_ref_parts": [
1343 "other_ref_parts" : [
1185 "<ref_type>",
1344 "<ref_type>",
1186 "<ref_name>",
1345 "<ref_name>",
1187 "<raw_id>"
1346 "<raw_id>"
1188 ],
1347 ],
1189 "comments": [
1348 "comments" : [
1190 {
1349 {
1191 "username": "<user_name>",
1350 "username" : "<user_name>",
1192 "text": "<comment text>",
1351 "text" : "<comment text>",
1193 "comment_id": "<comment_id>",
1352 "comment_id" : "<comment_id>"
1194 },
1353 },
1195 ...
1354 ...
1196 ],
1355 ],
1197 "owner": "<username>",
1356 "owner" : "<username>",
1198 "statuses": [
1357 "statuses" : [
1199 {
1358 {
1200 "status": "<status_of_review>", # "under_review", "approved" or "rejected"
1359 "status" : "<status_of_review>", # "under_review", "approved" or "rejected"
1201 "reviewer": "<user_name>",
1360 "reviewer" : "<user_name>",
1202 "modified_at": "<date_time_of_review>" # iso 8601 date, server's timezone
1361 "modified_at" : "<date_time_of_review>" # iso 8601 date, server's timezone
1203 },
1362 },
1204 ...
1363 ...
1205 ],
1364 ],
1206 "revisions": [
1365 "revisions" : [
1207 "<raw_id>",
1366 "<raw_id>",
1208 ...
1367 ...
1209 ]
1368 ]
1210 },
1369 },
1211 error: null
1370 error : null
1212
1371
1213 comment_pullrequest
1372 comment_pullrequest
1214 ^^^^^^^^^^^^^^^^^^^
1373 ^^^^^^^^^^^^^^^^^^^
@@ -1220,19 +1379,19 b' INPUT::'
1220
1379
1221 id : <id_for_response>
1380 id : <id_for_response>
1222 api_key : "<api_key>"
1381 api_key : "<api_key>"
1223 method : "comment_pullrequest"
1382 method : "comment_pullrequest"
1224 args: {
1383 args : {
1225 "pull_request_id": "<pull_request_id>",
1384 "pull_request_id" : "<pull_request_id>",
1226 "comment_msg": Optional(''),
1385 "comment_msg" : Optional(''),
1227 "status": Optional(None), # "under_review", "approved" or "rejected"
1386 "status" : Optional(None), # "under_review", "approved" or "rejected"
1228 "close_pr": Optional(False)",
1387 "close_pr" : Optional(False)"
1229 }
1388 }
1230
1389
1231 OUTPUT::
1390 OUTPUT::
1232
1391
1233 id : <id_given_in_input>
1392 id : <id_given_in_input>
1234 result: True
1393 result : True
1235 error: null
1394 error : null
1236
1395
1237
1396
1238 API access for web views
1397 API access for web views
@@ -47,7 +47,7 b" master_doc = 'index'"
47
47
48 # General information about the project.
48 # General information about the project.
49 project = 'Kallithea'
49 project = 'Kallithea'
50 copyright = '2010-2022 by various authors, licensed as GPLv3.'
50 copyright = '2010-2023 by various authors, licensed as GPLv3.'
51
51
52 # The version info for the project you're documenting, acts as replacement for
52 # The version info for the project you're documenting, acts as replacement for
53 # |version| and |release|, also used in various other places throughout the
53 # |version| and |release|, also used in various other places throughout the
@@ -76,6 +76,7 b' class RepoGroupsController(base.BaseCont'
76 repo_group = db.RepoGroup.get_or_404(group_id)
76 repo_group = db.RepoGroup.get_or_404(group_id)
77 data = repo_group.get_dict()
77 data = repo_group.get_dict()
78 data['group_name'] = repo_group.name
78 data['group_name'] = repo_group.name
79 data['owner'] = repo_group.owner.username
79
80
80 # fill repository group users
81 # fill repository group users
81 for p in repo_group.repo_group_to_perm:
82 for p in repo_group.repo_group_to_perm:
@@ -146,7 +147,7 b' class RepoGroupsController(base.BaseCont'
146 group_name=form_result['group_name'],
147 group_name=form_result['group_name'],
147 group_description=form_result['group_description'],
148 group_description=form_result['group_description'],
148 parent=form_result['parent_group_id'],
149 parent=form_result['parent_group_id'],
149 owner=request.authuser.user_id, # TODO: make editable
150 owner=request.authuser.user_id,
150 copy_permissions=form_result['group_copy_permissions']
151 copy_permissions=form_result['group_copy_permissions']
151 )
152 )
152 meta.Session().commit()
153 meta.Session().commit()
This diff has been collapsed as it changes many lines, (961 lines changed) Show them Hide them
@@ -65,8 +65,6 b' def store_update(updates, attr, name):'
65 def get_user_or_error(userid):
65 def get_user_or_error(userid):
66 """
66 """
67 Get user by id or name or return JsonRPCError if not found
67 Get user by id or name or return JsonRPCError if not found
68
69 :param userid:
70 """
68 """
71 user = UserModel().get_user(userid)
69 user = UserModel().get_user(userid)
72 if user is None:
70 if user is None:
@@ -77,8 +75,6 b' def get_user_or_error(userid):'
77 def get_repo_or_error(repoid):
75 def get_repo_or_error(repoid):
78 """
76 """
79 Get repo by id or name or return JsonRPCError if not found
77 Get repo by id or name or return JsonRPCError if not found
80
81 :param repoid:
82 """
78 """
83 repo = RepoModel().get_repo(repoid)
79 repo = RepoModel().get_repo(repoid)
84 if repo is None:
80 if repo is None:
@@ -89,8 +85,6 b' def get_repo_or_error(repoid):'
89 def get_repo_group_or_error(repogroupid):
85 def get_repo_group_or_error(repogroupid):
90 """
86 """
91 Get repo group by id or name or return JsonRPCError if not found
87 Get repo group by id or name or return JsonRPCError if not found
92
93 :param repogroupid:
94 """
88 """
95 repo_group = db.RepoGroup.guess_instance(repogroupid)
89 repo_group = db.RepoGroup.guess_instance(repogroupid)
96 if repo_group is None:
90 if repo_group is None:
@@ -102,8 +96,6 b' def get_repo_group_or_error(repogroupid)'
102 def get_user_group_or_error(usergroupid):
96 def get_user_group_or_error(usergroupid):
103 """
97 """
104 Get user group by id or name or return JsonRPCError if not found
98 Get user group by id or name or return JsonRPCError if not found
105
106 :param usergroupid:
107 """
99 """
108 user_group = UserGroupModel().get_group(usergroupid)
100 user_group = UserGroupModel().get_group(usergroupid)
109 if user_group is None:
101 if user_group is None:
@@ -114,8 +106,6 b' def get_user_group_or_error(usergroupid)'
114 def get_perm_or_error(permid, prefix=None):
106 def get_perm_or_error(permid, prefix=None):
115 """
107 """
116 Get permission by id or name or return JsonRPCError if not found
108 Get permission by id or name or return JsonRPCError if not found
117
118 :param permid:
119 """
109 """
120 perm = db.Permission.get_by_key(permid)
110 perm = db.Permission.get_by_key(permid)
121 if perm is None:
111 if perm is None:
@@ -130,8 +120,6 b' def get_perm_or_error(permid, prefix=Non'
130 def get_gist_or_error(gistid):
120 def get_gist_or_error(gistid):
131 """
121 """
132 Get gist by id or gist_access_id or return JsonRPCError if not found
122 Get gist by id or gist_access_id or return JsonRPCError if not found
133
134 :param gistid:
135 """
123 """
136 gist = GistModel().get_gist(gistid)
124 gist = GistModel().get_gist(gistid)
137 if gist is None:
125 if gist is None:
@@ -165,30 +153,15 b' class ApiController(JSONRPCController):'
165 automatically keep remote repos up to date. This command can be executed
153 automatically keep remote repos up to date. This command can be executed
166 only using api_key belonging to user with admin rights
154 only using api_key belonging to user with admin rights
167
155
168 :param repoid: repository name or repository id
169 :type repoid: str or int
170 :param clone_uri: repository URI to pull from (optional)
171 :type clone_uri: str
172
173 OUTPUT::
156 OUTPUT::
174
157
175 id : <id_given_in_input>
158 id : <id_given_in_input>
176 result : {
159 result : {
177 "msg": "Pulled from `<repository name>`"
160 "msg" : "Pulled from `<repository name>`",
178 "repository": "<repository name>"
161 "repository" : "<repository name>"
179 }
162 }
180 error : null
163 error : null
181
182 ERROR OUTPUT::
183
184 id : <id_given_in_input>
185 result : null
186 error : {
187 "Unable to pull changes from `<reponame>`"
188 }
189
190 """
164 """
191
192 repo = get_repo_or_error(repoid)
165 repo = get_repo_or_error(repoid)
193
166
194 try:
167 try:
@@ -214,29 +187,15 b' class ApiController(JSONRPCController):'
214 aka "clean zombies". This command can be executed only using api_key
187 aka "clean zombies". This command can be executed only using api_key
215 belonging to user with admin rights.
188 belonging to user with admin rights.
216
189
217 :param remove_obsolete: deletes repositories from
218 database that are not found on the filesystem
219 :type remove_obsolete: Optional(bool)
220
221 OUTPUT::
190 OUTPUT::
222
191
223 id : <id_given_in_input>
192 id : <id_given_in_input>
224 result : {
193 result : {
225 'added': [<added repository name>,...]
194 'added': [<added repository name>,...]
226 'removed': [<removed repository name>,...]
195 'removed': [<removed repository name>,...]
227 }
196 }
228 error : null
197 error : null
229
230 ERROR OUTPUT::
231
232 id : <id_given_in_input>
233 result : null
234 error : {
235 'Error occurred during rescan repositories action'
236 }
237
238 """
198 """
239
240 try:
199 try:
241 rm_obsolete = remove_obsolete
200 rm_obsolete = remove_obsolete
242 added, removed = repo2db_mapper(ScmModel().repo_scan(),
201 added, removed = repo2db_mapper(ScmModel().repo_scan(),
@@ -254,26 +213,14 b' class ApiController(JSONRPCController):'
254 This command can be executed only using api_key belonging to user with admin
213 This command can be executed only using api_key belonging to user with admin
255 rights or regular user that have write or admin or write access to repository.
214 rights or regular user that have write or admin or write access to repository.
256
215
257 :param repoid: repository name or repository id
258 :type repoid: str or int
259
260 OUTPUT::
216 OUTPUT::
261
217
262 id : <id_given_in_input>
218 id : <id_given_in_input>
263 result : {
219 result : {
264 'msg': Cache for repository `<repository name>` was invalidated,
220 'msg': Cache for repository `<repository name>` was invalidated,
265 'repository': <repository name>
221 'repository': <repository name>
266 }
222 }
267 error : null
223 error : null
268
269 ERROR OUTPUT::
270
271 id : <id_given_in_input>
272 result : null
273 error : {
274 'Error occurred during cache invalidation action'
275 }
276
277 """
224 """
278 repo = get_repo_or_error(repoid)
225 repo = get_repo_or_error(repoid)
279 if not HasPermissionAny('hg.admin')():
226 if not HasPermissionAny('hg.admin')():
@@ -301,23 +248,20 b' class ApiController(JSONRPCController):'
301 This command can be executed only using api_key belonging to user with
248 This command can be executed only using api_key belonging to user with
302 admin rights.
249 admin rights.
303
250
304 :param userid: username to show ips for
305 :type userid: Optional(str or int)
306
307 OUTPUT::
251 OUTPUT::
308
252
309 id : <id_given_in_input>
253 id : <id_given_in_input>
310 result : {
254 result : {
311 "server_ip_addr": "<ip_from_clien>",
255 "server_ip_addr" : "<ip_from_client>",
312 "user_ips": [
256 "user_ips" : [
313 {
257 {
314 "ip_addr": "<ip_with_mask>",
258 "ip_addr" : "<ip_with_mask>",
315 "ip_range": ["<start_ip>", "<end_ip>"],
259 "ip_range" : ["<start_ip>", "<end_ip>"]
316 },
260 },
317 ...
261 ...
318 ]
262 ]
319 }
263 }
320
264 error : null
321 """
265 """
322 if userid is None:
266 if userid is None:
323 userid = request.authuser.user_id
267 userid = request.authuser.user_id
@@ -336,17 +280,18 b' class ApiController(JSONRPCController):'
336 """
280 """
337 return server info, including Kallithea version and installed packages
281 return server info, including Kallithea version and installed packages
338
282
339
340 OUTPUT::
283 OUTPUT::
341
284
342 id : <id_given_in_input>
285 id : <id_given_in_input>
343 result : {
286 result : {
344 'modules': [<module name>,...]
287 'modules' : [ [<module name>, <module version>], ...]
345 'py_version': <python version>,
288 'py_version' : <python version>,
346 'platform': <platform type>,
289 'platform' : <platform type>,
347 'kallithea_version': <kallithea version>
290 'kallithea_version' : <kallithea version>,
348 }
291 'git_version' : '<git version>',
349 error : null
292 'git_path' : '<git path>'
293 }
294 error : null
350 """
295 """
351 return db.Setting.get_server_info()
296 return db.Setting.get_server_info()
352
297
@@ -358,39 +303,29 b' class ApiController(JSONRPCController):'
358 belonging to user with admin rights, or regular users that cannot
303 belonging to user with admin rights, or regular users that cannot
359 specify different userid than theirs
304 specify different userid than theirs
360
305
361 :param userid: user to get data for
362 :type userid: Optional(str or int)
363
364 OUTPUT::
306 OUTPUT::
365
307
366 id : <id_given_in_input>
308 id : <id_given_in_input>
367 result: None if user does not exist or
309 result : None if user does not exist or
368 {
310 {
369 "user_id" : "<user_id>",
311 "user_id" : "<user_id>",
370 "api_key" : "<api_key>",
371 "api_keys": "[<list of all API keys including additional ones>]"
372 "username" : "<username>",
312 "username" : "<username>",
373 "firstname": "<firstname>",
313 "firstname" : "<firstname>",
374 "lastname" : "<lastname>",
314 "lastname" : "<lastname>",
375 "email" : "<email>",
315 "email" : "<email>",
376 "emails": "[<list of all emails including additional ones>]",
316 "emails" : "[<list of all emails including additional ones>]",
377 "ip_addresses": "[<ip_address_for_user>,...]",
378 "active" : "<bool: user active>",
317 "active" : "<bool: user active>",
379 "admin" :  "<bool: user is admin>",
318 "admin" : "<bool: user is admin>",
380 "extern_name" : "<extern_name>",
319 "permissions" : {
381 "extern_type" : "<extern type>
320 "global" : ["hg.create.repository",
382 "last_login": "<last_login>",
321 "repository.read",
383 "permissions": {
322 "hg.register.manual_activate"],
384 "global": ["hg.create.repository",
323 "repositories" : {"repo1" : "repository.none"},
385 "repository.read",
324 "repositories_groups" : {"Group1" : "group.read"},
386 "hg.register.manual_activate"],
325 "user_groups" : { "usrgrp1" : "usergroup.admin" }
387 "repositories": {"repo1": "repository.none"},
326 }
388 "repositories_groups": {"Group1": "group.read"}
327 }
389 },
328 error : null
390 }
391
392 error: null
393
394 """
329 """
395 if not HasPermissionAny('hg.admin')():
330 if not HasPermissionAny('hg.admin')():
396 # make sure normal user does not pass someone else userid,
331 # make sure normal user does not pass someone else userid,
@@ -414,14 +349,12 b' class ApiController(JSONRPCController):'
414 Lists all existing users. This command can be executed only using api_key
349 Lists all existing users. This command can be executed only using api_key
415 belonging to user with admin rights.
350 belonging to user with admin rights.
416
351
417
418 OUTPUT::
352 OUTPUT::
419
353
420 id : <id_given_in_input>
354 id : <id_given_in_input>
421 result: [<user_object>, ...]
355 result : [<user_object>, ...]
422 error: null
356 error : null
423 """
357 """
424
425 return [
358 return [
426 user.get_api_data()
359 user.get_api_data()
427 for user in db.User.query()
360 for user in db.User.query()
@@ -439,49 +372,15 b' class ApiController(JSONRPCController):'
439 Creates new user. Returns new user object. This command can
372 Creates new user. Returns new user object. This command can
440 be executed only using api_key belonging to user with admin rights.
373 be executed only using api_key belonging to user with admin rights.
441
374
442 :param username: new username
443 :type username: str or int
444 :param email: email
445 :type email: str
446 :param password: password
447 :type password: Optional(str)
448 :param firstname: firstname
449 :type firstname: Optional(str)
450 :param lastname: lastname
451 :type lastname: Optional(str)
452 :param active: active
453 :type active: Optional(bool)
454 :param admin: admin
455 :type admin: Optional(bool)
456 :param extern_name: name of extern
457 :type extern_name: Optional(str)
458 :param extern_type: extern_type
459 :type extern_type: Optional(str)
460
461
462 OUTPUT::
375 OUTPUT::
463
376
464 id : <id_given_in_input>
377 id : <id_given_in_input>
465 result: {
378 result : {
466 "msg" : "created new user `<username>`",
379 "msg" : "created new user `<username>`",
467 "user": <user_obj>
380 "user" : <user_obj>
468 }
381 }
469 error: null
382 error : null
470
471 ERROR OUTPUT::
472
473 id : <id_given_in_input>
474 result : null
475 error : {
476 "user `<username>` already exist"
477 or
478 "email `<email>` already exist"
479 or
480 "failed to create user `<username>`"
481 }
482
483 """
383 """
484
485 if db.User.get_by_username(username):
384 if db.User.get_by_username(username):
486 raise JSONRPCError("user `%s` already exist" % (username,))
385 raise JSONRPCError("user `%s` already exist" % (username,))
487
386
@@ -519,47 +418,15 b' class ApiController(JSONRPCController):'
519 updates given user if such user exists. This command can
418 updates given user if such user exists. This command can
520 be executed only using api_key belonging to user with admin rights.
419 be executed only using api_key belonging to user with admin rights.
521
420
522 :param userid: userid to update
523 :type userid: str or int
524 :param username: new username
525 :type username: str or int
526 :param email: email
527 :type email: str
528 :param password: password
529 :type password: Optional(str)
530 :param firstname: firstname
531 :type firstname: Optional(str)
532 :param lastname: lastname
533 :type lastname: Optional(str)
534 :param active: active
535 :type active: Optional(bool)
536 :param admin: admin
537 :type admin: Optional(bool)
538 :param extern_name:
539 :type extern_name: Optional(str)
540 :param extern_type:
541 :type extern_type: Optional(str)
542
543
544 OUTPUT::
421 OUTPUT::
545
422
546 id : <id_given_in_input>
423 id : <id_given_in_input>
547 result: {
424 result : {
548 "msg" : "updated user ID:<userid> <username>",
425 "msg" : "updated user ID:<userid> <username>",
549 "user": <user_object>,
426 "user" : <user_object>
550 }
427 }
551 error: null
428 error : null
552
553 ERROR OUTPUT::
554
555 id : <id_given_in_input>
556 result : null
557 error : {
558 "failed to update user `<username>`"
559 }
560
561 """
429 """
562
563 user = get_user_or_error(userid)
430 user = get_user_or_error(userid)
564
431
565 # only non optional arguments will be stored in updates
432 # only non optional arguments will be stored in updates
@@ -596,26 +463,14 b' class ApiController(JSONRPCController):'
596 deletes given user if such user exists. This command can
463 deletes given user if such user exists. This command can
597 be executed only using api_key belonging to user with admin rights.
464 be executed only using api_key belonging to user with admin rights.
598
465
599 :param userid: user to delete
600 :type userid: str or int
601
602 OUTPUT::
466 OUTPUT::
603
467
604 id : <id_given_in_input>
468 id : <id_given_in_input>
605 result: {
469 result : {
606 "msg" : "deleted user ID:<userid> <username>",
470 "msg" : "deleted user ID:<userid> <username>",
607 "user": null
471 "user" : null
608 }
472 }
609 error: null
473 error : null
610
611 ERROR OUTPUT::
612
613 id : <id_given_in_input>
614 result : null
615 error : {
616 "failed to delete user ID:<userid> <username>"
617 }
618
619 """
474 """
620 user = get_user_or_error(userid)
475 user = get_user_or_error(userid)
621
476
@@ -639,9 +494,6 b' class ApiController(JSONRPCController):'
639 belonging to user with admin rights or user who has at least
494 belonging to user with admin rights or user who has at least
640 read access to user group.
495 read access to user group.
641
496
642 :param usergroupid: id of user_group to edit
643 :type usergroupid: str or int
644
645 OUTPUT::
497 OUTPUT::
646
498
647 id : <id_given_in_input>
499 id : <id_given_in_input>
@@ -649,11 +501,12 b' class ApiController(JSONRPCController):'
649 {
501 {
650 "users_group_id" : "<id>",
502 "users_group_id" : "<id>",
651 "group_name" : "<groupname>",
503 "group_name" : "<groupname>",
652 "active": "<bool>",
504 "group_description" : "<description>",
653 "members" : [<user_obj>,...]
505 "active" : "<bool>",
506 "owner" : "<username>",
507 "members" : [<user_obj>,...]
654 }
508 }
655 error : null
509 error : null
656
657 """
510 """
658 user_group = get_user_group_or_error(usergroupid)
511 user_group = get_user_group_or_error(usergroupid)
659 if not HasPermissionAny('hg.admin')():
512 if not HasPermissionAny('hg.admin')():
@@ -670,14 +523,12 b' class ApiController(JSONRPCController):'
670 api_key belonging to user with admin rights or user who has at least
523 api_key belonging to user with admin rights or user who has at least
671 read access to user group.
524 read access to user group.
672
525
673
674 OUTPUT::
526 OUTPUT::
675
527
676 id : <id_given_in_input>
528 id : <id_given_in_input>
677 result : [<user_group_obj>,...]
529 result : [<user_group_obj>,...]
678 error : null
530 error : null
679 """
531 """
680
681 return [
532 return [
682 user_group.get_api_data()
533 user_group.get_api_data()
683 for user_group in UserGroupList(db.UserGroup.query().all(), perm_level='read')
534 for user_group in UserGroupList(db.UserGroup.query().all(), perm_level='read')
@@ -691,36 +542,15 b' class ApiController(JSONRPCController):'
691 belonging to user with admin rights or an user who has create user group
542 belonging to user with admin rights or an user who has create user group
692 permission
543 permission
693
544
694 :param group_name: name of new user group
695 :type group_name: str
696 :param description: group description
697 :type description: str
698 :param owner: owner of group. If not passed apiuser is the owner
699 :type owner: Optional(str or int)
700 :param active: group is active
701 :type active: Optional(bool)
702
703 OUTPUT::
545 OUTPUT::
704
546
705 id : <id_given_in_input>
547 id : <id_given_in_input>
706 result: {
548 result : {
707 "msg": "created new user group `<groupname>`",
549 "msg" : "created new user group `<groupname>`",
708 "user_group": <user_group_object>
550 "user_group" : <user_group_object>
709 }
551 }
710 error: null
552 error : null
711
712 ERROR OUTPUT::
713
714 id : <id_given_in_input>
715 result : null
716 error : {
717 "user group `<group name>` already exist"
718 or
719 "failed to create group `<group name>`"
720 }
721
722 """
553 """
723
724 if UserGroupModel().get_by_name(group_name):
554 if UserGroupModel().get_by_name(group_name):
725 raise JSONRPCError("user group `%s` already exist" % (group_name,))
555 raise JSONRPCError("user group `%s` already exist" % (group_name,))
726
556
@@ -748,34 +578,14 b' class ApiController(JSONRPCController):'
748 Updates given usergroup. This command can be executed only using api_key
578 Updates given usergroup. This command can be executed only using api_key
749 belonging to user with admin rights or an admin of given user group
579 belonging to user with admin rights or an admin of given user group
750
580
751 :param usergroupid: id of user group to update
752 :type usergroupid: str or int
753 :param group_name: name of new user group
754 :type group_name: str
755 :param description: group description
756 :type description: str
757 :param owner: owner of group.
758 :type owner: Optional(str or int)
759 :param active: group is active
760 :type active: Optional(bool)
761
762 OUTPUT::
581 OUTPUT::
763
582
764 id : <id_given_in_input>
583 id : <id_given_in_input>
765 result : {
584 result : {
766 "msg": 'updated user group ID:<user group id> <user group name>',
585 "msg" : 'updated user group ID:<user group id> <user group name>',
767 "user_group": <user_group_object>
586 "user_group" : <user_group_object>
768 }
587 }
769 error : null
588 error : null
770
771 ERROR OUTPUT::
772
773 id : <id_given_in_input>
774 result : null
775 error : {
776 "failed to update user group `<user group name>`"
777 }
778
779 """
589 """
780 user_group = get_user_group_or_error(usergroupid)
590 user_group = get_user_group_or_error(usergroupid)
781 if not HasPermissionAny('hg.admin')():
591 if not HasPermissionAny('hg.admin')():
@@ -809,27 +619,13 b' class ApiController(JSONRPCController):'
809 This command can be executed only using api_key
619 This command can be executed only using api_key
810 belonging to user with admin rights or an admin of given user group
620 belonging to user with admin rights or an admin of given user group
811
621
812 :param usergroupid:
813 :type usergroupid: int
814
815 OUTPUT::
622 OUTPUT::
816
623
817 id : <id_given_in_input>
624 id : <id_given_in_input>
818 result : {
625 result : {
819 "msg": "deleted user group ID:<user_group_id> <user_group_name>"
626 "msg" : "deleted user group ID:<user_group_id> <user_group_name>"
820 }
627 }
821 error : null
628 error : null
822
823 ERROR OUTPUT::
824
825 id : <id_given_in_input>
826 result : null
827 error : {
828 "failed to delete user group ID:<user_group_id> <user_group_name>"
829 or
830 "RepoGroup assigned to <repo_groups_list>"
831 }
832
833 """
629 """
834 user_group = get_user_group_or_error(usergroupid)
630 user_group = get_user_group_or_error(usergroupid)
835 if not HasPermissionAny('hg.admin')():
631 if not HasPermissionAny('hg.admin')():
@@ -859,32 +655,17 b' class ApiController(JSONRPCController):'
859 """
655 """
860 Adds a user to a user group. If user exists in that group success will be
656 Adds a user to a user group. If user exists in that group success will be
861 `false`. This command can be executed only using api_key
657 `false`. This command can be executed only using api_key
862 belonging to user with admin rights or an admin of given user group
658 belonging to user with admin rights or an admin of a given user group
863
864 :param usergroupid:
865 :type usergroupid: int
866 :param userid:
867 :type userid: int
868
659
869 OUTPUT::
660 OUTPUT::
870
661
871 id : <id_given_in_input>
662 id : <id_given_in_input>
872 result : {
663 result : {
873 "success": True|False # depends on if member is in group
664 "success" : True|False # depends on if member is in group
874 "msg": "added member `<username>` to user group `<groupname>` |
665 "msg" : "added member `<username>` to a user group `<groupname>` |
875 User is already in that group"
666 User is already in that group"
876
667 }
877 }
668 error : null
878 error : null
879
880 ERROR OUTPUT::
881
882 id : <id_given_in_input>
883 result : null
884 error : {
885 "failed to add member to user group `<user_group_name>`"
886 }
887
888 """
669 """
889 user = get_user_or_error(userid)
670 user = get_user_or_error(userid)
890 user_group = get_user_group_or_error(usergroupid)
671 user_group = get_user_group_or_error(usergroupid)
@@ -920,20 +701,15 b' class ApiController(JSONRPCController):'
920 be `false`. This command can be executed only
701 be `false`. This command can be executed only
921 using api_key belonging to user with admin rights or an admin of given user group
702 using api_key belonging to user with admin rights or an admin of given user group
922
703
923 :param usergroupid:
924 :param userid:
925
926
927 OUTPUT::
704 OUTPUT::
928
705
929 id : <id_given_in_input>
706 id : <id_given_in_input>
930 result: {
707 result : {
931 "success": True|False, # depends on if member is in group
708 "success" : True|False, # depends on if member is in group
932 "msg": "removed member <username> from user group <groupname> |
709 "msg" : "removed member <username> from user group <groupname> |
933 User wasn't in group"
710 User wasn't in group"
934 }
711 }
935 error: null
712 error : null
936
937 """
713 """
938 user = get_user_or_error(userid)
714 user = get_user_or_error(userid)
939 user_group = get_user_group_or_error(usergroupid)
715 user_group = get_user_group_or_error(usergroupid)
@@ -967,66 +743,60 b' class ApiController(JSONRPCController):'
967 executed only using api_key belonging to user with admin
743 executed only using api_key belonging to user with admin
968 rights or regular user that have at least read access to repository.
744 rights or regular user that have at least read access to repository.
969
745
970 :param repoid: repository name or repository id
971 :type repoid: str or int
972
973 OUTPUT::
746 OUTPUT::
974
747
975 id : <id_given_in_input>
748 id : <id_given_in_input>
976 result : {
749 result : {
977 {
750 "repo_id" : "<repo_id>",
978 "repo_id" : "<repo_id>",
751 "repo_name" : "<reponame>",
979 "repo_name" : "<reponame>"
752 "repo_type" : "<repo_type>",
980 "repo_type" : "<repo_type>",
753 "clone_uri" : "<clone_uri>",
981 "clone_uri" : "<clone_uri>",
754 "enable_downloads" : "<bool>",
982 "enable_downloads": "<bool>",
755 "enable_statistics": "<bool>",
983 "enable_statistics": "<bool>",
756 "private" : "<bool>",
984 "private": "<bool>",
757 "created_on" : "<date_time_created>",
985 "created_on" : "<date_time_created>",
758 "description" : "<description>",
986 "description" : "<description>",
759 "landing_rev" : "<landing_rev>",
987 "landing_rev": "<landing_rev>",
760 "last_changeset" : {
988 "last_changeset": {
761 "author" : "<full_author>",
989 "author": "<full_author>",
762 "date" : "<date_time_of_commit>",
990 "date": "<date_time_of_commit>",
763 "message" : "<commit_message>",
991 "message": "<commit_message>",
764 "raw_id" : "<raw_id>",
992 "raw_id": "<raw_id>",
765 "revision": "<numeric_revision>",
993 "revision": "<numeric_revision>",
766 "short_id": "<short_id>"
994 "short_id": "<short_id>"
767 },
995 }
768 "owner" : "<repo_owner>",
996 "owner": "<repo_owner>",
769 "fork_of" : "<name_of_fork_parent>",
997 "fork_of": "<name_of_fork_parent>",
770 "members" : [
998 "members" : [
771 {
999 {
772 "name" : "<username>",
1000 "name": "<username>",
773 "type" : "user",
1001 "type" : "user",
774 "permission" : "repository.(read|write|admin)"
1002 "permission" : "repository.(read|write|admin)"
775 },
1003 },
776
1004
777 {
1005 {
778 "name" : "<usergroup name>",
1006 "name": "<usergroup name>",
779 "type" : "user_group",
1007 "type" : "user_group",
780 "permission" : "usergroup.(read|write|admin)"
1008 "permission" : "usergroup.(read|write|admin)"
781 },
1009 },
782
1010
783 ],
1011 ]
784 "followers" : [<user_obj>, ...],
1012 "followers": [<user_obj>, ...],
785 <if with_revision_names == True>
1013 <if with_revision_names == True>
786 "tags" : {
1014 "tags": {
787 "<tagname>" : "<raw_id>",
1015 "<tagname>": "<raw_id>",
788 ...
1016 ...
789 },
1017 },
790 "branches" : {
1018 "branches": {
791 "<branchname>" : "<raw_id>",
1019 "<branchname>": "<raw_id>",
792 ...
1020 ...
793 },
1021 },
794 "bookmarks" : {
1022 "bookmarks": {
795 "<bookmarkname>" : "<raw_id>",
1023 "<bookmarkname>": "<raw_id>",
796 ...
1024 ...
797 }
1025 },
798 }
1026 }
799 error : null
1027 }
1028 error : null
1029
1030 """
800 """
1031 repo = get_repo_or_error(repoid)
801 repo = get_repo_or_error(repoid)
1032
802
@@ -1073,28 +843,27 b' class ApiController(JSONRPCController):'
1073 api_key belonging to user with admin rights or regular user that have
843 api_key belonging to user with admin rights or regular user that have
1074 admin, write or read access to repository.
844 admin, write or read access to repository.
1075
845
1076
1077 OUTPUT::
846 OUTPUT::
1078
847
1079 id : <id_given_in_input>
848 id : <id_given_in_input>
1080 result: [
849 result : [
1081 {
850 {
1082 "repo_id" : "<repo_id>",
851 "repo_id" : "<repo_id>",
1083 "repo_name" : "<reponame>"
852 "repo_name" : "<reponame>",
1084 "repo_type" : "<repo_type>",
853 "repo_type" : "<repo_type>",
1085 "clone_uri" : "<clone_uri>",
854 "clone_uri" : "<clone_uri>",
1086 "private": : "<bool>",
855 "private" : "<bool>",
1087 "created_on" : "<datetimecreated>",
856 "created_on" : "<datetimecreated>",
1088 "description" : "<description>",
857 "description" : "<description>",
1089 "landing_rev": "<landing_rev>",
858 "landing_rev" : "<landing_rev>",
1090 "owner": "<repo_owner>",
859 "owner" : "<repo_owner>",
1091 "fork_of": "<name_of_fork_parent>",
860 "fork_of" : "<name_of_fork_parent>",
1092 "enable_downloads": "<bool>",
861 "enable_downloads" : "<bool>",
1093 "enable_statistics": "<bool>",
862 "enable_statistics": "<bool>"
1094 },
863 },
1095
864
1096 ]
865 ]
1097 error: null
866 error : null
1098 """
867 """
1099 if not HasPermissionAny('hg.admin')():
868 if not HasPermissionAny('hg.admin')():
1100 repos = request.authuser.get_all_user_repos()
869 repos = request.authuser.get_all_user_repos()
@@ -1115,27 +884,17 b' class ApiController(JSONRPCController):'
1115 `dirs`. This command can be executed only using api_key belonging to
884 `dirs`. This command can be executed only using api_key belonging to
1116 user with admin rights or regular user that have at least read access to repository.
885 user with admin rights or regular user that have at least read access to repository.
1117
886
1118 :param repoid: repository name or repository id
1119 :type repoid: str or int
1120 :param revision: revision for which listing should be done
1121 :type revision: str
1122 :param root_path: path from which start displaying
1123 :type root_path: str
1124 :param ret_type: return type 'all|files|dirs' nodes
1125 :type ret_type: Optional(str)
1126
1127
1128 OUTPUT::
887 OUTPUT::
1129
888
1130 id : <id_given_in_input>
889 id : <id_given_in_input>
1131 result: [
890 result : [
1132 {
891 {
1133 "name" : "<name>"
892 "name" : "<name>",
1134 "type" : "<type>",
893 "type" : "<type>"
1135 },
894 },
1136
895
1137 ]
896 ]
1138 error: null
897 error : null
1139 """
898 """
1140 repo = get_repo_or_error(repoid)
899 repo = get_repo_or_error(repoid)
1141
900
@@ -1178,46 +937,14 b' class ApiController(JSONRPCController):'
1178 belonging to user with admin rights or regular user that have create
937 belonging to user with admin rights or regular user that have create
1179 repository permission. Regular users cannot specify owner parameter
938 repository permission. Regular users cannot specify owner parameter
1180
939
1181 :param repo_name: repository name
1182 :type repo_name: str
1183 :param owner: user_id or username
1184 :type owner: Optional(str)
1185 :param repo_type: 'hg' or 'git'
1186 :type repo_type: Optional(str)
1187 :param description: repository description
1188 :type description: Optional(str)
1189 :param private:
1190 :type private: bool
1191 :param clone_uri:
1192 :type clone_uri: str
1193 :param landing_rev: <rev_type>:<rev>
1194 :type landing_rev: str
1195 :param enable_downloads:
1196 :type enable_downloads: bool
1197 :param enable_statistics:
1198 :type enable_statistics: bool
1199 :param copy_permissions: Copy permission from group that repository is
1200 being created.
1201 :type copy_permissions: bool
1202
1203 OUTPUT::
940 OUTPUT::
1204
941
1205 id : <id_given_in_input>
942 id : <id_given_in_input>
1206 result: {
943 result : {
1207 "msg": "Created new repository `<reponame>`",
944 "msg" : "Created new repository `<reponame>`",
1208 "success": true,
945 "success" : true
1209 "task": "<celery task id or None if done sync>"
946 }
1210 }
947 error : null
1211 error: null
1212
1213 ERROR OUTPUT::
1214
1215 id : <id_given_in_input>
1216 result : null
1217 error : {
1218 'failed to create repository `<repo_name>`
1219 }
1220
1221 """
948 """
1222 group_name = None
949 group_name = None
1223 repo_name_parts = repo_name.split('/')
950 repo_name_parts = repo_name.split('/')
@@ -1266,8 +993,8 b' class ApiController(JSONRPCController):'
1266 clone_uri=clone_uri,
993 clone_uri=clone_uri,
1267 repo_group=group_name,
994 repo_group=group_name,
1268 repo_landing_rev=landing_rev,
995 repo_landing_rev=landing_rev,
1269 enable_statistics=enable_statistics,
996 repo_enable_statistics=enable_statistics,
1270 enable_downloads=enable_downloads,
997 repo_enable_downloads=enable_downloads,
1271 repo_copy_permissions=copy_permissions,
998 repo_copy_permissions=copy_permissions,
1272 )
999 )
1273
1000
@@ -1291,21 +1018,8 b' class ApiController(JSONRPCController):'
1291 clone_uri=None, landing_rev=None,
1018 clone_uri=None, landing_rev=None,
1292 enable_statistics=None,
1019 enable_statistics=None,
1293 enable_downloads=None):
1020 enable_downloads=None):
1294
1295 """
1021 """
1296 Updates repo
1022 Updates repo
1297
1298 :param repoid: repository name or repository id
1299 :type repoid: str or int
1300 :param name:
1301 :param owner:
1302 :param group:
1303 :param description:
1304 :param private:
1305 :param clone_uri:
1306 :param landing_rev:
1307 :param enable_statistics:
1308 :param enable_downloads:
1309 """
1023 """
1310 repo = get_repo_or_error(repoid)
1024 repo = get_repo_or_error(repoid)
1311 if not HasPermissionAny('hg.admin')():
1025 if not HasPermissionAny('hg.admin')():
@@ -1365,39 +1079,29 b' class ApiController(JSONRPCController):'
1365 user with admin rights or regular user that have fork permission, and at least
1079 user with admin rights or regular user that have fork permission, and at least
1366 read access to forking repository. Regular users cannot specify owner parameter.
1080 read access to forking repository. Regular users cannot specify owner parameter.
1367
1081
1368 :param repoid: repository name or repository id
1369 :type repoid: str or int
1370 :param fork_name:
1371 :param owner:
1372 :param description:
1373 :param copy_permissions:
1374 :param private:
1375 :param landing_rev:
1376
1377 INPUT::
1082 INPUT::
1378
1083
1379 id : <id_for_response>
1084 id : <id_for_response>
1380 api_key : "<api_key>"
1085 api_key : "<api_key>"
1381 args: {
1086 method : "fork_repo"
1087 args : {
1382 "repoid" : "<reponame or repo_id>",
1088 "repoid" : "<reponame or repo_id>",
1383 "fork_name": "<forkname>",
1089 "fork_name" : "<forkname>",
1384 "owner": "<username or user_id = Optional(=apiuser)>",
1090 "owner" : "<username or user_id = Optional(=apiuser)>",
1385 "description": "<description>",
1091 "description" : "<description>",
1386 "copy_permissions": "<bool>",
1092 "copy_permissions": "<bool>",
1387 "private": "<bool>",
1093 "private" : "<bool>",
1388 "landing_rev": "<landing_rev>"
1094 "landing_rev" : "<landing_rev>"
1389 }
1095 }
1390
1096
1391 OUTPUT::
1097 OUTPUT::
1392
1098
1393 id : <id_given_in_input>
1099 id : <id_given_in_input>
1394 result: {
1100 result : {
1395 "msg": "Created fork of `<reponame>` as `<forkname>`",
1101 "msg" : "Created fork of `<reponame>` as `<forkname>`",
1396 "success": true,
1102 "success" : true
1397 "task": "<celery task id or None if done sync>"
1103 }
1398 }
1104 error : null
1399 error: null
1400
1401 """
1105 """
1402 repo = get_repo_or_error(repoid)
1106 repo = get_repo_or_error(repoid)
1403 repo_name = repo.repo_name
1107 repo_name = repo.repo_name
@@ -1472,20 +1176,14 b' class ApiController(JSONRPCController):'
1472 When `forks` param is set it's possible to detach or delete forks of deleting
1176 When `forks` param is set it's possible to detach or delete forks of deleting
1473 repository
1177 repository
1474
1178
1475 :param repoid: repository name or repository id
1476 :type repoid: str or int
1477 :param forks: `detach` or `delete`, what do do with attached forks for repo
1478 :type forks: Optional(str)
1479
1480 OUTPUT::
1179 OUTPUT::
1481
1180
1482 id : <id_given_in_input>
1181 id : <id_given_in_input>
1483 result: {
1182 result : {
1484 "msg": "Deleted repository `<reponame>`",
1183 "msg" : "Deleted repository `<reponame>`",
1485 "success": true
1184 "success" : true
1486 }
1185 }
1487 error: null
1186 error : null
1488
1489 """
1187 """
1490 repo = get_repo_or_error(repoid)
1188 repo = get_repo_or_error(repoid)
1491
1189
@@ -1526,20 +1224,14 b' class ApiController(JSONRPCController):'
1526 if found. This command can be executed only using api_key belonging to user
1224 if found. This command can be executed only using api_key belonging to user
1527 with admin rights.
1225 with admin rights.
1528
1226
1529 :param repoid: repository name or repository id
1530 :type repoid: str or int
1531 :param userid:
1532 :param perm: (repository.(none|read|write|admin))
1533 :type perm: str
1534
1535 OUTPUT::
1227 OUTPUT::
1536
1228
1537 id : <id_given_in_input>
1229 id : <id_given_in_input>
1538 result: {
1230 result : {
1539 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
1231 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
1540 "success": true
1232 "success" : true
1541 }
1233 }
1542 error: null
1234 error : null
1543 """
1235 """
1544 repo = get_repo_or_error(repoid)
1236 repo = get_repo_or_error(repoid)
1545 user = get_user_or_error(userid)
1237 user = get_user_or_error(userid)
@@ -1570,21 +1262,15 b' class ApiController(JSONRPCController):'
1570 Revoke permission for user on given repository. This command can be executed
1262 Revoke permission for user on given repository. This command can be executed
1571 only using api_key belonging to user with admin rights.
1263 only using api_key belonging to user with admin rights.
1572
1264
1573 :param repoid: repository name or repository id
1574 :type repoid: str or int
1575 :param userid:
1576
1577 OUTPUT::
1265 OUTPUT::
1578
1266
1579 id : <id_given_in_input>
1267 id : <id_given_in_input>
1580 result: {
1268 result : {
1581 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
1269 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
1582 "success": true
1270 "success" : true
1583 }
1271 }
1584 error: null
1272 error : null
1585
1586 """
1273 """
1587
1588 repo = get_repo_or_error(repoid)
1274 repo = get_repo_or_error(repoid)
1589 user = get_user_or_error(userid)
1275 user = get_user_or_error(userid)
1590 try:
1276 try:
@@ -1611,31 +1297,14 b' class ApiController(JSONRPCController):'
1611 existing one if found. This command can be executed only using
1297 existing one if found. This command can be executed only using
1612 api_key belonging to user with admin rights.
1298 api_key belonging to user with admin rights.
1613
1299
1614 :param repoid: repository name or repository id
1615 :type repoid: str or int
1616 :param usergroupid: id of usergroup
1617 :type usergroupid: str or int
1618 :param perm: (repository.(none|read|write|admin))
1619 :type perm: str
1620
1621 OUTPUT::
1300 OUTPUT::
1622
1301
1623 id : <id_given_in_input>
1302 id : <id_given_in_input>
1624 result : {
1303 result : {
1625 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
1304 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
1626 "success": true
1305 "success" : true
1627
1306 }
1628 }
1307 error : null
1629 error : null
1630
1631 ERROR OUTPUT::
1632
1633 id : <id_given_in_input>
1634 result : null
1635 error : {
1636 "failed to edit permission for user group: `<usergroup>` in repo `<repo>`'
1637 }
1638
1639 """
1308 """
1640 repo = get_repo_or_error(repoid)
1309 repo = get_repo_or_error(repoid)
1641 perm = get_perm_or_error(perm)
1310 perm = get_perm_or_error(perm)
@@ -1675,18 +1344,14 b' class ApiController(JSONRPCController):'
1675 Revoke permission for user group on given repository. This command can be
1344 Revoke permission for user group on given repository. This command can be
1676 executed only using api_key belonging to user with admin rights.
1345 executed only using api_key belonging to user with admin rights.
1677
1346
1678 :param repoid: repository name or repository id
1679 :type repoid: str or int
1680 :param usergroupid:
1681
1682 OUTPUT::
1347 OUTPUT::
1683
1348
1684 id : <id_given_in_input>
1349 id : <id_given_in_input>
1685 result: {
1350 result : {
1686 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
1351 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
1687 "success": true
1352 "success" : true
1688 }
1353 }
1689 error: null
1354 error : null
1690 """
1355 """
1691 repo = get_repo_or_error(repoid)
1356 repo = get_repo_or_error(repoid)
1692 user_group = get_user_group_or_error(usergroupid)
1357 user_group = get_user_group_or_error(usergroupid)
@@ -1722,9 +1387,6 b' class ApiController(JSONRPCController):'
1722 """
1387 """
1723 Returns given repo group together with permissions, and repositories
1388 Returns given repo group together with permissions, and repositories
1724 inside the group
1389 inside the group
1725
1726 :param repogroupid: id/name of repository group
1727 :type repogroupid: str or int
1728 """
1390 """
1729 repo_group = get_repo_group_or_error(repogroupid)
1391 repo_group = get_repo_group_or_error(repogroupid)
1730
1392
@@ -1757,7 +1419,6 b' class ApiController(JSONRPCController):'
1757 def get_repo_groups(self):
1419 def get_repo_groups(self):
1758 """
1420 """
1759 Returns all repository groups
1421 Returns all repository groups
1760
1761 """
1422 """
1762 return [
1423 return [
1763 repo_group.get_api_data()
1424 repo_group.get_api_data()
@@ -1773,34 +1434,14 b' class ApiController(JSONRPCController):'
1773 Creates a repository group. This command can be executed only using
1434 Creates a repository group. This command can be executed only using
1774 api_key belonging to user with admin rights.
1435 api_key belonging to user with admin rights.
1775
1436
1776 :param group_name:
1777 :type group_name:
1778 :param description:
1779 :type description:
1780 :param owner:
1781 :type owner:
1782 :param parent:
1783 :type parent:
1784 :param copy_permissions:
1785 :type copy_permissions:
1786
1787 OUTPUT::
1437 OUTPUT::
1788
1438
1789 id : <id_given_in_input>
1439 id : <id_given_in_input>
1790 result : {
1440 result : {
1791 "msg": "created new repo group `<repo_group_name>`"
1441 "msg" : "created new repo group `<repo_group_name>`",
1792 "repo_group": <repogroup_object>
1442 "repo_group" : <repogroup_object>
1793 }
1443 }
1794 error : null
1444 error : null
1795
1796 ERROR OUTPUT::
1797
1798 id : <id_given_in_input>
1799 result : null
1800 error : {
1801 failed to create repo group `<repogroupid>`
1802 }
1803
1804 """
1445 """
1805 if db.RepoGroup.get_by_group_name(group_name):
1446 if db.RepoGroup.get_by_group_name(group_name):
1806 raise JSONRPCError("repo group `%s` already exist" % (group_name,))
1447 raise JSONRPCError("repo group `%s` already exist" % (group_name,))
@@ -1835,14 +1476,18 b' class ApiController(JSONRPCController):'
1835 description=None,
1476 description=None,
1836 owner=None,
1477 owner=None,
1837 parent=None):
1478 parent=None):
1479 """
1480 TODO
1481 """
1838 repo_group = get_repo_group_or_error(repogroupid)
1482 repo_group = get_repo_group_or_error(repogroupid)
1483 parent_repo_group_id = None if parent is None else get_repo_group_or_error(parent).group_id
1839
1484
1840 updates = {}
1485 updates = {}
1841 try:
1486 try:
1842 store_update(updates, group_name, 'group_name')
1487 store_update(updates, group_name, 'group_name')
1843 store_update(updates, description, 'group_description')
1488 store_update(updates, description, 'group_description')
1844 store_update(updates, owner, 'owner')
1489 store_update(updates, owner, 'owner')
1845 store_update(updates, parent, 'parent_group')
1490 store_update(updates, parent_repo_group_id, 'parent_group_id')
1846 repo_group = RepoGroupModel().update(repo_group, updates)
1491 repo_group = RepoGroupModel().update(repo_group, updates)
1847 meta.Session().commit()
1492 meta.Session().commit()
1848 return dict(
1493 return dict(
@@ -1858,27 +1503,14 b' class ApiController(JSONRPCController):'
1858 @HasPermissionAnyDecorator('hg.admin')
1503 @HasPermissionAnyDecorator('hg.admin')
1859 def delete_repo_group(self, repogroupid):
1504 def delete_repo_group(self, repogroupid):
1860 """
1505 """
1861
1862 :param repogroupid: name or id of repository group
1863 :type repogroupid: str or int
1864
1865 OUTPUT::
1506 OUTPUT::
1866
1507
1867 id : <id_given_in_input>
1508 id : <id_given_in_input>
1868 result : {
1509 result : {
1869 'msg': 'deleted repo group ID:<repogroupid> <repogroupname>
1510 'msg' : 'deleted repo group ID:<repogroupid> <repogroupname>
1870 'repo_group': null
1511 'repo_group' : null
1871 }
1512 }
1872 error : null
1513 error : null
1873
1874 ERROR OUTPUT::
1875
1876 id : <id_given_in_input>
1877 result : null
1878 error : {
1879 "failed to delete repo group ID:<repogroupid> <repogroupname>"
1880 }
1881
1882 """
1514 """
1883 repo_group = get_repo_group_or_error(repogroupid)
1515 repo_group = get_repo_group_or_error(repogroupid)
1884
1516
@@ -1905,33 +1537,15 b' class ApiController(JSONRPCController):'
1905 to user with admin rights, or user who has admin right to given repository
1537 to user with admin rights, or user who has admin right to given repository
1906 group.
1538 group.
1907
1539
1908 :param repogroupid: name or id of repository group
1909 :type repogroupid: str or int
1910 :param userid:
1911 :param perm: (group.(none|read|write|admin))
1912 :type perm: str
1913 :param apply_to_children: 'none', 'repos', 'groups', 'all'
1914 :type apply_to_children: str
1915
1916 OUTPUT::
1540 OUTPUT::
1917
1541
1918 id : <id_given_in_input>
1542 id : <id_given_in_input>
1919 result: {
1543 result : {
1920 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
1544 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
1921 "success": true
1545 "success" : true
1922 }
1546 }
1923 error: null
1547 error : null
1924
1925 ERROR OUTPUT::
1926
1927 id : <id_given_in_input>
1928 result : null
1929 error : {
1930 "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
1931 }
1932
1933 """
1548 """
1934
1935 repo_group = get_repo_group_or_error(repogroupid)
1549 repo_group = get_repo_group_or_error(repogroupid)
1936
1550
1937 if not HasPermissionAny('hg.admin')():
1551 if not HasPermissionAny('hg.admin')():
@@ -1968,32 +1582,15 b' class ApiController(JSONRPCController):'
1968 be executed only using api_key belonging to user with admin rights, or
1582 be executed only using api_key belonging to user with admin rights, or
1969 user who has admin right to given repository group.
1583 user who has admin right to given repository group.
1970
1584
1971 :param repogroupid: name or id of repository group
1972 :type repogroupid: str or int
1973 :param userid:
1974 :type userid:
1975 :param apply_to_children: 'none', 'repos', 'groups', 'all'
1976 :type apply_to_children: str
1977
1978 OUTPUT::
1585 OUTPUT::
1979
1586
1980 id : <id_given_in_input>
1587 id : <id_given_in_input>
1981 result: {
1588 result : {
1982 "msg" : "Revoked perm (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
1589 "msg" : "Revoked perm (recursive:<apply_to_children>) for user: `<username>` in repo group: `<repo_group_name>`",
1983 "success": true
1590 "success" : true
1984 }
1591 }
1985 error: null
1592 error : null
1986
1987 ERROR OUTPUT::
1988
1989 id : <id_given_in_input>
1990 result : null
1991 error : {
1992 "failed to edit permission for user: `<userid>` in repo group: `<repo_group_name>`"
1993 }
1994
1995 """
1593 """
1996
1997 repo_group = get_repo_group_or_error(repogroupid)
1594 repo_group = get_repo_group_or_error(repogroupid)
1998
1595
1999 if not HasPermissionAny('hg.admin')():
1596 if not HasPermissionAny('hg.admin')():
@@ -2031,33 +1628,14 b' class ApiController(JSONRPCController):'
2031 api_key belonging to user with admin rights, or user who has admin
1628 api_key belonging to user with admin rights, or user who has admin
2032 right to given repository group.
1629 right to given repository group.
2033
1630
2034 :param repogroupid: name or id of repository group
2035 :type repogroupid: str or int
2036 :param usergroupid: id of usergroup
2037 :type usergroupid: str or int
2038 :param perm: (group.(none|read|write|admin))
2039 :type perm: str
2040 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2041 :type apply_to_children: str
2042
2043 OUTPUT::
1631 OUTPUT::
2044
1632
2045 id : <id_given_in_input>
1633 id : <id_given_in_input>
2046 result : {
1634 result : {
2047 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
1635 "msg" : "Granted perm: `<perm>` (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
2048 "success": true
1636 "success" : true
2049
2050 }
1637 }
2051 error : null
1638 error : null
2052
2053 ERROR OUTPUT::
2054
2055 id : <id_given_in_input>
2056 result : null
2057 error : {
2058 "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
2059 }
2060
2061 """
1639 """
2062 repo_group = get_repo_group_or_error(repogroupid)
1640 repo_group = get_repo_group_or_error(repogroupid)
2063 perm = get_perm_or_error(perm, prefix='group.')
1641 perm = get_perm_or_error(perm, prefix='group.')
@@ -2103,30 +1681,14 b' class ApiController(JSONRPCController):'
2103 executed only using api_key belonging to user with admin rights, or
1681 executed only using api_key belonging to user with admin rights, or
2104 user who has admin right to given repository group.
1682 user who has admin right to given repository group.
2105
1683
2106 :param repogroupid: name or id of repository group
2107 :type repogroupid: str or int
2108 :param usergroupid:
2109 :param apply_to_children: 'none', 'repos', 'groups', 'all'
2110 :type apply_to_children: str
2111
2112 OUTPUT::
1684 OUTPUT::
2113
1685
2114 id : <id_given_in_input>
1686 id : <id_given_in_input>
2115 result: {
1687 result : {
2116 "msg" : "Revoked perm (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
1688 "msg" : "Revoked perm (recursive:<apply_to_children>) for user group: `<usersgroupname>` in repo group: `<repo_group_name>`",
2117 "success": true
1689 "success" : true
2118 }
1690 }
2119 error: null
1691 error : null
2120
2121 ERROR OUTPUT::
2122
2123 id : <id_given_in_input>
2124 result : null
2125 error : {
2126 "failed to edit permission for user group: `<usergroup>` in repo group: `<repo_group_name>`"
2127 }
2128
2129
2130 """
1692 """
2131 repo_group = get_repo_group_or_error(repogroupid)
1693 repo_group = get_repo_group_or_error(repogroupid)
2132 user_group = get_user_group_or_error(usergroupid)
1694 user_group = get_user_group_or_error(usergroupid)
@@ -2162,9 +1724,6 b' class ApiController(JSONRPCController):'
2162 def get_gist(self, gistid):
1724 def get_gist(self, gistid):
2163 """
1725 """
2164 Get given gist by id
1726 Get given gist by id
2165
2166 :param gistid: id of private or public gist
2167 :type gistid: str
2168 """
1727 """
2169 gist = get_gist_or_error(gistid)
1728 gist = get_gist_or_error(gistid)
2170 if not HasPermissionAny('hg.admin')():
1729 if not HasPermissionAny('hg.admin')():
@@ -2176,9 +1735,6 b' class ApiController(JSONRPCController):'
2176 """
1735 """
2177 Get all gists for given user. If userid is empty returned gists
1736 Get all gists for given user. If userid is empty returned gists
2178 are for user who called the api
1737 are for user who called the api
2179
2180 :param userid: user to get gists for
2181 :type userid: Optional(str or int)
2182 """
1738 """
2183 if not HasPermissionAny('hg.admin')():
1739 if not HasPermissionAny('hg.admin')():
2184 # make sure normal user does not pass someone else userid,
1740 # make sure normal user does not pass someone else userid,
@@ -2204,40 +1760,17 b' class ApiController(JSONRPCController):'
2204 def create_gist(self, files, owner=None,
1760 def create_gist(self, files, owner=None,
2205 gist_type=db.Gist.GIST_PUBLIC, lifetime=-1,
1761 gist_type=db.Gist.GIST_PUBLIC, lifetime=-1,
2206 description=''):
1762 description=''):
2207
2208 """
1763 """
2209 Creates new Gist
1764 Creates new Gist
2210
1765
2211 :param files: files to be added to gist
2212 {'filename': {'content':'...', 'lexer': null},
2213 'filename2': {'content':'...', 'lexer': null}}
2214 :type files: dict
2215 :param owner: gist owner, defaults to api method caller
2216 :type owner: Optional(str or int)
2217 :param gist_type: type of gist 'public' or 'private'
2218 :type gist_type: Optional(str)
2219 :param lifetime: time in minutes of gist lifetime
2220 :type lifetime: Optional(int)
2221 :param description: gist description
2222 :type description: Optional(str)
2223
2224 OUTPUT::
1766 OUTPUT::
2225
1767
2226 id : <id_given_in_input>
1768 id : <id_given_in_input>
2227 result : {
1769 result : {
2228 "msg": "created new gist",
1770 "msg" : "created new gist",
2229 "gist": {}
1771 "gist" : <gist_object>
2230 }
1772 }
2231 error : null
1773 error : null
2232
2233 ERROR OUTPUT::
2234
2235 id : <id_given_in_input>
2236 result : null
2237 error : {
2238 "failed to create gist"
2239 }
2240
2241 """
1774 """
2242 try:
1775 try:
2243 if owner is None:
1776 if owner is None:
@@ -2265,26 +1798,14 b' class ApiController(JSONRPCController):'
2265 """
1798 """
2266 Deletes existing gist
1799 Deletes existing gist
2267
1800
2268 :param gistid: id of gist to delete
2269 :type gistid: str
2270
2271 OUTPUT::
1801 OUTPUT::
2272
1802
2273 id : <id_given_in_input>
1803 id : <id_given_in_input>
2274 result : {
1804 result : {
2275 "deleted gist ID: <gist_id>",
1805 "msg" : "deleted gist ID: <gist_id>",
2276 "gist": null
1806 "gist" : null
2277 }
1807 }
2278 error : null
1808 error : null
2279
2280 ERROR OUTPUT::
2281
2282 id : <id_given_in_input>
2283 result : null
2284 error : {
2285 "failed to delete gist ID:<gist_id>"
2286 }
2287
2288 """
1809 """
2289 gist = get_gist_or_error(gistid)
1810 gist = get_gist_or_error(gistid)
2290 if not HasPermissionAny('hg.admin')():
1811 if not HasPermissionAny('hg.admin')():
@@ -2306,6 +1827,9 b' class ApiController(JSONRPCController):'
2306 # permission check inside
1827 # permission check inside
2307 def get_changesets(self, repoid, start=None, end=None, start_date=None,
1828 def get_changesets(self, repoid, start=None, end=None, start_date=None,
2308 end_date=None, branch_name=None, reverse=False, with_file_list=False, max_revisions=None):
1829 end_date=None, branch_name=None, reverse=False, with_file_list=False, max_revisions=None):
1830 """
1831 TODO
1832 """
2309 repo = get_repo_or_error(repoid)
1833 repo = get_repo_or_error(repoid)
2310 if not HasRepoPermissionLevel('read')(repo.repo_name):
1834 if not HasRepoPermissionLevel('read')(repo.repo_name):
2311 raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
1835 raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
@@ -2323,7 +1847,10 b' class ApiController(JSONRPCController):'
2323 raise JSONRPCError('Repository is empty')
1847 raise JSONRPCError('Repository is empty')
2324
1848
2325 # permission check inside
1849 # permission check inside
2326 def get_changeset(self, repoid, raw_id, with_reviews=False):
1850 def get_changeset(self, repoid, raw_id, with_reviews=False, with_comments=False, with_inline_comments=False):
1851 """
1852 TODO
1853 """
2327 repo = get_repo_or_error(repoid)
1854 repo = get_repo_or_error(repoid)
2328 if not HasRepoPermissionLevel('read')(repo.repo_name):
1855 if not HasRepoPermissionLevel('read')(repo.repo_name):
2329 raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
1856 raise JSONRPCError('Access denied to repo %s' % repo.repo_name)
@@ -2335,9 +1862,19 b' class ApiController(JSONRPCController):'
2335
1862
2336 if with_reviews:
1863 if with_reviews:
2337 reviews = ChangesetStatusModel().get_statuses(
1864 reviews = ChangesetStatusModel().get_statuses(
2338 repo.repo_name, raw_id)
1865 repo.repo_name, changeset.raw_id)
2339 info["reviews"] = reviews
1866 info["reviews"] = reviews
2340
1867
1868 if with_comments:
1869 comments = ChangesetCommentsModel().get_comments(
1870 repo.repo_id, changeset.raw_id)
1871 info["comments"] = comments
1872
1873 if with_inline_comments:
1874 inline_comments = ChangesetCommentsModel().get_inline_comments(
1875 repo.repo_id, changeset.raw_id)
1876 info["inline_comments"] = inline_comments
1877
2341 return info
1878 return info
2342
1879
2343 # permission check inside
1880 # permission check inside
@@ -35,6 +35,7 b' from tg import tmpl_context as c'
35 from tg.i18n import ugettext as _
35 from tg.i18n import ugettext as _
36 from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPFound, HTTPNotFound
36 from webob.exc import HTTPBadRequest, HTTPForbidden, HTTPFound, HTTPNotFound
37
37
38 import kallithea
38 import kallithea.lib.helpers as h
39 import kallithea.lib.helpers as h
39 from kallithea.controllers import base
40 from kallithea.controllers import base
40 from kallithea.controllers.changeset import create_cs_pr_comment, delete_cs_pr_comment
41 from kallithea.controllers.changeset import create_cs_pr_comment, delete_cs_pr_comment
@@ -494,6 +495,8 b' class PullrequestsController(base.BaseRe'
494 except IndexError: # probably because c.cs_ranges is empty, probably because revisions are missing
495 except IndexError: # probably because c.cs_ranges is empty, probably because revisions are missing
495 pass
496 pass
496
497
498 rev_limit = safe_int(kallithea.CONFIG.get('next_iteration_rev_limit'), 0)
499
497 avail_revs = set()
500 avail_revs = set()
498 avail_show = []
501 avail_show = []
499 c.cs_branch_name = c.cs_ref_name
502 c.cs_branch_name = c.cs_ref_name
@@ -563,6 +566,14 b' class PullrequestsController(base.BaseRe'
563 except ChangesetDoesNotExistError:
566 except ChangesetDoesNotExistError:
564 c.update_msg = _('Error: some changesets not found when displaying pull request from %s.') % c.cs_rev
567 c.update_msg = _('Error: some changesets not found when displaying pull request from %s.') % c.cs_rev
565
568
569 if rev_limit:
570 if len(avail_revs) - 1 > rev_limit:
571 c.update_msg = _('%d additional changesets are not shown.') % (len(avail_revs) - 1)
572 avail_show = []
573 elif len(avail_show) - 1 > rev_limit:
574 c.update_msg = _('%d changesets available for merging are not shown.') % (len(avail_show) - len(avail_revs))
575 avail_show = sorted(avail_revs, reverse=True)
576
566 c.avail_revs = avail_revs
577 c.avail_revs = avail_revs
567 c.avail_cs = [org_scm_instance.get_changeset(r) for r in avail_show]
578 c.avail_cs = [org_scm_instance.get_changeset(r) for r in avail_show]
568 c.avail_jsdata = graph_data(org_scm_instance, avail_show)
579 c.avail_jsdata = graph_data(org_scm_instance, avail_show)
@@ -8,8 +8,8 b' msgstr ""'
8 "MIME-Version: 1.0\n"
8 "MIME-Version: 1.0\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
10 "Content-Transfer-Encoding: 8bit\n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
12 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
12 "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
13
13
14 msgid "Repository not found in the filesystem"
14 msgid "Repository not found in the filesystem"
15 msgstr "Рэпазітар не знойдзены на файлавай сістэме"
15 msgstr "Рэпазітар не знойдзены на файлавай сістэме"
@@ -1414,6 +1414,12 b' msgstr "\xd0\x90\xd0\xb4\xd0\xbc\xd1\x96\xd0\xbd\xd1\x96\xd1\x81\xd1\x82\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd0\xb5 \xd0\xb3\xd1\x80\xd1\x83\xd0\xbf \xd1\x80\xd1\x8d\xd0\xbf\xd0\xb0\xd0\xb7\xd1\x96\xd1\x82\xd0\xb0\xd1\x80\xd0\xbe\xd1\x9e"'
1414 msgid "Number of Top-level Repositories"
1414 msgid "Number of Top-level Repositories"
1415 msgstr "Лік рэпазітароў верхняга ўзроўня"
1415 msgstr "Лік рэпазітароў верхняга ўзроўня"
1416
1416
1417 msgid "Type of repository to create."
1418 msgstr "Тып стваранага рэпазітара."
1419
1420 msgid "Repository URL"
1421 msgstr "URL рэпазітара"
1422
1417 msgid ""
1423 msgid ""
1418 "Keep it short and to the point. Use a README file for longer descriptions."
1424 "Keep it short and to the point. Use a README file for longer descriptions."
1419 msgstr ""
1425 msgstr ""
@@ -1423,9 +1429,6 b' msgstr ""'
1423 msgid "Optionally select a group to put this repository into."
1429 msgid "Optionally select a group to put this repository into."
1424 msgstr "Апцыянальна абраць групу, у якую змясціць дадзены рэпазітар."
1430 msgstr "Апцыянальна абраць групу, у якую змясціць дадзены рэпазітар."
1425
1431
1426 msgid "Type of repository to create."
1427 msgstr "Тып стваранага рэпазітара."
1428
1429 msgid "Landing revision"
1432 msgid "Landing revision"
1430 msgstr "Рэвізія для выгрузкі"
1433 msgstr "Рэвізія для выгрузкі"
1431
1434
@@ -1529,13 +1532,6 b' msgstr "\xd0\x9f\xd0\xb0\xd1\x86\xd0\xb2\xd0\xb5\xd1\x80\xd0\xb4\xd0\xb7\xd1\x96\xd1\x86\xd0\xb5 \xd1\x81\xd0\xbf\xd0\xb0\xd0\xbc\xd0\xbf\xd0\xbe\xd1\x9e\xd0\xba\xd1\x83 \xd0\xb7\xd0\xbc\xd0\xb5\xd0\xbd \xd0\xb7 \xd0\xb0\xd0\xb4\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb0\xd0\xb3\xd0\xb0 \xd1\x80\xd1\x8d\xd0\xbf\xd0\xb0\xd0\xb7\xd1\x96\xd1\x82\xd0\xb0\xd1\x80\xd0\xb0."'
1529 msgid "Remote repository"
1532 msgid "Remote repository"
1530 msgstr "Аддалены рэпазітар"
1533 msgstr "Аддалены рэпазітар"
1531
1534
1532 msgid "Repository URL"
1533 msgstr "URL рэпазітара"
1534
1535 msgid "Default revision for files page, downloads, whoosh and readme"
1536 msgstr ""
1537 "Рэвізія па змоўчанні, з якой будзе рабіцца выгрузка файлаў пры спампоўцы"
1538
1539 msgid "Change owner of this repository."
1535 msgid "Change owner of this repository."
1540 msgstr "Змяніць уладальніка рэпазітара."
1536 msgstr "Змяніць уладальніка рэпазітара."
1541
1537
@@ -1891,11 +1887,11 b' msgstr "\xd0\x9d\xd1\x8f\xd0\xbc\xd0\xb0 \xd1\x81\xd1\x83\xd0\xbf\xd0\xb0\xd0\xb4\xd0\xb7\xd0\xb5\xd0\xbd\xd0\xbd\xd1\x8f\xd1\x9e"'
1891 msgid "Open New Pull Request from {0}"
1887 msgid "Open New Pull Request from {0}"
1892 msgstr "Стварыць новы pull-запыт з {0}"
1888 msgstr "Стварыць новы pull-запыт з {0}"
1893
1889
1894 msgid "Open New Pull Request for {0} &rarr; {1}"
1890 msgid "Open New Pull Request for {0}"
1895 msgstr "Стварыць новы pull-запыт для {0} &rarr; {1}"
1891 msgstr "Стварыць новы pull-запыт для {0}"
1896
1892
1897 msgid "Show Selected Changesets {0} &rarr; {1}"
1893 msgid "Show Selected Changesets {0}"
1898 msgstr "Паказаць выбраныя наборы змен: {0} &rarr; {1}"
1894 msgstr "Паказаць выбраныя наборы змен {0}"
1899
1895
1900 msgid "Selection Link"
1896 msgid "Selection Link"
1901 msgstr "Спасылка выбару"
1897 msgstr "Спасылка выбару"
@@ -958,8 +958,8 b' msgstr "Es gibt bereits ein Repository m'
958
958
959 msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
959 msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
960 msgstr ""
960 msgstr ""
961 "Es gibt bereits ein Repository mit \"%(repo)s\" in der Gruppe \"%(group)s"
961 "Es gibt bereits ein Repository mit \"%(repo)s\" in der Gruppe "
962 "\""
962 "\"%(group)s\""
963
963
964 msgid "Repository group with name \"%(repo)s\" already exists"
964 msgid "Repository group with name \"%(repo)s\" already exists"
965 msgstr "Eine Repositorygruppe mit dem Namen \"%(repo)s\" existiert bereits"
965 msgstr "Eine Repositorygruppe mit dem Namen \"%(repo)s\" existiert bereits"
@@ -1615,6 +1615,9 b' msgstr ""'
1615 "untergeordneten Elemente, einschließlich nicht-privater Repositories und "
1615 "untergeordneten Elemente, einschließlich nicht-privater Repositories und "
1616 "anderer Gruppen, falls ausgewählt."
1616 "anderer Gruppen, falls ausgewählt."
1617
1617
1618 msgid "Type name of user"
1619 msgstr "Typname des Benutzers"
1620
1618 msgid "Remove this group"
1621 msgid "Remove this group"
1619 msgstr "Diese Gruppe löschen"
1622 msgstr "Diese Gruppe löschen"
1620
1623
@@ -1630,9 +1633,15 b' msgstr "Repositorygruppenverwaltung"'
1630 msgid "Number of Top-level Repositories"
1633 msgid "Number of Top-level Repositories"
1631 msgstr "Anzahl der Repositories oberster Ebene"
1634 msgstr "Anzahl der Repositories oberster Ebene"
1632
1635
1636 msgid "Type of repository to create."
1637 msgstr "Repository Typ der erstellt werden soll."
1638
1633 msgid "Clone remote repository"
1639 msgid "Clone remote repository"
1634 msgstr "Entferntes Repository clonen"
1640 msgstr "Entferntes Repository clonen"
1635
1641
1642 msgid "Repository URL"
1643 msgstr "Repository URL"
1644
1636 msgid ""
1645 msgid ""
1637 "Optional: URL of a remote repository. If set, the repository will be "
1646 "Optional: URL of a remote repository. If set, the repository will be "
1638 "created as a clone from this URL."
1647 "created as a clone from this URL."
@@ -1651,9 +1660,6 b' msgstr ""'
1651 "Wähle bei Bedarf eine Gruppe, der dieses Repository zugeordnet werden "
1660 "Wähle bei Bedarf eine Gruppe, der dieses Repository zugeordnet werden "
1652 "soll."
1661 "soll."
1653
1662
1654 msgid "Type of repository to create."
1655 msgstr "Repository Typ der erstellt werden soll."
1656
1657 msgid "Landing revision"
1663 msgid "Landing revision"
1658 msgstr "Start Revision"
1664 msgstr "Start Revision"
1659
1665
@@ -1794,27 +1800,9 b' msgstr "Best\xc3\xa4tige die Abholung von \xc3\x84nderungen vom entfernten Repository."'
1794 msgid "This repository does not have a remote repository URL."
1800 msgid "This repository does not have a remote repository URL."
1795 msgstr "Für dieses Repository ist keine nicht-lokale URL angegeben."
1801 msgstr "Für dieses Repository ist keine nicht-lokale URL angegeben."
1796
1802
1797 msgid ""
1798 "In case this repository is renamed or moved into another group the "
1799 "repository URL changes.\n"
1800 " Using the above permanent URL guarantees "
1801 "that this repository always will be accessible on that URL.\n"
1802 " This is useful for CI systems, or any "
1803 "other cases that you need to hardcode the URL into a 3rd party service."
1804 msgstr ""
1805 "Falls dieses Repository umbenannt oder in eine andere Gruppe verschoben "
1806 "wird, ändert sich seine URL.\n"
1807 "Die Verwendung der permanenten URL garantiert, dass dieses Repository "
1808 "immer über diese URL erreichbar sein wird.\n"
1809 "Dies ist insbesondere für CI-Systeme oder in Fällen nützlich, in denen "
1810 "die URL des Repositories bei Dritten dauerhaft eingetragen wird."
1811
1812 msgid "Remote repository"
1803 msgid "Remote repository"
1813 msgstr "Entferntes Repository"
1804 msgstr "Entferntes Repository"
1814
1805
1815 msgid "Repository URL"
1816 msgstr "Repository URL"
1817
1818 msgid ""
1806 msgid ""
1819 "Optional: URL of a remote repository. If set, the repository can be "
1807 "Optional: URL of a remote repository. If set, the repository can be "
1820 "pulled from this URL."
1808 "pulled from this URL."
@@ -1822,12 +1810,6 b' msgstr ""'
1822 "Optional: URL eines entfernten Repositories. Falls gesetzt, dann kann das "
1810 "Optional: URL eines entfernten Repositories. Falls gesetzt, dann kann das "
1823 "Repository von dieser URL bezogen werden."
1811 "Repository von dieser URL bezogen werden."
1824
1812
1825 msgid "Default revision for files page, downloads, whoosh and readme"
1826 msgstr "Standardrevision für Dateiseite, Downloads, Whoosh und Readme"
1827
1828 msgid "Type name of user"
1829 msgstr "Typname des Benutzers"
1830
1831 msgid "Change owner of this repository."
1813 msgid "Change owner of this repository."
1832 msgstr "Besitzer des Repositorys ändern."
1814 msgstr "Besitzer des Repositorys ändern."
1833
1815
@@ -2496,8 +2478,5 b' msgstr "Schnelleinstieg"'
2496 msgid "Add or upload files directly via Kallithea"
2478 msgid "Add or upload files directly via Kallithea"
2497 msgstr "Dateien direkt über Kallithea hinzufügen oder hochladen"
2479 msgstr "Dateien direkt über Kallithea hinzufügen oder hochladen"
2498
2480
2499 msgid "Readme file from revision %s:%s"
2500 msgstr "Liesmich-Datei von Revision %s:%s"
2501
2502 msgid "Download %s as %s"
2481 msgid "Download %s as %s"
2503 msgstr "%s als %s herunterladen"
2482 msgstr "%s als %s herunterladen"
@@ -577,6 +577,13 b' msgstr "\xce\x94\xce\xb7\xce\xbc\xce\xb9\xce\xbf\xcf\x85\xcf\x81\xce\xb3\xce\xae\xce\xb8\xce\xb7\xce\xba\xce\xb5 \xce\xb7 \xce\xb5\xcf\x81\xce\xb3\xce\xb1\xcf\x83\xce\xaf\xce\xb1 \xcf\x84\xce\xb7\xcf\x82 \xce\xb1\xcf\x80\xce\xbf\xcf\x83\xcf\x84\xce\xbf\xce\xbb\xce\xae\xcf\x82 \xce\xb7\xce\xbb\xce\xb5\xce\xba\xcf\x84\xcf\x81\xce\xbf\xce\xbd\xce\xb9\xce\xba\xce\xbf\xcf\x8d \xcf\x84\xce\xb1\xcf\x87\xcf\x85\xce\xb4\xcf\x81\xce\xbf\xce\xbc\xce\xb5\xce\xaf\xce\xbf\xcf\x85"'
577 msgid "Hook already exists"
577 msgid "Hook already exists"
578 msgstr "Το άγκιστρο υπάρχει ήδη"
578 msgstr "Το άγκιστρο υπάρχει ήδη"
579
579
580 msgid ""
581 "Hook names with \".kallithea_\" are reserved for internal use. Please use "
582 "another hook name."
583 msgstr ""
584 "Άγκιστρα με το όνομα \".kallithea_\" είναι δεσμευμένα για εσωτερική "
585 "χρήση. Παρακαλώ δώστε άλλο όνομα στο άγκιστρο."
586
580 msgid "Added new hook"
587 msgid "Added new hook"
581 msgstr "Προσθήκη νέου άγκιστρου"
588 msgstr "Προσθήκη νέου άγκιστρου"
582
589
@@ -665,6 +672,12 b' msgstr ""'
665 msgid "No changes detected"
672 msgid "No changes detected"
666 msgstr "Δεν εντοπίστηκαν αλλαγές"
673 msgstr "Δεν εντοπίστηκαν αλλαγές"
667
674
675 msgid "Show whitespace changes"
676 msgstr "Εμφάνιση αλλαγής κενού"
677
678 msgid "Ignore whitespace changes"
679 msgstr "Αγνόηση αλλαγής κενού"
680
668 msgid "Increase diff context to %(num)s lines"
681 msgid "Increase diff context to %(num)s lines"
669 msgstr "Αύξηση του diff πλαισίου σε %(num)s γραμμές"
682 msgstr "Αύξηση του diff πλαισίου σε %(num)s γραμμές"
670
683
@@ -782,6 +795,54 b' msgstr "chmod"'
782 msgid "SSH key is missing"
795 msgid "SSH key is missing"
783 msgstr "Το κλειδί SSH λείπει"
796 msgstr "Το κλειδί SSH λείπει"
784
797
798 msgid ""
799 "Invalid SSH key - it must have both a key type and a base64 part, like "
800 "'ssh-rsa ASRNeaZu4FA...xlJp='"
801 msgstr ""
802 "Άκυρο κλειδί SSH - πρέπει να έχει έναν τύπο κλειδιού καθώς και ένα τμήμα "
803 "base64, όπως \"ssh-rsa ASRNeaZu4FA ... xlJp =\""
804
805 msgid ""
806 "Invalid SSH key - it must start with key type 'ssh-rsa', 'ssh-dss', 'ssh-"
807 "ed448', or 'ssh-ed25519'"
808 msgstr ""
809 "Άκυρο κλειδί SSH - πρέπει να ξεκινά με τύπο κλειδιού 'ssh-rsa',ssh-"
810 "dss','ssh-ed448' ή 'ssh-ed25519'"
811
812 msgid "Invalid SSH key - unexpected characters in base64 part %r"
813 msgstr "Άκυρο κλειδί SSH - μη αναμενόμενοι χαρακτήρες στο τμήμα base64 %r"
814
815 msgid ""
816 "Invalid SSH key - base64 part %r seems truncated (it can't be decoded)"
817 msgstr ""
818 "Άκυρο κλειδί SSH - το base64 μέρος %r φαίνεται κομμένο (δεν μπορεί να "
819 "αποκωδικοποιηθεί)"
820
821 msgid ""
822 "Invalid SSH key - base64 part %r seems truncated (it contains a partial "
823 "string length)"
824 msgstr ""
825 "Άκυρο κλειδί SSH - το base64 μέρος %r φαίνεται κομμένο (περιέχει ένα "
826 "μερικό μήκος συμβολοσειράς)"
827
828 msgid ""
829 "Invalid SSH key - base64 part %r seems truncated (it is too short for "
830 "declared string length %s)"
831 msgstr ""
832 "Άκυρο κλειδί SSH - το τμήμα base64 %r φαίνεται να είναι κομμένο (είναι "
833 "πολύ μικρό για το δηλωμένο μήκος συμβολοσειράς %s)"
834
835 msgid ""
836 "Invalid SSH key - base64 part %r seems truncated (it contains too few "
837 "strings for a %s key)"
838 msgstr ""
839 "Άκυρο κλειδί SSH - το base64 τμήμα %r φαίνεται να είναι περικομμένο "
840 "(περιέχει πολύ λίγες συμβολοσειρές για ένα κλειδί %s)"
841
842 msgid "Invalid SSH key - it is a %s key but the base64 part contains %r"
843 msgstr ""
844 "Άκυρο κλειδί SSH - είναι ένα κλειδί %s αλλά το base64 μέρος περιέχει %r"
845
785 msgid "%d year"
846 msgid "%d year"
786 msgid_plural "%d years"
847 msgid_plural "%d years"
787 msgstr[0] "%d έτος"
848 msgstr[0] "%d έτος"
@@ -935,9 +996,30 b' msgstr "\xce\x95\xce\xb9\xcf\x83\xce\xb1\xce\xb3\xce\xac\xce\xb3\xce\xb5\xcf\x84\xce\xb5 %(min)i \xcf\x87\xce\xb1\xcf\x81\xce\xb1\xce\xba\xcf\x84\xce\xae\xcf\x81\xce\xb5\xcf\x82 \xce\xae \xcf\x80\xce\xb5\xcf\x81\xce\xb9\xcf\x83\xcf\x83\xcf\x8c\xcf\x84\xce\xb5\xcf\x81\xce\xbf\xcf\x85\xcf\x82"'
935 msgid "Name must not contain only digits"
996 msgid "Name must not contain only digits"
936 msgstr "Το όνομα δεν πρέπει να περιέχει μόνο ψηφία"
997 msgstr "Το όνομα δεν πρέπει να περιέχει μόνο ψηφία"
937
998
999 msgid ""
1000 "[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
1001 "%(branch)s by %(cs_author_username)s"
1002 msgstr ""
1003 "[Σχόλιο] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" στο "
1004 "%(branch)s από %(cs_author_username)s"
1005
938 msgid "New user %(new_username)s registered"
1006 msgid "New user %(new_username)s registered"
939 msgstr "Καταχωρήθηκε νέος χρήστης %(new_username)s"
1007 msgstr "Καταχωρήθηκε νέος χρήστης %(new_username)s"
940
1008
1009 msgid ""
1010 "[Review] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1011 "%(pr_source_branch)s by %(pr_owner_username)s"
1012 msgstr ""
1013 "[Κριτική] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" στο "
1014 "%(pr_source_branch)s από %(pr_owner_username)s"
1015
1016 msgid ""
1017 "[Comment] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1018 "%(pr_source_branch)s by %(pr_owner_username)s"
1019 msgstr ""
1020 "[Σχόλιο] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" στο "
1021 "%(pr_source_branch)s από %(pr_owner_username)s"
1022
941 msgid "Closing"
1023 msgid "Closing"
942 msgstr "Κλείσιμο"
1024 msgstr "Κλείσιμο"
943
1025
@@ -1103,6 +1185,11 b' msgstr "\xce\x97 \xce\xbf\xce\xbc\xce\xac\xce\xb4\xce\xb1 \xce\xb1\xcf\x80\xce\xbf\xce\xb8\xce\xb5\xcf\x84\xce\xb7\xcf\x81\xce\xaf\xce\xbf\xcf\x85 \xce\xbc\xce\xb5 \xcf\x84\xce\xbf \xcf\x8c\xce\xbd\xce\xbf\xce\xbc\xce\xb1 \\"%(repo)s\\" \xcf\x85\xcf\x80\xce\xac\xcf\x81\xcf\x87\xce\xb5\xce\xb9 \xce\xae\xce\xb4\xce\xb7"'
1103 msgid "Invalid repository URL"
1185 msgid "Invalid repository URL"
1104 msgstr "Μη έγκυρη διεύθυνση URL αποθετηρίου"
1186 msgstr "Μη έγκυρη διεύθυνση URL αποθετηρίου"
1105
1187
1188 msgid "Invalid repository URL. It must be a valid http, https, or ssh URL"
1189 msgstr ""
1190 "Μη έγκυρο αποθετήριο URL. Πρέπει να είναι μια έγκυρη http, https ή ssh "
1191 "διεύθυνση URL"
1192
1106 msgid "Fork has to be the same type as parent"
1193 msgid "Fork has to be the same type as parent"
1107 msgstr "Ο κλώνος πρέπει να έχει τον ίδιο τύπο με τον γονέα του"
1194 msgstr "Ο κλώνος πρέπει να έχει τον ίδιο τύπο με τον γονέα του"
1108
1195
@@ -1823,6 +1910,9 b' msgstr ""'
1823 "συμπεριλαμβανομένων των μη ιδιωτικών αποθετηρίων και άλλων ομάδων, εάν "
1910 "συμπεριλαμβανομένων των μη ιδιωτικών αποθετηρίων και άλλων ομάδων, εάν "
1824 "επιλεγεί."
1911 "επιλεγεί."
1825
1912
1913 msgid "Type name of user"
1914 msgstr "Πληκτρολογήστε το όνομα του χρήστη"
1915
1826 msgid "Remove this group"
1916 msgid "Remove this group"
1827 msgstr "Κατάργηση αυτής της ομάδας"
1917 msgstr "Κατάργηση αυτής της ομάδας"
1828
1918
@@ -1838,9 +1928,15 b' msgstr "\xce\x94\xce\xb9\xce\xb1\xcf\x87\xce\xb5\xce\xaf\xcf\x81\xce\xb9\xcf\x83\xce\xb7 \xce\x9f\xce\xbc\xce\xac\xce\xb4\xcf\x89\xce\xbd \xce\x91\xcf\x80\xce\xbf\xce\xb8\xce\xb5\xcf\x84\xce\xb7\xcf\x81\xce\xaf\xce\xbf\xcf\x85"'
1838 msgid "Number of Top-level Repositories"
1928 msgid "Number of Top-level Repositories"
1839 msgstr "Αριθμός αποθετηρίων ανώτατου επιπέδου"
1929 msgstr "Αριθμός αποθετηρίων ανώτατου επιπέδου"
1840
1930
1931 msgid "Type of repository to create."
1932 msgstr "Τύπος αποθετηρίου προς δημιουργία."
1933
1841 msgid "Clone remote repository"
1934 msgid "Clone remote repository"
1842 msgstr "Κλωνοποίηση απομακρυσμένου αποθετηρίου"
1935 msgstr "Κλωνοποίηση απομακρυσμένου αποθετηρίου"
1843
1936
1937 msgid "Repository URL"
1938 msgstr "URL Αποθετηρίου"
1939
1844 msgid ""
1940 msgid ""
1845 "Optional: URL of a remote repository. If set, the repository will be "
1941 "Optional: URL of a remote repository. If set, the repository will be "
1846 "created as a clone from this URL."
1942 "created as a clone from this URL."
@@ -1858,9 +1954,6 b' msgid "Optionally select a group to put '
1858 msgstr ""
1954 msgstr ""
1859 "Προαιρετικά, επιλέξτε μια ομάδα για να τοποθετήσετε αυτό το αποθετήριο."
1955 "Προαιρετικά, επιλέξτε μια ομάδα για να τοποθετήσετε αυτό το αποθετήριο."
1860
1956
1861 msgid "Type of repository to create."
1862 msgstr "Τύπος αποθετηρίου προς δημιουργία."
1863
1864 msgid "Landing revision"
1957 msgid "Landing revision"
1865 msgstr "Αναθεώρηση εκφόρτωσης"
1958 msgstr "Αναθεώρηση εκφόρτωσης"
1866
1959
@@ -2008,29 +2101,9 b' msgstr ""'
2008 msgid "Permanent URL"
2101 msgid "Permanent URL"
2009 msgstr "Μόνιμη διεύθυνση URL"
2102 msgstr "Μόνιμη διεύθυνση URL"
2010
2103
2011 msgid ""
2012 "In case this repository is renamed or moved into another group the "
2013 "repository URL changes.\n"
2014 " Using the above permanent URL guarantees "
2015 "that this repository always will be accessible on that URL.\n"
2016 " This is useful for CI systems, or any "
2017 "other cases that you need to hardcode the URL into a 3rd party service."
2018 msgstr ""
2019 "Η διεύθυνση URL του αποθετηρίου αλλάζει όταν αυτό μετονομαστεί ή "
2020 "μετακινηθεί σε άλλη ομάδα.\n"
2021 "                               Η χρήση της παραπάνω μόνιμης διεύθυνσης "
2022 "URL εγγυάται ότι αυτό το αποθετήριο θα είναι πάντα προσβάσιμο σε αυτήν τη "
2023 "διεύθυνση URL.\n"
2024 "                               Αυτό είναι χρήσιμο για συστήματα CI ή για "
2025 "άλλες περιπτώσεις που χρειάζεστε να κωδικοποιήσετε τη διεύθυνση URL σε "
2026 "κάποια υπηρεσία τρίτου μέρους."
2027
2028 msgid "Remote repository"
2104 msgid "Remote repository"
2029 msgstr "Απομακρυσμένο αποθετήριο"
2105 msgstr "Απομακρυσμένο αποθετήριο"
2030
2106
2031 msgid "Repository URL"
2032 msgstr "URL Αποθετηρίου"
2033
2034 msgid ""
2107 msgid ""
2035 "Optional: URL of a remote repository. If set, the repository can be "
2108 "Optional: URL of a remote repository. If set, the repository can be "
2036 "pulled from this URL."
2109 "pulled from this URL."
@@ -2038,13 +2111,6 b' msgstr ""'
2038 "Προαιρετικό: Διεύθυνση URL ενός απομακρυσμένου αποθετηρίου. Εάν οριστεί, "
2111 "Προαιρετικό: Διεύθυνση URL ενός απομακρυσμένου αποθετηρίου. Εάν οριστεί, "
2039 "το αποθετήριο μπορεί να τραβηχτεί από αυτήν τη διεύθυνση URL."
2112 "το αποθετήριο μπορεί να τραβηχτεί από αυτήν τη διεύθυνση URL."
2040
2113
2041 msgid "Default revision for files page, downloads, whoosh and readme"
2042 msgstr ""
2043 "Προεπιλεγμένη αναθεώρηση για τη σελίδα αρχείων, λήψεων, Whoosh και readme"
2044
2045 msgid "Type name of user"
2046 msgstr "Πληκτρολογήστε το όνομα του χρήστη"
2047
2048 msgid "Change owner of this repository."
2114 msgid "Change owner of this repository."
2049 msgstr "Αλλάξτε τον κάτοχο αυτού του αποθετηρίου."
2115 msgstr "Αλλάξτε τον κάτοχο αυτού του αποθετηρίου."
2050
2116
@@ -2136,6 +2202,9 b' msgstr ""'
2136 msgid "Save Settings"
2202 msgid "Save Settings"
2137 msgstr "Αποθήκευση Ρυθμίσεων"
2203 msgstr "Αποθήκευση Ρυθμίσεων"
2138
2204
2205 msgid "Custom Hooks are not enabled"
2206 msgstr "Τα προσαρμοσμένα άγκιστρα δεν είναι ενεργά"
2207
2139 msgid "Failed to remove hook"
2208 msgid "Failed to remove hook"
2140 msgstr "Απέτυχε η αφαίρεση γάντζου"
2209 msgstr "Απέτυχε η αφαίρεση γάντζου"
2141
2210
@@ -2164,6 +2233,18 b' msgstr ""'
2164 msgid "Install Git hooks"
2233 msgid "Install Git hooks"
2165 msgstr "Εγκατάσταση Git hooks"
2234 msgstr "Εγκατάσταση Git hooks"
2166
2235
2236 msgid "Install and overwrite Git hooks"
2237 msgstr "Εγκατάσταση και επανεγγραφή Git hooks"
2238
2239 msgid ""
2240 "Install Kallithea's internal hooks for all Git repositories. Existing "
2241 "hooks that don't seem to come from Kallithea will be disabled by renaming "
2242 "to .bak extension."
2243 msgstr ""
2244 "Εγκαταστήστε τα εσωτερικά hooks της Kallithea για όλα τα αποθετήρια Git. "
2245 "Τα υπάρχοντα hooks που δεν φαίνεται να προέρχονται από την Kallithea θα "
2246 "απενεργοποιηθούν με τη μετονομασία σε επέκταση .bak."
2247
2167 msgid "Rescan Repositories"
2248 msgid "Rescan Repositories"
2168 msgstr "Επανασάρωση αποθετηρίων"
2249 msgstr "Επανασάρωση αποθετηρίων"
2169
2250
@@ -2665,11 +2746,11 b' msgstr "\xce\x94\xce\xb5\xce\xbd \xcf\x85\xcf\x80\xce\xac\xcf\x81\xcf\x87\xce\xbf\xcf\x85\xce\xbd \xce\xb1\xcf\x81\xcf\x87\xce\xb5\xce\xaf\xce\xb1 \xcf\x80\xce\xbf\xcf\x85 \xce\xbd\xce\xb1 \xcf\x84\xce\xb1\xce\xb9\xcf\x81\xce\xb9\xce\xac\xce\xb6\xce\xbf\xcf\x85\xce\xbd"'
2665 msgid "Open New Pull Request from {0}"
2746 msgid "Open New Pull Request from {0}"
2666 msgstr "Άνοιγμα νέας αίτησης έλξης από {0}"
2747 msgstr "Άνοιγμα νέας αίτησης έλξης από {0}"
2667
2748
2668 msgid "Open New Pull Request for {0} &rarr; {1}"
2749 msgid "Open New Pull Request for {0}"
2669 msgstr "Άνοιγμα νέου αιτήματος έλξης για {0} &rarr; {1}"
2750 msgstr "Άνοιγμα νέου αιτήματος έλξης για {0}"
2670
2751
2671 msgid "Show Selected Changesets {0} &rarr; {1}"
2752 msgid "Show Selected Changesets {0}"
2672 msgstr "Εμφάνιση Επιλεγμένων Σετ Αλλαγών {0} &rarr; {1}"
2753 msgstr "Εμφάνιση Επιλεγμένων Σετ Αλλαγών {0}"
2673
2754
2674 msgid "Selection Link"
2755 msgid "Selection Link"
2675 msgstr "Σύνδεσμος Επιλογής"
2756 msgstr "Σύνδεσμος Επιλογής"
@@ -2772,6 +2853,9 b' msgstr ""'
2772 msgid "Changeset status: %s by %s"
2853 msgid "Changeset status: %s by %s"
2773 msgstr "Κατάσταση σετ αλλαγών: %s από %s"
2854 msgstr "Κατάσταση σετ αλλαγών: %s από %s"
2774
2855
2856 msgid "(No commit message)"
2857 msgstr "(Χωρίς κείμενο commit)"
2858
2775 msgid "Expand commit message"
2859 msgid "Expand commit message"
2776 msgstr "Ανάπτυξη μηνύματος commit"
2860 msgstr "Ανάπτυξη μηνύματος commit"
2777
2861
@@ -2934,6 +3018,12 b' msgstr "\xce\x95\xce\xbc\xcf\x86\xce\xac\xce\xbd\xce\xb9\xcf\x83\xce\xb7 \xcf\x80\xce\xbb\xce\xae\xcf\x81\xce\xbf\xcf\x85\xcf\x82 \xce\xb4\xce\xb9\xce\xb1\xcf\x86\xce\xbf\xcf\x81\xce\xac\xcf\x82 \xce\xb3\xce\xb9\xce\xb1 \xce\xb1\xcf\x85\xcf\x84\xcf\x8c \xcf\x84\xce\xbf \xce\xb1\xcf\x81\xcf\x87\xce\xb5\xce\xaf\xce\xbf"'
2934 msgid "Show full side-by-side diff for this file"
3018 msgid "Show full side-by-side diff for this file"
2935 msgstr "Εμφάνιση πλήρους διαφοράς δίπλα-δίπλα για αυτό το αρχείο"
3019 msgstr "Εμφάνιση πλήρους διαφοράς δίπλα-δίπλα για αυτό το αρχείο"
2936
3020
3021 msgid "Raw diff for this file"
3022 msgstr "Διαφορές για αυτό το αρχείο"
3023
3024 msgid "Download diff for this file"
3025 msgstr "Μεταφόρτωση διαφοράς για αυτό το αρχείο"
3026
2937 msgid "Show inline comments"
3027 msgid "Show inline comments"
2938 msgstr "Εμφάνιση ενσωματωμένων σχολίων"
3028 msgstr "Εμφάνιση ενσωματωμένων σχολίων"
2939
3029
@@ -3620,8 +3710,5 b' msgstr "\xce\x8f\xce\xb8\xce\xb7\xcf\x83\xce\xb7 \xce\xbd\xce\xad\xce\xbf\xcf\x85 \xce\xb1\xcf\x80\xce\xbf\xce\xb8\xce\xb5\xcf\x84\xce\xb7\xcf\x81\xce\xaf\xce\xbf\xcf\x85"'
3620 msgid "Existing repository?"
3710 msgid "Existing repository?"
3621 msgstr "Υπάρχον αποθετήριο;"
3711 msgstr "Υπάρχον αποθετήριο;"
3622
3712
3623 msgid "Readme file from revision %s:%s"
3624 msgstr "Αρχείο Readme από την αναθεώρηση %s:%s"
3625
3626 msgid "Download %s as %s"
3713 msgid "Download %s as %s"
3627 msgstr "Λήψη %s ως %s"
3714 msgstr "Λήψη %s ως %s"
@@ -13,6 +13,9 b' msgstr ""'
13 msgid "There are no changesets yet"
13 msgid "There are no changesets yet"
14 msgstr "Aún no hay cambios"
14 msgstr "Aún no hay cambios"
15
15
16 msgid "SSH access is disabled."
17 msgstr "El acceso mediante SSH está desactivado."
18
16 msgid "None"
19 msgid "None"
17 msgstr "Ninguno"
20 msgstr "Ninguno"
18
21
@@ -77,6 +80,9 b' msgstr "%s%s canal"'
77 msgid "Click here to add new file"
80 msgid "Click here to add new file"
78 msgstr "Haga clic aquí para añadir un archivo nuevo"
81 msgstr "Haga clic aquí para añadir un archivo nuevo"
79
82
83 msgid "There are no files yet."
84 msgstr "Aún no hay archivos."
85
80 msgid "%s at %s"
86 msgid "%s at %s"
81 msgstr "%s en %s"
87 msgstr "%s en %s"
82
88
@@ -211,6 +217,9 b' msgstr "Petici\xc3\xb3n pull actualizada"'
211 msgid "Successfully deleted pull request"
217 msgid "Successfully deleted pull request"
212 msgstr "Petición pull eliminada correctamente"
218 msgstr "Petición pull eliminada correctamente"
213
219
220 msgid "Revision %s not found in %s"
221 msgstr "No se ha encontrado la revisión %s en %s"
222
214 msgid "This pull request has already been merged to %s."
223 msgid "This pull request has already been merged to %s."
215 msgstr "La petición pull ya ha sido incluida a %s."
224 msgstr "La petición pull ya ha sido incluida a %s."
216
225
@@ -238,7 +238,7 b' msgid "Bookmarks"'
238 msgstr "Signets"
238 msgstr "Signets"
239
239
240 msgid "Error creating pull request: %s"
240 msgid "Error creating pull request: %s"
241 msgstr "Erreur de création de la demande de pull : %s"
241 msgstr "Erreur de création de la demande de pull : %s"
242
242
243 msgid "Error occurred while creating pull request"
243 msgid "Error occurred while creating pull request"
244 msgstr "Une erreur est survenue durant la création de la pull request"
244 msgstr "Une erreur est survenue durant la création de la pull request"
@@ -286,7 +286,7 b' msgid "No additional changesets found fo'
286 msgstr "Pas de changeset additionnel trouvé pour cette requête de pull."
286 msgstr "Pas de changeset additionnel trouvé pour cette requête de pull."
287
287
288 msgid "Note: Branch %s has another head: %s."
288 msgid "Note: Branch %s has another head: %s."
289 msgstr "Note : La branche %s a une autre tête : %s."
289 msgstr "Note : La branche %s a une autre tête : %s."
290
290
291 msgid "Git pull requests don't support iterating yet."
291 msgid "Git pull requests don't support iterating yet."
292 msgstr ""
292 msgstr ""
@@ -371,7 +371,7 b' msgstr "Une erreur est survenue durant la mise \xc3\xa0 jour du gist %s"'
371
371
372 msgid "You can't edit this user since it's crucial for entire application"
372 msgid "You can't edit this user since it's crucial for entire application"
373 msgstr ""
373 msgstr ""
374 "Vous ne pouvez pas éditer cet utilisateur ; il est nécessaire pour le bon "
374 "Vous ne pouvez pas éditer cet utilisateur ; il est nécessaire pour le bon "
375 "fonctionnement de l’application"
375 "fonctionnement de l’application"
376
376
377 msgid "Your account was updated successfully"
377 msgid "Your account was updated successfully"
@@ -386,7 +386,7 b' msgstr ""'
386 "l'utilisateur"
386 "l'utilisateur"
387
387
388 msgid "Added email %s to user"
388 msgid "Added email %s to user"
389 msgstr "L’e-mail « %s » a été ajouté à l’utilisateur"
389 msgstr "L’e-mail « %s » a été ajouté à l’utilisateur"
390
390
391 msgid "An error occurred during email saving"
391 msgid "An error occurred during email saving"
392 msgstr "Une erreur est survenue durant l’enregistrement de l’e-mail"
392 msgstr "Une erreur est survenue durant l’enregistrement de l’e-mail"
@@ -561,7 +561,7 b' msgstr ""'
561 "l'application"
561 "l'application"
562
562
563 msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
563 msgid "Repositories successfully rescanned. Added: %s. Removed: %s."
564 msgstr "Dépôts ré-analysés avec succès. Ajouté: %s. Supprimé: %s."
564 msgstr "Dépôts ré-analysés avec succès. Ajouté : %s. Supprimé : %s."
565
565
566 msgid "Invalidated %s repositories"
566 msgid "Invalidated %s repositories"
567 msgstr "%s dépôts invalidés"
567 msgstr "%s dépôts invalidés"
@@ -590,8 +590,8 b' msgid ""'
590 "Hook names with \".kallithea_\" are reserved for internal use. Please use "
590 "Hook names with \".kallithea_\" are reserved for internal use. Please use "
591 "another hook name."
591 "another hook name."
592 msgstr ""
592 msgstr ""
593 "Les noms de hook avec \".kallithea_\" sont réservés pour un usage interne. "
593 "Les noms de hook avec \".kallithea_\" sont réservés pour un usage "
594 "Merci de choisir un autre nom pour le hook."
594 "interne. Merci de choisir un autre nom pour le hook."
595
595
596 msgid "Added new hook"
596 msgid "Added new hook"
597 msgstr "Le nouveau hook a été ajouté"
597 msgstr "Le nouveau hook a été ajouté"
@@ -679,7 +679,7 b' msgid ""'
679 "Changeset was too big and was cut off, use diff menu to display this diff"
679 "Changeset was too big and was cut off, use diff menu to display this diff"
680 msgstr ""
680 msgstr ""
681 "Cet ensemble de changements était trop gros pour être affiché et a été "
681 "Cet ensemble de changements était trop gros pour être affiché et a été "
682 "découpé, utilisez le menu « diff » pour afficher les différences"
682 "découpé, utilisez le menu « diff » pour afficher les différences"
683
683
684 msgid "No changes detected"
684 msgid "No changes detected"
685 msgstr "Aucun changement détecté"
685 msgstr "Aucun changement détecté"
@@ -694,10 +694,10 b' msgid "Increase diff context to %(num)s '
694 msgstr "Augmenter le contexte du diff à %(num)s lignes"
694 msgstr "Augmenter le contexte du diff à %(num)s lignes"
695
695
696 msgid "Deleted branch: %s"
696 msgid "Deleted branch: %s"
697 msgstr "Branche supprimée: %s"
697 msgstr "Branche supprimée : %s"
698
698
699 msgid "Created tag: %s"
699 msgid "Created tag: %s"
700 msgstr "Étiquette créée: %s"
700 msgstr "Étiquette créée : %s"
701
701
702 msgid "Changeset %s not found"
702 msgid "Changeset %s not found"
703 msgstr "Ensemble de changements %s non trouvé"
703 msgstr "Ensemble de changements %s non trouvé"
@@ -841,18 +841,19 b' msgid ""'
841 "Invalid SSH key - base64 part %r seems truncated (it is too short for "
841 "Invalid SSH key - base64 part %r seems truncated (it is too short for "
842 "declared string length %s)"
842 "declared string length %s)"
843 msgstr ""
843 msgstr ""
844 "Clé SSH invalide – la partie base64 %r semble tronquée (elle est trop court "
844 "Clé SSH invalide – la partie base64 %r semble tronquée (elle est trop "
845 "pour la taille déclarée %s)"
845 "court pour la taille déclarée %s)"
846
846
847 msgid ""
847 msgid ""
848 "Invalid SSH key - base64 part %r seems truncated (it contains too few "
848 "Invalid SSH key - base64 part %r seems truncated (it contains too few "
849 "strings for a %s key)"
849 "strings for a %s key)"
850 msgstr ""
850 msgstr ""
851 "Clé SSH invalide – la partie base64 %r semble tronquée (elle ne contient pas "
851 "Clé SSH invalide – la partie base64 %r semble tronquée (elle ne contient "
852 "assez de parties pour une clé %s)"
852 "pas assez de parties pour une clé %s)"
853
853
854 msgid "Invalid SSH key - it is a %s key but the base64 part contains %r"
854 msgid "Invalid SSH key - it is a %s key but the base64 part contains %r"
855 msgstr "Clé SSH invalide – c'est une clé %s mais la partie base64 contient %r"
855 msgstr ""
856 "Clé SSH invalide – c'est une clé %s mais la partie base64 contient %r"
856
857
857 msgid "%d year"
858 msgid "%d year"
858 msgid_plural "%d years"
859 msgid_plural "%d years"
@@ -1019,8 +1020,8 b' msgid ""'
1019 "[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
1020 "[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
1020 "%(branch)s by %(cs_author_username)s"
1021 "%(branch)s by %(cs_author_username)s"
1021 msgstr ""
1022 msgstr ""
1022 "[Commentaire] Changeset %(short_id)s « %(message_short)s » de %(repo_name)s "
1023 "[Commentaire] Changeset %(short_id)s « %(message_short)s » de "
1023 "dans %(branch)s par %(cs_author_username)s"
1024 "%(repo_name)s dans %(branch)s par %(cs_author_username)s"
1024
1025
1025 msgid "New user %(new_username)s registered"
1026 msgid "New user %(new_username)s registered"
1026 msgstr "Nouvel utilisateur %(new_username)s enregistré"
1027 msgstr "Nouvel utilisateur %(new_username)s enregistré"
@@ -1029,14 +1030,14 b' msgid ""'
1029 "[Review] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1030 "[Review] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1030 "%(pr_source_branch)s by %(pr_owner_username)s"
1031 "%(pr_source_branch)s by %(pr_owner_username)s"
1031 msgstr ""
1032 msgstr ""
1032 "[Revue] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » depuis "
1033 "[Revue] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » depuis "
1033 "%(pr_source_branch)s par %(pr_owner_username)s"
1034 "%(pr_source_branch)s par %(pr_owner_username)s"
1034
1035
1035 msgid ""
1036 msgid ""
1036 "[Comment] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1037 "[Comment] %(repo_name)s PR %(pr_nice_id)s \"%(pr_title_short)s\" from "
1037 "%(pr_source_branch)s by %(pr_owner_username)s"
1038 "%(pr_source_branch)s by %(pr_owner_username)s"
1038 msgstr ""
1039 msgstr ""
1039 "[Commentaire] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » "
1040 "[Commentaire] %(repo_name)s PR %(pr_nice_id)s « %(pr_title_short)s » "
1040 "depuis %(pr_source_branch)s par %(pr_owner_username)s"
1041 "depuis %(pr_source_branch)s par %(pr_owner_username)s"
1041
1042
1042 msgid "Closing"
1043 msgid "Closing"
@@ -1056,10 +1057,10 b' msgid "You are not authorized to create '
1056 msgstr "Vous n'êtes pas autorisé à créer cette requête de pull"
1057 msgstr "Vous n'êtes pas autorisé à créer cette requête de pull"
1057
1058
1058 msgid "Missing changesets since the previous iteration:"
1059 msgid "Missing changesets since the previous iteration:"
1059 msgstr "Changeset manquant depuis la précédente itération :"
1060 msgstr "Changeset manquant depuis la précédente itération :"
1060
1061
1061 msgid "New changesets on %s %s since the previous iteration:"
1062 msgid "New changesets on %s %s since the previous iteration:"
1062 msgstr "Nouveau changeset sur %s %s depuis la précédente itération :"
1063 msgstr "Nouveau changeset sur %s %s depuis la précédente itération :"
1063
1064
1064 msgid "Ancestor didn't change - diff since previous iteration:"
1065 msgid "Ancestor didn't change - diff since previous iteration:"
1065 msgstr "L'ancêtre n'a pas changé - diff depuis l'itération précédente :"
1066 msgstr "L'ancêtre n'a pas changé - diff depuis l'itération précédente :"
@@ -1081,7 +1082,7 b' msgid "latest tip"'
1081 msgstr "Dernier sommet"
1082 msgstr "Dernier sommet"
1082
1083
1083 msgid "SSH key %r is invalid: %s"
1084 msgid "SSH key %r is invalid: %s"
1084 msgstr "La clé SSH %r est invalide : %s"
1085 msgstr "La clé SSH %r est invalide : %s"
1085
1086
1086 msgid "SSH key %s is already used by %s"
1087 msgid "SSH key %s is already used by %s"
1087 msgstr "La clé SSH %s est déjà utilisée par %s"
1088 msgstr "La clé SSH %s est déjà utilisée par %s"
@@ -1092,7 +1093,7 b' msgstr "Cl\xc3\xa9 SSH avec l\'empreinte %r trouv\xc3\xa9e"'
1092 msgid ""
1093 msgid ""
1093 "You can't remove this user since it is crucial for the entire application"
1094 "You can't remove this user since it is crucial for the entire application"
1094 msgstr ""
1095 msgstr ""
1095 "Vous ne pouvez pas supprimer cet utilisateur ; il est nécessaire pour le "
1096 "Vous ne pouvez pas supprimer cet utilisateur ; il est nécessaire pour le "
1096 "bon fonctionnement de l’application"
1097 "bon fonctionnement de l’application"
1097
1098
1098 msgid ""
1099 msgid ""
@@ -1100,20 +1101,20 b' msgid ""'
1100 "owners or remove those repositories: %s"
1101 "owners or remove those repositories: %s"
1101 msgstr ""
1102 msgstr ""
1102 "L’utilisateur \"%s\" possède %s dépôts et ne peut être supprimé. Changez "
1103 "L’utilisateur \"%s\" possède %s dépôts et ne peut être supprimé. Changez "
1103 "les propriétaires ou supprimez ces dépôts : %s"
1104 "les propriétaires ou supprimez ces dépôts : %s"
1104
1105
1105 msgid ""
1106 msgid ""
1106 "User \"%s\" still owns %s repository groups and cannot be removed. Switch "
1107 "User \"%s\" still owns %s repository groups and cannot be removed. Switch "
1107 "owners or remove those repository groups: %s"
1108 "owners or remove those repository groups: %s"
1108 msgstr ""
1109 msgstr ""
1109 "L’utilisateur \"%s\" possède %s groupes de dépôt et ne peut être "
1110 "L’utilisateur \"%s\" possède %s groupes de dépôt et ne peut être "
1110 "supprimé. Changez les propriétaires ou supprimez ces dépôts : %s"
1111 "supprimé. Changez les propriétaires ou supprimez ces dépôts : %s"
1111
1112
1112 msgid ""
1113 msgid ""
1113 "User \"%s\" still owns %s user groups and cannot be removed. Switch "
1114 "User \"%s\" still owns %s user groups and cannot be removed. Switch "
1114 "owners or remove those user groups: %s"
1115 "owners or remove those user groups: %s"
1115 msgstr ""
1116 msgstr ""
1116 "L’utilisateur « %s » possède %s groupes d'utilisateurs et ne peut pas "
1117 "L’utilisateur « %s » possède %s groupes d'utilisateurs et ne peut pas "
1117 "être supprimé. Changez les propriétaires de ces groupes d'utilisateurs ou "
1118 "être supprimé. Changez les propriétaires de ces groupes d'utilisateurs ou "
1118 "supprimez-les : %s"
1119 "supprimez-les : %s"
1119
1120
@@ -1134,10 +1135,10 b' msgid "Value cannot be an empty list"'
1134 msgstr "Cette valeur ne peut être une liste vide"
1135 msgstr "Cette valeur ne peut être une liste vide"
1135
1136
1136 msgid "Username \"%(username)s\" already exists"
1137 msgid "Username \"%(username)s\" already exists"
1137 msgstr "Le nom d’utilisateur « %(username)s » existe déjà"
1138 msgstr "Le nom d’utilisateur « %(username)s » existe déjà"
1138
1139
1139 msgid "Username \"%(username)s\" cannot be used"
1140 msgid "Username \"%(username)s\" cannot be used"
1140 msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
1141 msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
1141
1142
1142 msgid ""
1143 msgid ""
1143 "Username may only contain alphanumeric characters underscores, periods or "
1144 "Username may only contain alphanumeric characters underscores, periods or "
@@ -1151,13 +1152,13 b' msgid "The input is not valid"'
1151 msgstr "L'entrée n'est pas valide"
1152 msgstr "L'entrée n'est pas valide"
1152
1153
1153 msgid "Username %(username)s is not valid"
1154 msgid "Username %(username)s is not valid"
1154 msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
1155 msgstr "Le nom d’utilisateur « %(username)s » n’est pas valide"
1155
1156
1156 msgid "Invalid user group name"
1157 msgid "Invalid user group name"
1157 msgstr "Nom de groupe d'utilisateurs invalide"
1158 msgstr "Nom de groupe d'utilisateurs invalide"
1158
1159
1159 msgid "User group \"%(usergroup)s\" already exists"
1160 msgid "User group \"%(usergroup)s\" already exists"
1160 msgstr "Le groupe d'utilisateurs « %(usergroup)s» existe déjà"
1161 msgstr "Le groupe d'utilisateurs « %(usergroup)s » existe déjà"
1161
1162
1162 msgid ""
1163 msgid ""
1163 "user group name may only contain alphanumeric characters underscores, "
1164 "user group name may only contain alphanumeric characters underscores, "
@@ -1171,10 +1172,10 b' msgid "Cannot assign this group as paren'
1171 msgstr "Impossible d’assigner ce groupe en tant que parent"
1172 msgstr "Impossible d’assigner ce groupe en tant que parent"
1172
1173
1173 msgid "Group \"%(group_name)s\" already exists"
1174 msgid "Group \"%(group_name)s\" already exists"
1174 msgstr "Le groupe « %(group_name)s » existe déjà"
1175 msgstr "Le groupe « %(group_name)s » existe déjà"
1175
1176
1176 msgid "Repository with name \"%(group_name)s\" already exists"
1177 msgid "Repository with name \"%(group_name)s\" already exists"
1177 msgstr "Un dépôt portant le nom « %(group_name)s » existe déjà"
1178 msgstr "Un dépôt portant le nom « %(group_name)s » existe déjà"
1178
1179
1179 msgid "Invalid characters (non-ascii) in password"
1180 msgid "Invalid characters (non-ascii) in password"
1180 msgstr "Caractères incorrects (non-ASCII) dans le mot de passe"
1181 msgstr "Caractères incorrects (non-ASCII) dans le mot de passe"
@@ -1189,23 +1190,24 b' msgid "Invalid username or password"'
1189 msgstr "Nom d'utilisateur ou mot de passe invalide"
1190 msgstr "Nom d'utilisateur ou mot de passe invalide"
1190
1191
1191 msgid "Repository name %(repo)s is not allowed"
1192 msgid "Repository name %(repo)s is not allowed"
1192 msgstr "Le nom de dépôt « %(repo)s » n’est pas autorisé"
1193 msgstr "Le nom de dépôt « %(repo)s » n’est pas autorisé"
1193
1194
1194 msgid "Repository named %(repo)s already exists"
1195 msgid "Repository named %(repo)s already exists"
1195 msgstr "Un dépôt portant le nom « %(repo)s » existe déjà"
1196 msgstr "Un dépôt portant le nom « %(repo)s » existe déjà"
1196
1197
1197 msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
1198 msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
1198 msgstr "Le dépôt « %(repo)s » existe déjà dans le groupe « %(group)s »"
1199 msgstr "Le dépôt « %(repo)s » existe déjà dans le groupe « %(group)s »"
1199
1200
1200 msgid "Repository group with name \"%(repo)s\" already exists"
1201 msgid "Repository group with name \"%(repo)s\" already exists"
1201 msgstr "Un groupe de dépôts avec le nom « %(repo)s » existe déjà"
1202 msgstr "Un groupe de dépôts avec le nom « %(repo)s » existe déjà"
1202
1203
1203 msgid "Invalid repository URL"
1204 msgid "Invalid repository URL"
1204 msgstr "URL de dépôt invalide"
1205 msgstr "URL de dépôt invalide"
1205
1206
1206 msgid "Invalid repository URL. It must be a valid http, https, or ssh URL"
1207 msgid "Invalid repository URL. It must be a valid http, https, or ssh URL"
1207 msgstr ""
1208 msgstr ""
1208 "URL de dépôt invalide. Ce doit être une URL valide de type http, https ou ssh"
1209 "URL de dépôt invalide. Ce doit être une URL valide de type http, https ou "
1210 "ssh"
1209
1211
1210 msgid "Fork has to be the same type as parent"
1212 msgid "Fork has to be the same type as parent"
1211 msgstr "Le fork doit être du même type que le parent"
1213 msgstr "Le fork doit être du même type que le parent"
@@ -1231,7 +1233,7 b' msgid "This email address is already in '
1231 msgstr "Cette adresse e-mail est déjà enregistrée"
1233 msgstr "Cette adresse e-mail est déjà enregistrée"
1232
1234
1233 msgid "Email address \"%(email)s\" not found"
1235 msgid "Email address \"%(email)s\" not found"
1234 msgstr "L’adresse e-mail « %(email)s » n’existe pas"
1236 msgstr "L’adresse e-mail « %(email)s » n’existe pas"
1235
1237
1236 msgid ""
1238 msgid ""
1237 "The LDAP Login attribute of the CN must be specified - this is the name "
1239 "The LDAP Login attribute of the CN must be specified - this is the name "
@@ -1308,10 +1310,10 b' msgid "Stay logged in after browser rest'
1308 msgstr "Rester connecté après un redémarrage du navigateur"
1310 msgstr "Rester connecté après un redémarrage du navigateur"
1309
1311
1310 msgid "Forgot your password?"
1312 msgid "Forgot your password?"
1311 msgstr "Mot de passe oublié?"
1313 msgstr "Mot de passe oublié ?"
1312
1314
1313 msgid "Don't have an account?"
1315 msgid "Don't have an account?"
1314 msgstr "Vous n’avez pas de compte?"
1316 msgstr "Vous n’avez pas de compte ?"
1315
1317
1316 msgid "Sign In"
1318 msgid "Sign In"
1317 msgstr "Connexion"
1319 msgstr "Connexion"
@@ -1596,13 +1598,13 b' msgid "Built-in"'
1596 msgstr "Inclus"
1598 msgstr "Inclus"
1597
1599
1598 msgid "Confirm to reset this API key: %s"
1600 msgid "Confirm to reset this API key: %s"
1599 msgstr "Confirmer la remise à zéro de cette clé d'API: %s"
1601 msgstr "Confirmer la remise à zéro de cette clé d'API : %s"
1600
1602
1601 msgid "Expired"
1603 msgid "Expired"
1602 msgstr "a expiré"
1604 msgstr "a expiré"
1603
1605
1604 msgid "Confirm to remove this API key: %s"
1606 msgid "Confirm to remove this API key: %s"
1605 msgstr "Confirmer la suppression de cette clé d'API: %s"
1607 msgstr "Confirmer la suppression de cette clé d'API : %s"
1606
1608
1607 msgid "Remove"
1609 msgid "Remove"
1608 msgstr "Supprimer"
1610 msgstr "Supprimer"
@@ -1645,7 +1647,7 b' msgid "Primary"'
1645 msgstr "Primaire"
1647 msgstr "Primaire"
1646
1648
1647 msgid "Confirm to delete this email: %s"
1649 msgid "Confirm to delete this email: %s"
1648 msgstr "Veuillez confirmer la suppression de l’e-mail : %s"
1650 msgstr "Veuillez confirmer la suppression de l’e-mail : %s"
1649
1651
1650 msgid "No additional emails specified."
1652 msgid "No additional emails specified."
1651 msgstr "Pas d'adresse e-mail supplémentaires spécifiées."
1653 msgstr "Pas d'adresse e-mail supplémentaires spécifiées."
@@ -1695,7 +1697,7 b' msgid "Last Used"'
1695 msgstr "Dernière utilisation"
1697 msgstr "Dernière utilisation"
1696
1698
1697 msgid "Confirm to remove this SSH key: %s"
1699 msgid "Confirm to remove this SSH key: %s"
1698 msgstr "Confirmer la suppression de cette clé SSH: %s"
1700 msgstr "Confirmer la suppression de cette clé SSH : %s"
1699
1701
1700 msgid "No SSH keys have been added"
1702 msgid "No SSH keys have been added"
1701 msgstr "Aucune clé SSH n'a été ajoutée"
1703 msgstr "Aucune clé SSH n'a été ajoutée"
@@ -1821,7 +1823,7 b' msgid "External auth account activation"'
1821 msgstr "Activation de l'authentification externe"
1823 msgstr "Activation de l'authentification externe"
1822
1824
1823 msgid "Confirm to delete this IP address: %s"
1825 msgid "Confirm to delete this IP address: %s"
1824 msgstr "Confirmer la suppression de cette adresse IP: %s"
1826 msgstr "Confirmer la suppression de cette adresse IP : %s"
1825
1827
1826 msgid "All IP addresses are allowed."
1828 msgid "All IP addresses are allowed."
1827 msgstr "Toutes les adresses IP sont autorisées."
1829 msgstr "Toutes les adresses IP sont autorisées."
@@ -1860,7 +1862,7 b' msgid "Permissions"'
1860 msgstr "Permissions"
1862 msgstr "Permissions"
1861
1863
1862 msgid "Repository Group: %s"
1864 msgid "Repository Group: %s"
1863 msgstr "Groupe de dépôts: %s"
1865 msgstr "Groupe de dépôts : %s"
1864
1866
1865 msgid "Top level repositories"
1867 msgid "Top level repositories"
1866 msgstr "Dépôts de niveau supérieur"
1868 msgstr "Dépôts de niveau supérieur"
@@ -1876,8 +1878,8 b' msgstr "Cr\xc3\xa9\xc3\xa9 le"'
1876
1878
1877 msgid "Confirm to delete this group: %s with %s repository"
1879 msgid "Confirm to delete this group: %s with %s repository"
1878 msgid_plural "Confirm to delete this group: %s with %s repositories"
1880 msgid_plural "Confirm to delete this group: %s with %s repositories"
1879 msgstr[0] "Confirmer la suppression de ce groupe: %s avec %s dépôt"
1881 msgstr[0] "Confirmer la suppression de ce groupe : %s avec %s dépôt"
1880 msgstr[1] "Confirmer la suppression de ce groupe: %s avec %s dépôts"
1882 msgstr[1] "Confirmer la suppression de ce groupe : %s avec %s dépôts"
1881
1883
1882 msgid "Delete this repository group"
1884 msgid "Delete this repository group"
1883 msgstr "Supprimer ce groupe de dépôts"
1885 msgstr "Supprimer ce groupe de dépôts"
@@ -1919,6 +1921,9 b' msgstr ""'
1919 "Ajouter ou révoquer la permission pour tous les enfants de ce groupe, y "
1921 "Ajouter ou révoquer la permission pour tous les enfants de ce groupe, y "
1920 "compris les dépôts non-privés et les autres groupes si sélectionné."
1922 "compris les dépôts non-privés et les autres groupes si sélectionné."
1921
1923
1924 msgid "Type name of user"
1925 msgstr "Saisir le nom de l'utilisateur"
1926
1922 msgid "Remove this group"
1927 msgid "Remove this group"
1923 msgstr "Supprimer ce groupe"
1928 msgstr "Supprimer ce groupe"
1924
1929
@@ -1934,9 +1939,15 b' msgstr "Administration des groupes de d\xc3\xa9p\xc3\xb4ts"'
1934 msgid "Number of Top-level Repositories"
1939 msgid "Number of Top-level Repositories"
1935 msgstr "Nombre de dépôts de niveau supérieur"
1940 msgstr "Nombre de dépôts de niveau supérieur"
1936
1941
1942 msgid "Type of repository to create."
1943 msgstr "Type de dépôt à créer."
1944
1937 msgid "Clone remote repository"
1945 msgid "Clone remote repository"
1938 msgstr "Cloner le dépôt distant"
1946 msgstr "Cloner le dépôt distant"
1939
1947
1948 msgid "Repository URL"
1949 msgstr "URL du dépôt"
1950
1940 msgid ""
1951 msgid ""
1941 "Optional: URL of a remote repository. If set, the repository will be "
1952 "Optional: URL of a remote repository. If set, the repository will be "
1942 "created as a clone from this URL."
1953 "created as a clone from this URL."
@@ -1953,9 +1964,6 b' msgstr ""'
1953 msgid "Optionally select a group to put this repository into."
1964 msgid "Optionally select a group to put this repository into."
1954 msgstr "Sélectionnez un groupe (optionel) dans lequel sera placé le dépôt."
1965 msgstr "Sélectionnez un groupe (optionel) dans lequel sera placé le dépôt."
1955
1966
1956 msgid "Type of repository to create."
1957 msgstr "Type de dépôt à créer."
1958
1959 msgid "Landing revision"
1967 msgid "Landing revision"
1960 msgstr "Révision d’arrivée"
1968 msgstr "Révision d’arrivée"
1961
1969
@@ -1977,7 +1985,7 b' msgid ""'
1977 "Repository \"%(repo_name)s\" is being created, you will be redirected "
1985 "Repository \"%(repo_name)s\" is being created, you will be redirected "
1978 "when this process is finished.repo_name"
1986 "when this process is finished.repo_name"
1979 msgstr ""
1987 msgstr ""
1980 "Le dépôt « %(repo_name)s » est en cours de création, vous allez être "
1988 "Le dépôt « %(repo_name)s » est en cours de création, vous allez être "
1981 "redirigé quand cette opération sera terminée."
1989 "redirigé quand cette opération sera terminée."
1982
1990
1983 msgid ""
1991 msgid ""
@@ -2100,28 +2108,9 b' msgstr "Ce d\xc3\xa9p\xc3\xb4t n\'a pas d\'URL de d\xc3\xa9p\xc3\xb4t distant."'
2100 msgid "Permanent URL"
2108 msgid "Permanent URL"
2101 msgstr "URL permanente"
2109 msgstr "URL permanente"
2102
2110
2103 msgid ""
2104 "In case this repository is renamed or moved into another group the "
2105 "repository URL changes.\n"
2106 " Using the above permanent URL guarantees "
2107 "that this repository always will be accessible on that URL.\n"
2108 " This is useful for CI systems, or any "
2109 "other cases that you need to hardcode the URL into a 3rd party service."
2110 msgstr ""
2111 "Si ce dépôt est renommé ou déplacé dans un autre groupe, l'URL du dépôt "
2112 "change.\n"
2113 " L'utilisation de l'URL permanente ci-"
2114 "dessus garantit que ce dépôt sera toujours accessible via cette URL.\n"
2115 " Cela peut être utile pour les systèmes "
2116 "d'intégration continue, ou dans tous les cas où vous devez saisir l'URL "
2117 "« en dur » dans un service tiers."
2118
2119 msgid "Remote repository"
2111 msgid "Remote repository"
2120 msgstr "Dépôt distant"
2112 msgstr "Dépôt distant"
2121
2113
2122 msgid "Repository URL"
2123 msgstr "URL du dépôt"
2124
2125 msgid ""
2114 msgid ""
2126 "Optional: URL of a remote repository. If set, the repository can be "
2115 "Optional: URL of a remote repository. If set, the repository can be "
2127 "pulled from this URL."
2116 "pulled from this URL."
@@ -2129,14 +2118,6 b' msgstr ""'
2129 "Optionel : URL d'un dépôt distant. Si renseigné, le dépôt sera pullé à "
2118 "Optionel : URL d'un dépôt distant. Si renseigné, le dépôt sera pullé à "
2130 "partir de cette URL."
2119 "partir de cette URL."
2131
2120
2132 msgid "Default revision for files page, downloads, whoosh and readme"
2133 msgstr ""
2134 "Révision par défaut pour les pages de fichiers, de téléchargements, de "
2135 "recherche et de documentation"
2136
2137 msgid "Type name of user"
2138 msgstr "Saisir le nom de l'utilisateur"
2139
2140 msgid "Change owner of this repository."
2121 msgid "Change owner of this repository."
2141 msgstr "Changer le propriétaire de ce dépôt."
2122 msgstr "Changer le propriétaire de ce dépôt."
2142
2123
@@ -2248,9 +2229,9 b' msgid ""'
2248 "post-receive hooks internally. Installation of these hooks is managed in "
2229 "post-receive hooks internally. Installation of these hooks is managed in "
2249 "%s."
2230 "%s."
2250 msgstr ""
2231 msgstr ""
2251 "Kallithea ne supporte pas les hooks Git personnalisés. Kallithea utilise des "
2232 "Kallithea ne supporte pas les hooks Git personnalisés. Kallithea utilise "
2252 "hooks Git de post-réception en interne. L'installation de ces hooks est "
2233 "des hooks Git de post-réception en interne. L'installation de ces hooks "
2253 "gérée dans %s."
2234 "est gérée dans %s."
2254
2235
2255 msgid "Custom Hooks are not enabled"
2236 msgid "Custom Hooks are not enabled"
2256 msgstr "Les Hooks personnalisés ne sont pas activés"
2237 msgstr "Les Hooks personnalisés ne sont pas activés"
@@ -2299,9 +2280,9 b' msgid ""'
2299 "hooks that don't seem to come from Kallithea will be disabled by renaming "
2280 "hooks that don't seem to come from Kallithea will be disabled by renaming "
2300 "to .bak extension."
2281 "to .bak extension."
2301 msgstr ""
2282 msgstr ""
2302 "Installe les hooks internes de Kallithea pour tous les dépôts Git. Les hooks "
2283 "Installe les hooks internes de Kallithea pour tous les dépôts Git. Les "
2303 "existants qui ne semblent pas être livrés avec Kallithea seront désactivés "
2284 "hooks existants qui ne semblent pas être livrés avec Kallithea seront "
2304 "en les renommant avec l'extension .bak."
2285 "désactivés en les renommant avec l'extension .bak."
2305
2286
2306 msgid "Rescan Repositories"
2287 msgid "Rescan Repositories"
2307 msgstr "Relancer le scan des dépôts"
2288 msgstr "Relancer le scan des dépôts"
@@ -2452,12 +2433,13 b' msgid ""'
2452 "hostname\n"
2433 "hostname\n"
2453 " "
2434 " "
2454 msgstr ""
2435 msgstr ""
2455 "Modèle de construction d'URL de clone. Par exemple : "
2436 "Modèle de construction d'URL de clone. Par exemple : '{scheme}://{user}"
2456 "'{scheme}://{user}@{netloc}/{repo}'.\n"
2437 "@{netloc}/{repo}'.\n"
2457 " Les variables "
2438 " Les variables "
2458 "suivantes sont disponibles :\n"
2439 "suivantes sont disponibles :\n"
2459 " {scheme} 'http' "
2440 " {scheme} "
2460 "ou 'https' envoyé à partir du serveur Kallithea en cours d'utilisation,\n"
2441 "'http' ou 'https' envoyé à partir du serveur Kallithea en cours "
2442 "d'utilisation,\n"
2461 " {user} nom de "
2443 " {user} nom de "
2462 "l'utilisateur courant,\n"
2444 "l'utilisateur courant,\n"
2463 " {netloc} "
2445 " {netloc} "
@@ -2466,8 +2448,8 b' msgstr ""'
2466 "complet du dépôt,\n"
2448 "complet du dépôt,\n"
2467 " {repoid} ID du "
2449 " {repoid} ID du "
2468 "dépôt, peut être utilisé pour cloner par ID,\n"
2450 "dépôt, peut être utilisé pour cloner par ID,\n"
2469 " {system_user} nom "
2451 " {system_user} "
2470 "de l'utilisateur système Kallithea,\n"
2452 "nom de l'utilisateur système Kallithea,\n"
2471 " {hostname} nom "
2453 " {hostname} nom "
2472 "d'hôte du serveur\n"
2454 "d'hôte du serveur\n"
2473 " "
2455 " "
@@ -2509,7 +2491,7 b' msgid "Show private repository icon on r'
2509 msgstr "Afficher l’icône de dépôt privé sur les dépôts"
2491 msgstr "Afficher l’icône de dépôt privé sur les dépôts"
2510
2492
2511 msgid "Show public/private icons next to repository names."
2493 msgid "Show public/private icons next to repository names."
2512 msgstr "Afficher l’icône « public/privé » à côté du nom des dépôts."
2494 msgstr "Afficher l’icône « public/privé » à côté du nom des dépôts."
2513
2495
2514 msgid "Meta Tagging"
2496 msgid "Meta Tagging"
2515 msgstr "Meta-tagging"
2497 msgstr "Meta-tagging"
@@ -2600,7 +2582,7 b' msgid "Member of User Groups"'
2600 msgstr "Membre des groupes d'utilisateurs"
2582 msgstr "Membre des groupes d'utilisateurs"
2601
2583
2602 msgid "Confirm to delete this user: %s"
2584 msgid "Confirm to delete this user: %s"
2603 msgstr "Voulez-vous vraiment supprimer l’utilisateur « %s » ?"
2585 msgstr "Voulez-vous vraiment supprimer l’utilisateur « %s » ?"
2604
2586
2605 msgid "Delete this user"
2587 msgid "Delete this user"
2606 msgstr "Supprimer cet utilisateur"
2588 msgstr "Supprimer cet utilisateur"
@@ -2714,7 +2696,7 b' msgid "Login to Your Account"'
2714 msgstr "Connexion à votre compte"
2696 msgstr "Connexion à votre compte"
2715
2697
2716 msgid "Forgot password?"
2698 msgid "Forgot password?"
2717 msgstr "Mot de passe oublié?"
2699 msgstr "Mot de passe oublié ?"
2718
2700
2719 msgid "Log Out"
2701 msgid "Log Out"
2720 msgstr "Se déconnecter"
2702 msgstr "Se déconnecter"
@@ -2800,11 +2782,11 b' msgstr "Aucun fichier correspondant"'
2800 msgid "Open New Pull Request from {0}"
2782 msgid "Open New Pull Request from {0}"
2801 msgstr "Ouvrir une nouvelle requête de pull à partir de {0}"
2783 msgstr "Ouvrir une nouvelle requête de pull à partir de {0}"
2802
2784
2803 msgid "Open New Pull Request for {0} &rarr; {1}"
2785 msgid "Open New Pull Request for {0}"
2804 msgstr "Ouvrir une nouvelle requête de pull pour {0} &rarr; {1}"
2786 msgstr "Ouvrir une nouvelle requête de pull pour {0}"
2805
2787
2806 msgid "Show Selected Changesets {0} &rarr; {1}"
2788 msgid "Show Selected Changesets {0}"
2807 msgstr "Afficher les changesets sélectionnés {0} &rarr; {1}"
2789 msgstr "Afficher les changesets sélectionnés {0}"
2808
2790
2809 msgid "Selection Link"
2791 msgid "Selection Link"
2810 msgstr "Lien vers la sélection"
2792 msgstr "Lien vers la sélection"
@@ -3147,10 +3129,10 b' msgid "Creating"'
3147 msgstr "En cours de création"
3129 msgstr "En cours de création"
3148
3130
3149 msgid "Mention in Comment on Changeset \"%s\""
3131 msgid "Mention in Comment on Changeset \"%s\""
3150 msgstr "Mention dans le commentaire sur le changeset « %s »"
3132 msgstr "Mention dans le commentaire sur le changeset « %s »"
3151
3133
3152 msgid "Comment on Changeset \"%s\""
3134 msgid "Comment on Changeset \"%s\""
3153 msgstr "Commentaire sur le changeset « %s »"
3135 msgstr "Commentaire sur le changeset « %s »"
3154
3136
3155 msgid "Changeset on"
3137 msgid "Changeset on"
3156 msgstr "Changeset sur"
3138 msgstr "Changeset sur"
@@ -3209,10 +3191,10 b' msgstr ""'
3209 "tenez pas compte de ce message."
3191 "tenez pas compte de ce message."
3210
3192
3211 msgid "Mention on Pull Request %s \"%s\" by %s"
3193 msgid "Mention on Pull Request %s \"%s\" by %s"
3212 msgstr "Mention sur la requête de pull %s « %s » par %s"
3194 msgstr "Mention sur la requête de pull %s « %s » par %s"
3213
3195
3214 msgid "Added as Reviewer of Pull Request %s \"%s\" by %s"
3196 msgid "Added as Reviewer of Pull Request %s \"%s\" by %s"
3215 msgstr "Ajouté comme relecteur de la requête de pull %s « %s » par %s"
3197 msgstr "Ajouté comme relecteur de la requête de pull %s « %s » par %s"
3216
3198
3217 msgid "Pull request"
3199 msgid "Pull request"
3218 msgstr "Requête de pull"
3200 msgstr "Requête de pull"
@@ -3227,13 +3209,13 b' msgid "View Pull Request"'
3227 msgstr "Afficher la requête de pull"
3209 msgstr "Afficher la requête de pull"
3228
3210
3229 msgid "Mention in Comment on Pull Request %s \"%s\""
3211 msgid "Mention in Comment on Pull Request %s \"%s\""
3230 msgstr "Mention dans le commentaire sur la requête de pull %s « %s »"
3212 msgstr "Mention dans le commentaire sur la requête de pull %s « %s »"
3231
3213
3232 msgid "Pull Request %s \"%s\" Closed"
3214 msgid "Pull Request %s \"%s\" Closed"
3233 msgstr "Requête de pull %s « %s » fermée"
3215 msgstr "Requête de pull %s « %s » fermée"
3234
3216
3235 msgid "Comment on Pull Request %s \"%s\""
3217 msgid "Comment on Pull Request %s \"%s\""
3236 msgstr "Commentaire sur la requête de pull %s « %s »"
3218 msgstr "Commentaire sur la requête de pull %s « %s »"
3237
3219
3238 msgid "New User Registration"
3220 msgid "New User Registration"
3239 msgstr "Nouvel enregistrement d'utilisateur"
3221 msgstr "Nouvel enregistrement d'utilisateur"
@@ -3763,8 +3745,5 b' msgstr "Pusher le nouveau d\xc3\xa9p\xc3\xb4t"'
3763 msgid "Existing repository?"
3745 msgid "Existing repository?"
3764 msgstr "Le dépôt existe déjà ?"
3746 msgstr "Le dépôt existe déjà ?"
3765
3747
3766 msgid "Readme file from revision %s:%s"
3767 msgstr "Fichier Lisez-moi de la revision %s:%s"
3768
3769 msgid "Download %s as %s"
3748 msgid "Download %s as %s"
3770 msgstr "Télécharge %s comme %s"
3749 msgstr "Télécharge %s comme %s"
@@ -1412,9 +1412,15 b' msgstr "\xe3\x83\xaa\xe3\x83\x9d\xe3\x82\xb8\xe3\x83\x88\xe3\x83\xaa\xe3\x82\xb0\xe3\x83\xab\xe3\x83\xbc\xe3\x83\x97\xe7\xae\xa1\xe7\x90\x86"'
1412 msgid "Number of Top-level Repositories"
1412 msgid "Number of Top-level Repositories"
1413 msgstr "トップレベルリポジトリ数"
1413 msgstr "トップレベルリポジトリ数"
1414
1414
1415 msgid "Type of repository to create."
1416 msgstr "作成するリポジトリの種別を指定します"
1417
1415 msgid "Clone remote repository"
1418 msgid "Clone remote repository"
1416 msgstr "リモートリポジトリをクローン"
1419 msgstr "リモートリポジトリをクローン"
1417
1420
1421 msgid "Repository URL"
1422 msgstr "リポジトリURL"
1423
1418 msgid ""
1424 msgid ""
1419 "Keep it short and to the point. Use a README file for longer descriptions."
1425 "Keep it short and to the point. Use a README file for longer descriptions."
1420 msgstr ""
1426 msgstr ""
@@ -1423,9 +1429,6 b' msgstr ""'
1423 msgid "Optionally select a group to put this repository into."
1429 msgid "Optionally select a group to put this repository into."
1424 msgstr "オプション:このリポジトリが属するグループを選択します"
1430 msgstr "オプション:このリポジトリが属するグループを選択します"
1425
1431
1426 msgid "Type of repository to create."
1427 msgstr "作成するリポジトリの種別を指定します"
1428
1429 msgid "Landing revision"
1432 msgid "Landing revision"
1430 msgstr "ランディングリビジョン"
1433 msgstr "ランディングリビジョン"
1431
1434
@@ -1547,26 +1550,9 b' msgstr "\xe3\x83\xaa\xe3\x83\xa2\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x9d\xe3\x82\xb8\xe3\x83\x88\xe3\x83\xaa\xe3\x81\x8b\xe3\x82\x89\xe5\xa4\x89\xe6\x9b\xb4\xe3\x82\x92\xe5\x8f\x96\xe3\x82\x8a\xe8\xbe\xbc\xe3\x82\x93\xe3\x81\xa7\xe3\x82\x82\xe3\x82\x88\xe3\x82\x8d\xe3\x81\x97\xe3\x81\x84\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8b\xef\xbc\x9f"'
1547 msgid "This repository does not have a remote repository URL."
1550 msgid "This repository does not have a remote repository URL."
1548 msgstr "このリポジトリにリモートURLは設定されていません"
1551 msgstr "このリポジトリにリモートURLは設定されていません"
1549
1552
1550 msgid ""
1551 "In case this repository is renamed or moved into another group the "
1552 "repository URL changes.\n"
1553 " Using the above permanent URL guarantees "
1554 "that this repository always will be accessible on that URL.\n"
1555 " This is useful for CI systems, or any "
1556 "other cases that you need to hardcode the URL into a 3rd party service."
1557 msgstr ""
1558 "通常、リポジトリの名前を変更したり、別のグループに移動すると、リポジトリの"
1559 "URLが変わります。\n"
1560 "上のURLを使えば、常にリポジトリにアクセスできます。\n"
1561 "この機能は、CIを使っている場合や、3rd pirtyのサービス向けにURLを固定化した"
1562 "いときに便利です。"
1563
1564 msgid "Remote repository"
1553 msgid "Remote repository"
1565 msgstr "リモートリポジトリ"
1554 msgstr "リモートリポジトリ"
1566
1555
1567 msgid "Repository URL"
1568 msgstr "リポジトリURL"
1569
1570 msgid ""
1556 msgid ""
1571 "Optional: URL of a remote repository. If set, the repository can be "
1557 "Optional: URL of a remote repository. If set, the repository can be "
1572 "pulled from this URL."
1558 "pulled from this URL."
@@ -1574,11 +1560,6 b' msgstr ""'
1574 "オプション: リモートリポジトリのURLです。設定した場合、このURLから変更を取"
1560 "オプション: リモートリポジトリのURLです。設定した場合、このURLから変更を取"
1575 "得することができます。"
1561 "得することができます。"
1576
1562
1577 msgid "Default revision for files page, downloads, whoosh and readme"
1578 msgstr ""
1579 "ファイルページ、ダウンロード、検索、READMEのデフォルトのリビジョンを指定し"
1580 "ます"
1581
1582 msgid "Change owner of this repository."
1563 msgid "Change owner of this repository."
1583 msgstr "リポジトリの所有者を変更"
1564 msgstr "リポジトリの所有者を変更"
1584
1565
@@ -2057,10 +2038,10 b' msgstr "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x81\xe3\x81\x99\xe3\x82\x8b\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x81\xaf\xe3\x81\x82\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x9b\xe3\x82\x93"'
2057 msgid "Open New Pull Request from {0}"
2038 msgid "Open New Pull Request from {0}"
2058 msgstr "新しいプルリクエストを{0}から作成"
2039 msgstr "新しいプルリクエストを{0}から作成"
2059
2040
2060 msgid "Open New Pull Request for {0} &rarr; {1}"
2041 msgid "Open New Pull Request for {0}"
2061 msgstr "{0} &rarr; {1}から新しいプルリクエストを作成する"
2042 msgstr "{0} &rarr; {1}から新しいプルリクエストを作成する"
2062
2043
2063 msgid "Show Selected Changesets {0} &rarr; {1}"
2044 msgid "Show Selected Changesets {0}"
2064 msgstr "選択したチェンジセット{0} &rarr; {0}を表示"
2045 msgstr "選択したチェンジセット{0} &rarr; {0}を表示"
2065
2046
2066 msgid "Collapse Diff"
2047 msgid "Collapse Diff"
@@ -2757,8 +2738,5 b' msgstr "\xe6\x96\xb0\xe3\x81\x97\xe3\x81\x84\xe3\x83\xaa\xe3\x83\x9d\xe3\x82\xb8\xe3\x83\x88\xe3\x83\xaa\xe3\x82\x92\xe3\x83\x97\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa5"'
2757 msgid "Existing repository?"
2738 msgid "Existing repository?"
2758 msgstr "存在するリポジトリをプッシュ"
2739 msgstr "存在するリポジトリをプッシュ"
2759
2740
2760 msgid "Readme file from revision %s:%s"
2761 msgstr "リビジョン %s:%s の README ファイル"
2762
2763 msgid "Download %s as %s"
2741 msgid "Download %s as %s"
2764 msgstr "%s を %s でダウンロード"
2742 msgstr "%s を %s でダウンロード"
@@ -896,6 +896,9 b' msgstr "Legg til ny"'
896 msgid "Both"
896 msgid "Both"
897 msgstr "Begge"
897 msgstr "Begge"
898
898
899 msgid "Type name of user"
900 msgstr "Skriv inn brukerens navn"
901
899 msgid "Remove this group"
902 msgid "Remove this group"
900 msgstr "Fjern denne gruppen"
903 msgstr "Fjern denne gruppen"
901
904
@@ -955,9 +958,6 b' msgstr "Privat pakkebr\xc3\xb8nn"'
955 msgid "Fork of repository"
958 msgid "Fork of repository"
956 msgstr "Forgrening av pakkebrønn"
959 msgstr "Forgrening av pakkebrønn"
957
960
958 msgid "Type name of user"
959 msgstr "Skriv inn brukerens navn"
960
961 msgid "Processed commits"
961 msgid "Processed commits"
962 msgstr "Behandlede innsendelser"
962 msgstr "Behandlede innsendelser"
963
963
@@ -215,8 +215,8 b' msgstr "Repository paginagrootte"'
215 msgid "Open New Pull Request from {0}"
215 msgid "Open New Pull Request from {0}"
216 msgstr "Open nieuwe pull request vanaf {0}"
216 msgstr "Open nieuwe pull request vanaf {0}"
217
217
218 msgid "Show Selected Changesets {0} &rarr; {1}"
218 msgid "Show Selected Changesets {0}"
219 msgstr "Toon geselecteerde changesets {0} &rarr; {1}"
219 msgstr "Toon geselecteerde changesets {0}"
220
220
221 msgid "Select changeset"
221 msgid "Select changeset"
222 msgstr "Selecteer een changeset"
222 msgstr "Selecteer een changeset"
@@ -8,8 +8,8 b' msgstr ""'
8 "MIME-Version: 1.0\n"
8 "MIME-Version: 1.0\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
10 "Content-Transfer-Encoding: 8bit\n"
11 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n"
11 "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && "
12 "%100<10 || n%100>=20) ? 1 : 2;\n"
12 "(n%100<10 || n%100>=20) ? 1 : 2;\n"
13
13
14 msgid ""
14 msgid ""
15 "CSRF token leak has been detected - all form tokens have been expired"
15 "CSRF token leak has been detected - all form tokens have been expired"
@@ -176,6 +176,9 b' msgstr "Nieprawid\xc5\x82owy token resetowania has\xc5\x82a"'
176 msgid "Successfully updated password"
176 msgid "Successfully updated password"
177 msgstr "Pomyślnie zaktualizowano hasło"
177 msgstr "Pomyślnie zaktualizowano hasło"
178
178
179 msgid "Invalid reviewer \"%s\" specified"
180 msgstr "Podano nieprawidłowego recenzenta \"%s\""
181
179 msgid "%s (closed)"
182 msgid "%s (closed)"
180 msgstr "%s (zamknięty)"
183 msgstr "%s (zamknięty)"
181
184
@@ -1506,6 +1509,9 b' msgstr "Dodaj nowe"'
1506 msgid "Both"
1509 msgid "Both"
1507 msgstr "Oba"
1510 msgstr "Oba"
1508
1511
1512 msgid "Type of repository to create."
1513 msgstr "Rodzaj repozytorium do stworzenia."
1514
1509 msgid ""
1515 msgid ""
1510 "Keep it short and to the point. Use a README file for longer descriptions."
1516 "Keep it short and to the point. Use a README file for longer descriptions."
1511 msgstr ""
1517 msgstr ""
@@ -1514,9 +1520,6 b' msgstr ""'
1514 msgid "Optionally select a group to put this repository into."
1520 msgid "Optionally select a group to put this repository into."
1515 msgstr "Opcjonalnie wybierz grupę do wprowadzenia tego repozytorium."
1521 msgstr "Opcjonalnie wybierz grupę do wprowadzenia tego repozytorium."
1516
1522
1517 msgid "Type of repository to create."
1518 msgstr "Rodzaj repozytorium do stworzenia."
1519
1520 msgid "Landing revision"
1523 msgid "Landing revision"
1521 msgstr "Docelowa rewizja"
1524 msgstr "Docelowa rewizja"
1522
1525
@@ -1562,9 +1565,6 b' msgstr "Nowy opis pola"'
1562 msgid "Enter description of a field"
1565 msgid "Enter description of a field"
1563 msgstr "Wprowadź opis pola"
1566 msgstr "Wprowadź opis pola"
1564
1567
1565 msgid "Default revision for files page, downloads, whoosh and readme"
1566 msgstr "Wersja domyślna dla plików stronicowania, pobierania plików, readme"
1567
1568 msgid "Change owner of this repository."
1568 msgid "Change owner of this repository."
1569 msgstr "Zmiana właściciela tego repozytorium."
1569 msgstr "Zmiana właściciela tego repozytorium."
1570
1570
@@ -889,6 +889,9 b' msgstr[1] "Confirme para apagar este grupo: %s com %s reposit\xc3\xb3rios"'
889 msgid "Add new"
889 msgid "Add new"
890 msgstr "Adicionar novo"
890 msgstr "Adicionar novo"
891
891
892 msgid "Type of repository to create."
893 msgstr "Tipo de repositório a criar."
894
892 msgid ""
895 msgid ""
893 "Keep it short and to the point. Use a README file for longer descriptions."
896 "Keep it short and to the point. Use a README file for longer descriptions."
894 msgstr ""
897 msgstr ""
@@ -898,9 +901,6 b' msgstr ""'
898 msgid "Optionally select a group to put this repository into."
901 msgid "Optionally select a group to put this repository into."
899 msgstr "Opcionalmente selecione um grupo no qual pôr esse repositório."
902 msgstr "Opcionalmente selecione um grupo no qual pôr esse repositório."
900
903
901 msgid "Type of repository to create."
902 msgstr "Tipo de repositório a criar."
903
904 msgid "Landing revision"
904 msgid "Landing revision"
905 msgstr "Revisão de pouso"
905 msgstr "Revisão de pouso"
906
906
@@ -943,11 +943,6 b' msgstr "Nova descri\xc3\xa7\xc3\xa3o de campo"'
943 msgid "Enter description of a field"
943 msgid "Enter description of a field"
944 msgstr "Entre com a descrição de um campo"
944 msgstr "Entre com a descrição de um campo"
945
945
946 msgid "Default revision for files page, downloads, whoosh and readme"
947 msgstr ""
948 "Revisão predefinida para página de ficheiros, descarregamentos, whoosh e "
949 "readme"
950
951 msgid "Change owner of this repository."
946 msgid "Change owner of this repository."
952 msgstr "Mudar o dono desse repositório."
947 msgstr "Mudar o dono desse repositório."
953
948
@@ -889,6 +889,9 b' msgstr[1] "Confirme para excluir este grupo: %s com %s reposit\xc3\xb3rios"'
889 msgid "Add new"
889 msgid "Add new"
890 msgstr "Adicionar novo"
890 msgstr "Adicionar novo"
891
891
892 msgid "Type of repository to create."
893 msgstr "Tipo de repositório a criar."
894
892 msgid ""
895 msgid ""
893 "Keep it short and to the point. Use a README file for longer descriptions."
896 "Keep it short and to the point. Use a README file for longer descriptions."
894 msgstr ""
897 msgstr ""
@@ -898,9 +901,6 b' msgstr ""'
898 msgid "Optionally select a group to put this repository into."
901 msgid "Optionally select a group to put this repository into."
899 msgstr "Opcionalmente selecione um grupo no qual colocar esse repositório."
902 msgstr "Opcionalmente selecione um grupo no qual colocar esse repositório."
900
903
901 msgid "Type of repository to create."
902 msgstr "Tipo de repositório a criar."
903
904 msgid "Landing revision"
904 msgid "Landing revision"
905 msgstr "Revisão de pouso"
905 msgstr "Revisão de pouso"
906
906
@@ -943,9 +943,6 b' msgstr "Nova descri\xc3\xa7\xc3\xa3o de campo"'
943 msgid "Enter description of a field"
943 msgid "Enter description of a field"
944 msgstr "Entre com a descrição de um campo"
944 msgstr "Entre com a descrição de um campo"
945
945
946 msgid "Default revision for files page, downloads, whoosh and readme"
947 msgstr "Revisão padrão para página de arquivos, downloads, whoosh e readme"
948
949 msgid "Change owner of this repository."
946 msgid "Change owner of this repository."
950 msgstr "Mudar o dono desse repositório."
947 msgstr "Mudar o dono desse repositório."
951
948
@@ -8,8 +8,8 b' msgstr ""'
8 "MIME-Version: 1.0\n"
8 "MIME-Version: 1.0\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
10 "Content-Transfer-Encoding: 8bit\n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
12 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
12 "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
13
13
14 msgid ""
14 msgid ""
15 "CSRF token leak has been detected - all form tokens have been expired"
15 "CSRF token leak has been detected - all form tokens have been expired"
@@ -934,6 +934,13 b' msgstr "\xd0\x92\xd0\xb2\xd0\xb5\xd0\xb4\xd0\xb8\xd1\x82\xd0\xb5 \xd0\xbd\xd0\xb5 \xd0\xbc\xd0\xb5\xd0\xbd\xd0\xb5\xd0\xb5 %(min)i \xd1\x81\xd0\xb8\xd0\xbc\xd0\xb2\xd0\xbe\xd0\xbb\xd0\xbe\xd0\xb2"'
934 msgid "Name must not contain only digits"
934 msgid "Name must not contain only digits"
935 msgstr "Имя не может состоять только из цифр"
935 msgstr "Имя не может состоять только из цифр"
936
936
937 msgid ""
938 "[Comment] %(repo_name)s changeset %(short_id)s \"%(message_short)s\" on "
939 "%(branch)s by %(cs_author_username)s"
940 msgstr ""
941 "[Комментарий] к набору изменений %(short_id)s «%(message_short)s» "
942 "репозитория %(repo_name)s в %(branch)s от %(cs_author_username)s"
943
937 msgid "New user %(new_username)s registered"
944 msgid "New user %(new_username)s registered"
938 msgstr "Новый пользователь \"%(new_username)s\" зарегистрирован"
945 msgstr "Новый пользователь \"%(new_username)s\" зарегистрирован"
939
946
@@ -1811,6 +1818,9 b' msgstr ""'
1811 "Установить или отозвать права всех дочерних элементов этой группы, "
1818 "Установить или отозвать права всех дочерних элементов этой группы, "
1812 "включая публичные репозитории и другие группы, если они выбраны."
1819 "включая публичные репозитории и другие группы, если они выбраны."
1813
1820
1821 msgid "Type name of user"
1822 msgstr "Введите имя пользователя"
1823
1814 msgid "Remove this group"
1824 msgid "Remove this group"
1815 msgstr "Удалить группу"
1825 msgstr "Удалить группу"
1816
1826
@@ -1826,9 +1836,15 b' msgstr "\xd0\x90\xd0\xb4\xd0\xbc\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x81\xd1\x82\xd1\x80\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd0\xb5 \xd0\xb3\xd1\x80\xd1\x83\xd0\xbf\xd0\xbf \xd1\x80\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb5\xd0\xb2"'
1826 msgid "Number of Top-level Repositories"
1836 msgid "Number of Top-level Repositories"
1827 msgstr "Число репозиториев верхнего уровня"
1837 msgstr "Число репозиториев верхнего уровня"
1828
1838
1839 msgid "Type of repository to create."
1840 msgstr "Тип создаваемого репозитория."
1841
1829 msgid "Clone remote repository"
1842 msgid "Clone remote repository"
1830 msgstr "Клонировать удалённый репозиторий"
1843 msgstr "Клонировать удалённый репозиторий"
1831
1844
1845 msgid "Repository URL"
1846 msgstr "URL репозитория"
1847
1832 msgid ""
1848 msgid ""
1833 "Optional: URL of a remote repository. If set, the repository will be "
1849 "Optional: URL of a remote repository. If set, the repository will be "
1834 "created as a clone from this URL."
1850 "created as a clone from this URL."
@@ -1844,9 +1860,6 b' msgstr ""'
1844 msgid "Optionally select a group to put this repository into."
1860 msgid "Optionally select a group to put this repository into."
1845 msgstr "Опционально выбрать группу, в которую поместить данный репозиторий."
1861 msgstr "Опционально выбрать группу, в которую поместить данный репозиторий."
1846
1862
1847 msgid "Type of repository to create."
1848 msgstr "Тип создаваемого репозитория."
1849
1850 msgid "Landing revision"
1863 msgid "Landing revision"
1851 msgstr "Ревизия для выгрузки"
1864 msgstr "Ревизия для выгрузки"
1852
1865
@@ -1989,27 +2002,9 b' msgstr "\xd0\x94\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8b\xd0\xb9 \xd1\x80\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb9 \xd0\xbd\xd0\xb5 \xd0\xb8\xd0\xbc\xd0\xb5\xd0\xb5\xd1\x82 URL \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd1\x91\xd0\xbd\xd0\xbd\xd0\xbe\xd0\xb3\xd0\xbe \xd1\x80\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd1\x8f."'
1989 msgid "Permanent URL"
2002 msgid "Permanent URL"
1990 msgstr "Постоянный URL"
2003 msgstr "Постоянный URL"
1991
2004
1992 msgid ""
1993 "In case this repository is renamed or moved into another group the "
1994 "repository URL changes.\n"
1995 " Using the above permanent URL guarantees "
1996 "that this repository always will be accessible on that URL.\n"
1997 " This is useful for CI systems, or any "
1998 "other cases that you need to hardcode the URL into a 3rd party service."
1999 msgstr ""
2000 "В случае, когда репозиторий переименовывается или перемещается в другую "
2001 "группу, URL репозитория изменяется.\n"
2002 " Использование постоянного URL гарантирует, "
2003 "что данный репозиторий всегда будет доступен по этому URL.\n"
2004 " Это может быть полезно в CI-системах, или "
2005 "в любом другом случае, требующем встраивания URL в код ПО."
2006
2007 msgid "Remote repository"
2005 msgid "Remote repository"
2008 msgstr "Удалённый репозиторий"
2006 msgstr "Удалённый репозиторий"
2009
2007
2010 msgid "Repository URL"
2011 msgstr "URL репозитория"
2012
2013 msgid ""
2008 msgid ""
2014 "Optional: URL of a remote repository. If set, the repository can be "
2009 "Optional: URL of a remote repository. If set, the repository can be "
2015 "pulled from this URL."
2010 "pulled from this URL."
@@ -2017,14 +2012,6 b' msgstr ""'
2017 "Опционально: URL удалённого репозитория. Если задан, то репозиторий можно "
2012 "Опционально: URL удалённого репозитория. Если задан, то репозиторий можно "
2018 "получить по заданному адресу."
2013 "получить по заданному адресу."
2019
2014
2020 msgid "Default revision for files page, downloads, whoosh and readme"
2021 msgstr ""
2022 "Ревизия по умолчанию, из которой будет производиться выгрузка файлов при "
2023 "скачивании"
2024
2025 msgid "Type name of user"
2026 msgstr "Введите имя пользователя"
2027
2028 msgid "Change owner of this repository."
2015 msgid "Change owner of this repository."
2029 msgstr "Изменить владельца репозитория."
2016 msgstr "Изменить владельца репозитория."
2030
2017
@@ -2645,11 +2632,11 b' msgstr "\xd0\x9d\xd0\xb5\xd1\x82 \xd1\x81\xd0\xbe\xd0\xb2\xd0\xbf\xd0\xb0\xd0\xb4\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb9"'
2645 msgid "Open New Pull Request from {0}"
2632 msgid "Open New Pull Request from {0}"
2646 msgstr "Открыть новый pull-запрос от {0}"
2633 msgstr "Открыть новый pull-запрос от {0}"
2647
2634
2648 msgid "Open New Pull Request for {0} &rarr; {1}"
2635 msgid "Open New Pull Request for {0}"
2649 msgstr "Открыть новый pull-запрос для {0} &rarr; {1}"
2636 msgstr "Открыть новый pull-запрос для {0}"
2650
2637
2651 msgid "Show Selected Changesets {0} &rarr; {1}"
2638 msgid "Show Selected Changesets {0}"
2652 msgstr "Показать выбранные наборы изменений: {0} &rarr; {1}"
2639 msgstr "Показать выбранные наборы изменений: {0}"
2653
2640
2654 msgid "Selection Link"
2641 msgid "Selection Link"
2655 msgstr "Ссылка выбора"
2642 msgstr "Ссылка выбора"
@@ -3598,8 +3585,5 b' msgstr "\xd0\x9e\xd1\x82\xd0\xbf\xd1\x80\xd0\xb0\xd0\xb2\xd0\xb8\xd1\x82\xd1\x8c \xd0\xbd\xd0\xbe\xd0\xb2\xd1\x8b\xd0\xb9 \xd1\x80\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb9"'
3598 msgid "Existing repository?"
3585 msgid "Existing repository?"
3599 msgstr "Существующий репозиторий?"
3586 msgstr "Существующий репозиторий?"
3600
3587
3601 msgid "Readme file from revision %s:%s"
3602 msgstr "Файл readme из ревизии %s:%s"
3603
3604 msgid "Download %s as %s"
3588 msgid "Download %s as %s"
3605 msgstr "Скачать %s как %s"
3589 msgstr "Скачать %s как %s"
@@ -8,8 +8,8 b' msgstr ""'
8 "MIME-Version: 1.0\n"
8 "MIME-Version: 1.0\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
9 "Content-Type: text/plain; charset=UTF-8\n"
10 "Content-Transfer-Encoding: 8bit\n"
10 "Content-Transfer-Encoding: 8bit\n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
11 "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
12 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
12 "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
13
13
14 msgid ""
14 msgid ""
15 "CSRF token leak has been detected - all form tokens have been expired"
15 "CSRF token leak has been detected - all form tokens have been expired"
@@ -1054,6 +1054,9 b' msgstr ""'
1054 "Встановіть або скасуйте дозвіл для всіх дітей цієї групи, включно з "
1054 "Встановіть або скасуйте дозвіл для всіх дітей цієї групи, включно з "
1055 "неприватними репозиторіями та іншими групами, якщо вони вибрані."
1055 "неприватними репозиторіями та іншими групами, якщо вони вибрані."
1056
1056
1057 msgid "Type name of user"
1058 msgstr "Введіть ім'я користувача"
1059
1057 msgid "Remove this group"
1060 msgid "Remove this group"
1058 msgstr "Видалити цю групу"
1061 msgstr "Видалити цю групу"
1059
1062
@@ -1069,15 +1072,18 b' msgstr "\xd0\x90\xd0\xb4\xd0\xbc\xd1\x96\xd0\xbd\xd1\x96\xd1\x81\xd1\x82\xd1\x80\xd1\x83\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8f \xd0\x93\xd1\x80\xd1\x83\xd0\xbf \xd0\xa0\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd1\x96\xd1\x97\xd0\xb2"'
1069 msgid "Number of Top-level Repositories"
1072 msgid "Number of Top-level Repositories"
1070 msgstr "Кількість репозиторіїв верхнього рівня"
1073 msgstr "Кількість репозиторіїв верхнього рівня"
1071
1074
1075 msgid "Type of repository to create."
1076 msgstr "Тип сховища для створення."
1077
1072 msgid "Clone remote repository"
1078 msgid "Clone remote repository"
1073 msgstr "Клонувати віддалений репозиторій"
1079 msgstr "Клонувати віддалений репозиторій"
1074
1080
1081 msgid "Repository URL"
1082 msgstr "URL репозиторію"
1083
1075 msgid "Optionally select a group to put this repository into."
1084 msgid "Optionally select a group to put this repository into."
1076 msgstr "За бажанням виберіть групу, в яку буде розміщено цей репозиторій."
1085 msgstr "За бажанням виберіть групу, в яку буде розміщено цей репозиторій."
1077
1086
1078 msgid "Type of repository to create."
1079 msgstr "Тип сховища для створення."
1080
1081 msgid "Landing revision"
1087 msgid "Landing revision"
1082 msgstr "Цільова редакція"
1088 msgstr "Цільова редакція"
1083
1089
@@ -1205,9 +1211,6 b' msgstr "\xd0\xa3 \xd1\x86\xd1\x8c\xd0\xbe\xd0\xbc\xd1\x83 \xd1\x81\xd1\x85\xd0\xbe\xd0\xb2\xd0\xb8\xd1\x89\xd1\x96 \xd0\xbd\xd0\xb5\xd0\xbc\xd0\xb0\xd1\x94 URL-\xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81\xd0\xb8 \xd0\xb2\xd1\x96\xd0\xb4\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xbe\xd0\xb3\xd0\xbe \xd1\x81\xd1\x85\xd0\xbe\xd0\xb2\xd0\xb8\xd1\x89\xd0\xb0."'
1205 msgid "Remote repository"
1211 msgid "Remote repository"
1206 msgstr "Віддалений репозиторій"
1212 msgstr "Віддалений репозиторій"
1207
1213
1208 msgid "Repository URL"
1209 msgstr "URL репозиторію"
1210
1211 msgid ""
1214 msgid ""
1212 "Optional: URL of a remote repository. If set, the repository can be "
1215 "Optional: URL of a remote repository. If set, the repository can be "
1213 "pulled from this URL."
1216 "pulled from this URL."
@@ -1215,9 +1218,6 b' msgstr ""'
1215 "Опціонально: URL-адреса віддаленого сховища. Якщо встановлено, сховище "
1218 "Опціонально: URL-адреса віддаленого сховища. Якщо встановлено, сховище "
1216 "можна витягнути з цієї URL-адреси."
1219 "можна витягнути з цієї URL-адреси."
1217
1220
1218 msgid "Type name of user"
1219 msgstr "Введіть ім'я користувача"
1220
1221 msgid "Change owner of this repository."
1221 msgid "Change owner of this repository."
1222 msgstr "Змінити власника цього сховища."
1222 msgstr "Змінити власника цього сховища."
1223
1223
@@ -569,7 +569,7 b' msgstr "\xe4\xb8\x8d\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\x90\x88\xe6\xb3\x95\xe7\x9a\x84\xe8\xb7\xaf\xe5\xbe\x84"'
569 msgid ""
569 msgid ""
570 "The LDAP Login attribute of the CN must be specified - this is the name "
570 "The LDAP Login attribute of the CN must be specified - this is the name "
571 "of the attribute that is equivalent to \"username\""
571 "of the attribute that is equivalent to \"username\""
572 msgstr "LDAP 登属性的 CN 必须指定 - 这个名字作为用户名"
572 msgstr "LDAP 登属性的 CN 必须指定 - 这个名字作为用户名"
573
573
574 msgid "Repository"
574 msgid "Repository"
575 msgstr "版本库"
575 msgstr "版本库"
@@ -715,6 +715,9 b' msgid "Confirm to delete this group: %s '
715 msgid_plural "Confirm to delete this group: %s with %s repositories"
715 msgid_plural "Confirm to delete this group: %s with %s repositories"
716 msgstr[0] "确认删除这个版本库组:%s包含%s个版本库"
716 msgstr[0] "确认删除这个版本库组:%s包含%s个版本库"
717
717
718 msgid "Type of repository to create."
719 msgstr "要创建的版本库类型。"
720
718 msgid ""
721 msgid ""
719 "Keep it short and to the point. Use a README file for longer descriptions."
722 "Keep it short and to the point. Use a README file for longer descriptions."
720 msgstr "保持简短。用README文件来写更长的描述。"
723 msgstr "保持简短。用README文件来写更长的描述。"
@@ -722,9 +725,6 b' msgstr "\xe4\xbf\x9d\xe6\x8c\x81\xe7\xae\x80\xe7\x9f\xad\xe3\x80\x82\xe7\x94\xa8README\xe6\x96\x87\xe4\xbb\xb6\xe6\x9d\xa5\xe5\x86\x99\xe6\x9b\xb4\xe9\x95\xbf\xe7\x9a\x84\xe6\x8f\x8f\xe8\xbf\xb0\xe3\x80\x82"'
722 msgid "Optionally select a group to put this repository into."
725 msgid "Optionally select a group to put this repository into."
723 msgstr "可选的选择一个组将版本库放到其中。"
726 msgstr "可选的选择一个组将版本库放到其中。"
724
727
725 msgid "Type of repository to create."
726 msgstr "要创建的版本库类型。"
727
728 msgid "Landing revision"
728 msgid "Landing revision"
729 msgstr "默认修订"
729 msgstr "默认修订"
730
730
@@ -743,9 +743,6 b' msgstr "\xe7\xa1\xae\xe8\xae\xa4\xe5\x88\xa0\xe9\x99\xa4\xe7\x89\x88\xe6\x9c\xac\xe5\xba\x93\xef\xbc\x9a%s"'
743 msgid "Key"
743 msgid "Key"
744 msgstr "键"
744 msgstr "键"
745
745
746 msgid "Default revision for files page, downloads, whoosh and readme"
747 msgstr "文件浏览、下载、whoosh和README的默认修订版本"
748
749 msgid "Change owner of this repository."
746 msgid "Change owner of this repository."
750 msgstr "修改这个版本库的所有者。"
747 msgstr "修改这个版本库的所有者。"
751
748
@@ -863,8 +860,8 b' msgstr "\xe5\xbc\x80\xe5\xa7\x8b\xe5\x85\xb3\xe6\xb3\xa8\xe8\xaf\xa5\xe7\x89\x88\xe6\x9c\xac\xe5\xba\x93"'
863 msgid "Group"
860 msgid "Group"
864 msgstr "组"
861 msgstr "组"
865
862
866 msgid "Show Selected Changesets {0} &rarr; {1}"
863 msgid "Show Selected Changesets {0}"
867 msgstr "显示选中的修订集 {0} &rarr; {1}"
864 msgstr "显示选中的修订集 {0}"
868
865
869 msgid "Select changeset"
866 msgid "Select changeset"
870 msgstr "选择修订集"
867 msgstr "选择修订集"
@@ -946,7 +943,7 b' msgid "You need to be logged in to comme'
946 msgstr "您必须登录才能评论。"
943 msgstr "您必须登录才能评论。"
947
944
948 msgid "Login now"
945 msgid "Login now"
949 msgstr "现在登"
946 msgstr "现在登"
950
947
951 msgid "Hide"
948 msgid "Hide"
952 msgstr "隐藏"
949 msgstr "隐藏"
@@ -913,7 +913,7 b' class Repository(meta.Base, BaseDbModel)'
913 STATE_ERROR = 'repo_state_error'
913 STATE_ERROR = 'repo_state_error'
914
914
915 repo_id = Column(Integer(), primary_key=True)
915 repo_id = Column(Integer(), primary_key=True)
916 repo_name = Column(Unicode(255), nullable=False, unique=True)
916 repo_name = Column(Unicode(255), nullable=False, unique=True) # full path, must be updated (based on get_new_name) when name or path changes
917 repo_state = Column(String(255), nullable=False)
917 repo_state = Column(String(255), nullable=False)
918
918
919 clone_uri = Column(String(255), nullable=True) # FIXME: not nullable?
919 clone_uri = Column(String(255), nullable=True) # FIXME: not nullable?
@@ -1337,7 +1337,7 b' class RepoGroup(meta.Base, BaseDbModel):'
1337 SEP = ' &raquo; '
1337 SEP = ' &raquo; '
1338
1338
1339 group_id = Column(Integer(), primary_key=True)
1339 group_id = Column(Integer(), primary_key=True)
1340 group_name = Column(Unicode(255), nullable=False, unique=True) # full path
1340 group_name = Column(Unicode(255), nullable=False, unique=True) # full path, must be updated (based on get_new_name) when name or path changes
1341 parent_group_id = Column('group_parent_id', Integer(), ForeignKey('groups.group_id'), nullable=True)
1341 parent_group_id = Column('group_parent_id', Integer(), ForeignKey('groups.group_id'), nullable=True)
1342 group_description = Column(Unicode(10000), nullable=False)
1342 group_description = Column(Unicode(10000), nullable=False)
1343 owner_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
1343 owner_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
@@ -1914,6 +1914,7 b' class ChangesetComment(meta.Base, BaseDb'
1914 return dict(
1914 return dict(
1915 comment_id=self.comment_id,
1915 comment_id=self.comment_id,
1916 username=self.author.username,
1916 username=self.author.username,
1917 created_on=self.created_on.replace(microsecond=0),
1917 text=self.text,
1918 text=self.text,
1918 )
1919 )
1919
1920
@@ -173,6 +173,7 b' def RepoGroupForm(edit=False, old_data=N'
173 group_copy_permissions = v.StringBoolean(if_missing=False)
173 group_copy_permissions = v.StringBoolean(if_missing=False)
174
174
175 if edit:
175 if edit:
176 owner = All(v.UnicodeString(not_empty=True), v.ValidRepoUser())
176 # FIXME: do a special check that we cannot move a group to one of
177 # FIXME: do a special check that we cannot move a group to one of
177 # its children
178 # its children
178 pass
179 pass
@@ -711,13 +711,10 b' def create_repo(form_data, cur_user):'
711 copy_fork_permissions = form_data.get('copy_permissions')
711 copy_fork_permissions = form_data.get('copy_permissions')
712 copy_group_permissions = form_data.get('repo_copy_permissions')
712 copy_group_permissions = form_data.get('repo_copy_permissions')
713 fork_of = form_data.get('fork_parent_id')
713 fork_of = form_data.get('fork_parent_id')
714 enable_statistics = form_data['repo_enable_statistics']
715 enable_downloads = form_data['repo_enable_downloads']
714 state = form_data.get('repo_state', db.Repository.STATE_PENDING)
716 state = form_data.get('repo_state', db.Repository.STATE_PENDING)
715
717
716 # repo creation defaults, private and repo_type are filled in form
717 defs = db.Setting.get_default_repo_settings(strip_prefix=True)
718 enable_statistics = defs.get('repo_enable_statistics')
719 enable_downloads = defs.get('repo_enable_downloads')
720
721 try:
718 try:
722 db_repo = RepoModel()._create_repo(
719 db_repo = RepoModel()._create_repo(
723 repo_name=repo_name_full,
720 repo_name=repo_name_full,
@@ -278,45 +278,46 b' class RepoGroupModel(object):'
278 def update(self, repo_group, repo_group_args):
278 def update(self, repo_group, repo_group_args):
279 try:
279 try:
280 repo_group = db.RepoGroup.guess_instance(repo_group)
280 repo_group = db.RepoGroup.guess_instance(repo_group)
281 old_path = repo_group.full_path
281 old_path = repo_group.full_path # aka .group_name
282
282
283 # change properties
283 if 'owner' in repo_group_args:
284 repo_group.owner = db.User.get_by_username(repo_group_args['owner'])
284 if 'group_description' in repo_group_args:
285 if 'group_description' in repo_group_args:
285 repo_group.group_description = repo_group_args['group_description']
286 repo_group.group_description = repo_group_args['group_description']
286 if 'parent_group_id' in repo_group_args:
287 if 'parent_group_id' in repo_group_args:
287 repo_group.parent_group_id = repo_group_args['parent_group_id']
288
289 if 'parent_group_id' in repo_group_args:
290 assert repo_group_args['parent_group_id'] != '-1', repo_group_args # RepoGroupForm should have converted to None
288 assert repo_group_args['parent_group_id'] != '-1', repo_group_args # RepoGroupForm should have converted to None
291 repo_group.parent_group = db.RepoGroup.get(repo_group_args['parent_group_id'])
289 new_parent_group = db.RepoGroup.get(repo_group_args['parent_group_id'])
290 if new_parent_group is not repo_group.parent_group:
291 repo_group.parent_group = new_parent_group
292 repo_group.group_name = repo_group.get_new_name(repo_group.name)
293 log.debug('Moving repo group %s to %s', old_path, repo_group.group_name)
292 if 'group_name' in repo_group_args:
294 if 'group_name' in repo_group_args:
293 group_name = repo_group_args['group_name']
295 group_name = repo_group_args['group_name']
294 if kallithea.lib.utils2.repo_name_slug(group_name) != group_name:
296 if kallithea.lib.utils2.repo_name_slug(group_name) != group_name:
295 raise Exception('invalid repo group name %s' % group_name)
297 raise Exception('invalid repo group name %s' % group_name)
296 repo_group.group_name = repo_group.get_new_name(group_name)
298 if repo_group.name != group_name:
299 repo_group.group_name = repo_group.get_new_name(group_name)
300 log.debug('Renaming repo group %s to %s', old_path, repo_group.group_name)
297 new_path = repo_group.full_path
301 new_path = repo_group.full_path
298 meta.Session().add(repo_group)
302 meta.Session().add(repo_group)
299
303
300 # iterate over all members of this groups and do fixes
304 # Iterate over all members of this repo group and update the full
301 # if obj is a repoGroup also fix the name of the group according
305 # path (repo_name and group_name) based on the (already updated)
302 # to the parent
306 # full path of the parent.
303 # if obj is a Repo fix it's name
307 # This can potentially be a heavy operation.
304 # this can be potentially heavy operation
305 for obj in repo_group.recursive_groups_and_repos():
308 for obj in repo_group.recursive_groups_and_repos():
306 # set the value from it's parent
309 if obj is repo_group:
310 continue # already updated and logged
307 if isinstance(obj, db.RepoGroup):
311 if isinstance(obj, db.RepoGroup):
308 new_name = obj.get_new_name(obj.name)
312 new_name = obj.get_new_name(obj.name)
309 log.debug('Fixing group %s to new name %s'
313 log.debug('Fixing repo group %s to new name %s', obj.group_name, new_name)
310 % (obj.group_name, new_name))
311 obj.group_name = new_name
314 obj.group_name = new_name
312 elif isinstance(obj, db.Repository):
315 elif isinstance(obj, db.Repository):
313 # we need to get all repositories from this new group and
314 # rename them accordingly to new group path
315 new_name = obj.get_new_name(obj.just_name)
316 new_name = obj.get_new_name(obj.just_name)
316 log.debug('Fixing repo %s to new name %s'
317 log.debug('Fixing repo %s to new name %s', obj.repo_name, new_name)
317 % (obj.repo_name, new_name))
318 obj.repo_name = new_name
318 obj.repo_name = new_name
319
319
320 # Rename in file system
320 self._rename_group(old_path, new_path)
321 self._rename_group(old_path, new_path)
321
322
322 return repo_group
323 return repo_group
@@ -24,7 +24,15 b''
24 necessarily limited to the following:</p>
24 necessarily limited to the following:</p>
25 <ul>
25 <ul>
26
26
27 <li>Copyright &copy; 2012&ndash;2021, Mads Kiilerich</li>
27 <li>Copyright &copy; 2012&ndash;2023, Mads Kiilerich</li>
28 <li>Copyright &copy; 2019&ndash;2020, 2022&ndash;2023, Manuel Jacob</li>
29 <li>Copyright &copy; 2023, Mathias De Mare</li>
30 <li>Copyright &copy; 2016&ndash;2017, 2020, 2022, Asterios Dimitriou</li>
31 <li>Copyright &copy; 2022, Jaime Marquínez Ferrándiz</li>
32 <li>Copyright &copy; 2022, Louis Bertrand</li>
33 <li>Copyright &copy; 2022, toras9000</li>
34 <li>Copyright &copy; 2022, yzqzss</li>
35 <li>Copyright &copy; 2022, МАН69К</li>
28 <li>Copyright &copy; 2014&ndash;2021, Thomas De Schampheleire</li>
36 <li>Copyright &copy; 2014&ndash;2021, Thomas De Schampheleire</li>
29 <li>Copyright &copy; 2015&ndash;2017, 2019&ndash;2021, Étienne Gilli</li>
37 <li>Copyright &copy; 2015&ndash;2017, 2019&ndash;2021, Étienne Gilli</li>
30 <li>Copyright &copy; 2018&ndash;2021, ssantos</li>
38 <li>Copyright &copy; 2018&ndash;2021, ssantos</li>
@@ -35,10 +43,8 b''
35 <li>Copyright &copy; 2021, Michalis</li>
43 <li>Copyright &copy; 2021, Michalis</li>
36 <li>Copyright &copy; 2021, vs</li>
44 <li>Copyright &copy; 2021, vs</li>
37 <li>Copyright &copy; 2021, Александр</li>
45 <li>Copyright &copy; 2021, Александр</li>
38 <li>Copyright &copy; 2016&ndash;2017, 2020, Asterios Dimitriou</li>
39 <li>Copyright &copy; 2017&ndash;2020, Allan Nordhøy</li>
46 <li>Copyright &copy; 2017&ndash;2020, Allan Nordhøy</li>
40 <li>Copyright &copy; 2017, 2020, Anton Schur</li>
47 <li>Copyright &copy; 2017, 2020, Anton Schur</li>
41 <li>Copyright &copy; 2019&ndash;2020, Manuel Jacob</li>
42 <li>Copyright &copy; 2020, Artem</li>
48 <li>Copyright &copy; 2020, Artem</li>
43 <li>Copyright &copy; 2020, David Ignjić</li>
49 <li>Copyright &copy; 2020, David Ignjić</li>
44 <li>Copyright &copy; 2020, Dennis Fink</li>
50 <li>Copyright &copy; 2020, Dennis Fink</li>
@@ -9,6 +9,13 b''
9 </div>
9 </div>
10
10
11 <div class="form-group">
11 <div class="form-group">
12 <label class="control-label" for="owner">${_('Owner')}:</label>
13 <div>
14 ${h.text('owner',class_='form-control', placeholder=_('Type name of user'))}
15 </div>
16 </div>
17
18 <div class="form-group">
12 <label class="control-label" for="group_description">${_('Description')}:</label>
19 <label class="control-label" for="group_description">${_('Description')}:</label>
13 <div>
20 <div>
14 ${h.textarea('group_description',cols=23,rows=5,class_='form-control')}
21 ${h.textarea('group_description',cols=23,rows=5,class_='form-control')}
@@ -47,5 +54,6 b''
47 $("#parent_group_id").select2({
54 $("#parent_group_id").select2({
48 'dropdownAutoWidth': true
55 'dropdownAutoWidth': true
49 });
56 });
57 SimpleUserAutoComplete($('#owner'));
50 });
58 });
51 </script>
59 </script>
@@ -1,17 +1,22 b''
1 ## -*- coding: utf-8 -*-
2
3 ${h.form(url('repos'))}
1 ${h.form(url('repos'))}
4 <div class="form">
2 <div class="form">
5 <div class="form-group">
3 <div class="form-group">
6 <label class="control-label" for="repo_name">${_('Name')}:</label>
4 <label class="control-label" for="repo_name">${_('Name')}:</label>
7 <div>
5 <div>
8 ${h.text('repo_name',class_='form-control')}
6 ${h.text('repo_name',class_='form-control')}
9 </div>
7 </div>
10 </div>
8 </div>
11 <div id="remote_clone" class="form-group">
9 <div class="form-group">
10 <label class="control-label" for="repo_type">${_('Type')}:</label>
11 <div>
12 ${h.select('repo_type','hg',c.backends,class_='form-control')}
13 <span class="help-block">${_('Type of repository to create.')}</span>
14 </div>
15 </div>
16 <div class="form-group">
12 <label class="control-label" for="clone_uri">${_('Clone remote repository')}:</label>
17 <label class="control-label" for="clone_uri">${_('Clone remote repository')}:</label>
13 <div>
18 <div>
14 ${h.text('clone_uri',class_='form-control')}
19 ${h.text('clone_uri',class_='form-control', placeholder=_('Repository URL'))}
15 <span class="help-block">
20 <span class="help-block">
16 ${_('Optional: URL of a remote repository. If set, the repository will be created as a clone from this URL.')}
21 ${_('Optional: URL of a remote repository. If set, the repository will be created as a clone from this URL.')}
17 </span>
22 </span>
@@ -39,16 +44,9 b''
39 </div>
44 </div>
40 </div>
45 </div>
41 <div class="form-group">
46 <div class="form-group">
42 <label class="control-label" for="repo_type">${_('Type')}:</label>
43 <div>
44 ${h.select('repo_type','hg',c.backends,class_='form-control')}
45 <span class="help-block">${_('Type of repository to create.')}</span>
46 </div>
47 </div>
48 <div class="form-group">
49 <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
47 <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
50 <div>
48 <div>
51 ${h.select('repo_landing_rev','',c.landing_revs,class_='form-control')}
49 ${h.select('repo_landing_rev',None,c.landing_revs,class_='form-control')}
52 <span class="help-block">${_('Default revision for files page, downloads, full text search index and readme generation')}</span>
50 <span class="help-block">${_('Default revision for files page, downloads, full text search index and readme generation')}</span>
53 </div>
51 </div>
54 </div>
52 </div>
@@ -60,14 +58,37 b''
60 </div>
58 </div>
61 </div>
59 </div>
62 <div class="form-group">
60 <div class="form-group">
61 <label class="control-label" for="repo_enable_statistics">${_('Enable statistics')}:</label>
62 <div>
63 ${h.checkbox('repo_enable_statistics',value="True")}
64 <span class="help-block">${_('Enable statistics window on summary page.')}</span>
65 </div>
66 </div>
67 <div class="form-group">
68 <label class="control-label" for="repo_enable_downloads">${_('Enable downloads')}:</label>
69 <div>
70 ${h.checkbox('repo_enable_downloads',value="True")}
71 <span class="help-block">${_('Enable download menu on summary page.')}</span>
72 </div>
73 </div>
74 <div class="form-group">
63 <div class="buttons">
75 <div class="buttons">
64 ${h.submit('add',_('Add'),class_="btn btn-default")}
76 ${h.submit('add',_('Add'),class_="btn btn-default")}
65 </div>
77 </div>
66 </div>
78 </div>
67 </div>
79 </div>
80 ${h.end_form()}
81
68 <script>
82 <script>
69 'use strict';
83 'use strict';
70 $(document).ready(function(){
84 $(document).ready(function(){
85 $('#repo_type').select2({
86 'minimumResultsForSearch': -1
87 });
88 $('#repo_group').select2({
89 'dropdownAutoWidth': true
90 });
91
71 function setCopyPermsOption(group_val){
92 function setCopyPermsOption(group_val){
72 if(group_val != "-1"){
93 if(group_val != "-1"){
73 $('#copy_perms').show();
94 $('#copy_perms').show();
@@ -77,22 +98,14 b''
77 }
98 }
78 }
99 }
79
100
80 $("#repo_group").select2({
81 'dropdownAutoWidth': true
82 });
83
84 setCopyPermsOption($('#repo_group').val());
101 setCopyPermsOption($('#repo_group').val());
85 $("#repo_group").on("change", function(e) {
102 $('#repo_group').on("change", function(e) {
86 setCopyPermsOption(e.val);
103 setCopyPermsOption(e.val);
87 });
104 });
88
105
89 $("#repo_type").select2({
106 $('#repo_landing_rev').select2({
90 'minimumResultsForSearch': -1
91 });
92 $("#repo_landing_rev").select2({
93 'minimumResultsForSearch': -1
107 'minimumResultsForSearch': -1
94 });
108 });
95 $('#repo_name').focus();
109 $('#repo_name').focus();
96 });
110 });
97 </script>
111 </script>
98 ${h.end_form()}
@@ -1,115 +1,112 b''
1 ${h.form(url('update_repo', repo_name=c.repo_info.repo_name))}
1 ${h.form(url('update_repo', repo_name=c.repo_info.repo_name))}
2 <div class="form">
2 <div class="form">
3 <div class="form-group">
3 <div class="form-group">
4 <label class="control-label" for="repo_name">${_('Name')}:</label>
4 <label class="control-label" for="repo_name">${_('Name')}:</label>
5 <div>
5 <div>
6 ${h.text('repo_name',class_='form-control')}
6 ${h.text('repo_name',class_='form-control')}
7 </div>
7 </div>
8 </div>
9 <div class="form-group">
10 <label class="control-label" for="permanent_url">${_('Permanent URL')}:</label>
11 <div>
12 ${h.text('permanent_url',class_='form-control', readonly='1')}
13 <span class="help-block">
14 ${_('''In case this repository is renamed or moved into another group the repository URL changes.
15 Using the above permanent URL guarantees that this repository always will be accessible on that URL.
16 This is useful for CI systems, or any other cases that you need to hardcode the URL into a 3rd party service.''')}
17 </span>
18 </div>
19 </div>
20 <div class="form-group">
21 <label class="control-label" for="clone_uri">${_('Remote repository')}:</label>
22 <div>
23 ${h.text('clone_uri',class_='form-control', placeholder=_('Repository URL'))}
24 ${h.hidden('clone_uri_hidden', c.repo_info.clone_uri_hidden)}
25 <span class="help-block">
26 ${_('Optional: URL of a remote repository. If set, the repository can be pulled from this URL.')}
27 </span>
28 </div>
29 </div>
30 <div class="form-group">
31 <label class="control-label" for="repo_description">${_('Description')}:</label>
32 <div>
33 ${h.textarea('repo_description',class_='form-control')}
34 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
35 </div>
36 </div>
37 <div class="form-group">
38 <label class="control-label" for="repo_group">${_('Repository group')}:</label>
39 <div>
40 ${h.select('repo_group',None,c.repo_groups,class_='form-control')}
41 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
8 </div>
42 </div>
43 </div>
44 <div class="form-group">
45 <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
46 <div>
47 ${h.select('repo_landing_rev',None,c.landing_revs,class_='form-control')}
48 <span class="help-block">${_('Default revision for files page, downloads, full text search index and readme generation')}</span>
49 </div>
50 </div>
51 <div class="form-group">
52 <label class="control-label" for="owner">${_('Owner')}:</label>
53 <div>
54 ${h.text('owner',class_='form-control', placeholder=_('Type name of user'))}
55 <span class="help-block">${_('Change owner of this repository.')}</span>
56 </div>
57 </div>
58 <div class="form-group">
59 <label class="control-label" for="repo_private">${_('Private repository')}:</label>
60 <div>
61 ${h.checkbox('repo_private',value="True")}
62 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
63 </div>
64 </div>
65 <div class="form-group">
66 <label class="control-label" for="repo_enable_statistics">${_('Enable statistics')}:</label>
67 <div>
68 ${h.checkbox('repo_enable_statistics',value="True")}
69 <span class="help-block">${_('Enable statistics window on summary page.')}</span>
70 </div>
71 </div>
72 <div class="form-group">
73 <label class="control-label" for="repo_enable_downloads">${_('Enable downloads')}:</label>
74 <div>
75 ${h.checkbox('repo_enable_downloads',value="True")}
76 <span class="help-block">${_('Enable download menu on summary page.')}</span>
77 </div>
78 </div>
79
80 %if c.visual.repository_fields:
81 ## EXTRA FIELDS
82 %for field in c.repo_fields:
9 <div class="form-group">
83 <div class="form-group">
10 <label class="control-label" for="permanent_url">${_('Permanent URL')}:</label>
84 <label class="control-label" for="${field.field_key_prefixed}">${field.field_label} (${field.field_key}):</label>
11 <div>
12 ${h.text('permanent_url',class_='form-control', readonly='1')}
13 <span class="help-block">
14 ${_('''In case this repository is renamed or moved into another group the repository URL changes.
15 Using the above permanent URL guarantees that this repository always will be accessible on that URL.
16 This is useful for CI systems, or any other cases that you need to hardcode the URL into a 3rd party service.''')}
17 </span>
18 </div>
19 </div>
20 <div class="form-group">
21 <label class="control-label" for="clone_uri">${_('Remote repository')}:</label>
22 <div>
85 <div>
23 <div id="alter_clone_uri">
86 ${h.text(field.field_key_prefixed, field.field_value, class_='form-control')}
24 ${h.text('clone_uri',class_='form-control', placeholder=_('Repository URL'))}
87 %if field.field_desc:
25 ${h.hidden('clone_uri_hidden', c.repo_info.clone_uri_hidden)}
88 <span class="help-block">${field.field_desc}</span>
26 </div>
89 %endif
27 <span id="alter_clone_uri_help_block" class="help-block">
28 ${_('Optional: URL of a remote repository. If set, the repository can be pulled from this URL.')}
29 </span>
30 </div>
31 </div>
32 <div class="form-group">
33 <label class="control-label" for="repo_group">${_('Repository group')}:</label>
34 <div>
35 ${h.select('repo_group','',c.repo_groups,class_='form-control')}
36 <span class="help-block">${_('Optionally select a group to put this repository into.')}</span>
37 </div>
38 </div>
39 <div class="form-group">
40 <label class="control-label" for="repo_landing_rev">${_('Landing revision')}:</label>
41 <div>
42 ${h.select('repo_landing_rev','',c.landing_revs,class_='form-control')}
43 <span class="help-block">${_('Default revision for files page, downloads, whoosh and readme')}</span>
44 </div>
45 </div>
46 <div class="form-group">
47 <label class="control-label" for="owner">${_('Owner')}:</label>
48 <div>
49 ${h.text('owner',class_='form-control', placeholder=_('Type name of user'))}
50 <span class="help-block">${_('Change owner of this repository.')}</span>
51 </div>
90 </div>
52 </div>
91 </div>
53 <div class="form-group">
92 %endfor
54 <label class="control-label" for="repo_description">${_('Description')}:</label>
93 %endif
55 <div>
94 <div class="form-group">
56 ${h.textarea('repo_description',class_='form-control')}
95 <div class="buttons">
57 <span class="help-block">${_('Keep it short and to the point. Use a README file for longer descriptions.')}</span>
96 ${h.submit('save',_('Save'),class_="btn btn-default")}
58 </div>
97 ${h.reset('reset',_('Reset'),class_="btn btn-default")}
59 </div>
60
61 <div class="form-group">
62 <label class="control-label" for="repo_private">${_('Private repository')}:</label>
63 <div>
64 ${h.checkbox('repo_private',value="True")}
65 <span class="help-block">${_('Private repositories are only visible to people explicitly added as collaborators.')}</span>
66 </div>
67 </div>
68 <div class="form-group">
69 <label class="control-label" for="repo_enable_statistics">${_('Enable statistics')}:</label>
70 <div>
71 ${h.checkbox('repo_enable_statistics',value="True")}
72 <span class="help-block">${_('Enable statistics window on summary page.')}</span>
73 </div>
74 </div>
98 </div>
75 <div class="form-group">
99 </div>
76 <label class="control-label" for="repo_enable_downloads">${_('Enable downloads')}:</label>
77 <div>
78 ${h.checkbox('repo_enable_downloads',value="True")}
79 <span class="help-block">${_('Enable download menu on summary page.')}</span>
80 </div>
81 </div>
82
83 %if c.visual.repository_fields:
84 ## EXTRA FIELDS
85 %for field in c.repo_fields:
86 <div class="form-group">
87 <label class="control-label" for="${field.field_key_prefixed}">${field.field_label} (${field.field_key}):</label>
88 <div>
89 ${h.text(field.field_key_prefixed, field.field_value, class_='form-control')}
90 %if field.field_desc:
91 <span class="help-block">${field.field_desc}</span>
92 %endif
93 </div>
94 </div>
95 %endfor
96 %endif
97 <div class="form-group">
98 <div class="buttons">
99 ${h.submit('save',_('Save'),class_="btn btn-default")}
100 ${h.reset('reset',_('Reset'),class_="btn btn-default")}
101 </div>
102 </div>
103 </div>
100 </div>
104 ${h.end_form()}
101 ${h.end_form()}
105
102
106 <script>
103 <script>
107 'use strict';
104 'use strict';
108 $(document).ready(function(){
105 $(document).ready(function(){
109 $('#repo_landing_rev').select2({
106 $('#repo_group').select2({
110 'dropdownAutoWidth': true
107 'dropdownAutoWidth': true
111 });
108 });
112 $('#repo_group').select2({
109 $('#repo_landing_rev').select2({
113 'dropdownAutoWidth': true
110 'dropdownAutoWidth': true
114 });
111 });
115
112
@@ -23,7 +23,7 b''
23 <a class="navbar-link" href="${h.url('kallithea_project_url')}" target="_blank">Kallithea</a>,
23 <a class="navbar-link" href="${h.url('kallithea_project_url')}" target="_blank">Kallithea</a>,
24 %endif
24 %endif
25 which is
25 which is
26 <a class="navbar-link" href="${h.canonical_url('about')}#copyright">&copy; 2010&ndash;2022 by various authors &amp; licensed under GPLv3</a>.
26 <a class="navbar-link" href="${h.canonical_url('about')}#copyright">&copy; 2010&ndash;2023 by various authors &amp; licensed under GPLv3</a>.
27 %if c.issues_url:
27 %if c.issues_url:
28 &ndash; <a class="navbar-link" href="${c.issues_url}" target="_blank">${_('Support')}</a>
28 &ndash; <a class="navbar-link" href="${c.issues_url}" target="_blank">${_('Support')}</a>
29 %endif
29 %endif
@@ -38,8 +38,8 b''
38 'Search truncated': ${h.jshtml(_('Search truncated'))},
38 'Search truncated': ${h.jshtml(_('Search truncated'))},
39 'No matching files': ${h.jshtml(_('No matching files'))},
39 'No matching files': ${h.jshtml(_('No matching files'))},
40 'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
40 'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
41 'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
41 'Open New Pull Request for {0}': ${h.js(_('Open New Pull Request for {0}'))},
42 'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
42 'Show Selected Changesets {0}': ${h.js(_('Show Selected Changesets {0}'))},
43 'Selection Link': ${h.jshtml(_('Selection Link'))},
43 'Selection Link': ${h.jshtml(_('Selection Link'))},
44 'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
44 'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
45 'Expand Diff': ${h.jshtml(_('Expand Diff'))},
45 'Expand Diff': ${h.jshtml(_('Expand Diff'))},
@@ -109,13 +109,13 b''
109 pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},
109 pyroutes.url('changeset_home', {'repo_name': ${h.js(c.repo_name)},
110 'revision': rev_start + '...' + rev_end}));
110 'revision': rev_start + '...' + rev_end}));
111 $('#rev_range_container').html(
111 $('#rev_range_container').html(
112 _TM['Show Selected Changesets {0} &rarr; {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12)));
112 _TM['Show Selected Changesets {0}'].format(rev_start.substr(0, 12) + ' &rarr; ' + rev_end.substr(0, 12)));
113 $('#rev_range_container').show();
113 $('#rev_range_container').show();
114 $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
114 $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
115 {'repo_name': ${h.js(c.repo_name)},
115 {'repo_name': ${h.js(c.repo_name)},
116 'rev_start': rev_start,
116 'rev_start': rev_start,
117 'rev_end': rev_end}));
117 'rev_end': rev_end}));
118 $('#open_new_pr').html(_TM['Open New Pull Request for {0} &rarr; {1}'].format(rev_start.substr(0, 12), rev_end.substr(0, 12)));
118 $('#open_new_pr').html(_TM['Open New Pull Request for {0}'].format(rev_start.substr(0, 12) + ' &rarr; ' + rev_end.substr(0, 12)));
119 } else {
119 } else {
120 $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
120 $('#open_new_pr').prop('href', pyroutes.url('pullrequest_home',
121 {'repo_name': ${h.js(c.repo_name)},
121 {'repo_name': ${h.js(c.repo_name)},
@@ -224,7 +224,7 b' hg push ${c.clone_repo_url}'
224 <div id="readme" class="anchor">
224 <div id="readme" class="anchor">
225 </div>
225 </div>
226 <div class="panel panel-primary">
226 <div class="panel panel-primary">
227 <div class="panel-heading" title="${_('Readme file from revision %s:%s') % (c.db_repo.landing_rev[0], c.db_repo.landing_rev[1])}">
227 <div class="panel-heading" title="${_('Readme file from %s') % (c.db_repo.landing_rev[1])}">
228 <div class="panel-title">
228 <div class="panel-title">
229 <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
229 <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
230 </div>
230 </div>
@@ -16,6 +16,7 b''
16 Tests for the JSON-RPC web api.
16 Tests for the JSON-RPC web api.
17 """
17 """
18
18
19 import datetime
19 import os
20 import os
20 import random
21 import random
21 import re
22 import re
@@ -260,7 +261,7 b' class _BaseTestApi(object):'
260 self._compare_error(id_, expected, given=response.body)
261 self._compare_error(id_, expected, given=response.body)
261
262
262 def test_api_pull_remote(self):
263 def test_api_pull_remote(self):
263 # Note: pulling from local repos is a mis-feature - it will bypass access control
264 # Note: pulling from local repos is a misfeature - it will bypass access control
264 # ... but ok, if the path already has been set in the database
265 # ... but ok, if the path already has been set in the database
265 repo_name = 'test_pull'
266 repo_name = 'test_pull'
266 r = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
267 r = fixture.create_repo(repo_name, repo_type=self.REPO_TYPE)
@@ -784,24 +785,73 b' class _BaseTestApi(object):'
784 finally:
785 finally:
785 RepoModel().revoke_user_permission(self.REPO, self.TEST_USER_LOGIN)
786 RepoModel().revoke_user_permission(self.REPO, self.TEST_USER_LOGIN)
786
787
787 def test_api_create_repo(self):
788 @base.parametrize('changing_attr,updates', [
788 repo_name = 'api-repo'
789 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
790 ('description', {'description': 'new description'}),
791 ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
792 ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
793 ('clone_uri', {'clone_uri': None}),
794 ('landing_rev', {'landing_rev': 'branch:master'}),
795 ('private', {'private': True}),
796 ('enable_statistics', {'enable_statistics': True}),
797 ('enable_downloads', {'enable_downloads': True}),
798 ('repo_group', {'group': 'test_group_for_update'}),
799 ])
800 def test_api_create_repo(self, changing_attr, updates):
801 repo_name = repo_name_full = 'new_repo'
802
803 if changing_attr == 'repo_group':
804 group_name = updates['group']
805 fixture.create_repo_group(group_name)
806 repo_name_full = '/'.join([group_name, repo_name])
807 updates = {}
808
789 id_, params = _build_data(self.apikey, 'create_repo',
809 id_, params = _build_data(self.apikey, 'create_repo',
790 repo_name=repo_name,
810 repo_type=self.REPO_TYPE, repo_name=repo_name_full, **updates)
791 owner=base.TEST_USER_ADMIN_LOGIN,
792 repo_type=self.REPO_TYPE,
793 )
794 response = api_call(self, params)
811 response = api_call(self, params)
795
812
796 repo = RepoModel().get_by_repo_name(repo_name)
813 try:
797 assert repo is not None
814 expected = {
798 ret = {
815 'msg': 'Created new repository `%s`' % repo_name_full,
799 'msg': 'Created new repository `%s`' % repo_name,
816 'success': True}
800 'success': True,
817 if changing_attr == 'clone_uri' and updates['clone_uri']:
801 }
818 expected = 'failed to create repository `%s`' % repo_name
802 expected = ret
819 self._compare_error(id_, expected, given=response.body)
803 self._compare_ok(id_, expected, given=response.body)
820 return
804 fixture.destroy_repo(repo_name)
821 else:
822 self._compare_ok(id_, expected, given=response.body)
823
824 repo = db.Repository.get_by_repo_name(repo_name_full)
825 assert repo is not None
826
827 expected_data = {
828 'clone_uri': None,
829 'created_on': repo.created_on,
830 'description': repo_name,
831 'enable_downloads': False,
832 'enable_statistics': False,
833 'fork_of': None,
834 'landing_rev': ['rev', 'tip'],
835 'last_changeset': {'author': '',
836 'date': datetime.datetime(1970, 1, 1, 0, 0),
837 'message': '',
838 'raw_id': '0000000000000000000000000000000000000000',
839 'revision': -1,
840 'short_id': '000000000000'},
841 'owner': 'test_admin',
842 'private': False,
843 'repo_id': repo.repo_id,
844 'repo_name': repo_name_full,
845 'repo_type': self.REPO_TYPE,
846 }
847 expected_data.update(updates)
848 if changing_attr == 'landing_rev':
849 expected_data['landing_rev'] = expected_data['landing_rev'].split(':', 1)
850 assert repo.get_api_data() == expected_data
851 finally:
852 fixture.destroy_repo(repo_name_full)
853 if changing_attr == 'repo_group':
854 fixture.destroy_repo_group(group_name)
805
855
806 @base.parametrize('repo_name', [
856 @base.parametrize('repo_name', [
807 '',
857 '',
@@ -827,7 +877,7 b' class _BaseTestApi(object):'
827 fixture.destroy_repo(repo_name)
877 fixture.destroy_repo(repo_name)
828
878
829 def test_api_create_repo_clone_uri_local(self):
879 def test_api_create_repo_clone_uri_local(self):
830 # cloning from local repos was a mis-feature - it would bypass access control
880 # cloning from local repos was a misfeature - it would bypass access control
831 # TODO: introduce other test coverage of actual remote cloning
881 # TODO: introduce other test coverage of actual remote cloning
832 clone_uri = os.path.join(base.TESTS_TMP_PATH, self.REPO)
882 clone_uri = os.path.join(base.TESTS_TMP_PATH, self.REPO)
833 repo_name = 'api-repo'
883 repo_name = 'api-repo'
@@ -1004,9 +1054,10 b' class _BaseTestApi(object):'
1004 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
1054 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
1005 ('description', {'description': 'new description'}),
1055 ('description', {'description': 'new description'}),
1006 ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
1056 ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
1007 ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a mis-feature - it would bypass access control
1057 ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
1008 ('clone_uri', {'clone_uri': None}),
1058 ('clone_uri', {'clone_uri': None}),
1009 ('landing_rev', {'landing_rev': 'branch:master'}),
1059 ('landing_rev', {'landing_rev': 'branch:master'}),
1060 ('private', {'private': True}),
1010 ('enable_statistics', {'enable_statistics': True}),
1061 ('enable_statistics', {'enable_statistics': True}),
1011 ('enable_downloads', {'enable_downloads': True}),
1062 ('enable_downloads', {'enable_downloads': True}),
1012 ('name', {'name': 'new_repo_name'}),
1063 ('name', {'name': 'new_repo_name'}),
@@ -1020,20 +1071,32 b' class _BaseTestApi(object):'
1020
1071
1021 id_, params = _build_data(self.apikey, 'update_repo',
1072 id_, params = _build_data(self.apikey, 'update_repo',
1022 repoid=repo_name, **updates)
1073 repoid=repo_name, **updates)
1023 response = api_call(self, params)
1074
1024 if changing_attr == 'name':
1075 if changing_attr == 'name':
1025 repo_name = updates['name']
1076 repo_name = updates['name']
1026 if changing_attr == 'repo_group':
1077 if changing_attr == 'repo_group':
1027 repo_name = '/'.join([updates['group'], repo_name])
1078 repo_name = '/'.join([updates['group'], repo_name])
1079 expected = {
1080 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name),
1081 'repository': repo.get_api_data()
1082 }
1083 expected['repository'].update(updates)
1084 if changing_attr == 'clone_uri' and updates['clone_uri'] is None:
1085 expected['repository']['clone_uri'] = ''
1086 if changing_attr == 'landing_rev':
1087 expected['repository']['landing_rev'] = expected['repository']['landing_rev'].split(':', 1)
1088 if changing_attr == 'name':
1089 expected['repository']['repo_name'] = expected['repository'].pop('name')
1090 if changing_attr == 'repo_group':
1091 expected['repository']['repo_name'] = expected['repository'].pop('group') + '/' + repo.repo_name
1092
1093 response = api_call(self, params)
1094
1028 try:
1095 try:
1029 if changing_attr == 'clone_uri' and updates['clone_uri']:
1096 if changing_attr == 'clone_uri' and updates['clone_uri']:
1030 expected = 'failed to update repo `%s`' % repo_name
1097 expected = 'failed to update repo `%s`' % repo_name
1031 self._compare_error(id_, expected, given=response.body)
1098 self._compare_error(id_, expected, given=response.body)
1032 else:
1099 else:
1033 expected = {
1034 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name),
1035 'repository': repo.get_api_data()
1036 }
1037 self._compare_ok(id_, expected, given=response.body)
1100 self._compare_ok(id_, expected, given=response.body)
1038 finally:
1101 finally:
1039 fixture.destroy_repo(repo_name)
1102 fixture.destroy_repo(repo_name)
@@ -1044,7 +1107,7 b' class _BaseTestApi(object):'
1044 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
1107 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
1045 ('description', {'description': 'new description'}),
1108 ('description', {'description': 'new description'}),
1046 ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
1109 ('clone_uri', {'clone_uri': 'http://example.com/repo'}), # will fail - pulling from non-existing repo should fail
1047 ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a mis-feature - it would bypass access control
1110 ('clone_uri', {'clone_uri': '/repo'}), # will fail - pulling from local repo was a misfeature - it would bypass access control
1048 ('clone_uri', {'clone_uri': None}),
1111 ('clone_uri', {'clone_uri': None}),
1049 ('landing_rev', {'landing_rev': 'branch:master'}),
1112 ('landing_rev', {'landing_rev': 'branch:master'}),
1050 ('enable_statistics', {'enable_statistics': True}),
1113 ('enable_statistics', {'enable_statistics': True}),
@@ -1788,6 +1851,47 b' class _BaseTestApi(object):'
1788 )
1851 )
1789 self._compare_error(id_, expected, given=response.body)
1852 self._compare_error(id_, expected, given=response.body)
1790
1853
1854 @base.parametrize('changing_attr,updates', [
1855 ('owner', {'owner': base.TEST_USER_REGULAR_LOGIN}),
1856 ('description', {'description': 'new description'}),
1857 ('group_name', {'group_name': 'new_repo_name'}),
1858 ('parent', {'parent': 'test_group_for_update'}),
1859 ])
1860 def test_api_update_repo_group(self, changing_attr, updates):
1861 group_name = 'lololo'
1862 repo_group = fixture.create_repo_group(group_name)
1863
1864 new_group_name = group_name
1865 if changing_attr == 'group_name':
1866 assert repo_group.parent_group_id is None # lazy assumption for this test
1867 new_group_name = updates['group_name']
1868 if changing_attr == 'parent':
1869 new_group_name = '/'.join([updates['parent'], group_name.rsplit('/', 1)[-1]])
1870
1871 expected = {
1872 'msg': 'updated repository group ID:%s %s' % (repo_group.group_id, new_group_name),
1873 'repo_group': repo_group.get_api_data()
1874 }
1875 expected['repo_group'].update(updates)
1876 if 'description' in updates:
1877 expected['repo_group']['group_description'] = expected['repo_group'].pop('description')
1878
1879 if changing_attr == 'parent':
1880 new_parent = fixture.create_repo_group(updates['parent'])
1881 expected['repo_group']['parent_group'] = expected['repo_group'].pop('parent')
1882 expected['repo_group']['group_name'] = new_group_name
1883
1884 id_, params = _build_data(self.apikey, 'update_repo_group',
1885 repogroupid=group_name, **updates)
1886 response = api_call(self, params)
1887
1888 try:
1889 self._compare_ok(id_, expected, given=response.body)
1890 finally:
1891 if changing_attr == 'parent':
1892 fixture.destroy_repo_group(new_parent.group_id)
1893 fixture.destroy_repo_group(new_group_name)
1894
1791 @base.parametrize('name,perm,apply_to_children', [
1895 @base.parametrize('name,perm,apply_to_children', [
1792 ('none', 'group.none', 'none'),
1896 ('none', 'group.none', 'none'),
1793 ('read', 'group.read', 'none'),
1897 ('read', 'group.read', 'none'),
@@ -2375,6 +2479,8 b' class _BaseTestApi(object):'
2375 result = ext_json.loads(response.body)["result"]
2479 result = ext_json.loads(response.body)["result"]
2376 assert result["raw_id"] == self.TEST_REVISION
2480 assert result["raw_id"] == self.TEST_REVISION
2377 assert "reviews" not in result
2481 assert "reviews" not in result
2482 assert "comments" not in result
2483 assert "inline_comments" not in result
2378
2484
2379 def test_api_get_changeset_with_reviews(self):
2485 def test_api_get_changeset_with_reviews(self):
2380 reviewobjs = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved")
2486 reviewobjs = fixture.review_changeset(self.REPO, self.TEST_REVISION, "approved")
@@ -2385,6 +2491,8 b' class _BaseTestApi(object):'
2385 result = ext_json.loads(response.body)["result"]
2491 result = ext_json.loads(response.body)["result"]
2386 assert result["raw_id"] == self.TEST_REVISION
2492 assert result["raw_id"] == self.TEST_REVISION
2387 assert "reviews" in result
2493 assert "reviews" in result
2494 assert "comments" not in result
2495 assert "inline_comments" not in result
2388 assert len(result["reviews"]) == 1
2496 assert len(result["reviews"]) == 1
2389 review = result["reviews"][0]
2497 review = result["reviews"][0]
2390 expected = {
2498 expected = {
@@ -2394,6 +2502,49 b' class _BaseTestApi(object):'
2394 }
2502 }
2395 assert review == expected
2503 assert review == expected
2396
2504
2505 def test_api_get_changeset_with_comments(self):
2506 commentobj = fixture.add_changeset_comment(self.REPO, self.TEST_REVISION, "example changeset comment")
2507 id_, params = _build_data(self.apikey, 'get_changeset',
2508 repoid=self.REPO, raw_id=self.TEST_REVISION,
2509 with_comments=True)
2510 response = api_call(self, params)
2511 result = ext_json.loads(response.body)["result"]
2512 assert result["raw_id"] == self.TEST_REVISION
2513 assert "reviews" not in result
2514 assert "comments" in result
2515 assert "inline_comments" not in result
2516 comment = result["comments"][-1]
2517 expected = {
2518 'comment_id': commentobj.comment_id,
2519 'text': 'example changeset comment',
2520 'username': 'test_admin',
2521 'created_on': commentobj.created_on.replace(microsecond=0).isoformat(),
2522 }
2523 assert comment == expected
2524
2525 def test_api_get_changeset_with_inline_comments(self):
2526 commentobj = fixture.add_changeset_comment(self.REPO, self.TEST_REVISION, "example inline comment", f_path='vcs/__init__.py', line_no="n3")
2527 id_, params = _build_data(self.apikey, 'get_changeset',
2528 repoid=self.REPO, raw_id=self.TEST_REVISION,
2529 with_inline_comments=True)
2530 response = api_call(self, params)
2531 result = ext_json.loads(response.body)["result"]
2532 assert result["raw_id"] == self.TEST_REVISION
2533 assert "reviews" not in result
2534 assert "comments" not in result
2535 assert "inline_comments" in result
2536 expected = [
2537 ['vcs/__init__.py', {
2538 'n3': [{
2539 'comment_id': commentobj.comment_id,
2540 'text': 'example inline comment',
2541 'username': 'test_admin',
2542 'created_on': commentobj.created_on.replace(microsecond=0).isoformat(),
2543 }]
2544 }]
2545 ]
2546 assert result["inline_comments"] == expected
2547
2397 def test_api_get_changeset_that_does_not_exist(self):
2548 def test_api_get_changeset_that_does_not_exist(self):
2398 """ Fetch changeset status for non-existant changeset.
2549 """ Fetch changeset status for non-existant changeset.
2399 revision id is the above git hash used in the test above with the
2550 revision id is the above git hash used in the test above with the
@@ -2436,7 +2587,8 b' class _BaseTestApi(object):'
2436 "org_ref_parts": ["branch", "stable", self.TEST_PR_SRC],
2587 "org_ref_parts": ["branch", "stable", self.TEST_PR_SRC],
2437 "other_ref_parts": ["branch", "default", self.TEST_PR_DST],
2588 "other_ref_parts": ["branch", "default", self.TEST_PR_DST],
2438 "comments": [{"username": base.TEST_USER_ADMIN_LOGIN, "text": "",
2589 "comments": [{"username": base.TEST_USER_ADMIN_LOGIN, "text": "",
2439 "comment_id": pullrequest.comments[0].comment_id}],
2590 "comment_id": pullrequest.comments[0].comment_id,
2591 "created_on": "2000-01-01T00:00:00"}],
2440 "owner": base.TEST_USER_ADMIN_LOGIN,
2592 "owner": base.TEST_USER_ADMIN_LOGIN,
2441 "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))],
2593 "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))],
2442 "title": "get test",
2594 "title": "get test",
@@ -95,6 +95,8 b' class Fixture(object):'
95 repo_group='-1',
95 repo_group='-1',
96 repo_description='DESC',
96 repo_description='DESC',
97 repo_private=False,
97 repo_private=False,
98 repo_enable_statistics=False,
99 repo_enable_downloads=False,
98 repo_landing_rev='rev:tip',
100 repo_landing_rev='rev:tip',
99 repo_copy_permissions=False,
101 repo_copy_permissions=False,
100 repo_state=db.Repository.STATE_CREATED,
102 repo_state=db.Repository.STATE_CREATED,
@@ -327,6 +329,11 b' class Fixture(object):'
327 meta.Session().commit()
329 meta.Session().commit()
328 return csm
330 return csm
329
331
332 def add_changeset_comment(self, repo, revision, text, author=TEST_USER_ADMIN_LOGIN, f_path=None, line_no=None):
333 comment = ChangesetCommentsModel().create(text, repo, author, revision=revision, f_path=f_path, line_no=line_no, send_email=False)
334 meta.Session().commit()
335 return comment
336
330 def create_pullrequest(self, testcontroller, repo_name, pr_src_rev, pr_dst_rev, title='title'):
337 def create_pullrequest(self, testcontroller, repo_name, pr_src_rev, pr_dst_rev, title='title'):
331 org_ref = 'branch:stable:%s' % pr_src_rev
338 org_ref = 'branch:stable:%s' % pr_src_rev
332 other_ref = 'branch:default:%s' % pr_dst_rev
339 other_ref = 'branch:default:%s' % pr_dst_rev
@@ -53,6 +53,7 b' class TestRepoGroupsController(base.Test'
53 # edit
53 # edit
54 response = self.app.post(base.url('update_repos_group', group_name=group_name),
54 response = self.app.post(base.url('update_repos_group', group_name=group_name),
55 {'group_name': group_name,
55 {'group_name': group_name,
56 'owner': base.TEST_USER_REGULAR2_LOGIN,
56 'group_description': 'lolo',
57 'group_description': 'lolo',
57 '_session_csrf_secret_token': self.session_csrf_secret_token()})
58 '_session_csrf_secret_token': self.session_csrf_secret_token()})
58 self.checkSessionFlash(response, 'Updated repository group %s' % group_name)
59 self.checkSessionFlash(response, 'Updated repository group %s' % group_name)
@@ -75,6 +75,8 b' requirements = ['
75 "pip >= 20.0, < 999",
75 "pip >= 20.0, < 999",
76 "chardet >= 3",
76 "chardet >= 3",
77 ]
77 ]
78 if sys.version_info < (3, 8):
79 requirements.append("importlib-metadata < 5")
78
80
79 dependency_links = [
81 dependency_links = [
80 ]
82 ]
General Comments 0
You need to be logged in to leave comments. Login now