Changeset - cd50d1b5f35b
CONTRIBUTORS
Show inline comments
 
@@ -23,12 +23,13 @@ List of contributors to RhodeCode projec
 
    Takumi IINO <trot.thunder@gmail.com>
 
    Indra Talip <indra.talip@gmail.com>
 
    James Rhodes <jrhodes@redpointsoftware.com.au>
 
    Dominik Ruf <dominikruf@gmail.com>
 
    xpol <xpolife@gmail.com>
 
    Vincent Caron <vcaron@bearstech.com>
 
    Zachary Auclair <zach101@gmail.com>
 
    Stefan Engel <mail@engel-stefan.de>
 
    Andrew Shadura <bugzilla@tut.by>
 
    Raoul Thill <raoul.thill@gmail.com>
 
    Philip Jameson <philip.j@hostdime.com>
 
    Mads Kiilerich <madski@unity3d.com>
 
    Dan Sheridan <djs@adelard.com>
docs/api/api.rst
Show inline comments
 
@@ -146,79 +146,115 @@ INPUT::
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : "{'added': [<list of names of added repos>], 
 
               'removed': [<list of names of removed repos>]}"
 
    error :  null
 

	
 

	
 
lock
 
----
 

	
 
Set locking state on given repository by given user.
 
Set locking state on given repository by given user. If userid param is skipped
 
, then it is set to id of user whos calling this method.
 
This command can be executed only using api_key belonging to user with admin 
 
rights.
 
rights or regular user that have admin or write access to repository.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "lock"
 
    args :    {
 
                "repoid" : "<reponame or repo_id>"
 
                "userid" : "<user_id or username>",
 
                "userid" : "<user_id or username = Optional(=apiuser)>",
 
                "locked" : "<bool true|false>"
 
                
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result : "User `<username>` set lock state for repo `<reponame>` to `true|false`"
 
    error :  null
 

	
 

	
 
show_ip
 
-------
 

	
 
Shows IP address as seen from RhodeCode server, together with all
 
defined IP addresses for given user.
 
This command can be executed only using api_key belonging to user with admin 
 
rights.
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "show_ip"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
              }
 

	
 
OUTPUT::
 

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

	
 

	
 
get_user
 
--------
 

	
 
Get's an user by username or user_id, Returns empty result if user is not found.
 
If userid param is skipped it is set to id of user who is calling this method.
 
This command can be executed only using api_key belonging to user with admin 
 
rights.
 
rights, or regular users that cannot specify different userid than theirs
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_user"
 
    args :    { 
 
                "userid" : "<username or user_id>"
 
                "userid" : "<username or user_id Optional(=apiuser)>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: None if user does not exist or 
 
            {
 
                "user_id" :  "<user_id>",
 
                "username" : "<username>",
 
                "firstname": "<firstname>",
 
                "lastname" : "<lastname>",
 
                "email" :    "<email>",
 
                "emails":    "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
                "user_id" :     "<user_id>",
 
                "username" :    "<username>",
 
                "firstname":    "<firstname>",
 
                "lastname" :    "<lastname>",
 
                "email" :       "<email>",
 
                "emails":       "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login":   "<last_login>",
 
                "permissions": {
 
                    "global": ["hg.create.repository",
 
                               "repository.read",
 
                               "hg.register.manual_activate"],
 
                    "repositories": {"repo1": "repository.none"},
 
                    "repositories_groups": {"Group1": "group.read"}
 
                 },
 
            }
 

	
 
    error:  null
 

	
 

	
 
@@ -232,34 +268,35 @@ belonging to user with admin rights.
 
INPUT::
 

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

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: [
 
              {
 
                "user_id" :  "<user_id>",
 
                "username" : "<username>",
 
                "firstname": "<firstname>",
 
                "lastname" : "<lastname>",
 
                "email" :    "<email>",
 
                "emails":    "<list_of_all_additional_emails>",
 
                "active" :   "<bool>",
 
                "admin" :    "<bool>",
 
                "ldap_dn" :  "<ldap_dn>",
 
                "last_login": "<last_login>",
 
                "user_id" :     "<user_id>",
 
                "username" :    "<username>",
 
                "firstname":    "<firstname>",
 
                "lastname" :    "<lastname>",
 
                "email" :       "<email>",
 
                "emails":       "<list_of_all_additional_emails>",
 
                "ip_addresses": "<list_of_ip_addresses_for_user>",
 
                "active" :      "<bool>",
 
                "admin" :       "<bool>",
 
                "ldap_dn" :     "<ldap_dn>",
 
                "last_login":   "<last_login>",
 
              },
 
    	
 
            ]
 
    error:  null
 

	
 

	
 
create_user
 
-----------
 

	
 
Creates new user. This command can 
 
be executed only using api_key belonging to user with admin rights.
 

	
 
@@ -306,32 +343,32 @@ update_user
 

	
 
updates given user if such user exists. This command can 
 
be executed only using api_key belonging to user with admin rights.
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "update_user"
 
    args :    {
 
                "userid" : "<user_id or username>",
 
                "username" :  "<username> = Optional",
 
                "email" :     "<useremail> = Optional",
 
                "password" :  "<password> = Optional",
 
                "firstname" : "<firstname> = Optional",
 
                "lastname" :  "<lastname> = Optional",
 
                "active" :    "<bool> = Optional",
 
                "admin" :     "<bool> = Optional",
 
                "ldap_dn" :   "<ldap_dn> = Optional"
 
                "username" :  "<username> = Optional(None)",
 
                "email" :     "<useremail> = Optional(None)",
 
                "password" :  "<password> = Optional(None)",
 
                "firstname" : "<firstname> = Optional(None)",
 
                "lastname" :  "<lastname> = Optional(None)",
 
                "active" :    "<bool> = Optional(None)",
 
                "admin" :     "<bool> = Optional(None)",
 
                "ldap_dn" :   "<ldap_dn> = Optional(None)"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: {
 
              "msg" : "updated user ID:<userid> <username>",
 
              "user": {
 
                "user_id" :  "<user_id>",
 
                "username" : "<username>",
 
                "firstname": "<firstname>",
 
                "lastname" : "<lastname>",
 
@@ -528,110 +565,126 @@ OUTPUT::
 
    result: {
 
              "success":  True|False,  # depends on if member is in group
 
              "msg": "removed member <username> from users group <groupname> | 
 
                      User wasn't in group"
 
            }
 
    error:  null
 

	
 

	
 
get_repo
 
--------
 

	
 
Gets an existing repository by it's name or repository_id. Members will return
 
either users_group or user associated to that repository. This command can 
 
be executed only using api_key belonging to user with admin rights.
 
either users_group or user associated to that repository. This command can be 
 
executed only using api_key belonging to user with admin 
 
rights or regular user that have at least read access to repository.
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "get_repo"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: None if repository does not exist or
 
            {
 
                "repo_id" :     "<repo_id>",
 
                "repo_name" :   "<reponame>"
 
                "repo_type" :   "<repo_type>",
 
                "clone_uri" :   "<clone_uri>",
 
                "private": :    "<bool>",
 
                "created_on" :  "<datetimecreated>",                
 
                "description" : "<description>",
 
                "landing_rev":  "<landing_rev>",
 
                "owner":        "<repo_owner>",
 
                "fork_of":  "<name_of_fork_parent>",
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "enable_downloads":  "<bool>",
 
                "enable_locking":    "<bool>",
 
                "enable_statistics": "<bool>",                
 
                "private":           "<bool>",
 
                "created_on" :       "<date_time_created>",                
 
                "description" :      "<description>",
 
                "landing_rev":       "<landing_rev>",
 
                "last_changeset":    {
 
                                       "author":   "<full_author>",
 
                                       "date":     "<date_time_of_commit>",
 
                                       "message":  "<commit_message>",
 
                                       "raw_id":   "<raw_id>",
 
                                       "revision": "<numeric_revision>",
 
                                       "short_id": "<short_id>"
 
                                     }
 
                "owner":             "<repo_owner>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "members" :     [
 
                                  { 
 
                                    "type": "user",
 
                                    "user_id" :  "<user_id>",
 
                                    "username" : "<username>",
 
                                    "firstname": "<firstname>",
 
                                    "lastname" : "<lastname>",
 
                                    "email" :    "<email>",
 
                                    "emails":    "<list_of_all_additional_emails>",
 
                                    "active" :   "<bool>",
 
                                    "admin" :    "<bool>",
 
                                    "ldap_dn" :  "<ldap_dn>",
 
                                    "last_login": "<last_login>",
 
                                    "user_id" :    "<user_id>",
 
                                    "username" :   "<username>",
 
                                    "firstname":   "<firstname>",
 
                                    "lastname" :   "<lastname>",
 
                                    "email" :      "<email>",
 
                                    "emails":      "<list_of_all_additional_emails>",
 
                                    "active" :     "<bool>",
 
                                    "admin" :      "<bool>",
 
                                    "ldap_dn" :    "<ldap_dn>",
 
                                    "last_login":  "<last_login>",
 
                                    "permission" : "repository.(read|write|admin)"
 
                                  },
 
 
                                  { 
 
                                    "type": "users_group",
 
                                    "id" :       "<usersgroupid>",
 
                                    "name" :     "<usersgroupname>",
 
                                    "active":    "<bool>",
 
                                    "permission" : "repository.(read|write|admin)"
 
                                  },
 
 
                                ]
 
            }
 
    error:  null
 

	
 

	
 
get_repos
 
---------
 

	
 
Lists all existing repositories. This command can be executed only using api_key
 
belonging to user with admin rights
 
Lists all existing repositories. This command can be executed only using 
 
api_key belonging to user with admin rights or regular user that have 
 
admin, write or read access to repository.
 

	
 

	
 
INPUT::
 

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

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: [
 
              {
 
                "repo_id" :     "<repo_id>",
 
                "repo_name" :   "<reponame>"
 
                "repo_type" :   "<repo_type>",
 
                "clone_uri" :   "<clone_uri>",
 
                "private": :    "<bool>",
 
                "created_on" :  "<datetimecreated>",                
 
                "description" : "<description>",
 
                "landing_rev":  "<landing_rev>",
 
                "owner":        "<repo_owner>",
 
                "fork_of":  "<name_of_fork_parent>",
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private": :         "<bool>",
 
                "created_on" :       "<datetimecreated>",                
 
                "description" :      "<description>",
 
                "landing_rev":       "<landing_rev>",
 
                "owner":             "<repo_owner>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "enable_downloads":  "<bool>",
 
                "enable_locking":    "<bool>",
 
                "enable_statistics": "<bool>",                   
 
              },
 
 
            ]
 
    error:  null
 

	
 

	
 
get_repo_nodes
 
--------------
 

	
 
returns a list of nodes and it's children in a flat list for a given path 
 
at given revision. It's possible to specify ret_type to show only `files` or 
 
`dirs`. This command can be executed only using api_key belonging to user 
 
@@ -657,72 +710,115 @@ OUTPUT::
 
              {
 
                "name" :        "<name>"
 
                "type" :        "<type>",
 
              },
 
 
            ]
 
    error:  null
 

	
 

	
 
create_repo
 
-----------
 

	
 
Creates a repository. This command can be executed only using api_key
 
belonging to user with admin rights.
 
If repository name contains "/", all needed repository groups will be created.
 
For example "foo/bar/baz" will create groups "foo", "bar" (with "foo" as parent),
 
and create "baz" repository with "bar" as group.
 
Creates a repository. If repository name contains "/", all needed repository
 
groups will be created. For example "foo/bar/baz" will create groups 
 
"foo", "bar" (with "foo" as parent), and create "baz" repository with 
 
"bar" as group. This command can be executed only using api_key belonging to user with admin 
 
rights or regular user that have create repository permission. Regular users
 
cannot specify owner parameter
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "create_repo"
 
    args:     {
 
                "repo_name" :   "<reponame>",
 
                "owner" :       "<onwer_name_or_id>",
 
                "repo_type" :   "<repo_type>",
 
                "description" : "<description> = Optional('')",
 
                "private" :     "<bool> = Optional(False)",
 
                "clone_uri" :   "<clone_uri> = Optional(None)",
 
                "landing_rev" : "<landing_rev> = Optional('tip')",
 
                "repo_name" :        "<reponame>",
 
                "owner" :            "<onwer_name_or_id = Optional(=apiuser)>",
 
                "repo_type" :        "<repo_type> = Optional('hg')",
 
                "description" :      "<description> = Optional('')",
 
                "private" :          "<bool> = Optional(False)",
 
                "clone_uri" :        "<clone_uri> = Optional(None)",
 
                "landing_rev" :      "<landing_rev> = Optional('tip')",
 
                "enable_downloads":  "<bool> = Optional(False)",
 
                "enable_locking":    "<bool> = Optional(False)",
 
                "enable_statistics": "<bool> = Optional(False)",
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: {
 
              "msg": "Created new repository `<reponame>`",
 
              "repo": {
 
                "repo_id" :     "<repo_id>",
 
                "repo_name" :   "<reponame>"
 
                "repo_type" :   "<repo_type>",
 
                "clone_uri" :   "<clone_uri>",
 
                "private": :    "<bool>",
 
                "created_on" :  "<datetimecreated>",                
 
                "description" : "<description>",
 
                "landing_rev":  "<landing_rev>",
 
                "owner":        "<repo_owner>",
 
                "fork_of":  "<name_of_fork_parent>",
 
                "repo_id" :          "<repo_id>",
 
                "repo_name" :        "<reponame>"
 
                "repo_type" :        "<repo_type>",
 
                "clone_uri" :        "<clone_uri>",
 
                "private": :         "<bool>",
 
                "created_on" :       "<datetimecreated>",                
 
                "description" :      "<description>",
 
                "landing_rev":       "<landing_rev>",
 
                "owner":             "<username or user_id>",
 
                "fork_of":           "<name_of_fork_parent>",
 
                "enable_downloads":  "<bool>",
 
                "enable_locking":    "<bool>",
 
                "enable_statistics": "<bool>",                     
 
              },
 
            }
 
    error:  null
 

	
 

	
 
fork_repo
 
---------
 

	
 
Creates a fork of given repo. In case of using celery this will
 
immidiatelly return success message, while fork is going to be created
 
asynchronous. This command can be executed only using api_key belonging to
 
user with admin rights or regular user that have fork permission, and at least
 
read access to forking repository. Regular users cannot specify owner parameter.
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "fork_repo"
 
    args:     {
 
                "repoid" :          "<reponame or repo_id>",
 
                "fork_name":        "<forkname>",
 
                "owner":            "<username or user_id = Optional(=apiuser)>",
 
                "description":      "<description>",
 
                "copy_permissions": "<bool>",
 
                "private":          "<bool>",
 
                "landing_rev":      "<landing_rev>"
 
                                
 
              }
 

	
 
OUTPUT::
 

	
 
    id : <id_given_in_input>
 
    result: {
 
              "msg": "Created fork of `<reponame>` as `<forkname>`",
 
              "success": true
 
            }
 
    error:  null
 

	
 

	
 
delete_repo
 
-----------
 

	
 
Deletes a repository. This command can be executed only using api_key
 
belonging to user with admin rights.
 
Deletes a repository. This command can be executed only using api_key belonging to user with admin 
 
rights or regular user that have admin access to repository.
 

	
 

	
 
INPUT::
 

	
 
    id : <id_for_response>
 
    api_key : "<api_key>"
 
    method :  "delete_repo"
 
    args:     {
 
                "repoid" : "<reponame or repo_id>"
 
              }
 

	
 
OUTPUT::
docs/changelog.rst
Show inline comments
 
.. _changelog:
 

	
 
=========
 
Changelog
 
=========
 

	
 
1.5.2 (**2013-01-14**)
 
----------------------
 

	
 
news
 
++++
 

	
 
- IP restrictions for users. Each user can get a set of whitelist IP+mask for
 
  extra protection. Useful for buildbots etc.
 
- added full last changeset info to lightweight dashboard. lightweight dashboard
 
  is now fully functional replacement of original dashboard.
 
- implemented certain API calls for non-admin users.
 
- enabled all Markdown Extra plugins
 
- implemented #725 Pull Request View - Show origin repo URL
 
- show comments from pull requests into associated changesets
 

	
 
fixes
 
+++++
 

	
 
- update repoinfo script is more failsafe
 
- fixed #687  Lazy loaded tooltip bug with simultaneous ajax requests
 
- fixed #691: Notifications for pull requests: move link to top for better
 
  readability
 
- fixed #699: fix missing fork docs for API
 
- fixed #693 Opening changeset from pull request fails
 
- fixed #710 File view stripping empty lines from beginning and end of file
 
- fixed issues with getting repos by path on windows, caused GIT hooks to fail
 
- fixed issues with groups paginator on main dashboard
 
- improved fetch/pull command for git repos, now pulling all refs
 
- fixed issue #719 Journal revision ID tooltip AJAX query path is incorrect
 
  when running in a subdir
 
- fixed issue #702 API methods without arguments fail when "args":null
 
- set the status of changesets initially on pull request. Fixes issues #690 and #587
 

	
 
1.5.1 (**2012-12-13**)
 
----------------------
 

	
 
news
 
++++
 

	
 
- implements #677: Don't allow to close pull requests when they are 
 
  under-review status
 
- implemented #670 Implementation of Roles in Pull Request
 

	
 
fixes
docs/installation.rst
Show inline comments
 
@@ -34,24 +34,28 @@ Step by step installation example for Wi
 

	
 
:ref:`installation_win`
 

	
 

	
 
Step by step installation example for Linux
 
-------------------------------------------
 

	
 

	
 
For installing RhodeCode i highly recommend using separate virtualenv_. This
 
way many required by RhodeCode libraries will remain sandboxed from your main
 
python and making things less problematic when doing system python updates. 
 

	
 
Alternative very detailed installation instructions for Ubuntu Server with
 
celery, indexer and daemon scripts: https://gist.github.com/4546398
 

	
 

	
 
- Assuming you have installed virtualenv_ create a new virtual environment 
 
  using virtualenv command:: 
 

	
 
    virtualenv --no-site-packages /opt/rhodecode-venv
 

	
 

	
 
.. note:: Using ``--no-site-packages`` when generating your
 
   virtualenv is **very important**. This flag provides the necessary
 
   isolation for running the set of packages required by
 
   RhodeCode.  If you do not specify ``--no-site-packages``,
 
   it's possible that RhodeCode will not install properly into
 
   the virtualenv, or, even if it does, may not run properly,
rhodecode/__init__.py
Show inline comments
 
@@ -17,37 +17,37 @@
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import sys
 
import platform
 

	
 
VERSION = (1, 5, 1)
 
VERSION = (1, 5, 2)
 

	
 
try:
 
    from rhodecode.lib import get_current_revision
 
    _rev = get_current_revision(quiet=True)
 
    if _rev and len(VERSION) > 3:
 
        VERSION += ('dev%s' % _rev[0],)
 
except ImportError:
 
    pass
 

	
 
__version__ = ('.'.join((str(each) for each in VERSION[:3])) +
 
               '.'.join(VERSION[3:]))
 
__dbversion__ = 9  # defines current db version for migrations
 
__dbversion__ = 10  # defines current db version for migrations
 
__platform__ = platform.system()
 
__license__ = 'GPLv3'
 
__py_version__ = sys.version_info
 
__author__ = 'Marcin Kuzminski'
 
__url__ = 'http://rhodecode.org'
 

	
 
PLATFORM_WIN = ('Windows')
 
PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS') #depracated
 

	
 
is_windows = __platform__ in PLATFORM_WIN
 
is_unix = not is_windows
 

	
rhodecode/config/routing.py
Show inline comments
 
@@ -213,24 +213,28 @@ def make_map(config):
 
        m.connect("user", "/users/{id}",
 
                  action="show", conditions=dict(method=["GET"]))
 
        m.connect("formatted_user", "/users/{id}.{format}",
 
                  action="show", conditions=dict(method=["GET"]))
 

	
 
        #EXTRAS USER ROUTES
 
        m.connect("user_perm", "/users_perm/{id}",
 
                  action="update_perm", conditions=dict(method=["PUT"]))
 
        m.connect("user_emails", "/users_emails/{id}",
 
                  action="add_email", conditions=dict(method=["PUT"]))
 
        m.connect("user_emails_delete", "/users_emails/{id}",
 
                  action="delete_email", conditions=dict(method=["DELETE"]))
 
        m.connect("user_ips", "/users_ips/{id}",
 
                  action="add_ip", conditions=dict(method=["PUT"]))
 
        m.connect("user_ips_delete", "/users_ips/{id}",
 
                  action="delete_ip", conditions=dict(method=["DELETE"]))
 

	
 
    #ADMIN USERS GROUPS REST ROUTES
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='admin/users_groups') as m:
 
        m.connect("users_groups", "/users_groups",
 
                  action="create", conditions=dict(method=["POST"]))
 
        m.connect("users_groups", "/users_groups",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("formatted_users_groups", "/users_groups.{format}",
 
                  action="index", conditions=dict(method=["GET"]))
 
        m.connect("new_users_group", "/users_groups/new",
 
                  action="new", conditions=dict(method=["GET"]))
 
@@ -346,26 +350,24 @@ def make_map(config):
 
        m.connect('admin_home', '', action='index')
 
        m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
 
                  action='add_repo')
 

	
 
    #==========================================================================
 
    # API V2
 
    #==========================================================================
 
    with rmap.submapper(path_prefix=ADMIN_PREFIX,
 
                        controller='api/api') as m:
 
        m.connect('api', '/api')
 

	
 
    #USER JOURNAL
 
    rmap.connect('journal_my_repos', '%s/journal_my_repos' % ADMIN_PREFIX,
 
                 controller='journal', action='index_my_repos')
 
    rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
 
                 controller='journal', action='index')
 
    rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
 
                 controller='journal', action='journal_rss')
 
    rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
 
                 controller='journal', action='journal_atom')
 

	
 
    rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
 
                 controller='journal', action="public_journal")
 

	
 
    rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
 
                 controller='journal', action="public_journal_rss")
