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