rhodecode/controllers/admin/notifications.py
Show inline comments
 
@@ -101,65 +101,65 @@ class NotificationsController(BaseContro
 
        # url('new_notification')
 

	
 
    def update(self, notification_id):
 
        """PUT /_admin/notifications/id: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('notification', notification_id=ID),
 
        #           method='put')
 
        # url('notification', notification_id=ID)
 
        try:
 
            no = Notification.get(notification_id)
 
            owner = lambda: (no.notifications_to_users.user.user_id
 
                             == c.rhodecode_user.user_id)
 
            owner = all(un.user.user_id == c.rhodecode_user.user_id
 
                        for un in no.notifications_to_users)
 
            if h.HasPermissionAny('hg.admin')() or owner:
 
                    NotificationModel().mark_read(c.rhodecode_user.user_id, no)
 
                    Session().commit()
 
                    return 'ok'
 
        except Exception:
 
            Session.rollback()
 
            log.error(traceback.format_exc())
 
        return 'fail'
 

	
 
    def delete(self, notification_id):
 
        """DELETE /_admin/notifications/id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # Or using helpers:
 
        #    h.form(url('notification', notification_id=ID),
 
        #           method='delete')
 
        # url('notification', notification_id=ID)
 

	
 
        try:
 
            no = Notification.get(notification_id)
 
            owner = lambda: (no.notifications_to_users.user.user_id
 
                             == c.rhodecode_user.user_id)
 
            owner = all(un.user.user_id == c.rhodecode_user.user_id
 
                        for un in no.notifications_to_users)
 
            if h.HasPermissionAny('hg.admin')() or owner:
 
                    NotificationModel().delete(c.rhodecode_user.user_id, no)
 
                    Session().commit()
 
                    return 'ok'
 
        except Exception:
 
            Session.rollback()
 
            log.error(traceback.format_exc())
 
        return 'fail'
 

	
 
    def show(self, notification_id, format='html'):
 
        """GET /_admin/notifications/id: Show a specific item"""
 
        # url('notification', notification_id=ID)
 
        c.user = self.rhodecode_user
 
        no = Notification.get(notification_id)
 

	
 
        owner = lambda: (no.notifications_to_users.user.user_id
 
                         == c.user.user_id)
 
        owner = all(un.user.user_id == c.rhodecode_user.user_id
 
                    for un in no.notifications_to_users)
 
        if no and (h.HasPermissionAny('hg.admin', 'repository.admin')() or owner):
 
            unotification = NotificationModel()\
 
                            .get_user_notification(c.user.user_id, no)
 

	
 
            # if this association to user is not valid, we don't want to show
 
            # this message
 
            if unotification:
 
                if unotification.read is False:
 
                    unotification.mark_as_read()
 
                    Session().commit()
 
                c.notification = no
 

	
rhodecode/controllers/admin/permissions.py
Show inline comments
 
@@ -24,29 +24,30 @@
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 
import traceback
 
import formencode
 
from formencode import htmlfill
 

	
 
from pylons import request, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator,\
 
    AuthUser
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.forms import DefaultPermissionsForm
 
from rhodecode.model.permission import PermissionModel
 
from rhodecode.model.db import User
 
from rhodecode.model.db import User, UserIpMap
 
from rhodecode.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PermissionsController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
    # To properly map this controller, ensure your config/routing.py
 
    # file has a resource setup:
 
    #     map.resource('permission', 'permissions')
 

	
 
    @LoginRequired()
 
@@ -96,92 +97,98 @@ class PermissionsController(BaseControll
 
    def new(self, format='html'):
 
        """GET /permissions/new: Form to create a new item"""
 
        # url('new_permission')
 

	
 
    def update(self, id):
 
        """PUT /permissions/id: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('permission', id=ID),
 
        #           method='put')
 
        # url('permission', id=ID)
 

	
 
        permission_model = PermissionModel()
 
        if id == 'default':
 
            c.user = default_user = User.get_by_username('default')
 
            c.perm_user = AuthUser(user_id=default_user.user_id)
 
            c.user_ip_map = UserIpMap.query()\
 
                            .filter(UserIpMap.user == default_user).all()
 
            permission_model = PermissionModel()
 

	
 
        _form = DefaultPermissionsForm([x[0] for x in self.repo_perms_choices],
 
                                       [x[0] for x in self.group_perms_choices],
 
                                       [x[0] for x in self.register_choices],
 
                                       [x[0] for x in self.create_choices],
 
                                       [x[0] for x in self.fork_choices])()
 
            _form = DefaultPermissionsForm(
 
                    [x[0] for x in self.repo_perms_choices],
 
                    [x[0] for x in self.group_perms_choices],
 
                    [x[0] for x in self.register_choices],
 
                    [x[0] for x in self.create_choices],
 
                    [x[0] for x in self.fork_choices])()
 

	
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            form_result.update({'perm_user_name': id})
 
            permission_model.update(form_result)
 
            Session().commit()
 
            h.flash(_('Default permissions updated successfully'),
 
                    category='success')
 
            try:
 
                form_result = _form.to_python(dict(request.POST))
 
                form_result.update({'perm_user_name': id})
 
                permission_model.update(form_result)
 
                Session().commit()
 
                h.flash(_('Default permissions updated successfully'),
 
                        category='success')
 

	
 
        except formencode.Invalid, errors:
 
            defaults = errors.value
 
            except formencode.Invalid, errors:
 
                defaults = errors.value
 

	
 
            return htmlfill.render(
 
                render('admin/permissions/permissions.html'),
 
                defaults=defaults,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during update of permissions'),
 
                    category='error')
 
                return htmlfill.render(
 
                    render('admin/permissions/permissions.html'),
 
                    defaults=defaults,
 
                    errors=errors.error_dict or {},
 
                    prefix_error=False,
 
                    encoding="UTF-8")
 
            except Exception:
 
                log.error(traceback.format_exc())
 
                h.flash(_('error occurred during update of permissions'),
 
                        category='error')
 

	
 
        return redirect(url('edit_permission', id=id))
 

	
 
    def delete(self, id):
 
        """DELETE /permissions/id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
        # Or using helpers:
 
        #    h.form(url('permission', id=ID),
 
        #           method='delete')
 
        # url('permission', id=ID)
 

	
 
    def show(self, id, format='html'):
 
        """GET /permissions/id: Show a specific item"""
 
        # url('permission', id=ID)
 

	
 
    def edit(self, id, format='html'):
 
        """GET /permissions/id/edit: Form to edit an existing item"""
 
        #url('edit_permission', id=ID)
 

	
 
        #this form can only edit default user permissions
 
        if id == 'default':
 
            default_user = User.get_by_username('default')
 
            defaults = {'_method': 'put',
 
                        'anonymous': default_user.active}
 

	
 
            c.user = default_user = User.get_by_username('default')
 
            defaults = {'anonymous': default_user.active}
 
            c.perm_user = AuthUser(user_id=default_user.user_id)
 
            c.user_ip_map = UserIpMap.query()\
 
                            .filter(UserIpMap.user == default_user).all()
 
            for p in default_user.user_perms:
 
                if p.permission.permission_name.startswith('repository.'):
 
                    defaults['default_repo_perm'] = p.permission.permission_name
 

	
 
                if p.permission.permission_name.startswith('group.'):
 
                    defaults['default_group_perm'] = p.permission.permission_name
 

	
 
                if p.permission.permission_name.startswith('hg.register.'):
 
                    defaults['default_register'] = p.permission.permission_name
 

	
 
                if p.permission.permission_name.startswith('hg.create.'):
 
                    defaults['default_create'] = p.permission.permission_name
 

	
 
                if p.permission.permission_name.startswith('hg.fork.'):
 
                    defaults['default_fork'] = p.permission.permission_name
 

	
 
            return htmlfill.render(
 
                render('admin/permissions/permissions.html'),
 
                defaults=defaults,
 
                encoding="UTF-8",
 
                force_defaults=True,
 
                force_defaults=False
 
            )
 
        else:
 
            return redirect(url('admin_home'))
rhodecode/controllers/admin/repos.py
Show inline comments
 
@@ -126,58 +126,28 @@ class ReposController(BaseController):
 
        defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
 
        return defaults
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def index(self, format='html'):
 
        """GET /repos: All items in the collection"""
 
        # url('repos')
 

	
 
        c.repos_list = Repository.query()\
 
                        .order_by(func.lower(Repository.repo_name))\
 
                        .all()
 

	
 
        repos_data = []
 
        total_records = len(c.repos_list)
 

	
 
        _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
 
        template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
        quick_menu = lambda repo_name: (template.get_def("quick_menu")
 
                                        .render(repo_name, _=_, h=h, c=c))
 
        repo_lnk = lambda name, rtype, private, fork_of: (
 
            template.get_def("repo_name")
 
            .render(name, rtype, private, fork_of, short_name=False,
 
                    admin=True, _=_, h=h, c=c))
 

	
 
        repo_actions = lambda repo_name: (template.get_def("repo_actions")
 
                                       .render(repo_name, _=_, h=h, c=c))
 

	
 
        for repo in c.repos_list:
 
            repos_data.append({
 
                "menu": quick_menu(repo.repo_name),
 
                "raw_name": repo.repo_name.lower(),
 
                "name": repo_lnk(repo.repo_name, repo.repo_type,
 
                                 repo.private, repo.fork),
 
                "desc": repo.description,
 
                "owner": repo.user.username,
 
                "action": repo_actions(repo.repo_name),
 
            })
 

	
 
        c.data = json.dumps({
 
            "totalRecords": total_records,
 
            "startIndex": 0,
 
            "sort": "name",
 
            "dir": "asc",
 
            "records": repos_data
 
        })
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        return render('admin/repos/repos.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create(self):
 
        """
 
        POST /repos: Create a new item"""
 
        # url('repos')
 

	
 
        self.__load_defaults()
 
        form_result = {}
 
        try:
rhodecode/controllers/admin/repos_groups.py
Show inline comments
 
@@ -286,72 +286,36 @@ class ReposGroupsController(BaseControll
 
        c.group = RepoGroup.get_or_404(id)
 
        c.group_repos = c.group.repositories.all()
 

	
 
        #overwrite our cached list with current filter
 
        gr_filter = c.group_repos
 
        c.repo_cnt = 0
 

	
 
        groups = RepoGroup.query().order_by(RepoGroup.group_name)\
 
            .filter(RepoGroup.group_parent_id == id).all()
 
        c.groups = self.scm_model.get_repos_groups(groups)
 

	
 
        if c.visual.lightweight_dashboard is False:
 
            c.cached_repo_list = self.scm_model.get_repos(all_repos=gr_filter)
 

	
 
            c.repos_list = c.cached_repo_list
 
            c.repos_list = self.scm_model.get_repos(all_repos=gr_filter)
 
        ## lightweight version of dashboard
 
        else:
 
            c.repos_list = Repository.query()\
 
                            .filter(Repository.group_id == id)\
 
                            .order_by(func.lower(Repository.repo_name))\
 
                            .all()
 
            repos_data = []
 
            total_records = len(c.repos_list)
 

	
 
            _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
 
            template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
            quick_menu = lambda repo_name: (template.get_def("quick_menu")
 
                                            .render(repo_name, _=_, h=h, c=c))
 
            repo_lnk = lambda name, rtype, private, fork_of: (
 
                template.get_def("repo_name")
 
                .render(name, rtype, private, fork_of, short_name=False,
 
                        admin=False, _=_, h=h, c=c))
 
            last_change = lambda last_change:  (template.get_def("last_change")
 
                                           .render(last_change, _=_, h=h, c=c))
 
            rss_lnk = lambda repo_name: (template.get_def("rss")
 
                                           .render(repo_name, _=_, h=h, c=c))
 
            atom_lnk = lambda repo_name: (template.get_def("atom")
 
                                           .render(repo_name, _=_, h=h, c=c))
 

	
 
            for repo in c.repos_list:
 
                repos_data.append({
 
                    "menu": quick_menu(repo.repo_name),
 
                    "raw_name": repo.repo_name.lower(),
 
                    "name": repo_lnk(repo.repo_name, repo.repo_type,
 
                                     repo.private, repo.fork),
 
                    "last_change": last_change(repo.last_db_change),
 
                    "desc": repo.description,
 
                    "owner": h.person(repo.user.username),
 
                    "rss": rss_lnk(repo.repo_name),
 
                    "atom": atom_lnk(repo.repo_name),
 
                })
 

	
 
            c.data = json.dumps({
 
                "totalRecords": total_records,
 
                "startIndex": 0,
 
                "sort": "name",
 
                "dir": "asc",
 
                "records": repos_data
 
            })
 
            repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                       admin=False)
 
            #json used to render the grid
 
            c.data = json.dumps(repos_data)
 

	
 
        return render('admin/repos_groups/repos_groups.html')
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def edit(self, id, format='html'):
 
        """GET /repos_groups/id/edit: Form to edit an existing item"""
 
        # url('edit_repos_group', id=ID)
 

	
 
        c.repos_group = ReposGroupModel()._get_repos_group(id)
 
        defaults = self.__load_data(c.repos_group.group_id)
 

	
 
        # we need to exclude this group from the group list for editing
rhodecode/controllers/admin/settings.py
Show inline comments
 
@@ -39,29 +39,30 @@ from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    HasPermissionAnyDecorator, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.celerylib import tasks, run_task
 
from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
 
    set_rhodecode_config, repo_name_slug, check_git_version
 
from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
 
    RhodeCodeSetting, PullRequest, PullRequestReviewers
 
from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
 
    ApplicationUiSettingsForm, ApplicationVisualisationForm
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.db import User
 
from rhodecode.model.notification import EmailNotificationModel
 
from rhodecode.model.meta import Session
 
from rhodecode.lib.utils2 import str2bool
 

	
 
from rhodecode.lib.utils2 import str2bool, safe_unicode
 
from rhodecode.lib.compat import json
 
log = logging.getLogger(__name__)
 

	
 

	
 
class SettingsController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
    # To properly map this controller, ensure your config/routing.py
 
    # file has a resource setup:
 
    #     map.resource('setting', 'settings', controller='admin/settings',
 
    #         path_prefix='/admin', name_prefix='admin_')
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
@@ -110,28 +111,29 @@ class SettingsController(BaseController)
 
        #           method='put')
 
        # url('admin_setting', setting_id=ID)
 

	
 
        if setting_id == 'mapping':
 
            rm_obsolete = request.POST.get('destroy', False)
 
            log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
 
            initial = ScmModel().repo_scan()
 
            log.debug('invalidating all repositories')
 
            for repo_name in initial.keys():
 
                invalidate_cache('get_repo_cached_%s' % repo_name)
 

	
 
            added, removed = repo2db_mapper(initial, rm_obsolete)
 

	
 
            h.flash(_('Repositories successfully'
 
                      ' rescanned added: %s,removed: %s') % (added, removed),
 
                      category='success')
 
            _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
 
            h.flash(_('Repositories successfully '
 
                      'rescanned added: %s ; removed: %s') %
 
                    (_repr(added), _repr(removed)),
 
                    category='success')
 

	
 
        if setting_id == 'whoosh':
 
            repo_location = self._get_hg_ui_settings()['paths_root_path']
 
            full_index = request.POST.get('full_index', False)
 
            run_task(tasks.whoosh_index, repo_location, full_index)
 
            h.flash(_('Whoosh reindex task scheduled'), category='success')
 

	
 
        if setting_id == 'global':
 

	
 
            application_form = ApplicationSettingsForm()()
 
            try:
 
                form_result = application_form.to_python(dict(request.POST))
 
@@ -327,25 +329,25 @@ class SettingsController(BaseController)
 

	
 
            return redirect(url('admin_edit_setting', setting_id='hooks'))
 

	
 
        if setting_id == 'email':
 
            test_email = request.POST.get('test_email')
 
            test_email_subj = 'RhodeCode TestEmail'
 
            test_email_body = 'RhodeCode Email test'
 

	
 
            test_email_html_body = EmailNotificationModel()\
 
                .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
 
                                body=test_email_body)
 

	
 
            recipients = [test_email] if [test_email] else None
 
            recipients = [test_email] if test_email else None
 

	
 
            run_task(tasks.send_email, recipients, test_email_subj,
 
                     test_email_body, test_email_html_body)
 

	
 
            h.flash(_('Email task created'), category='success')
 
        return redirect(url('admin_settings'))
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def delete(self, setting_id):
 
        """DELETE /admin/settings/setting_id: Delete an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="DELETE" />
 
@@ -372,108 +374,115 @@ class SettingsController(BaseController)
 
        # url('admin_edit_setting', setting_id=ID)
 

	
 
        c.hooks = RhodeCodeUi.get_builtin_hooks()
 
        c.custom_hooks = RhodeCodeUi.get_custom_hooks()
 

	
 
        return htmlfill.render(
 
            render('admin/settings/hooks.html'),
 
            defaults={},
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 

	
 
    def _load_my_repos_data(self):
 
        repos_list = Session().query(Repository)\
 
                     .filter(Repository.user_id ==
 
                             self.rhodecode_user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        return json.dumps(repos_data)
 

	
 
    @NotAnonymous()
 
    def my_account(self):
 
        """
 
        GET /_admin/my_account Displays info about my account
 
        """
 
        # url('admin_settings_my_account')
 

	
 
        c.user = User.get(self.rhodecode_user.user_id)
 
        all_repos = Session().query(Repository)\
 
                     .filter(Repository.user_id == c.user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        c.user_repos = ScmModel().get_repos(all_repos)
 
        c.ldap_dn = c.user.ldap_dn
 

	
 
        if c.user.username == 'default':
 
            h.flash(_("You can't edit this user since it's"
 
              " crucial for entire application"), category='warning')
 
            return redirect(url('users'))
 

	
 
        #json used to render the grid
 
        c.data = self._load_my_repos_data()
 

	
 
        defaults = c.user.get_dict()
 

	
 
        c.form = htmlfill.render(
 
            render('admin/users/user_edit_my_account_form.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False
 
        )
 
        return render('admin/users/user_edit_my_account.html')
 

	
 
    @NotAnonymous()
 
    def my_account_update(self):
 
        """PUT /_admin/my_account_update: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('admin_settings_my_account_update'),
 
        #           method='put')
 
        # url('admin_settings_my_account_update', id=ID)
 
        uid = self.rhodecode_user.user_id
 
        c.user = User.get(self.rhodecode_user.user_id)
 
        c.ldap_dn = c.user.ldap_dn
 
        email = self.rhodecode_user.email
 
        _form = UserForm(edit=True,
 
                         old_data={'user_id': uid, 'email': email})()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            UserModel().update_my_account(uid, form_result)
 
            skip_attrs = ['admin', 'active']  # skip attr for my account
 
            if c.ldap_dn:
 
                #forbid updating username for ldap accounts
 
                skip_attrs.append('username')
 
            UserModel().update(uid, form_result, skip_attrs=skip_attrs)
 
            h.flash(_('Your account was updated successfully'),
 
                    category='success')
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            c.user = User.get(self.rhodecode_user.user_id)
 

	
 
            #json used to render the grid
 
            c.data = self._load_my_repos_data()
 
            c.form = htmlfill.render(
 
                render('admin/users/user_edit_my_account_form.html'),
 
                defaults=errors.value,
 
                errors=errors.error_dict or {},
 
                prefix_error=False,
 
                encoding="UTF-8")
 
            return render('admin/users/user_edit_my_account.html')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('error occurred during update of user %s') \
 
                    % form_result.get('username'), category='error')
 

	
 
        return redirect(url('my_account'))
 

	
 
    @NotAnonymous()
 
    def my_account_my_repos(self):
 
        all_repos = Session().query(Repository)\
 
            .filter(Repository.user_id == self.rhodecode_user.user_id)\
 
            .order_by(func.lower(Repository.repo_name))\
 
            .all()
 
        c.user_repos = ScmModel().get_repos(all_repos)
 
        return render('admin/users/user_edit_my_account_repos.html')
 

	
 
    @NotAnonymous()
 
    def my_account_my_pullrequests(self):
 
        c.my_pull_requests = PullRequest.query()\
 
                                .filter(PullRequest.user_id==
 
                                .filter(PullRequest.user_id ==
 
                                        self.rhodecode_user.user_id)\
 
                                .all()
 
        c.participate_in_pull_requests = \
 
            [x.pull_request for x in PullRequestReviewers.query()\
 
                                    .filter(PullRequestReviewers.user_id==
 
                                    .filter(PullRequestReviewers.user_id ==
 
                                            self.rhodecode_user.user_id)\
 
                                    .all()]
 
        return render('admin/users/user_edit_my_account_pullrequests.html')
 

	
 
    @NotAnonymous()
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create_repository(self):
 
        """GET /_admin/create_repository: Form to create a new item"""
 

	
 
        c.repo_groups = RepoGroup.groups_choices(check_perms=True)
 
        c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
 
        choices, c.landing_revs = ScmModel().get_repo_landing_revs()
rhodecode/controllers/admin/users.py
Show inline comments
 
@@ -32,25 +32,25 @@ from formencode import htmlfill
 
from pylons import request, session, tmpl_context as c, url, config
 
from pylons.controllers.util import redirect
 
from pylons.i18n.translation import _
 

	
 
import rhodecode
 
from rhodecode.lib.exceptions import DefaultUserException, \
 
    UserOwnsReposException
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    AuthUser
 
from rhodecode.lib.base import BaseController, render
 

	
 
from rhodecode.model.db import User, UserEmailMap
 
from rhodecode.model.db import User, UserEmailMap, UserIpMap
 
from rhodecode.model.forms import UserForm
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.meta import Session
 
from rhodecode.lib.utils import action_logger
 
from rhodecode.lib.compat import json
 
from rhodecode.lib.utils2 import datetime_to_time, str2bool
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class UsersController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
@@ -150,43 +150,45 @@ class UsersController(BaseController):
 

	
 
    def update(self, id):
 
        """PUT /users/id: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('update_user', id=ID),
 
        #           method='put')
 
        # url('user', id=ID)
 
        user_model = UserModel()
 
        c.user = user_model.get(id)
 
        c.ldap_dn = c.user.ldap_dn
 
        c.perm_user = AuthUser(user_id=id)
 
        c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr)
 
        _form = UserForm(edit=True, old_data={'user_id': id,
 
                                              'email': c.user.email})()
 
        form_result = {}
 
        try:
 
            form_result = _form.to_python(dict(request.POST))
 
            skip_attrs = []
 
            if c.ldap_dn:
 
                #forbid updating username for ldap accounts
 
                skip_attrs = ['username']
 
            user_model.update(id, form_result, skip_attrs=skip_attrs)
 
            usr = form_result['username']
 
            action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr,
 
                          None, self.ip_addr, self.sa)
 
            h.flash(_('User updated successfully'), category='success')
 
            Session().commit()
 
        except formencode.Invalid, errors:
 
            c.user_email_map = UserEmailMap.query()\
 
                            .filter(UserEmailMap.user == c.user).all()
 
            c.user_ip_map = UserIpMap.query()\
 
                            .filter(UserIpMap.user == c.user).all()
 
            defaults = errors.value
 
            e = errors.error_dict or {}
 
            defaults.update({
 
                'create_repo_perm': user_model.has_perm(id, 'hg.create.repository'),
 
                'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'),
 
                '_method': 'put'
 
            })
 
            return htmlfill.render(
 
                render('admin/users/user_edit.html'),
 
                defaults=defaults,
 
                errors=e,
 
                prefix_error=False,
 
@@ -222,30 +224,32 @@ class UsersController(BaseController):
 
        """GET /users/id: Show a specific item"""
 
        # url('user', id=ID)
 

	
 
    def edit(self, id, format='html'):
 
        """GET /users/id/edit: Form to edit an existing item"""
 
        # url('edit_user', id=ID)
 
        c.user = User.get_or_404(id)
 

	
 
        if c.user.username == 'default':
 
            h.flash(_("You can't edit this user"), category='warning')
 
            return redirect(url('users'))
 

	
 
        c.perm_user = AuthUser(user_id=id)
 
        c.perm_user = AuthUser(user_id=id, ip_addr=self.ip_addr)
 
        c.user.permissions = {}
 
        c.granted_permissions = UserModel().fill_perms(c.user)\
 
            .permissions['global']
 
        c.user_email_map = UserEmailMap.query()\
 
                        .filter(UserEmailMap.user == c.user).all()
 
        c.user_ip_map = UserIpMap.query()\
 
                        .filter(UserIpMap.user == c.user).all()
 
        user_model = UserModel()
 
        c.ldap_dn = c.user.ldap_dn
 
        defaults = c.user.get_dict()
 
        defaults.update({
 
            'create_repo_perm': user_model.has_perm(id, 'hg.create.repository'),
 
            'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'),
 
        })
 

	
 
        return htmlfill.render(
 
            render('admin/users/user_edit.html'),
 
            defaults=defaults,
 
            encoding="UTF-8",
 
@@ -290,37 +294,69 @@ class UsersController(BaseController):
 

	
 
            Session().commit()
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during permissions saving'),
 
                    category='error')
 
        return redirect(url('edit_user', id=id))
 

	
 
    def add_email(self, id):
 
        """POST /user_emails:Add an existing item"""
 
        # url('user_emails', id=ID, method='put')
 

	
 
        #TODO: validation and form !!!
 
        email = request.POST.get('new_email')
 
        user_model = UserModel()
 

	
 
        try:
 
            user_model.add_extra_email(id, email)
 
            Session().commit()
 
            h.flash(_("Added email %s to user") % email, category='success')
 
        except formencode.Invalid, error:
 
            msg = error.error_dict['email']
 
            h.flash(msg, category='error')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during email saving'),
 
                    category='error')
 
        return redirect(url('edit_user', id=id))
 

	
 
    def delete_email(self, id):
 
        """DELETE /user_emails_delete/id: Delete an existing item"""
 
        # url('user_emails_delete', id=ID, method='delete')
 
        user_model = UserModel()
 
        user_model.delete_extra_email(id, request.POST.get('del_email'))
 
        Session().commit()
 
        h.flash(_("Removed email from user"), category='success')
 
        return redirect(url('edit_user', id=id))
 

	
 
    def add_ip(self, id):
 
        """POST /user_ips:Add an existing item"""
 
        # url('user_ips', id=ID, method='put')
 

	
 
        ip = request.POST.get('new_ip')
 
        user_model = UserModel()
 

	
 
        try:
 
            user_model.add_extra_ip(id, ip)
 
            Session().commit()
 
            h.flash(_("Added ip %s to user") % ip, category='success')
 
        except formencode.Invalid, error:
 
            msg = error.error_dict['ip']
 
            h.flash(msg, category='error')
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            h.flash(_('An error occurred during ip saving'),
 
                    category='error')
 
        if 'default_user' in request.POST:
 
            return redirect(url('edit_permission', id='default'))
 
        return redirect(url('edit_user', id=id))
 

	
 
    def delete_ip(self, id):
 
        """DELETE /user_ips_delete/id: Delete an existing item"""
 
        # url('user_ips_delete', id=ID, method='delete')
 
        user_model = UserModel()
 
        user_model.delete_extra_ip(id, request.POST.get('del_ip'))
 
        Session().commit()
 
        h.flash(_("Removed ip from user"), category='success')
 
        if 'default_user' in request.POST:
 
            return redirect(url('edit_permission', id='default'))
 
        return redirect(url('edit_user', id=id))
rhodecode/controllers/api/__init__.py
Show inline comments
 
@@ -23,35 +23,33 @@
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import inspect
 
import logging
 
import types
 
import urllib
 
import traceback
 
import time
 

	
 
from rhodecode.lib.compat import izip_longest, json
 

	
 
from paste.response import replace_header
 

	
 
from pylons.controllers import WSGIController
 

	
 

	
 
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
 
HTTPBadRequest, HTTPError
 

	
 
from rhodecode.model.db import User
 
from rhodecode.model import meta
 
from rhodecode.lib.compat import izip_longest, json
 
from rhodecode.lib.auth import AuthUser
 
from rhodecode.lib.base import _get_ip_addr, _get_access_path
 
from rhodecode.lib.utils2 import safe_unicode
 

	
 
log = logging.getLogger('JSONRPC')
 

	
 

	
 
class JSONRPCError(BaseException):
 

	
 
    def __init__(self, message):
 
        self.message = message
 
        super(JSONRPCError, self).__init__()
 
@@ -77,37 +75,41 @@ class JSONRPCController(WSGIController):
 
     A WSGI-speaking JSON-RPC controller class
 

	
 
     See the specification:
 
     <http://json-rpc.org/wiki/specification>`.
 

	
 
     Valid controller return values should be json-serializable objects.
 

	
 
     Sub-classes should catch their exceptions and raise JSONRPCError
 
     if they want to pass meaningful errors to the client.
 

	
 
     """
 

	
 
    def _get_ip_addr(self, environ):
 
        return _get_ip_addr(environ)
 

	
 
    def _get_method_args(self):
 
        """
 
        Return `self._rpc_args` to dispatched controller method
 
        chosen by __call__
 
        """
 
        return self._rpc_args
 

	
 
    def __call__(self, environ, start_response):
 
        """
 
        Parse the request body as JSON, look up the method on the
 
        controller and if it exists, dispatch to it.
 
        """
 
        start = time.time()
 
        ip_addr = self.ip_addr = self._get_ip_addr(environ)
 
        self._req_id = None
 
        if 'CONTENT_LENGTH' not in environ:
 
            log.debug("No Content-Length")
 
            return jsonrpc_error(retid=self._req_id,
 
                                 message="No Content-Length in request")
 
        else:
 
            length = environ['CONTENT_LENGTH'] or 0
 
            length = int(environ['CONTENT_LENGTH'])
 
            log.debug('Content-Length: %s' % length)
 

	
 
        if length == 0:
 
            log.debug("Content-Length is 0")
 
@@ -121,39 +123,50 @@ class JSONRPCController(WSGIController):
 
        except ValueError, e:
 
            # catch JSON errors Here
 
            return jsonrpc_error(retid=self._req_id,
 
                                 message="JSON parse error ERR:%s RAW:%r" \
 
                                 % (e, urllib.unquote_plus(raw_body)))
 

	
 
        # check AUTH based on API KEY
 
        try:
 
            self._req_api_key = json_body['api_key']
 
            self._req_id = json_body['id']
 
            self._req_method = json_body['method']
 
            self._request_params = json_body['args']
 
            if not isinstance(self._request_params, dict):
 
                self._request_params = {}
 

	
 
            log.debug(
 
                'method: %s, params: %s' % (self._req_method,
 
                                            self._request_params)
 
            )
 
        except KeyError, e:
 
            return jsonrpc_error(retid=self._req_id,
 
                                 message='Incorrect JSON query missing %s' % e)
 

	
 
        # check if we can find this session using api_key
 
        try:
 
            u = User.get_by_api_key(self._req_api_key)
 
            if u is None:
 
                return jsonrpc_error(retid=self._req_id,
 
                                     message='Invalid API KEY')
 
            auth_u = AuthUser(u.user_id, self._req_api_key)
 

	
 
            #check if we are allowed to use this IP
 
            auth_u = AuthUser(u.user_id, self._req_api_key, ip_addr=ip_addr)
 
            if not auth_u.ip_allowed:
 
                return jsonrpc_error(retid=self._req_id,
 
                        message='request from IP:%s not allowed' % (ip_addr))
 
            else:
 
                log.info('Access for IP:%s allowed' % (ip_addr))
 

	
 
        except Exception, e:
 
            return jsonrpc_error(retid=self._req_id,
 
                                 message='Invalid API KEY')
 

	
 
        self._error = None
 
        try:
 
            self._func = self._find_method()
 
        except AttributeError, e:
 
            return jsonrpc_error(retid=self._req_id,
 
                                 message=str(e))
 

	
 
        # now that we have a method, add self._req_params to
 
@@ -193,24 +206,25 @@ class JSONRPCController(WSGIController):
 

	
 
            # skip the required param check if it's default value is
 
            # NotImplementedType (default_empty)
 
            if (default == default_empty and arg not in self._request_params):
 
                return jsonrpc_error(
 
                    retid=self._req_id,
 
                    message=(
 
                        'Missing non optional `%s` arg in JSON DATA' % arg
 
                    )
 
                )
 

	
 
        self._rpc_args = {USER_SESSION_ATTR: u}
 

	
 
        self._rpc_args.update(self._request_params)
 

	
 
        self._rpc_args['action'] = self._req_method
 
        self._rpc_args['environ'] = environ
 
        self._rpc_args['start_response'] = start_response
 

	
 
        status = []
 
        headers = []
 
        exc_info = []
 

	
 
        def change_content(new_status, new_headers, new_exc_info=None):
 
            status.append(new_status)
rhodecode/controllers/api/api.py
Show inline comments
 
@@ -18,40 +18,58 @@
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import traceback
 
import logging
 
from pylons.controllers.util import abort
 

	
 
from rhodecode.controllers.api import JSONRPCController, JSONRPCError
 
from rhodecode.lib.auth import HasPermissionAllDecorator, \
 
    HasPermissionAnyDecorator, PasswordGenerator, AuthUser
 
from rhodecode.lib.auth import PasswordGenerator, AuthUser, \
 
    HasPermissionAllDecorator, HasPermissionAnyDecorator, \
 
    HasPermissionAnyApi, HasRepoPermissionAnyApi
 
from rhodecode.lib.utils import map_groups, repo2db_mapper
 
from rhodecode.model.meta import Session
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.users_group import UsersGroupModel
 
from rhodecode.model.permission import PermissionModel
 
from rhodecode.model.db import Repository
 
from rhodecode.model.db import Repository, RhodeCodeSetting, UserIpMap
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class OptionalAttr(object):
 
    """
 
    Special Optional Option that defines other attribute
 
    """
 
    def __init__(self, attr_name):
 
        self.attr_name = attr_name
 

	
 
    def __repr__(self):
 
        return '<OptionalAttr:%s>' % self.attr_name
 

	
 
    def __call__(self):
 
        return self
 
#alias
 
OAttr = OptionalAttr
 

	
 

	
 
class Optional(object):
 
    """
 
    Defines an optional parameter::
 

	
 
        param = param.getval() if isinstance(param, Optional) else param
 
        param = param() if isinstance(param, Optional) else param
 

	
 
    is equivalent of::
 

	
 
        param = Optional.extract(param)
 

	
 
    """
 
@@ -175,59 +193,101 @@ class ApiController(JSONRPCController):
 

	
 
        try:
 
            rm_obsolete = Optional.extract(remove_obsolete)
 
            added, removed = repo2db_mapper(ScmModel().repo_scan(),
 
                                            remove_obsolete=rm_obsolete)
 
            return {'added': added, 'removed': removed}
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'Error occurred during rescan repositories action'
 
            )
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def lock(self, apiuser, repoid, userid, locked):
 
    def lock(self, apiuser, repoid, locked, userid=Optional(OAttr('apiuser'))):
 
        """
 
        Set locking state on particular repository by given user
 
        Set locking state on particular repository by given user, if
 
        this command is runned by non-admin account userid is set to user
 
        who is calling this method
 

	
 
        :param apiuser:
 
        :param repoid:
 
        :param userid:
 
        :param locked:
 
        """
 
        repo = get_repo_or_error(repoid)
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser):
 
            pass
 
        elif HasRepoPermissionAnyApi('repository.admin',
 
                                     'repository.write')(user=apiuser,
 
                                                         repo_name=repo.repo_name):
 
            #make sure normal user does not pass someone else userid,
 
            #he is not allowed to do that
 
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
 
                raise JSONRPCError(
 
                    'userid is not the same as your user'
 
                )
 
        else:
 
            raise JSONRPCError('repository `%s` does not exist' % (repoid))
 

	
 
        if isinstance(userid, Optional):
 
            userid = apiuser.user_id
 
        user = get_user_or_error(userid)
 
        locked = bool(locked)
 
        try:
 
            if locked:
 
                Repository.lock(repo, user.user_id)
 
            else:
 
                Repository.unlock(repo)
 

	
 
            return ('User `%s` set lock state for repo `%s` to `%s`'
 
                    % (user.username, repo.repo_name, locked))
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'Error occurred locking repository `%s`' % repo.repo_name
 
            )
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def get_user(self, apiuser, userid):
 
        """"
 
        Get a user by username
 
    def show_ip(self, apiuser, userid):
 
        """
 
        Shows IP address as seen from RhodeCode server, together with all
 
        defined IP addresses for given user
 

	
 
        :param apiuser:
 
        :param userid:
 
        """
 
        user = get_user_or_error(userid)
 
        ips = UserIpMap.query().filter(UserIpMap.user == user).all()
 
        return dict(
 
            ip_addr_server=self.ip_addr,
 
            user_ips=ips
 
        )
 

	
 
    def get_user(self, apiuser, userid=Optional(OAttr('apiuser'))):
 
        """"
 
        Get a user by username, or userid, if userid is given
 

	
 
        :param apiuser:
 
        :param userid:
 
        """
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
 
            #make sure normal user does not pass someone else userid,
 
            #he is not allowed to do that
 
            if not isinstance(userid, Optional) and userid != apiuser.user_id:
 
                raise JSONRPCError(
 
                    'userid is not the same as your user'
 
                )
 

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

	
 
        user = get_user_or_error(userid)
 
        data = user.get_api_data()
 
        data['permissions'] = AuthUser(user_id=user.user_id).permissions
 
        return data
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def get_users(self, apiuser):
 
        """"
 
        Get all users
 

	
 
        :param apiuser:
 
@@ -470,69 +530,77 @@ class ApiController(JSONRPCController):
 
                    )
 
            msg = msg if success else "User wasn't in group"
 
            Session().commit()
 
            return dict(success=success, msg=msg)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to remove member from users group `%s`' % (
 
                        users_group.users_group_name
 
                    )
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_repo(self, apiuser, repoid):
 
        """"
 
        Get repository by name
 

	
 
        :param apiuser:
 
        :param repoid:
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
 
            # check if we have admin permission for this repo !
 
            if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
 
                                            repo_name=repo.repo_name) is False:
 
                raise JSONRPCError('repository `%s` does not exist' % (repoid))
 

	
 
        members = []
 
        for user in repo.repo_to_perm:
 
            perm = user.permission.permission_name
 
            user = user.user
 
            user_data = user.get_api_data()
 
            user_data['type'] = "user"
 
            user_data['permission'] = perm
 
            members.append(user_data)
 

	
 
        for users_group in repo.users_group_to_perm:
 
            perm = users_group.permission.permission_name
 
            users_group = users_group.users_group
 
            users_group_data = users_group.get_api_data()
 
            users_group_data['type'] = "users_group"
 
            users_group_data['permission'] = perm
 
            members.append(users_group_data)
 

	
 
        data = repo.get_api_data()
 
        data['members'] = members
 
        return data
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def get_repos(self, apiuser):
 
        """"
 
        Get all repositories
 

	
 
        :param apiuser:
 
        """
 
        result = []
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
 
            repos = RepoModel().get_all_user_repos(user=apiuser)
 
        else:
 
            repos = RepoModel().get_all()
 

	
 
        result = []
 
        for repo in RepoModel().get_all():
 
        for repo in repos:
 
            result.append(repo.get_api_data())
 
        return result
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    @HasPermissionAllDecorator('hg.admin')
 
    def get_repo_nodes(self, apiuser, repoid, revision, root_path,
 
                       ret_type='all'):
 
        """
 
        returns a list of nodes and it's children
 
        for a given path at given revision. It's possible to specify ret_type
 
        to show only files or dirs
 

	
 
        :param apiuser:
 
        :param repoid: name or id of repository
 
        :param revision: revision for which listing should be done
 
        :param root_path: path from which start displaying
 
        :param ret_type: return type 'all|files|dirs' nodes
 
@@ -547,90 +615,133 @@ class ApiController(JSONRPCController):
 
                'dirs': _d,
 
            }
 
            return _map[ret_type]
 
        except KeyError:
 
            raise JSONRPCError('ret_type must be one of %s' % _map.keys())
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to get repo: `%s` nodes' % repo.repo_name
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
 
    def create_repo(self, apiuser, repo_name, owner, repo_type,
 
    def create_repo(self, apiuser, repo_name, owner=Optional(OAttr('apiuser')),
 
                    repo_type=Optional('hg'),
 
                    description=Optional(''), private=Optional(False),
 
                    clone_uri=Optional(None), landing_rev=Optional('tip')):
 
                    clone_uri=Optional(None), landing_rev=Optional('tip'),
 
                    enable_statistics=Optional(False),
 
                    enable_locking=Optional(False),
 
                    enable_downloads=Optional(False)):
 
        """
 
        Create repository, if clone_url is given it makes a remote clone
 
        if repo_name is withina  group name the groups will be created
 
        if repo_name is within a group name the groups will be created
 
        automatically if they aren't present
 

	
 
        :param apiuser:
 
        :param repo_name:
 
        :param onwer:
 
        :param repo_type:
 
        :param description:
 
        :param private:
 
        :param clone_uri:
 
        :param landing_rev:
 
        """
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
 
            if not isinstance(owner, Optional):
 
                #forbid setting owner for non-admins
 
                raise JSONRPCError(
 
                    'Only RhodeCode admin can specify `owner` param'
 
                )
 
        if isinstance(owner, Optional):
 
            owner = apiuser.user_id
 

	
 
        owner = get_user_or_error(owner)
 

	
 
        if RepoModel().get_by_repo_name(repo_name):
 
            raise JSONRPCError("repo `%s` already exist" % repo_name)
 

	
 
        private = Optional.extract(private)
 
        defs = RhodeCodeSetting.get_default_repo_settings(strip_prefix=True)
 
        if isinstance(private, Optional):
 
            private = defs.get('repo_private') or Optional.extract(private)
 
        if isinstance(repo_type, Optional):
 
            repo_type = defs.get('repo_type')
 
        if isinstance(enable_statistics, Optional):
 
            enable_statistics = defs.get('repo_enable_statistics')
 
        if isinstance(enable_locking, Optional):
 
            enable_locking = defs.get('repo_enable_locking')
 
        if isinstance(enable_downloads, Optional):
 
            enable_downloads = defs.get('repo_enable_downloads')
 

	
 
        clone_uri = Optional.extract(clone_uri)
 
        description = Optional.extract(description)
 
        landing_rev = Optional.extract(landing_rev)
 

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

	
 
            repo = RepoModel().create_repo(
 
                repo_name=repo_name,
 
                repo_type=repo_type,
 
                description=description,
 
                owner=owner,
 
                private=private,
 
                clone_uri=clone_uri,
 
                repos_group=group,
 
                landing_rev=landing_rev,
 
                enable_statistics=enable_statistics,
 
                enable_downloads=enable_downloads,
 
                enable_locking=enable_locking
 
            )
 

	
 
            Session().commit()
 

	
 
            return dict(
 
                msg="Created new repository `%s`" % (repo.repo_name),
 
                repo=repo.get_api_data()
 
            )
 

	
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError('failed to create repository `%s`' % repo_name)
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def fork_repo(self, apiuser, repoid, fork_name, owner,
 
    @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
 
    def fork_repo(self, apiuser, repoid, fork_name, owner=Optional(OAttr('apiuser')),
 
                  description=Optional(''), copy_permissions=Optional(False),
 
                  private=Optional(False), landing_rev=Optional('tip')):
 
        repo = get_repo_or_error(repoid)
 
        repo_name = repo.repo_name
 
        owner = get_user_or_error(owner)
 

	
 
        _repo = RepoModel().get_by_repo_name(fork_name)
 
        if _repo:
 
            type_ = 'fork' if _repo.fork else 'repo'
 
            raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))
 

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

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

	
 
        owner = get_user_or_error(owner)
 

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

	
 
            form_data = dict(
 
                repo_name=fork_name,
 
                repo_name_full=fork_name,
 
                repo_group=group,
 
                repo_type=repo.repo_type,
 
                description=Optional.extract(description),
 
                private=Optional.extract(private),
 
                copy_permissions=Optional.extract(copy_permissions),
 
@@ -643,48 +754,53 @@ class ApiController(JSONRPCController):
 
                msg='Created fork of `%s` as `%s`' % (repo.repo_name,
 
                                                      fork_name),
 
                success=True  # cannot return the repo data here since fork
 
                              # cann be done async
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to fork repository `%s` as `%s`' % (repo_name,
 
                                                            fork_name)
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    def delete_repo(self, apiuser, repoid):
 
        """
 
        Deletes a given repository
 

	
 
        :param apiuser:
 
        :param repoid:
 
        """
 
        repo = get_repo_or_error(repoid)
 

	
 
        if HasPermissionAnyApi('hg.admin')(user=apiuser) is False:
 
            # check if we have admin permission for this repo !
 
            if HasRepoPermissionAnyApi('repository.admin')(user=apiuser,
 
                                            repo_name=repo.repo_name) is False:
 
                 raise JSONRPCError('repository `%s` does not exist' % (repoid))
 

	
 
        try:
 
            RepoModel().delete(repo)
 
            Session().commit()
 
            return dict(
 
                msg='Deleted repository `%s`' % repo.repo_name,
 
                success=True
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to delete repository `%s`' % repo.repo_name
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    @HasPermissionAllDecorator('hg.admin')
 
    def grant_user_permission(self, apiuser, repoid, userid, perm):
 
        """
 
        Grant permission for user on given repository, or update existing one
 
        if found
 

	
 
        :param repoid:
 
        :param userid:
 
        :param perm:
 
        """
 
        repo = get_repo_or_error(repoid)
 
        user = get_user_or_error(userid)
 
        perm = get_perm_or_error(perm)
 
@@ -699,25 +815,25 @@ class ApiController(JSONRPCController):
 
                    perm.permission_name, user.username, repo.repo_name
 
                ),
 
                success=True
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to edit permission for user: `%s` in repo: `%s`' % (
 
                    userid, repoid
 
                )
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    @HasPermissionAllDecorator('hg.admin')
 
    def revoke_user_permission(self, apiuser, repoid, userid):
 
        """
 
        Revoke permission for user on given repository
 

	
 
        :param apiuser:
 
        :param repoid:
 
        :param userid:
 
        """
 

	
 
        repo = get_repo_or_error(repoid)
 
        user = get_user_or_error(userid)
 
        try:
 
@@ -730,25 +846,25 @@ class ApiController(JSONRPCController):
 
                    user.username, repo.repo_name
 
                ),
 
                success=True
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to edit permission for user: `%s` in repo: `%s`' % (
 
                    userid, repoid
 
                )
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    @HasPermissionAllDecorator('hg.admin')
 
    def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
 
                                     perm):
 
        """
 
        Grant permission for users group on given repository, or update
 
        existing one if found
 

	
 
        :param apiuser:
 
        :param repoid:
 
        :param usersgroupid:
 
        :param perm:
 
        """
 
        repo = get_repo_or_error(repoid)
 
@@ -769,25 +885,25 @@ class ApiController(JSONRPCController):
 
                ),
 
                success=True
 
            )
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            raise JSONRPCError(
 
                'failed to edit permission for users group: `%s` in '
 
                'repo: `%s`' % (
 
                    usersgroupid, repo.repo_name
 
                )
 
            )
 

	
 
    @HasPermissionAnyDecorator('hg.admin')
 
    @HasPermissionAllDecorator('hg.admin')
 
    def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
 
        """
 
        Revoke permission for users group on given repository
 

	
 
        :param apiuser:
 
        :param repoid:
 
        :param usersgroupid:
 
        """
 
        repo = get_repo_or_error(repoid)
 
        users_group = get_users_group_or_error(usersgroupid)
 

	
 
        try:
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -212,31 +212,43 @@ class ChangesetController(BaseRepoContro
 
        c.lines_deleted = 0  # count of lines removes
 

	
 
        c.changeset_statuses = ChangesetStatus.STATUSES
 
        c.comments = []
 
        c.statuses = []
 
        c.inline_comments = []
 
        c.inline_cnt = 0
 

	
 
        # Iterate over ranges (default changeset view is always one changeset)
 
        for changeset in c.cs_ranges:
 
            inlines = []
 
            if method == 'show':
 
                c.statuses.extend([ChangesetStatusModel()\
 
                                  .get_status(c.rhodecode_db_repo.repo_id,
 
                                              changeset.raw_id)])
 
                c.statuses.extend([ChangesetStatusModel().get_status(
 
                            c.rhodecode_db_repo.repo_id, changeset.raw_id)])
 

	
 
                c.comments.extend(ChangesetCommentsModel()\
 
                                  .get_comments(c.rhodecode_db_repo.repo_id,
 
                                                revision=changeset.raw_id))
 

	
 
                #comments from PR
 
                st = ChangesetStatusModel().get_statuses(
 
                            c.rhodecode_db_repo.repo_id, changeset.raw_id,
 
                            with_revisions=True)
 
                # from associated statuses, check the pull requests, and
 
                # show comments from them
 

	
 
                prs = set([x.pull_request for x in
 
                           filter(lambda x: x.pull_request != None, st)])
 

	
 
                for pr in prs:
 
                    c.comments.extend(pr.comments)
 
                inlines = ChangesetCommentsModel()\
 
                            .get_inline_comments(c.rhodecode_db_repo.repo_id,
 
                                                 revision=changeset.raw_id)
 
                c.inline_comments.extend(inlines)
 

	
 
            c.changes[changeset.raw_id] = []
 

	
 
            cs2 = changeset.raw_id
 
            cs1 = changeset.parents[0].raw_id if changeset.parents else EmptyChangeset()
 
            context_lcl = get_line_ctx('', request.GET)
 
            ign_whitespace_lcl = ign_whitespace_lcl = get_ignore_ws('', request.GET)
 

	
 
@@ -260,24 +272,27 @@ class ChangesetController(BaseRepoContro
 
                        c.lines_deleted += st[1]
 
                    fid = h.FID(changeset.raw_id, f['filename'])
 
                    diff = diff_processor.as_html(enable_comments=enable_comments,
 
                                                  parsed_lines=[f])
 
                    cs_changes[fid] = [cs1, cs2, f['operation'], f['filename'],
 
                                       diff, st]
 
            else:
 
                # downloads/raw we only need RAW diff nothing else
 
                diff = diff_processor.as_raw()
 
                cs_changes[''] = [None, None, None, None, diff, None]
 
            c.changes[changeset.raw_id] = cs_changes
 

	
 
        #sort comments by how they were generated
 
        c.comments = sorted(c.comments, key=lambda x: x.comment_id)
 

	
 
        # count inline comments
 
        for __, lines in c.inline_comments:
 
            for comments in lines.values():
 
                c.inline_cnt += len(comments)
 

	
 
        if len(c.cs_ranges) == 1:
 
            c.changeset = c.cs_ranges[0]
 
            c.parent_tmpl = ''.join(['# Parent  %s\n' % x.raw_id
 
                                     for x in c.changeset.parents])
 
        if method == 'download':
 
            response.content_type = 'text/plain'
 
            response.content_disposition = 'attachment; filename=%s.diff' \
 
@@ -333,25 +348,25 @@ class ChangesetController(BaseRepoContro
 

	
 
            try:
 
                ChangesetStatusModel().set_status(
 
                    c.rhodecode_db_repo.repo_id,
 
                    status,
 
                    c.rhodecode_user.user_id,
 
                    comm,
 
                    revision=revision,
 
                    dont_allow_on_closed_pull_request=True
 
                )
 
            except StatusChangeOnClosedPullRequestError:
 
                log.error(traceback.format_exc())
 
                msg = _('Changing status on a changeset associated with'
 
                msg = _('Changing status on a changeset associated with '
 
                        'a closed pull request is not allowed')
 
                h.flash(msg, category='warning')
 
                return redirect(h.url('changeset_home', repo_name=repo_name,
 
                                      revision=revision))
 
        action_logger(self.rhodecode_user,
 
                      'user_commented_revision:%s' % revision,
 
                      c.rhodecode_db_repo, self.ip_addr, self.sa)
 

	
 
        Session().commit()
 

	
 
        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return redirect(h.url('changeset_home', repo_name=repo_name,
 
@@ -362,25 +377,25 @@ class ChangesetController(BaseRepoContro
 
        }
 
        if comm:
 
            c.co = comm
 
            data.update(comm.get_dict())
 
            data.update({'rendered_text':
 
                         render('changeset/changeset_comment_block.html')})
 

	
 
        return data
 

	
 
    @jsonify
 
    def delete_comment(self, repo_name, comment_id):
 
        co = ChangesetComment.get(comment_id)
 
        owner = lambda: co.author.user_id == c.rhodecode_user.user_id
 
        owner = co.author.user_id == c.rhodecode_user.user_id
 
        if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
 
            ChangesetCommentsModel().delete(comment=co)
 
            Session().commit()
 
            return True
 
        else:
 
            raise HTTPForbidden()
 

	
 
    @jsonify
 
    def changeset_info(self, repo_name, revision):
 
        if request.is_xhr:
 
            try:
 
                return c.rhodecode_repo.get_changeset(revision)
rhodecode/controllers/compare.py
Show inline comments
 
@@ -94,26 +94,29 @@ class CompareController(BaseRepoControll
 
        rev_start = request.GET.get('rev_start')
 
        rev_end = request.GET.get('rev_end')
 

	
 
        c.swap_url = h.url('compare_url', repo_name=other_repo,
 
              org_ref_type=other_ref[0], org_ref=other_ref[1],
 
              other_ref_type=org_ref[0], other_ref=org_ref[1],
 
              repo=org_repo, as_form=request.GET.get('as_form'),
 
              bundle=incoming_changesets)
 

	
 
        c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
 
        c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
 

	
 
        if c.org_repo is None or c.other_repo is None:
 
            log.error('Could not found repo %s or %s' % (org_repo, other_repo))
 
        if c.org_repo is None:
 
            log.error('Could not find org repo %s' % org_repo)
 
            raise HTTPNotFound
 
        if c.other_repo is None:
 
            log.error('Could not find other repo %s' % other_repo)
 
            raise HTTPNotFound
 

	
 
        if c.org_repo != c.other_repo and h.is_git(c.rhodecode_repo):
 
            log.error('compare of two remote repos not available for GIT REPOS')
 
            raise HTTPNotFound
 

	
 
        if c.org_repo.scm_instance.alias != c.other_repo.scm_instance.alias:
 
            log.error('compare of two different kind of remote repos not available')
 
            raise HTTPNotFound
 

	
 
        partial = request.environ.get('HTTP_X_PARTIAL_XHR')
 
        self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
rhodecode/controllers/home.py
Show inline comments
 
@@ -19,99 +19,61 @@
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 

	
 
from pylons import tmpl_context as c, request
 
from pylons.i18n.translation import _
 
from webob.exc import HTTPBadRequest
 
from sqlalchemy.sql.expression import func
 

	
 
import rhodecode
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.ext_json import json
 
from rhodecode.lib.auth import LoginRequired
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.db import Repository
 
from sqlalchemy.sql.expression import func
 
from rhodecode.model.repo import RepoModel
 

	
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class HomeController(BaseController):
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
        super(HomeController, self).__before__()
 

	
 
    def index(self):
 
        c.groups = self.scm_model.get_repos_groups()
 
        c.group = None
 

	
 
        if c.visual.lightweight_dashboard is False:
 
            c.repos_list = self.scm_model.get_repos()
 
        ## lightweight version of dashboard
 
        else:
 
            c.repos_list = Repository.query()\
 
                            .filter(Repository.group_id == None)\
 
                            .order_by(func.lower(Repository.repo_name))\
 
                            .all()
 
            repos_data = []
 
            total_records = len(c.repos_list)
 

	
 
            _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
 
            template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
 

	
 
            quick_menu = lambda repo_name: (template.get_def("quick_menu")
 
                                            .render(repo_name, _=_, h=h, c=c))
 
            repo_lnk = lambda name, rtype, private, fork_of: (
 
                template.get_def("repo_name")
 
                .render(name, rtype, private, fork_of, short_name=False,
 
                        admin=False, _=_, h=h, c=c))
 
            last_change = lambda last_change:  (template.get_def("last_change")
 
                                           .render(last_change, _=_, h=h, c=c))
 
            rss_lnk = lambda repo_name: (template.get_def("rss")
 
                                           .render(repo_name, _=_, h=h, c=c))
 
            atom_lnk = lambda repo_name: (template.get_def("atom")
 
                                           .render(repo_name, _=_, h=h, c=c))
 

	
 
            def desc(desc):
 
                if c.visual.stylify_metatags:
 
                    return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
 
                else:
 
                    return h.urlify_text(h.truncate(desc, 60))
 

	
 
            for repo in c.repos_list:
 
                repos_data.append({
 
                    "menu": quick_menu(repo.repo_name),
 
                    "raw_name": repo.repo_name.lower(),
 
                    "name": repo_lnk(repo.repo_name, repo.repo_type,
 
                                     repo.private, repo.fork),
 
                    "last_change": last_change(repo.last_db_change),
 
                    "desc": desc(repo.description),
 
                    "owner": h.person(repo.user.username),
 
                    "rss": rss_lnk(repo.repo_name),
 
                    "atom": atom_lnk(repo.repo_name),
 
                })
 

	
 
            c.data = json.dumps({
 
                "totalRecords": total_records,
 
                "startIndex": 0,
 
                "sort": "name",
 
                "dir": "asc",
 
                "records": repos_data
 
            })
 
            repos_data = RepoModel().get_repos_as_dict(repos_list=c.repos_list,
 
                                                       admin=False)
 
            #json used to render the grid
 
            c.data = json.dumps(repos_data)
 

	
 
        return render('/index.html')
 

	
 
    def repo_switcher(self):
 
        if request.is_xhr:
 
            all_repos = Repository.query().order_by(Repository.repo_name).all()
 
            c.repos_list = self.scm_model.get_repos(all_repos,
 
                                                    sort_key='name_sort',
 
                                                    simple=True)
 
            return render('/repo_switcher_list.html')
 
        else:
 
            raise HTTPBadRequest()
rhodecode/controllers/journal.py
Show inline comments
 
@@ -18,40 +18,42 @@
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
from itertools import groupby
 

	
 
from sqlalchemy import or_
 
from sqlalchemy.orm import joinedload
 
from sqlalchemy.sql.expression import func
 

	
 
from webhelpers.paginate import Page
 
from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
 

	
 
from webob.exc import HTTPBadRequest
 
from pylons import request, tmpl_context as c, response, url
 
from pylons.i18n.translation import _
 

	
 
import rhodecode.lib.helpers as h
 
from rhodecode.lib.auth import LoginRequired, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.model.db import UserLog, UserFollowing, Repository, User
 
from rhodecode.model.meta import Session
 
from sqlalchemy.sql.expression import func
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.lib.utils2 import safe_int, AttributeDict
 
from rhodecode.controllers.admin.admin import _journal_filter
 
from rhodecode.model.repo import RepoModel
 
from rhodecode.lib.compat import json
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class JournalController(BaseController):
 

	
 
    def __before__(self):
 
        super(JournalController, self).__before__()
 
        self.language = 'en-us'
 
        self.ttl = "5"
 
        self.feed_nr = 20
 
        c.search_term = request.GET.get('filter')
 
@@ -69,36 +71,91 @@ class JournalController(BaseController):
 

	
 
        journal = self._get_journal_data(c.following)
 

	
 
        def url_generator(**kw):
 
            return url.current(filter=c.search_term, **kw)
 

	
 
        c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
 
        c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
 

	
 
        c.journal_data = render('journal/journal_data.html')
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            return c.journal_data
 
        return render('journal/journal.html')
 

	
 
        repos_list = Session().query(Repository)\
 
                     .filter(Repository.user_id ==
 
                             self.rhodecode_user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 

	
 
        repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
 
                                                   admin=True)
 
        #json used to render the grid
 
        c.data = json.dumps(repos_data)
 

	
 
        watched_repos_data = []
 

	
 
        ## watched repos
 
        _render = RepoModel._render_datatable
 

	
 
        def quick_menu(repo_name):
 
            return _render('quick_menu', repo_name)
 

	
 
        def repo_lnk(name, rtype, private, fork_of):
 
            return _render('repo_name', name, rtype, private, fork_of,
 
                           short_name=False, admin=False)
 

	
 
        def last_rev(repo_name, cs_cache):
 
            return _render('revision', repo_name, cs_cache.get('revision'),
 
                           cs_cache.get('raw_id'), cs_cache.get('author'),
 
                           cs_cache.get('message'))
 

	
 
    @LoginRequired()
 
    @NotAnonymous()
 
    def index_my_repos(self):
 
        c.user = User.get(self.rhodecode_user.user_id)
 
        if request.environ.get('HTTP_X_PARTIAL_XHR'):
 
            all_repos = self.sa.query(Repository)\
 
                     .filter(Repository.user_id == c.user.user_id)\
 
                     .order_by(func.lower(Repository.repo_name)).all()
 
            c.user_repos = ScmModel().get_repos(all_repos)
 
            return render('journal/journal_page_repos.html')
 
        def desc(desc):
 
            from pylons import tmpl_context as c
 
            if c.visual.stylify_metatags:
 
                return h.urlify_text(h.desc_stylize(h.truncate(desc, 60)))
 
            else:
 
                return h.urlify_text(h.truncate(desc, 60))
 

	
 
        def repo_actions(repo_name):
 
            return _render('repo_actions', repo_name)
 

	
 
        def owner_actions(user_id, username):
 
            return _render('user_name', user_id, username)
 

	
 
        def toogle_follow(repo_id):
 
            return  _render('toggle_follow', repo_id)
 

	
 
        for entry in c.following:
 
            repo = entry.follows_repository
 
            cs_cache = repo.changeset_cache
 
            row = {
 
                "menu": quick_menu(repo.repo_name),
 
                "raw_name": repo.repo_name.lower(),
 
                "name": repo_lnk(repo.repo_name, repo.repo_type,
 
                                 repo.private, repo.fork),
 
                "last_changeset": last_rev(repo.repo_name, cs_cache),
 
                "raw_tip": cs_cache.get('revision'),
 
                "action": toogle_follow(repo.repo_id)
 
            }
 

	
 
            watched_repos_data.append(row)
 

	
 
        c.watched_data = json.dumps({
 
            "totalRecords": len(c.following),
 
            "startIndex": 0,
 
            "sort": "name",
 
            "dir": "asc",
 
            "records": watched_repos_data
 
        })
 
        return render('journal/journal.html')
 

	
 
    @LoginRequired(api_access=True)
 
    @NotAnonymous()
 
    def journal_atom(self):
 
        """
 
        Produce an atom-1.0 feed via feedgenerator module
 
        """
 
        following = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
 
            .options(joinedload(UserFollowing.follows_repository))\
 
            .all()
 
        return self._atom_feed(following, public=False)
rhodecode/controllers/login.py
Show inline comments
 
@@ -45,28 +45,27 @@ from rhodecode.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class LoginController(BaseController):
 

	
 
    def __before__(self):
 
        super(LoginController, self).__before__()
 

	
 
    def index(self):
 
        # redirect if already logged in
 
        c.came_from = request.GET.get('came_from')
 

	
 
        if self.rhodecode_user.is_authenticated \
 
                            and self.rhodecode_user.username != 'default':
 

	
 
        not_default = self.rhodecode_user.username != 'default'
 
        ip_allowed = self.rhodecode_user.ip_allowed
 
        if self.rhodecode_user.is_authenticated and not_default and ip_allowed:
 
            return redirect(url('home'))
 

	
 
        if request.POST:
 
            # import Login Form validator class
 
            login_form = LoginForm()
 
            try:
 
                session.invalidate()
 
                c.form_result = login_form.to_python(dict(request.POST))
 
                # form checks for username/password, now we're authenticated
 
                username = c.form_result['username']
 
                user = User.get_by_username(username, case_insensitive=True)
 
                auth_user = AuthUser(user.user_id)
rhodecode/controllers/pullrequests.py
Show inline comments
 
@@ -88,25 +88,25 @@ class PullrequestsController(BaseRepoCon
 
        Get's default revision to do compare on pull request
 

	
 
        :param repo:
 
        """
 
        repo = repo.scm_instance
 
        if 'default' in repo.branches:
 
            return 'default'
 
        else:
 
            #if repo doesn't have default branch return first found
 
            return repo.branches.keys()[0]
 

	
 
    def _get_is_allowed_change_status(self, pull_request):
 
        owner = self.rhodecode_user.user_id == pull_request.user_id 
 
        owner = self.rhodecode_user.user_id == pull_request.user_id
 
        reviewer = self.rhodecode_user.user_id in [x.user_id for x in
 
                                                   pull_request.reviewers]
 
        return (self.rhodecode_user.admin or owner or reviewer)
 

	
 
    def show_all(self, repo_name):
 
        c.pull_requests = PullRequestModel().get_all(repo_name)
 
        c.repo_name = repo_name
 
        return render('/pullrequests/pullrequest_show_all.html')
 

	
 
    @NotAnonymous()
 
    def index(self):
 
        org_repo = c.rhodecode_db_repo
 
@@ -290,25 +290,25 @@ class PullrequestsController(BaseRepoCon
 
        c.org_repo = org_repo
 
        c.other_repo = other_repo
 

	
 
        c.fulldiff = fulldiff = request.GET.get('fulldiff')
 

	
 
        c.cs_ranges = [org_repo.get_changeset(x) for x in pull_request.revisions]
 

	
 
        other_ref = ('rev', getattr(c.cs_ranges[0].parents[0]
 
                                  if c.cs_ranges[0].parents
 
                                  else EmptyChangeset(), 'raw_id'))
 

	
 
        c.statuses = org_repo.statuses([x.raw_id for x in c.cs_ranges])
 
        c.target_repo = c.repo_name
 
        c.target_repo = other_repo.repo_name
 
        # defines that we need hidden inputs with changesets
 
        c.as_form = request.GET.get('as_form', False)
 

	
 
        c.org_ref = org_ref[1]
 
        c.other_ref = other_ref[1]
 

	
 
        diff_limit = self.cut_off_limit if not fulldiff else None
 

	
 
        #we swap org/other ref since we run a simple diff on one repo
 
        _diff = diffs.differ(org_repo, other_ref, other_repo, org_ref)
 

	
 
        diff_processor = diffs.DiffProcessor(_diff or '', format='gitdiff',
 
@@ -330,25 +330,24 @@ class PullrequestsController(BaseRepoCon
 
                c.lines_deleted += st[1]
 
            fid = h.FID('', f['filename'])
 
            c.files.append([fid, f['operation'], f['filename'], f['stats']])
 
            diff = diff_processor.as_html(enable_comments=enable_comments,
 
                                          parsed_lines=[f])
 
            c.changes[fid] = [f['operation'], f['filename'], diff]
 

	
 
    def show(self, repo_name, pull_request_id):
 
        repo_model = RepoModel()
 
        c.users_array = repo_model.get_users_js()
 
        c.users_groups_array = repo_model.get_users_groups_js()
 
        c.pull_request = PullRequest.get_or_404(pull_request_id)
 
        c.target_repo = c.pull_request.org_repo.repo_name
 
        c.allowed_to_change_status = self._get_is_allowed_change_status(c.pull_request)
 
        cc_model = ChangesetCommentsModel()
 
        cs_model = ChangesetStatusModel()
 
        _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo,
 
                                            pull_request=c.pull_request,
 
                                            with_revisions=True)
 

	
 
        cs_statuses = defaultdict(list)
 
        for st in _cs_statuses:
 
            cs_statuses[st.author.username] += [st]
 

	
 
        c.pull_request_reviewers = []
 
@@ -469,19 +468,19 @@ class PullrequestsController(BaseRepoCon
 
                         render('changeset/changeset_comment_block.html')})
 

	
 
        return data
 

	
 
    @NotAnonymous()
 
    @jsonify
 
    def delete_comment(self, repo_name, comment_id):
 
        co = ChangesetComment.get(comment_id)
 
        if co.pull_request.is_closed():
 
            #don't allow deleting comments on closed pull request
 
            raise HTTPForbidden()
 

	
 
        owner = lambda: co.author.user_id == c.rhodecode_user.user_id
 
        owner = co.author.user_id == c.rhodecode_user.user_id
 
        if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
 
            ChangesetCommentsModel().delete(comment=co)
 
            Session().commit()
 
            return True
 
        else:
 
            raise HTTPForbidden()
rhodecode/i18n/ja/LC_MESSAGES/rhodecode.mo
Show inline comments
 
binary diff not shown
rhodecode/i18n/ja/LC_MESSAGES/rhodecode.po
Show inline comments
 
@@ -4,25 +4,25 @@
 
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
 
# Takumi IINO <trot.thunder@gmail.com> 2012
 
# WAKAYAMA Shirou <shirou.faw@gmail.com> 2012
 
#
 
# Mercurial Japanese Translation.
 
# - http://selenic.com/repo/hg/file/stable/i18n/ja.po
 
# ========================================
 
msgid ""
 
msgstr ""
 
"Project-Id-Version: RhodeCode 1.2.0\n"
 
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
 
"POT-Creation-Date: 2012-12-14 04:19+0100\n"
 
"PO-Revision-Date: 2012-10-27 15:06+0900\n"
 
"PO-Revision-Date: 2013-01-02 01:39+0900\n"
 
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 
"Language-Team: ja <LL@li.org>\n"
 
"Plural-Forms: nplurals=1; plural=0\n"
 
"MIME-Version: 1.0\n"
 
"Content-Type: text/plain; charset=utf-8\n"
 
"Content-Transfer-Encoding: 8bit\n"
 
"Generated-By: Babel 0.9.6\n"
 

	
 
#: rhodecode/controllers/changelog.py:95
 
msgid "All Branches"
 
msgstr "すべてのブランチ"
 

	
 
@@ -32,27 +32,27 @@ msgstr "空白を表示"
 

	
 
#: rhodecode/controllers/changeset.py:90 rhodecode/controllers/changeset.py:97
 
msgid "ignore white space"
 
msgstr "空白を無視"
 

	
 
#: rhodecode/controllers/changeset.py:163
 
#, python-format
 
msgid "%s line context"
 
msgstr ""
 

	
 
#: rhodecode/controllers/changeset.py:314
 
#: rhodecode/controllers/pullrequests.py:417
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Status change -> %s"
 
msgstr ""
 
msgstr "ステータス変更 -> %s"
 

	
 
#: rhodecode/controllers/changeset.py:345
 
msgid ""
 
"Changing status on a changeset associated witha closed pull request is "
 
"not allowed"
 
msgstr ""
 

	
 
#: rhodecode/controllers/compare.py:75
 
#: rhodecode/controllers/pullrequests.py:121
 
#: rhodecode/controllers/shortlog.py:100
 
msgid "There are no changesets yet"
 
msgstr "まだ変更がありません"
 
@@ -62,25 +62,25 @@ msgid "Home page"
 
msgstr "ホームページ"
 

	
 
#: rhodecode/controllers/error.py:98
 
msgid "The request could not be understood by the server due to malformed syntax."
 
msgstr "形式が間違っているため、サーバーはリクエストを処理出来ませんでした"
 

	
 
#: rhodecode/controllers/error.py:101
 
msgid "Unauthorized access to resource"
 
msgstr "リソースにアクセスする権限がありません"
 

	
 
#: rhodecode/controllers/error.py:103
 
msgid "You don't have permission to view this page"
 
msgstr "このページを見る権限がありません"
 
msgstr "このページを閲覧する権限がありません"
 

	
 
#: rhodecode/controllers/error.py:105
 
msgid "The resource could not be found"
 
msgstr "リソースが見つかりません"
 

	
 
#: rhodecode/controllers/error.py:107
 
msgid ""
 
"The server encountered an unexpected condition which prevented it from "
 
"fulfilling the request."
 
msgstr ""
 

	
 
#: rhodecode/controllers/feed.py:52
 
@@ -276,61 +276,57 @@ msgstr "リポジトリ %s の更新中にエラーが発生しました"
 
#, python-format
 
msgid "deleted repository %s"
 
msgstr "リポジトリ %s を削除しました"
 

	
 
#: rhodecode/controllers/settings.py:166
 
#: rhodecode/controllers/admin/repos.py:325
 
#: rhodecode/controllers/admin/repos.py:331
 
#, python-format
 
msgid "An error occurred during deletion of %s"
 
msgstr "リポジトリ %s の削除中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/settings.py:185
 
#, fuzzy
 
msgid "unlocked"
 
msgstr "変更可能にする"
 
msgstr "アンロック"
 

	
 
#: rhodecode/controllers/settings.py:188
 
#, fuzzy
 
msgid "locked"
 
msgstr "変更可能にする"
 
msgstr "ロック"
 

	
 
#: rhodecode/controllers/settings.py:190
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Repository has been %s"
 
msgstr ""
 
msgstr "リポジトリは %s されています"
 

	
 
#: rhodecode/controllers/settings.py:194
 
#: rhodecode/controllers/admin/repos.py:423
 
msgid "An error occurred during unlocking"
 
msgstr "アンロック時にエラーが発生しました"
 

	
 
#: rhodecode/controllers/summary.py:140
 
msgid "No data loaded yet"
 
msgstr "まだデータが読み込まれていません"
 

	
 
#: rhodecode/controllers/summary.py:144
 
#: rhodecode/templates/summary/summary.html:157
 
msgid "Statistics are disabled for this repository"
 
msgstr "このリポジトリの統計は無効化されています"
 

	
 
#: rhodecode/controllers/admin/defaults.py:96
 
#, fuzzy
 
msgid "Default settings updated successfully"
 
msgstr "LDAP設定を更新しました"
 
msgstr "デフォルト設定を更新しました"
 

	
 
#: rhodecode/controllers/admin/defaults.py:110
 
#, fuzzy
 
msgid "error occurred during update of defaults"
 
msgstr "ユーザー %s の更新中にエラーが発生しました"
 
msgstr "デフォルト設定の更新中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/ldap_settings.py:50
 
msgid "BASE"
 
msgstr "BASE"
 

	
 
#: rhodecode/controllers/admin/ldap_settings.py:51
 
msgid "ONELEVEL"
 
msgstr "ONELEVEL"
 

	
 
#: rhodecode/controllers/admin/ldap_settings.py:52
 
msgid "SUBTREE"
 
msgstr "SUBTREE"
 
@@ -464,49 +460,49 @@ msgstr "リポジトリ %s を %s から作成"
 
#, python-format
 
msgid "created repository %s"
 
msgstr "リポジトリ %s を作成しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:225
 
#, python-format
 
msgid "error occurred during creation of repository %s"
 
msgstr "リポジトリ %s を作成中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:320
 
#, python-format
 
msgid "Cannot delete %s it still contains attached forks"
 
msgstr ""
 
msgstr "フォークしたリポジトリが存在するため、 %s は削除できません"
 

	
 
#: rhodecode/controllers/admin/repos.py:349
 
msgid "An error occurred during deletion of repository user"
 
msgstr "リポジトリユーザーの削除中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:368
 
msgid "An error occurred during deletion of repository users groups"
 
msgstr "リポジトリユーザーグループの削除中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:386
 
msgid "An error occurred during deletion of repository stats"
 
msgstr "リポジトリステートの削除中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:403
 
msgid "An error occurred during cache invalidation"
 
msgstr "キャッシュの無効化時にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:443
 
msgid "Updated repository visibility in public journal"
 
msgstr ""
 
msgstr "公開ジャーナルでのリポジトリの可視性を更新しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:447
 
msgid "An error occurred during setting this repository in public journal"
 
msgstr ""
 
msgstr "このリポジトリの公開ジャーナルの設定中にエラーが発生しました"
 

	
 
#: rhodecode/controllers/admin/repos.py:452 rhodecode/model/validators.py:300
 
msgid "Token mismatch"
 
msgstr "トークンが合いません"
 

	
 
#: rhodecode/controllers/admin/repos.py:465
 
msgid "Pulled from remote location"
 
msgstr "リモートから取得"
 

	
 
#: rhodecode/controllers/admin/repos.py:467
 
msgid "An error occurred during pull from remote location"
 
msgstr "リモートから取得中にエラーが発生しました"
 
@@ -741,83 +737,83 @@ msgid "You need to be a registered user 
 
msgstr "このアクションを実行するためには登録ユーザーである必要があります"
 

	
 
#: rhodecode/lib/auth.py:540
 
msgid "You need to be a signed in to view this page"
 
msgstr "このページを閲覧するためにはサインインが必要です"
 

	
 
#: rhodecode/lib/diffs.py:74
 
msgid "binary file"
 
msgstr "バイナリファイル"
 

	
 
#: rhodecode/lib/diffs.py:90
 
msgid "Changeset was too big and was cut off, use diff menu to display this diff"
 
msgstr ""
 
msgstr "チェンジセットが大きすぎるため省略しました。差分を表示する場合は差分メニューを使用してください"
 

	
 
#: rhodecode/lib/diffs.py:100
 
msgid "No changes detected"
 
msgstr "検出された変更はありません"
 

	
 
#: rhodecode/lib/helpers.py:374
 
#, python-format
 
msgid "%a, %d %b %Y %H:%M:%S"
 
msgstr "%a, %d %b %Y %H:%M:%S"
 

	
 
#: rhodecode/lib/helpers.py:486
 
msgid "True"
 
msgstr "True"
 

	
 
#: rhodecode/lib/helpers.py:490
 
msgid "False"
 
msgstr "False"
 

	
 
#: rhodecode/lib/helpers.py:530
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Deleted branch: %s"
 
msgstr "リポジトリ %s を削除しました"
 
msgstr "削除されたブランチ: %s"
 

	
 
#: rhodecode/lib/helpers.py:533
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Created tag: %s"
 
msgstr "ユーザー %s を作成しました"
 
msgstr "作成したタグ: %s"
 

	
 
#: rhodecode/lib/helpers.py:546
 
msgid "Changeset not found"
 
msgstr "リビジョンが見つかりません"
 

	
 
#: rhodecode/lib/helpers.py:589
 
#, python-format
 
msgid "Show all combined changesets %s->%s"
 
msgstr "%s から %s までのすべてのチェンジセットを表示"
 

	
 
#: rhodecode/lib/helpers.py:595
 
msgid "compare view"
 
msgstr "比較の表示"
 

	
 
#: rhodecode/lib/helpers.py:615
 
msgid "and"
 
msgstr ""
 
msgstr ""
 

	
 
#: rhodecode/lib/helpers.py:616
 
#, python-format
 
msgid "%s more"
 
msgstr ""
 
msgstr "%s 以上"
 

	
 
#: rhodecode/lib/helpers.py:617 rhodecode/templates/changelog/changelog.html:51
 
msgid "revisions"
 
msgstr "リビジョン"
 

	
 
#: rhodecode/lib/helpers.py:641
 
#, fuzzy, python-format
 
#, python-format
 
msgid "fork name %s"
 
msgstr ""
 
msgstr "フォーク名 %s"
 

	
 
#: rhodecode/lib/helpers.py:658
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:4
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:12
 
#, python-format
 
msgid "Pull request #%s"
 
msgstr "プルリクエスト #%s"
 

	
 
#: rhodecode/lib/helpers.py:664
 
msgid "[deleted] repository"
 
msgstr "リポジトリを[削除]"
 

	
 
@@ -950,27 +946,27 @@ msgstr[0] "%d 秒"
 

	
 
#: rhodecode/lib/utils2.py:424
 
#, python-format
 
msgid "in %s"
 
msgstr ""
 

	
 
#: rhodecode/lib/utils2.py:426
 
#, python-format
 
msgid "%s ago"
 
msgstr "%s 前"
 

	
 
#: rhodecode/lib/utils2.py:428
 
#, fuzzy, python-format
 
#, python-format
 
msgid "in %s and %s"
 
msgstr "%s と %s 前"
 
msgstr ""
 

	
 
#: rhodecode/lib/utils2.py:431
 
#, python-format
 
msgid "%s and %s ago"
 
msgstr "%s と %s 前"
 

	
 
#: rhodecode/lib/utils2.py:434
 
msgid "just now"
 
msgstr "ちょうどいま"
 

	
 
#: rhodecode/lib/celerylib/tasks.py:270
 
msgid "password reset link"
 
@@ -1075,85 +1071,85 @@ msgid "Enter a value %(min)i characters 
 
msgstr "%(min)i 文字以上必要です"
 

	
 
#: rhodecode/model/forms.py:52
 
msgid "Please enter a password"
 
msgstr "パスワードを入力してください"
 

	
 
#: rhodecode/model/forms.py:53
 
#, python-format
 
msgid "Enter %(min)i characters or more"
 
msgstr "%(min)i 文字以上必要です"
 

	
 
#: rhodecode/model/notification.py:220
 
#, fuzzy, python-format
 
#, python-format
 
msgid "commented on commit at %(when)s"
 
msgstr ""
 
msgstr "コミットにコメント %(when)s"
 

	
 
#: rhodecode/model/notification.py:221
 
#, python-format
 
msgid "sent message at %(when)s"
 
msgstr ""
 
msgstr "メッセージを送信 %(when)s"
 

	
 
#: rhodecode/model/notification.py:222
 
#, python-format
 
msgid "mentioned you at %(when)s"
 
msgstr ""
 
msgstr "Mention %(when)s"
 

	
 
#: rhodecode/model/notification.py:223
 
#, python-format
 
msgid "registered in RhodeCode at %(when)s"
 
msgstr ""
 
msgstr "RhodeCodeに登録 %(when)s"
 

	
 
#: rhodecode/model/notification.py:224
 
#, fuzzy, python-format
 
#, python-format
 
msgid "opened new pull request at %(when)s"
 
msgstr ""
 
msgstr "新しいプルリクエストを作成 %(when)s"
 

	
 
#: rhodecode/model/notification.py:225
 
#, fuzzy, python-format
 
#, python-format
 
msgid "commented on pull request at %(when)s"
 
msgstr ""
 
msgstr "プルリクエストにコメント %(when)s"
 

	
 
#: rhodecode/model/pull_request.py:90
 
#, python-format
 
msgid "%(user)s wants you to review pull request #%(pr_id)s"
 
msgstr ""
 
msgstr "%(user)s がプリリクエスト #%(pr_id)s のレビューを求めています"
 

	
 
#: rhodecode/model/scm.py:542
 
msgid "latest tip"
 
msgstr "最新のtip"
 

	
 
#: rhodecode/model/user.py:232
 
msgid "new user registration"
 
msgstr "新規ユーザー登録"
 

	
 
#: rhodecode/model/user.py:257 rhodecode/model/user.py:281
 
#: rhodecode/model/user.py:303
 
msgid "You can't Edit this user since it's crucial for entire application"
 
msgstr ""
 
msgstr "アプリケーション全体にとって重要なユーザなため、編集出来ません"
 

	
 
#: rhodecode/model/user.py:327
 
msgid "You can't remove this user since it's crucial for entire application"
 
msgstr ""
 
msgstr "アプリケーション全体にとって重要なユーザなため、削除できません"
 

	
 
#: rhodecode/model/user.py:333
 
#, python-format
 
msgid ""
 
"user \"%s\" still owns %s repositories and cannot be removed. Switch "
 
"owners or remove those repositories. %s"
 
msgstr ""
 

	
 
#: rhodecode/model/validators.py:36 rhodecode/model/validators.py:37
 
msgid "Value cannot be an empty list"
 
msgstr ""
 
msgstr "空のリストには出来ません"
 

	
 
#: rhodecode/model/validators.py:83
 
#, python-format
 
msgid "Username \"%(username)s\" already exists"
 
msgstr "ユーザー名 \"%(username)s\" はすでに使われています"
 

	
 
#: rhodecode/model/validators.py:85
 
#, python-format
 
msgid "Username \"%(username)s\" is forbidden"
 
msgstr "ユーザー名 \"%(username)s\" は許可されていません"
 

	
 
#: rhodecode/model/validators.py:87
 
@@ -1235,34 +1231,33 @@ msgstr "リポジトリ \"%(repo)s\" は グループ \"%(group)s\" にすでに存在します"
 

	
 
#: rhodecode/model/validators.py:319
 
#, python-format
 
msgid "Repositories group with name \"%(repo)s\" already exists"
 
msgstr "リポジトリグループ名 \"%(repo)s\" はすでに存在します"
 

	
 
#: rhodecode/model/validators.py:432
 
msgid "invalid clone url"
 
msgstr "無効なクローンURIです"
 

	
 
#: rhodecode/model/validators.py:433
 
msgid "Invalid clone url, provide a valid clone http(s)/svn+http(s) url"
 
msgstr ""
 
msgstr "無効なクローンURIです。有効な http(s)/svn+http(s) のURIを指定してください"
 

	
 
#: rhodecode/model/validators.py:458
 
msgid "Fork have to be the same type as parent"
 
msgstr "フォークは親と同じタイプの必要があります"
 

	
 
#: rhodecode/model/validators.py:473
 
#, fuzzy
 
msgid "You don't have permissions to create repository in this group"
 
msgstr "このページを見る権限がありません"
 
msgstr "このグループでリポジトリを作成する権限がありません"
 

	
 
#: rhodecode/model/validators.py:498
 
msgid "This username or users group name is not valid"
 
msgstr "ユーザー名かユーザーグループが不正です"
 

	
 
#: rhodecode/model/validators.py:591
 
msgid "This is not a valid path"
 
msgstr "不正なパスです"
 

	
 
#: rhodecode/model/validators.py:606
 
msgid "This e-mail address is already taken"
 
msgstr "このメールアドレスはすでに取得されています"
 
@@ -1608,40 +1603,38 @@ msgstr "ブックマーク"
 

	
 
#: rhodecode/templates/switch_to_list.html:35
 
#: rhodecode/templates/bookmarks/bookmarks_data.html:32
 
msgid "There are no bookmarks yet"
 
msgstr "まだブックマークがありません"
 

	
 
#: rhodecode/templates/admin/admin.html:5
 
#: rhodecode/templates/admin/admin.html:13
 
msgid "Admin journal"
 
msgstr "管理者ジャーナル"
 

	
 
#: rhodecode/templates/admin/admin.html:10
 
#, fuzzy
 
msgid "journal filter..."
 
msgstr "クイックフィルタ..."
 
msgstr "ジャーナルフィルタ..."
 

	
 
#: rhodecode/templates/admin/admin.html:12
 
#: rhodecode/templates/journal/journal.html:11
 
#, fuzzy
 
msgid "filter"
 
msgstr "ファイル"
 
msgstr "フィルタ"
 

	
 
#: rhodecode/templates/admin/admin.html:13
 
#: rhodecode/templates/journal/journal.html:12
 
#, python-format
 
msgid "%s entry"
 
msgid_plural "%s entries"
 
msgstr[0] ""
 
msgstr[0] "%s エントリ"
 

	
 
#: rhodecode/templates/admin/admin_log.html:6
 
#: rhodecode/templates/admin/repos/repos.html:74
 
#: rhodecode/templates/admin/users/user_edit_my_account_repos.html:8
 
#: rhodecode/templates/admin/users/user_edit_my_account_repos.html:9
 
#: rhodecode/templates/journal/journal_page_repos.html:9
 
#: rhodecode/templates/journal/journal_page_repos.html:10
 
msgid "Action"
 
msgstr "アクション"
 

	
 
#: rhodecode/templates/admin/admin_log.html:7
 
#: rhodecode/templates/admin/permissions/permissions.html:41
 
@@ -1659,32 +1652,30 @@ msgid "Date"
 
msgstr "日時"
 

	
 
#: rhodecode/templates/admin/admin_log.html:9
 
msgid "From IP"
 
msgstr "アクセス元IPアドレス"
 

	
 
#: rhodecode/templates/admin/admin_log.html:63
 
msgid "No actions yet"
 
msgstr "まだアクションがありません"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:5
 
#: rhodecode/templates/admin/defaults/defaults.html:25
 
#, fuzzy
 
msgid "Repositories defaults"
 
msgstr "リポジトリグループ"
 
msgstr "リポジトリのデフォルト設定"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:11
 
#, fuzzy
 
msgid "Defaults"
 
msgstr "default"
 
msgstr "デフォルト設定"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:35
 
#: rhodecode/templates/admin/repos/repo_add_base.html:38
 
#: rhodecode/templates/admin/repos/repo_edit.html:58
 
msgid "Type"
 
msgstr "リポジトリのタイプ"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:48
 
#: rhodecode/templates/admin/repos/repo_add_base.html:69
 
#: rhodecode/templates/admin/repos/repo_edit.html:89
 
#: rhodecode/templates/forks/fork.html:72
 
#: rhodecode/templates/settings/repo_settings.html:80
 
@@ -1713,25 +1704,25 @@ msgstr "ダウンロードを有効にする"
 
msgid "Enable download menu on summary page."
 
msgstr "概要ページのダウンロードメニューを有効にします"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:75
 
#: rhodecode/templates/admin/repos/repo_edit.html:112
 
#: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:66
 
msgid "Enable locking"
 
msgstr "ロックを有効にする"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:79
 
#: rhodecode/templates/admin/repos/repo_edit.html:116
 
msgid "Enable lock-by-pulling on repository."
 
msgstr ""
 
msgstr "リポジトリのpullのロックを有効にします"
 

	
 
#: rhodecode/templates/admin/defaults/defaults.html:84
 
#: rhodecode/templates/admin/ldap/ldap.html:89
 
#: rhodecode/templates/admin/repos/repo_edit.html:141
 
#: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:74
 
#: rhodecode/templates/admin/settings/hooks.html:73
 
#: rhodecode/templates/admin/users/user_edit.html:133
 
#: rhodecode/templates/admin/users/user_edit.html:178
 
#: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:135
 
#: rhodecode/templates/settings/repo_settings.html:94
 
msgid "Save"
 
@@ -2067,38 +2058,37 @@ msgstr "キャッシュ"
 
#: rhodecode/templates/admin/repos/repo_edit.html:190
 
msgid "Invalidate repository cache"
 
msgstr "リポジトリのキャッシュを無効化"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:190
 
msgid "Confirm to invalidate repository cache"
 
msgstr "リポジトリのキャッシュを無効化してもよろしいですか?"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:193
 
msgid ""
 
"Manually invalidate cache for this repository. On first access repository"
 
" will be cached again"
 
msgstr ""
 
msgstr "このリポジトリのキャッシュを手動で無効化します。リポジトリへの初回アクセス時に再びキャッシュされます。"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:198
 
msgid "List of cached values"
 
msgstr ""
 
msgstr "キャッシュしている値の一覧"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:201
 
msgid "Prefix"
 
msgstr ""
 
msgstr "プレフィックス"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:202
 
#, fuzzy
 
msgid "Key"
 
msgstr "APIキー"
 
msgstr "キー"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:203
 
#: rhodecode/templates/admin/users/user_add.html:86
 
#: rhodecode/templates/admin/users/user_edit.html:117
 
#: rhodecode/templates/admin/users_groups/users_group_add.html:41
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:42
 
msgid "Active"
 
msgstr "アクティブ"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:218
 
#: rhodecode/templates/base/base.html:331
 
#: rhodecode/templates/base/base.html:333
 
@@ -2137,25 +2127,25 @@ msgid "lock repo"
 
msgstr "リポジトリのロック"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:246
 
msgid "Confirm to lock repository"
 
msgstr "このリポジトリをロックしますか?"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:247
 
msgid "Repository is not locked"
 
msgstr "リポジトリはロックされていません"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:252
 
msgid "Force locking on repository. Works only when anonymous access is disabled"
 
msgstr ""
 
msgstr "リポジトリを強制ロックします。匿名アクセスが無効になっている場合のみ動作します。"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:259
 
msgid "Set as fork of"
 
msgstr "フォーク元の設定"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:268
 
msgid "Manually set this repository as a fork of another from the list"
 
msgstr "このリポジトリをリスト中の他のリポジトリのフォークとして、手動で設定します"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:274
 
#: rhodecode/templates/changeset/changeset_file_comment.html:26
 
msgid "Delete"
 
@@ -2164,32 +2154,31 @@ msgstr "削除"
 
#: rhodecode/templates/admin/repos/repo_edit.html:278
 
#: rhodecode/templates/settings/repo_settings.html:115
 
msgid "Remove this repository"
 
msgstr "このリポジトリを削除"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:278
 
#: rhodecode/templates/settings/repo_settings.html:115
 
msgid "Confirm to delete this repository"
 
msgstr "このリポジトリを削除しますか?"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit.html:282
 
#: rhodecode/templates/settings/repo_settings.html:119
 
#, fuzzy
 
msgid ""
 
"This repository will be renamed in a special way in order to be "
 
"unaccesible for RhodeCode and VCS systems. If you need fully delete it "
 
"from file system please do it manually"
 
msgstr ""
 
"このリポジトリはRhodeCodeとVCSシステムからアクセスされないような名前に、特別な方法で変更されます。\n"
 
"もし、ファイルシステムから完全に削除したい場合、手動で行ってください"
 
"このリポジトリはRhodeCodeとVCSシステムからアクセス出来ないようにするために特別な方法でリネームされます。\n"
 
"完全な削除が必要な場合はファイルシステムから手動で削除してください"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit_perms.html:3
 
#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:3
 
msgid "none"
 
msgstr "なし"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit_perms.html:4
 
#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:4
 
msgid "read"
 
msgstr "読込"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit_perms.html:5
 
@@ -2241,25 +2230,25 @@ msgstr "ユーザーの削除に失敗しました"
 

	
 
#: rhodecode/templates/admin/repos/repo_edit_perms.html:112
 
#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:103
 
msgid "Failed to remove users group"
 
msgstr "ユーザーグループの削除に失敗しました"
 

	
 
#: rhodecode/templates/admin/repos/repos.html:5
 
msgid "Repositories administration"
 
msgstr "リポジトリ管理"
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:73
 
msgid "apply to children"
 
msgstr ""
 
msgstr "子リポジトリにも適用"
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:74
 
msgid ""
 
"Set or revoke permission to all children of that group, including "
 
"repositories and other groups"
 
msgstr ""
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_groups.html:9
 
#: rhodecode/templates/base/base.html:122
 
#: rhodecode/templates/base/base.html:313
 
#: rhodecode/templates/base/base.html:315
 
#: rhodecode/templates/base/base.html:317
 
@@ -2347,28 +2336,28 @@ msgstr "トップレベルリポジトリの数"
 
msgid "action"
 
msgstr "アクション"
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_groups_show.html:55
 
#: rhodecode/templates/admin/users/user_edit.html:259
 
#: rhodecode/templates/admin/users_groups/users_groups.html:44
 
#: rhodecode/templates/data_table/_dt_elements.html:7
 
#: rhodecode/templates/data_table/_dt_elements.html:121
 
msgid "delete"
 
msgstr "削除"
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_groups_show.html:55
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Confirm to delete this group: %s with %s repository"
 
msgid_plural "Confirm to delete this group: %s with %s repositories"
 
msgstr[0] ""
 
msgstr[0] "このグループを削除してもよろしいですか?: %s %s リポジトリ"
 

	
 
#: rhodecode/templates/admin/repos_groups/repos_groups_show.html:63
 
msgid "There are no repositories groups yet"
 
msgstr "まだリポジトリグループがありません"
 

	
 
#: rhodecode/templates/admin/settings/hooks.html:5
 
#: rhodecode/templates/admin/settings/settings.html:5
 
msgid "Settings administration"
 
msgstr "設定管理"
 

	
 
#: rhodecode/templates/admin/settings/hooks.html:9
 
#: rhodecode/templates/admin/settings/settings.html:9
 
@@ -2385,29 +2374,29 @@ msgid "Custom hooks"
 
msgstr "カスタムフック"
 

	
 
#: rhodecode/templates/admin/settings/hooks.html:56
 
msgid "remove"
 
msgstr "削除"
 

	
 
#: rhodecode/templates/admin/settings/hooks.html:88
 
msgid "Failed to remove hook"
 
msgstr "フックの削除に失敗しました"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:24
 
msgid "Remap and rescan repositories"
 
msgstr ""
 
msgstr "リポジトリの再マッピングと再スキャン"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:32
 
msgid "rescan option"
 
msgstr ""
 
msgstr "再スキャンオプション"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:38
 
msgid ""
 
"In case a repository was deleted from filesystem and there are leftovers "
 
"in the database check this option to scan obsolete data in database and "
 
"remove it."
 
msgstr ""
 

	
 
#: rhodecode/templates/admin/settings/settings.html:39
 
msgid "destroy old data"
 
msgstr "古いデータを削除する"
 

	
 
@@ -2455,31 +2444,30 @@ msgstr "GAコード"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:112
 
#: rhodecode/templates/admin/settings/settings.html:178
 
#: rhodecode/templates/admin/settings/settings.html:268
 
msgid "Save settings"
 
msgstr "設定を保存"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:119
 
msgid "Visualisation settings"
 
msgstr "表示の設定"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:127
 
#, fuzzy
 
msgid "General"
 
msgstr "有効にする"
 
msgstr "一般"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:132
 
msgid "Use lightweight dashboard"
 
msgstr ""
 
msgstr "軽量ダッシュボードを使用"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:139
 
msgid "Icons"
 
msgstr "アイコン"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:144
 
msgid "Show public repo icon on repositories"
 
msgstr "公開リポジトリのアイコンを表示"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:148
 
msgid "Show private repo icon on repositories"
 
msgstr "非公開リポジトリのアイコンを表示"
 
@@ -2499,25 +2487,25 @@ msgstr "VCSの設定"
 
#: rhodecode/templates/admin/settings/settings.html:196
 
msgid "Web"
 
msgstr "Web"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:201
 
msgid "require ssl for vcs operations"
 
msgstr "VCSの操作にSSLを必須とする"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:203
 
msgid ""
 
"RhodeCode will require SSL for pushing or pulling. If SSL is missing it "
 
"will return HTTP Error 406: Not Acceptable"
 
msgstr ""
 
msgstr "RhodeCodeはPushとPullにSSLを要求します。もしSSLでない場合、HTTP Error 406: Not Acceptalbeを返します"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:209
 
msgid "Hooks"
 
msgstr "フック"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:214
 
msgid "Update repository after push (hg update)"
 
msgstr "プッシュ後にリポジトリをを更新する (hg update)"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:218
 
msgid "Show repository size after push"
 
msgstr "プッシュ後にリポジトリのサイズを表示する"
 
@@ -2552,30 +2540,33 @@ msgid ""
 
"locations"
 
msgstr "hgsubversion のインストールが必要です。リモートロケーションのsvnからクローン出来るようになります"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:256
 
msgid "Repositories location"
 
msgstr "リポジトリロケーション"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:261
 
msgid ""
 
"This a crucial application setting. If you are really sure you need to "
 
"change this, you must restart application in order to make this setting "
 
"take effect. Click this label to unlock."
 
msgstr "これはアプリケーションの重要な設定です。本当に変更が必要でしょうか。もし、変更した場合、変更を反映さ競るためにアプリケーションを再起動する必要があります。変更可能にするにはこのラベルをクリックして下さい"
 
msgstr ""
 
"これはアプリケーションの重要な設定です。本当に変更が必要でしょうか。"
 
"もし、変更した場合、変更を反映さ競るためにアプリケーションを再起動する必要があります。"
 
"アンロックにするにはこのラベルをクリックして下さい"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:262
 
#: rhodecode/templates/base/base.html:221
 
msgid "unlock"
 
msgstr "変更可能にする"
 
msgstr "アンロック"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:263
 
msgid ""
 
"Location where repositories are stored. After changing this value a "
 
"restart, and rescan is required"
 
msgstr ""
 

	
 
#: rhodecode/templates/admin/settings/settings.html:283
 
msgid "Test Email"
 
msgstr "テストメール"
 

	
 
#: rhodecode/templates/admin/settings/settings.html:291
 
@@ -2860,37 +2851,34 @@ msgstr "全ての要素を削除"
 
msgid "Available members"
 
msgstr "有効なメンバー"
 

	
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:79
 
msgid "Add all elements"
 
msgstr "全ての要素を追加"
 

	
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:146
 
msgid "Group members"
 
msgstr "グループメンバー"
 

	
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:163
 
#, fuzzy
 
msgid "No members yet"
 
msgstr "メンバー"
 
msgstr "まだメンバーがいません"
 

	
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:171
 
#, fuzzy
 
msgid "Permissions defined for this group"
 
msgstr "権限管理"
 
msgstr "このリポジトリの権限設定"
 

	
 
#: rhodecode/templates/admin/users_groups/users_group_edit.html:178
 
#, fuzzy
 
msgid "No permissions set yet"
 
msgstr "権限のコピー"
 
msgstr "まだ権限設定がありません"
 

	
 
#: rhodecode/templates/admin/users_groups/users_groups.html:5
 
msgid "Users groups administration"
 
msgstr "ユーザーグループ管理"
 

	
 
#: rhodecode/templates/admin/users_groups/users_groups.html:23
 
msgid "ADD NEW USER GROUP"
 
msgstr "新しいユーザーグループを追加"
 

	
 
#: rhodecode/templates/admin/users_groups/users_groups.html:32
 
msgid "group name"
 
msgstr "グループ名"
 
@@ -2983,69 +2971,66 @@ msgstr "ブランチの切り替え"
 
#: rhodecode/templates/data_table/_dt_elements.html:33
 
#: rhodecode/templates/data_table/_dt_elements.html:35
 
msgid "Files"
 
msgstr "ファイル"
 

	
 
#: rhodecode/templates/base/base.html:195
 
#: rhodecode/templates/base/base.html:199
 
msgid "Options"
 
msgstr "オプション"
 

	
 
#: rhodecode/templates/base/base.html:204
 
#: rhodecode/templates/base/base.html:206
 
#, fuzzy
 
msgid "repository settings"
 
msgstr "リポジトリ作成"
 
msgstr "リポジトリ設定"
 

	
 
#: rhodecode/templates/base/base.html:210
 
#: rhodecode/templates/data_table/_dt_elements.html:80
 
#: rhodecode/templates/forks/fork.html:13
 
msgid "fork"
 
msgstr "フォーク"
 

	
 
#: rhodecode/templates/base/base.html:212 rhodecode/templates/base/root.html:50
 
#: rhodecode/templates/changelog/changelog.html:43
 
msgid "Open new pull request"
 
msgstr "新しいプルリクエストを作成"
 

	
 
#: rhodecode/templates/base/base.html:215
 
#: rhodecode/templates/forks/forks_data.html:21
 
msgid "Compare fork"
 
msgstr "フォークを比較"
 

	
 
#: rhodecode/templates/base/base.html:217
 
msgid "search"
 
msgstr "検索"
 

	
 
#: rhodecode/templates/base/base.html:223
 
#, fuzzy
 
msgid "lock"
 
msgstr "変更可能にする"
 
msgstr "ロック"
 

	
 
#: rhodecode/templates/base/base.html:234
 
msgid "repositories groups"
 
msgstr "リポジトリグループ"
 

	
 
#: rhodecode/templates/base/base.html:236
 
msgid "users groups"
 
msgstr "ユーザーグループ"
 

	
 
#: rhodecode/templates/base/base.html:237
 
msgid "permissions"
 
msgstr "権限"
 

	
 
#: rhodecode/templates/base/base.html:239
 
#, fuzzy
 
msgid "defaults"
 
msgstr "default"
 
msgstr "デフォルト設定"
 

	
 
#: rhodecode/templates/base/base.html:240
 
msgid "settings"
 
msgstr "設定"
 

	
 
#: rhodecode/templates/base/base.html:251
 
#: rhodecode/templates/base/base.html:253
 
msgid "Followers"
 
msgstr "フォロワー"
 

	
 
#: rhodecode/templates/base/base.html:259
 
#: rhodecode/templates/base/base.html:261
 
@@ -3078,31 +3063,30 @@ msgstr "このリポジトリのフォローする"
 
msgid "Group"
 
msgstr "グループ"
 

	
 
#: rhodecode/templates/base/root.html:48
 
msgid "search truncated"
 
msgstr "検索結果は省略されています"
 

	
 
#: rhodecode/templates/base/root.html:49
 
msgid "no matching files"
 
msgstr "マッチするファイルはありません"
 

	
 
#: rhodecode/templates/base/root.html:51
 
#, fuzzy
 
msgid "Open new pull request for selected changesets"
 
msgstr "新しいプルリクエストを作成"
 
msgstr "選択したチェンジセットから新しいプルリクエストを作成"
 

	
 
#: rhodecode/templates/base/root.html:52
 
msgid "Show selected changes __S -> __E"
 
msgstr ""
 
msgstr "選択した変更 __S -> __E を表示"
 

	
 
#: rhodecode/templates/base/root.html:53
 
msgid "Selection link"
 
msgstr ""
 

	
 
#: rhodecode/templates/bookmarks/bookmarks.html:5
 
#, python-format
 
msgid "%s Bookmarks"
 
msgstr "%s ブックマーク"
 

	
 
#: rhodecode/templates/bookmarks/bookmarks.html:39
 
#: rhodecode/templates/bookmarks/bookmarks_data.html:8
 
@@ -3134,38 +3118,36 @@ msgstr "比較"
 
#: rhodecode/templates/changelog/changelog.html:6
 
#, python-format
 
msgid "%s Changelog"
 
msgstr "%s チェンジログ"
 

	
 
#: rhodecode/templates/changelog/changelog.html:15
 
#, python-format
 
msgid "showing %d out of %d revision"
 
msgid_plural "showing %d out of %d revisions"
 
msgstr[0] ""
 

	
 
#: rhodecode/templates/changelog/changelog.html:37
 
#, fuzzy
 
msgid "Clear selection"
 
msgstr "検索設定"
 
msgstr "選択を解除"
 

	
 
#: rhodecode/templates/changelog/changelog.html:40
 
#: rhodecode/templates/forks/forks_data.html:19
 
#, python-format
 
msgid "compare fork with %s"
 
msgstr "%s とフォークを比較"
 

	
 
#: rhodecode/templates/changelog/changelog.html:40
 
#, fuzzy
 
msgid "Compare fork with parent"
 
msgstr "%s とフォークを比較"
 
msgstr "フォークを比較"
 

	
 
#: rhodecode/templates/changelog/changelog.html:49
 
msgid "Show"
 
msgstr "表示"
 

	
 
#: rhodecode/templates/changelog/changelog.html:74
 
#: rhodecode/templates/summary/summary.html:375
 
msgid "show more"
 
msgstr "もっと表示"
 

	
 
#: rhodecode/templates/changelog/changelog.html:78
 
msgid "Affected number of files, click to show more details"
 
@@ -3250,70 +3232,69 @@ msgstr "%s ファイルに影響"
 

	
 
#: rhodecode/templates/changeset/changeset.html:6
 
#, python-format
 
msgid "%s Changeset"
 
msgstr "%s チェンジセット"
 

	
 
#: rhodecode/templates/changeset/changeset.html:14
 
msgid "Changeset"
 
msgstr "チェンジセット"
 

	
 
#: rhodecode/templates/changeset/changeset.html:52
 
msgid "No children"
 
msgstr ""
 
msgstr "子リビジョンはありません"
 

	
 
#: rhodecode/templates/changeset/changeset.html:70
 
#: rhodecode/templates/changeset/diff_block.html:20
 
msgid "raw diff"
 
msgstr "差分を表示"
 

	
 
#: rhodecode/templates/changeset/changeset.html:71
 
#, fuzzy
 
msgid "patch diff"
 
msgstr "差分を表示"
 
msgstr "パッチとして差分を表示"
 

	
 
#: rhodecode/templates/changeset/changeset.html:72
 
#: rhodecode/templates/changeset/diff_block.html:21
 
msgid "download diff"
 
msgstr "差分をダウンロード"
 

	
 
#: rhodecode/templates/changeset/changeset.html:76
 
#: rhodecode/templates/changeset/changeset_file_comment.html:82
 
#, python-format
 
msgid "%d comment"
 
msgid_plural "%d comments"
 
msgstr[0] "%d コメント"
 

	
 
#: rhodecode/templates/changeset/changeset.html:76
 
#: rhodecode/templates/changeset/changeset_file_comment.html:82
 
#, python-format
 
msgid "(%d inline)"
 
msgid_plural "(%d inline)"
 
msgstr[0] "(%d インライン)"
 

	
 
#: rhodecode/templates/changeset/changeset.html:122
 
#: rhodecode/templates/compare/compare_diff.html:44
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:76
 
#, fuzzy, python-format
 
#, python-format
 
msgid "%s file changed"
 
msgid_plural "%s files changed"
 
msgstr[0] ""
 
msgstr[0] "%s ファイルに影響"
 

	
 
#: rhodecode/templates/changeset/changeset.html:124
 
#: rhodecode/templates/compare/compare_diff.html:46
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:78
 
#, fuzzy, python-format
 
#, python-format
 
msgid "%s file changed with %s insertions and %s deletions"
 
msgid_plural "%s files changed with %s insertions and %s deletions"
 
msgstr[0] "%s ファイルに影響。 %s 個の追加と %s 個の削除:"
 
msgstr[0] "%s ファイルに影響。 %s 個の追加と %s 個の削除"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:42
 
msgid "Submitting..."
 
msgstr "サブミット中..."
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:45
 
msgid "Commenting on line {1}."
 
msgstr "{1} 行目にコメント"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:46
 
#: rhodecode/templates/changeset/changeset_file_comment.html:121
 
#, python-format
 
@@ -3340,77 +3321,75 @@ msgid "You need to be logged in to comme
 
msgstr "コメントするにはログインが必要です"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:67
 
msgid "Login now"
 
msgstr "今すぐログインする"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:118
 
msgid "Leave a comment"
 
msgstr "コメントを残す"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:125
 
msgid "Check this to change current status of code-review for this changeset"
 
msgstr ""
 
msgstr "チェックするとチェンジセットの現在のコードレビューステータスを変更出来ます"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:125
 
msgid "change status"
 
msgstr "ステータスを変更する"
 

	
 
#: rhodecode/templates/changeset/changeset_file_comment.html:145
 
msgid "Comment and close"
 
msgstr "コメントしてクローズ"
 

	
 
#: rhodecode/templates/changeset/changeset_range.html:5
 
#, python-format
 
msgid "%s Changesets"
 
msgstr "%s チェンジセット"
 

	
 
#: rhodecode/templates/changeset/changeset_range.html:29
 
#: rhodecode/templates/compare/compare_diff.html:29
 
msgid "Compare View"
 
msgstr "比較ビュー"
 

	
 
#: rhodecode/templates/changeset/changeset_range.html:29
 
#, fuzzy
 
msgid "Show combined compare"
 
msgstr "インラインコメントを表示"
 
msgstr "結合した比較ビューを表示"
 

	
 
#: rhodecode/templates/changeset/changeset_range.html:54
 
msgid "Files affected"
 
msgstr "影響のあるファイル"
 

	
 
#: rhodecode/templates/changeset/diff_block.html:19
 
msgid "show full diff for this file"
 
msgstr ""
 
msgstr "このファイルの全差分を表示"
 

	
 
#: rhodecode/templates/changeset/diff_block.html:27
 
msgid "show inline comments"
 
msgstr "インラインコメントを表示"
 

	
 
#: rhodecode/templates/compare/compare_cs.html:5
 
msgid "No changesets"
 
msgstr "チェンジセットはありません"
 

	
 
#: rhodecode/templates/compare/compare_diff.html:37
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:69
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Showing %s commit"
 
msgid_plural "Showing %s commits"
 
msgstr[0] ""
 
msgstr[0] "%s コミットを表示"
 

	
 
#: rhodecode/templates/compare/compare_diff.html:52
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:84
 
#, fuzzy
 
msgid "No files"
 
msgstr "ファイル"
 
msgstr "ファイルはありません"
 

	
 
#: rhodecode/templates/data_table/_dt_elements.html:39
 
#: rhodecode/templates/data_table/_dt_elements.html:41
 
#: rhodecode/templates/data_table/_dt_elements.html:43
 
msgid "Fork"
 
msgstr "フォーク"
 

	
 
#: rhodecode/templates/data_table/_dt_elements.html:60
 
#: rhodecode/templates/journal/journal.html:89
 
#: rhodecode/templates/summary/summary.html:77
 
msgid "Mercurial repository"
 
msgstr "Mercurialリポジトリ"
 
@@ -3446,97 +3425,91 @@ msgstr "%s の RSS フィードを購読"
 
#: rhodecode/templates/data_table/_dt_elements.html:109
 
#: rhodecode/templates/data_table/_dt_elements.html:111
 
#, python-format
 
msgid "Subscribe to %s atom feed"
 
msgstr "%s の ATOM フィードを購読"
 

	
 
#: rhodecode/templates/data_table/_dt_elements.html:122
 
#, python-format
 
msgid "Confirm to delete this user: %s"
 
msgstr "このユーザーを本当に削除してよろしいですか?: %s"
 

	
 
#: rhodecode/templates/email_templates/changeset_comment.html:10
 
#, fuzzy
 
msgid "New status$"
 
msgstr "ステータスを変更する"
 
msgstr "新しいステータス$"
 

	
 
#: rhodecode/templates/email_templates/main.html:8
 
#, fuzzy
 
msgid "This is a notification from RhodeCode."
 
msgstr "RhodeCodeからの通知があります"
 
msgstr "RhodeCodeからの通知です"
 

	
 
#: rhodecode/templates/email_templates/password_reset.html:4
 
msgid "Hello"
 
msgstr ""
 
msgstr "こんにちは"
 

	
 
#: rhodecode/templates/email_templates/password_reset.html:6
 
msgid "We received a request to create a new password for your account."
 
msgstr ""
 
msgstr "あなたのアカウントの新しいパスワードの生成リクエストを受け取りました。"
 

	
 
#: rhodecode/templates/email_templates/password_reset.html:8
 
msgid "You can generate it by clicking following URL"
 
msgstr ""
 
msgstr "下のURLをクリックすることで再生成が行えます。"
 

	
 
#: rhodecode/templates/email_templates/password_reset.html:12
 
msgid "If you didn't request new password please ignore this email."
 
msgstr ""
 
msgstr "新しいパスワードのリクエストをしていない場合は、このメールを無視して下さい。"
 

	
 
#: rhodecode/templates/email_templates/pull_request.html:4
 
#, python-format
 
msgid ""
 
"User %s opened pull request for repository %s and wants you to review "
 
"changes."
 
msgstr ""
 
msgstr "ユーザ %s がリポジトリ %s で新しいプルリクエストを作成しました。変更をレビューしてください。"
 

	
 
#: rhodecode/templates/email_templates/pull_request.html:5
 
#, fuzzy
 
msgid "title"
 
msgstr "タイトル"
 

	
 
#: rhodecode/templates/email_templates/pull_request.html:6
 
#: rhodecode/templates/pullrequests/pullrequest.html:115
 
msgid "description"
 
msgstr "説明"
 

	
 
#: rhodecode/templates/email_templates/pull_request.html:11
 
msgid "revisions for reviewing"
 
msgstr ""
 
msgstr "レビュー対象のリビジョン"
 

	
 
#: rhodecode/templates/email_templates/pull_request.html:18
 
#, fuzzy
 
msgid "View this pull request here"
 
msgstr "このプルリクエストにレビュアーを追加"
 
msgstr "このプルリクエストを閲覧する"
 

	
 
#: rhodecode/templates/email_templates/pull_request_comment.html:4
 
#, fuzzy, python-format
 
#, python-format
 
msgid "User %s commented on pull request #%s for repository %s"
 
msgstr ""
 
msgstr "ユーザ %s がプルリクエスト #%s (リポジトリ %s) にコメントしました。"
 

	
 
#: rhodecode/templates/email_templates/pull_request_comment.html:10
 
#, fuzzy
 
msgid "New status"
 
msgstr "ステータスを変更する"
 
msgstr "新しいステータス"
 

	
 
#: rhodecode/templates/email_templates/pull_request_comment.html:14
 
msgid "View this comment here"
 
msgstr ""
 
msgstr "このコメントを閲覧する"
 

	
 
#: rhodecode/templates/email_templates/registration.html:4
 
#, fuzzy
 
msgid "A new user have registered in RhodeCode"
 
msgstr "rhodecodeへの登録を受け付けました"
 
msgstr "新しいユーザがRhodeCodeへ登録しました"
 

	
 
#: rhodecode/templates/email_templates/registration.html:9
 
msgid "View this user here"
 
msgstr ""
 
msgstr "このユーザを閲覧する"
 

	
 
#: rhodecode/templates/errors/error_document.html:46
 
#, python-format
 
msgid "You will be redirected to %s in %s seconds"
 
msgstr ""
 

	
 
#: rhodecode/templates/files/file_diff.html:4
 
#, python-format
 
msgid "%s File diff"
 
msgstr "%s ファイル差分"
 

	
 
#: rhodecode/templates/files/file_diff.html:12
 
@@ -3600,25 +3573,25 @@ msgstr "ディレクトリの区切りには / を使います"
 
#: rhodecode/templates/files/files_edit.html:63
 
#: rhodecode/templates/shortlog/shortlog_data.html:6
 
msgid "commit message"
 
msgstr "コミットメッセージ"
 

	
 
#: rhodecode/templates/files/files_add.html:81
 
#: rhodecode/templates/files/files_edit.html:67
 
msgid "Commit changes"
 
msgstr "変更をコミット"
 

	
 
#: rhodecode/templates/files/files_browser.html:13
 
msgid "view"
 
msgstr "表示"
 
msgstr "閲覧"
 

	
 
#: rhodecode/templates/files/files_browser.html:14
 
msgid "previous revision"
 
msgstr "前のリビジョン"
 

	
 
#: rhodecode/templates/files/files_browser.html:16
 
msgid "next revision"
 
msgstr "次のリビジョン"
 

	
 
#: rhodecode/templates/files/files_browser.html:23
 
msgid "follow current branch"
 
msgstr "このブランチで追跡"
 
@@ -3688,38 +3661,36 @@ msgstr "ファイルを編集"
 
msgid "History"
 
msgstr "変更履歴"
 

	
 
#: rhodecode/templates/files/files_history_box.html:9
 
msgid "diff to revision"
 
msgstr "このリビジョンの差分を見る"
 

	
 
#: rhodecode/templates/files/files_history_box.html:10
 
msgid "show at revision"
 
msgstr "このリビジョンを見る"
 

	
 
#: rhodecode/templates/files/files_history_box.html:11
 
#, fuzzy
 
msgid "show full history"
 
msgstr "ファイル一覧を読み込み中..."
 
msgstr "すべての履歴を表示"
 

	
 
#: rhodecode/templates/files/files_history_box.html:16
 
#, python-format
 
msgid "%s author"
 
msgid_plural "%s authors"
 
msgstr[0] "%s 作成者"
 

	
 
#: rhodecode/templates/files/files_source.html:6
 
#, fuzzy
 
msgid "Load file history"
 
msgstr "ファイル一覧を読み込み中..."
 
msgstr "ファイルの履歴を読み込む"
 

	
 
#: rhodecode/templates/files/files_source.html:21
 
msgid "show source"
 
msgstr "ソースを表示"
 

	
 
#: rhodecode/templates/files/files_source.html:44
 
#, python-format
 
msgid "Binary file (%s)"
 
msgstr "バイナリファイル (%s)"
 

	
 
#: rhodecode/templates/files/files_source.html:53
 
msgid "File is too big to display"
 
@@ -3900,61 +3871,59 @@ msgstr "タイトル"
 
#: rhodecode/templates/pullrequests/pullrequest.html:123
 
msgid "Send pull request"
 
msgstr "プルリクエストを送る"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:23
 
#, python-format
 
msgid "Closed %s"
 
msgstr "%s にクローズ"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:23
 
#, python-format
 
msgid "with status %s"
 
msgstr ""
 
msgstr "ステータス: %s"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:31
 
msgid "Status"
 
msgstr "ステータス"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:36
 
msgid "Pull request status"
 
msgstr "プルリクエストステータス"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:44
 
msgid "Still not reviewed by"
 
msgstr "未レビュー"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:48
 
#, python-format
 
msgid "%d reviewer"
 
msgid_plural "%d reviewers"
 
msgstr[0] "%d レビュアー"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:50
 
#, fuzzy
 
msgid "pull request was reviewed by all reviewers"
 
msgstr "プルリクエストレビュアー"
 
msgstr "プルリクエストはすべてのレビュアーにレビューされました"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:58
 
msgid "Created on"
 
msgstr "作成日"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:65
 
msgid "Compare view"
 
msgstr "比較ビュー"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show.html:112
 
#, fuzzy
 
msgid "reviewer"
 
msgstr "%d レビュアー"
 
msgstr "レビュアー"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show_all.html:4
 
msgid "all pull requests"
 
msgstr "すべてのプルリクエスト"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show_all.html:12
 
msgid "All pull requests"
 
msgstr "すべてのプルリクエスト"
 

	
 
#: rhodecode/templates/pullrequests/pullrequest_show_all.html:27
 
msgid "Closed"
 
msgstr "クローズ"
 
@@ -4003,30 +3972,28 @@ msgstr "ファイル名"
 
#: rhodecode/templates/search/search_commit.html:35
 
#: rhodecode/templates/search/search_content.html:21
 
#: rhodecode/templates/search/search_path.html:15
 
msgid "Permission denied"
 
msgstr "権限がありません"
 

	
 
#: rhodecode/templates/settings/repo_settings.html:5
 
#, python-format
 
msgid "%s Settings"
 
msgstr "%s 設定"
 

	
 
#: rhodecode/templates/settings/repo_settings.html:102
 
#, fuzzy
 
msgid "Delete repository"
 
msgstr "リポジトリを[削除]"
 
msgstr "リポジトリを削除"
 

	
 
#: rhodecode/templates/settings/repo_settings.html:109
 
#, fuzzy
 
msgid "Remove repo"
 
msgstr "削除"
 

	
 
#: rhodecode/templates/shortlog/shortlog.html:5
 
#, python-format
 
msgid "%s Shortlog"
 
msgstr "%s 短いログ"
 

	
 
#: rhodecode/templates/shortlog/shortlog.html:15
 
#: rhodecode/templates/shortlog/shortlog.html:19
 
msgid "shortlog"
 
msgstr "ログ"
 
@@ -4071,45 +4038,44 @@ msgstr "リポジトリ %s ATOM フィード"
 

	
 
#: rhodecode/templates/summary/summary.html:21
 
#, python-format
 
msgid "repo %s RSS feed"
 
msgstr "リポジトリ %s RSS フィード"
 

	
 
#: rhodecode/templates/summary/summary.html:49
 
#: rhodecode/templates/summary/summary.html:52
 
msgid "ATOM"
 
msgstr "ATOM"
 

	
 
#: rhodecode/templates/summary/summary.html:70
 
#, fuzzy, python-format
 
#, python-format
 
msgid "Repository locked by %s"
 
msgstr ""
 
msgstr "リポジトリは %s によってロックされました"
 

	
 
#: rhodecode/templates/summary/summary.html:72
 
#, fuzzy
 
msgid "Repository unlocked"
 
msgstr "リポジトリはロックされていません"
 

	
 
#: rhodecode/templates/summary/summary.html:91
 
#, python-format
 
msgid "Non changable ID %s"
 
msgstr ""
 
msgstr "変更不能ID %s"
 

	
 
#: rhodecode/templates/summary/summary.html:96
 
msgid "public"
 
msgstr "公開"
 

	
 
#: rhodecode/templates/summary/summary.html:104
 
msgid "remote clone"
 
msgstr ""
 
msgstr "リモートクローン"
 

	
 
#: rhodecode/templates/summary/summary.html:125
 
msgid "Contact"
 
msgstr "コンタクト"
 

	
 
#: rhodecode/templates/summary/summary.html:139
 
msgid "Clone url"
 
msgstr "クローンURL"
 

	
 
#: rhodecode/templates/summary/summary.html:142
 
msgid "Show by Name"
 
msgstr "名前で表示"
 
@@ -4162,25 +4128,25 @@ msgstr "収集した統計情報: "
 

	
 
#: rhodecode/templates/summary/summary.html:227
 
msgid "Shortlog"
 
msgstr "ログ"
 

	
 
#: rhodecode/templates/summary/summary.html:229
 
msgid "Quick start"
 
msgstr "クイックスタート"
 

	
 
#: rhodecode/templates/summary/summary.html:243
 
#, python-format
 
msgid "Readme file at revision '%s'"
 
msgstr ""
 
msgstr "リビジョン '%s' のReadmeファイル"
 

	
 
#: rhodecode/templates/summary/summary.html:246
 
msgid "Permalink to this readme"
 
msgstr "パーマリンク"
 

	
 
#: rhodecode/templates/summary/summary.html:304
 
#, python-format
 
msgid "Download %s as %s"
 
msgstr "%s を %sとしてダウンロード"
 

	
 
#: rhodecode/templates/summary/summary.html:661
 
msgid "commits"
 
@@ -4211,27 +4177,26 @@ msgid "file changed"
 
msgstr "変更されたファイル"
 

	
 
#: rhodecode/templates/summary/summary.html:670
 
msgid "file removed"
 
msgstr "削除されたファイル"
 

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

	
 
#: rhodecode/templates/tags/tags.html:29
 
#, fuzzy
 
msgid "Compare tags"
 
msgstr "比較"
 
msgstr "タグの比較"
 

	
 
#~ msgid ""
 
#~ "%s repository is not mapped to db"
 
#~ " perhaps it was created or renamed"
 
#~ " from the file system please run "
 
#~ "the application again in order to "
 
#~ "rescan repositories"
 
#~ msgstr ""
 
#~ "%s "
 
#~ "リポジトリはDB内に見つかりませんでした。おそらくファイルシステム上で作られたか名前が変更されたためです。リポジトリをもう一度チェックするためにアプリケーションを立ち上げ直してください。"
 

	
 
#~ msgid ""

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)