##// END OF EJS Templates
Merge beta branch into stable
marcink -
r2776:63e58ef8 merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,38 b''
1 language: python
2 python:
3 - "2.5"
4 - "2.6"
5 - "2.7"
6
7 env:
8 - TEST_DB=sqlite:////tmp/rhodecode_test.sqlite
9 - TEST_DB=mysql://root@127.0.0.1/rhodecode_test
10 - TEST_DB=postgresql://postgres@127.0.0.1/rhodecode_test
11
12 # command to install dependencies
13 before_script:
14 - mysql -e 'create database rhodecode_test;'
15 - psql -c 'create database rhodecode_test;' -U postgres
16 - git --version
17
18 before_install:
19 - sudo apt-get remove git
20 - sudo add-apt-repository ppa:pdoes/ppa -y
21 - sudo apt-get update -y
22 - sudo apt-get install git -y
23
24 install:
25 - pip install mysql-python psycopg2 mock unittest2
26 - pip install . --use-mirrors
27
28 # command to run tests
29 script: nosetests
30
31 notifications:
32 email:
33 - marcinkuz@gmail.com
34 irc: "irc.freenode.org#rhodecode"
35
36 branches:
37 only:
38 - dev
@@ -0,0 +1,244 b''
1 .. _installation_win:
2
3
4 Step by step Installation for Windows
5 =====================================
6
7
8 RhodeCode step-by-step install Guide for Windows
9
10 Target OS: Windows XP SP3 English (Clean installation)
11 + All Windows Updates until 24-may-2012
12
13 Step1 - Install Visual Studio 2008 Express
14 ------------------------------------------
15
16
17 Optional: You can also install MingW, but VS2008 installation is easier
18
19 Download "Visual C++ 2008 Express Edition with SP1" from:
20 http://www.microsoft.com/visualstudio/en-us/products/2008-editions/express
21 (if not found or relocated, google for "visual studio 2008 express" for
22 updated link)
23
24 You can also download full ISO file for offline installation, just
25 choose "All - Offline Install ISO image file" in the previous page and
26 choose "Visual C++ 2008 Express" when installing.
27
28
29 .. note::
30
31 Silverlight Runtime and SQL Server 2008 Express Edition are not
32 required, you can uncheck them
33
34
35 Step2 - Install Python
36 ----------------------
37
38 Install Python 2.x.y (x >= 5) x86 version (32bit). DO NOT USE A 3.x version.
39 Download Python 2.x.y from:
40 http://www.python.org/download/
41
42 Choose "Windows Installer" (32bit version) not "Windows X86-64
43 Installer". While writing this guide, the latest version was v2.7.3.
44 Remember the specific major and minor version installed, because it will
45 be needed in the next step. In this case, it is "2.7".
46
47
48 Step3 - Install Win32py extensions
49 ----------------------------------
50
51 Download pywin32 from:
52 http://sourceforge.net/projects/pywin32/files/
53
54 - Click on "pywin32" folder
55 - Click on the first folder (in this case, Build 217, maybe newer when you try)
56 - Choose the file ending with ".win32-py2.x.exe" -> x being the minor
57 version of Python you installed (in this case, 7)
58 When writing this guide, the file was:
59 http://sourceforge.net/projects/pywin32/files/pywin32/Build%20217/pywin32-217.win32-py2.7.exe/download
60
61
62 Step4 - Python BIN
63 ------------------
64
65 Add Python BIN folder to the path
66
67 You have to add the Python folder to the path, you can do it manually
68 (editing "PATH" environment variable) or using Windows Support Tools
69 that came preinstalled in Vista/7 and can be installed in Windows XP.
70
71 - Using support tools on WINDOWS XP:
72 If you use Windows XP you can install them using Windows XP CD and
73 navigating to \SUPPORT\TOOLS. There, execute Setup.EXE (not MSI).
74 Afterwards, open a CMD and type::
75
76 SETX PATH "%PATH%;[your-python-path]" -M
77
78 Close CMD (the path variable will be updated then)
79
80 - Using support tools on WINDOWS Vista/7:
81
82 Open a CMD and type::
83
84 SETX PATH "%PATH%;[your-python-path]" /M
85
86 Please substitute [your-python-path] with your Python installation path.
87 Typically: C:\\Python27
88
89
90 Step5 - RhodeCode folder structure
91 ----------------------------------
92
93 Create a RhodeCode folder structure
94
95 This is only a example to install RhodeCode, you can of course change
96 it. However, this guide will follow the proposed structure, so please
97 later adapt the paths if you change them. My recommendation is to use
98 folders with NO SPACES. But you can try if you are brave...
99
100 Create the following folder structure::
101
102 C:\RhodeCode
103 C:\RhodeCode\Bin
104 C:\RhodeCode\Env
105 C:\RhodeCode\Repos
106
107
108 Step6 - Install virtualenv
109 ---------------------------
110
111 Install Virtual Env for Python
112
113 Navigate to: http://www.virtualenv.org/en/latest/index.html#installation
114 Right click on "virtualenv.py" file and choose "Save link as...".
115 Download to C:\\RhodeCode (or whatever you want)
116 (the file is located at
117 https://raw.github.com/pypa/virtualenv/master/virtualenv.py)
118
119 Create a virtual Python environment in C:\\RhodeCode\\Env (or similar). To
120 do so, open a CMD (Python Path should be included in Step3), navigate
121 where you downloaded "virtualenv.py", and write::
122
123 python virtualenv.py C:\RhodeCode\Env
124
125 (--no-site-packages is now the default behaviour of virtualenv, no need
126 to include it)
127
128
129 Step7 - Install RhodeCode
130 -------------------------
131
132 Finally, install RhodeCode
133
134 Close previously opened command prompt/s, and open a Visual Studio 2008
135 Command Prompt (**IMPORTANT!!**). To do so, go to Start Menu, and then open
136 "Microsoft Visual C++ 2008 Express Edition" -> "Visual Studio Tools" ->
137 "Visual Studio 2008 Command Prompt"
138
139 In that CMD (loaded with VS2008 PATHs) type::
140
141 cd C:\RhodeCode\Env\Scripts (or similar)
142 activate
143
144 The prompt will change into "(Env) C:\\RhodeCode\\Env\\Scripts" or similar
145 (depending of your folder structure). Then type::
146
147 pip install rhodecode
148
149 (long step, please wait until fully complete)
150
151 Some warnings will appear, don't worry as they are normal.
152
153
154 Step8 - Configuring RhodeCode
155 -----------------------------
156
157
158 steps taken from http://packages.python.org/RhodeCode/setup.html
159
160 You have to use the same Visual Studio 2008 command prompt as Step7, so
161 if you closed it reopen it following the same commands (including the
162 "activate" one). When ready, just type::
163
164 cd C:\RhodeCode\Bin
165 paster make-config RhodeCode production.ini
166
167 Then, you must edit production.ini to fit your needs (ip address, ip
168 port, mail settings, database, whatever). I recommend using NotePad++
169 (free) or similar text editor, as it handles well the EndOfLine
170 character differences between Unix and Windows
171 (http://notepad-plus-plus.org/)
172
173 For the sake of simplicity lets run it with the default settings. After
174 your edits (if any), in the previous Command Prompt, type::
175
176 paster setup-rhodecode production.ini
177
178 (this time a NEW database will be installed, you must follow a different
179 step to later UPGRADE to a newer RhodeCode version)
180
181 The script will ask you for confirmation about creating a NEW database,
182 answer yes (y)
183 The script will ask you for repository path, answer C:\\RhodeCode\\Repos
184 (or similar)
185 The script will ask you for admin username and password, answer "admin"
186 + "123456" (or whatever you want)
187 The script will ask you for admin mail, answer "admin@xxxx.com" (or
188 whatever you want)
189
190 If you make some mistake and the script does not end, don't worry, start
191 it again.
192
193
194 Step9 - Running RhodeCode
195 -------------------------
196
197
198 In the previous command prompt, being in the C:\\RhodeCode\\Bin folder,
199 just type::
200
201 paster serve production.ini
202
203 Open yout web server, and go to http://127.0.0.1:5000
204
205 It works!! :-)
206
207 Remark:
208 If it does not work first time, just Ctrl-C the CMD process and start it
209 again. Don't forget the "http://" in Internet Explorer
210
211
212
213 What this Guide does not cover:
214
215 - Installing Celery
216 - Running RhodeCode as Windows Service. You can investigate here:
217
218 - http://pypi.python.org/pypi/wsgisvc
219 - http://ryrobes.com/python/running-python-scripts-as-a-windows-service/
220 - http://wiki.pylonshq.com/display/pylonscookbook/How+to+run+Pylons+as+a+Windows+service
221
222 - Using Apache. You can investigate here:
223
224 - https://groups.google.com/group/rhodecode/msg/c433074e813ffdc4
225
226
227 Upgrading
228 =========
229
230 Stop running RhodeCode
231 Open a CommandPrompt like in Step7 (VS2008 path + activate) and type::
232
233 easy_install -U rhodecode
234 cd \RhodeCode\Bin
235
236 { backup your production.ini file now} ::
237
238 paster make-config RhodeCode production.ini
239
240 (check changes and update your production.ini accordingly) ::
241
242 paster upgrade-db production.ini (update database)
243
244 Full steps in http://packages.python.org/RhodeCode/upgrade.html No newline at end of file
@@ -0,0 +1,41 b''
1 .. _locking:
2
3 ===================================
4 RhodeCode repository locking system
5 ===================================
6
7
8 | Repos with **locking function=disabled** is the default, that's how repos work
9 today.
10 | Repos with **locking function=enabled** behaves like follows:
11
12 Repos have a state called `locked` that can be true or false.
13 The hg/git commands `hg/git clone`, `hg/git pull`, and `hg/git push`
14 influence this state:
15
16 - The command `hg/git pull <repo>` will lock that repo (locked=true)
17 if the user has write/admin permissions on this repo
18
19 - The command `hg/git clone <repo>` will lock that repo (locked=true) if the
20 user has write/admin permissions on this repo
21
22
23 RhodeCode will remember the user id who locked the repo
24 only this specific user can unlock the repo (locked=false) by calling
25
26 - `hg/git push <repo>`
27
28 every other command on that repo from this user and
29 every command from any other user will result in http return code 423 (locked)
30
31
32 additionally the http error includes the <user> that locked the repo
33 (e.g. “repository <repo> locked by user <user>”)
34
35
36 So the scenario of use for repos with `locking function` enabled is that
37 every initial clone and every pull gives users (with write permission)
38 the exclusive right to do a push.
39
40
41 Each repo can be manually unlocked by admin from the repo settings menu. No newline at end of file
@@ -0,0 +1,50 b''
1 .. _performance:
2
3 ================================
4 Optimizing RhodeCode Performance
5 ================================
6
7 When serving large amount of big repositories RhodeCode can start
8 performing slower than expected. Because of demanding nature of handling large
9 amount of data from version control systems here are some tips how to get
10 the best performance.
11
12 * RhodeCode will perform better on machines with faster disks (SSD/SAN). It's
13 more important to have faster disk than faster CPU.
14
15 * Slowness on initial page can be easily fixed by grouping repositories, and/or
16 increasing cache size (see below)
17
18
19 Follow these few steps to improve performance of RhodeCode system.
20
21
22 1. Increase cache
23
24 in the .ini file::
25
26 beaker.cache.sql_cache_long.expire=3600 <-- set this to higher number
27
28 This option affects the cache expiration time for main page. Having
29 few hundreds of repositories on main page can sometimes make the system
30 to behave slow when cache expires for all of them. Increasing `expire`
31 option to day (86400) or a week (604800) will improve general response
32 times for the main page. RhodeCode has an intelligent cache expiration
33 system and it will expire cache for repositories that had been changed.
34
35 2. Switch from sqlite to postgres or mysql
36
37 sqlite is a good option when having small load on the system. But due to
38 locking issues with sqlite, it's not recommended to use it for larger
39 setup. Switching to mysql or postgres will result in a immediate
40 performance increase.
41
42 3. Scale RhodeCode horizontally
43
44 - running two or more instances on the same server can speed up things a lot
45 - load balance using round robin or ip hash
46 - you need to handle consistent user session storage by switching to
47 db sessions, client side sessions or sharing session data folder across
48 instances. See http://beaker.readthedocs.org/ docs for details.
49 - remember that each instance needs it's own .ini file and unique
50 `instance_id` set in them No newline at end of file
@@ -0,0 +1,70 b''
1 .. _troubleshooting:
2
3
4 ===============
5 Troubleshooting
6 ===============
7
8 :Q: **Missing static files?**
9 :A: Make sure either to set the `static_files = true` in the .ini file or
10 double check the root path for your http setup. It should point to
11 for example:
12 /home/my-virtual-python/lib/python2.6/site-packages/rhodecode/public
13
14 |
15
16 :Q: **Can't install celery/rabbitmq?**
17 :A: Don't worry RhodeCode works without them too. No extra setup is required.
18 Try out great celery docs for further help.
19
20 |
21
22 :Q: **Long lasting push timeouts?**
23 :A: Make sure you set a longer timeouts in your proxy/fcgi settings, timeouts
24 are caused by https server and not RhodeCode.
25
26 |
27
28 :Q: **Large pushes timeouts?**
29 :A: Make sure you set a proper max_body_size for the http server. Very often
30 Apache, Nginx or other http servers kill the connection due to to large
31 body.
32
33 |
34
35 :Q: **Apache doesn't pass basicAuth on pull/push?**
36 :A: Make sure you added `WSGIPassAuthorization true`.
37
38 |
39
40 :Q: **Git fails on push/pull?**
41 :A: Make sure you're using an wsgi http server that can handle chunked encoding
42 such as `waitress` or `gunicorn`
43
44 |
45
46 :Q: **How i use hooks in RhodeCode?**
47 :A: It's easy if they are python hooks just use advanced link in hooks section
48 in Admin panel, that works only for Mercurial. If you want to use githooks,
49 just install proper one in repository eg. create file in
50 `/gitrepo/hooks/pre-receive`. You can also use RhodeCode-extensions to
51 connect to callback hooks, for both Git and Mercurial.
52
53 |
54
55 :Q: **RhodeCode is slow for me, how can i make it faster?**
56 :A: See the :ref:`performance` section
57
58 For further questions search the `Issues tracker`_, or post a message in the
59 `google group rhodecode`_
60
61 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
62 .. _python: http://www.python.org/
63 .. _mercurial: http://mercurial.selenic.com/
64 .. _celery: http://celeryproject.org/
65 .. _rabbitmq: http://www.rabbitmq.com/
66 .. _python-ldap: http://www.python-ldap.org/
67 .. _mercurial-server: http://www.lshift.net/mercurial-server.html
68 .. _PublishingRepositories: http://mercurial.selenic.com/wiki/PublishingRepositories
69 .. _Issues tracker: https://bitbucket.org/marcinkuzminski/rhodecode/issues
70 .. _google group rhodecode: http://groups.google.com/group/rhodecode No newline at end of file
@@ -0,0 +1,51 b''
1 ; RhodeCode Supervisord
2 ; ##########################
3 ; for help see http://supervisord.org/configuration.html
4 ; ##########################
5
6 [inet_http_server] ; inet (TCP) server disabled by default
7 port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for all iface)
8 ;username=user ; (default is no username (open server))
9 ;password=123 ; (default is no password (open server))
10
11 [supervisord]
12 logfile=/%(here)s/supervisord_rhodecode.log ; (main log file;default $CWD/supervisord.log)
13 logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
14 logfile_backups=10 ; (num of main logfile rotation backups;default 10)
15 loglevel=info ; (log level;default info; others: debug,warn,trace)
16 pidfile=/%(here)s/supervisord_rhodecode.pid ; (supervisord pidfile;default supervisord.pid)
17 nodaemon=true ; (start in foreground if true;default false)
18 minfds=1024 ; (min. avail startup file descriptors;default 1024)
19 minprocs=200 ; (min. avail process descriptors;default 200)
20 umask=022 ; (process file creation umask;default 022)
21 user=marcink ; (default is current user, required if root)
22 ;identifier=supervisor ; (supervisord identifier, default is 'supervisor')
23 ;directory=/tmp ; (default is not to cd during start)
24 ;nocleanup=true ; (don't clean up tempfiles at start;default false)
25 ;childlogdir=/tmp ; ('AUTO' child log dir, default $TEMP)
26 environment=HOME=/home/marcink ; (key value pairs to add to environment)
27 ;strip_ansi=false ; (strip ansi escape codes in logs; def. false)
28
29 ; the below section must remain in the config file for RPC
30 ; (supervisorctl/web interface) to work, additional interfaces may be
31 ; added by defining them in separate rpcinterface: sections
32 [rpcinterface:supervisor]
33 supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
34
35 [supervisorctl]
36 serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
37 ;username=user ; should be same as http_username if set
38 ;password=123 ; should be same as http_password if set
39 ;prompt=mysupervisor ; cmd line prompt (default "supervisor")
40 ;history_file=~/.sc_history ; use readline history if available
41
42
43 ; restart with supervisorctl restart rhodecode:*
44 [program:rhodecode]
45 numprocs = 1
46 numprocs_start = 5000 # possible should match ports
47 directory=/home/marcink/rhodecode-dir
48 command = /home/marcink/v-env/bin/paster serve rc.ini
49 process_name = %(program_name)s_%(process_num)04d
50 redirect_stderr=true
51 stdout_logfile=/%(here)s/rhodecode.log No newline at end of file
1 NO CONTENT: new file 100644
@@ -0,0 +1,249 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.bin.backup_manager
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 Api CLI client for RhodeCode
7
8 :created_on: Jun 3, 2012
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
26 from __future__ import with_statement
27 import os
28 import sys
29 import random
30 import urllib2
31 import pprint
32 import argparse
33
34 try:
35 from rhodecode.lib.ext_json import json
36 except ImportError:
37 try:
38 import simplejson as json
39 except ImportError:
40 import json
41
42
43 CONFIG_NAME = '.rhodecode'
44 FORMAT_PRETTY = 'pretty'
45 FORMAT_JSON = 'json'
46
47
48 class RcConf(object):
49 """
50 RhodeCode config for API
51
52 conf = RcConf()
53 conf['key']
54
55 """
56
57 def __init__(self, config_location=None, autoload=True, autocreate=False,
58 config=None):
59 self._conf_name = CONFIG_NAME if not config_location else config_location
60 self._conf = {}
61 if autocreate:
62 self.make_config(config)
63 if autoload:
64 self._conf = self.load_config()
65
66 def __getitem__(self, key):
67 return self._conf[key]
68
69 def __nonzero__(self):
70 if self._conf:
71 return True
72 return False
73
74 def __eq__(self):
75 return self._conf.__eq__()
76
77 def __repr__(self):
78 return 'RcConf<%s>' % self._conf.__repr__()
79
80 def make_config(self, config):
81 """
82 Saves given config as a JSON dump in the _conf_name location
83
84 :param config:
85 :type config:
86 """
87 update = False
88 if os.path.exists(self._conf_name):
89 update = True
90 with open(self._conf_name, 'wb') as f:
91 json.dump(config, f, indent=4)
92
93 if update:
94 sys.stdout.write('Updated config in %s\n' % self._conf_name)
95 else:
96 sys.stdout.write('Created new config in %s\n' % self._conf_name)
97
98 def update_config(self, new_config):
99 """
100 Reads the JSON config updates it's values with new_config and
101 saves it back as JSON dump
102
103 :param new_config:
104 """
105 config = {}
106 try:
107 with open(self._conf_name, 'rb') as conf:
108 config = json.load(conf)
109 except IOError, e:
110 sys.stderr.write(str(e) + '\n')
111
112 config.update(new_config)
113 self.make_config(config)
114
115 def load_config(self):
116 """
117 Loads config from file and returns loaded JSON object
118 """
119 try:
120 with open(self._conf_name, 'rb') as conf:
121 return json.load(conf)
122 except IOError, e:
123 #sys.stderr.write(str(e) + '\n')
124 pass
125
126
127 def api_call(apikey, apihost, format, method=None, **kw):
128 """
129 Api_call wrapper for RhodeCode
130
131 :param apikey:
132 :param apihost:
133 :param format: formatting, pretty means prints and pprint of json
134 json returns unparsed json
135 :param method:
136 """
137 def _build_data(random_id):
138 """
139 Builds API data with given random ID
140
141 :param random_id:
142 :type random_id:
143 """
144 return {
145 "id": random_id,
146 "api_key": apikey,
147 "method": method,
148 "args": kw
149 }
150
151 if not method:
152 raise Exception('please specify method name !')
153 id_ = random.randrange(1, 9999)
154 req = urllib2.Request('%s/_admin/api' % apihost,
155 data=json.dumps(_build_data(id_)),
156 headers={'content-type': 'text/plain'})
157 if format == FORMAT_PRETTY:
158 sys.stdout.write('calling %s to %s \n' % (req.get_data(), apihost))
159 ret = urllib2.urlopen(req)
160 raw_json = ret.read()
161 json_data = json.loads(raw_json)
162 id_ret = json_data['id']
163 _formatted_json = pprint.pformat(json_data)
164 if id_ret == id_:
165 if format == FORMAT_JSON:
166 sys.stdout.write(str(raw_json))
167 else:
168 sys.stdout.write('rhodecode returned:\n%s\n' % (_formatted_json))
169
170 else:
171 raise Exception('something went wrong. '
172 'ID mismatch got %s, expected %s | %s' % (
173 id_ret, id_, _formatted_json))
174
175
176 def argparser(argv):
177 usage = (
178 "rhodecode_api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
179 " [--config=CONFIG] "
180 "_create_config or METHOD <key:val> <key2:val> ..."
181 )
182
183 parser = argparse.ArgumentParser(description='RhodeCode API cli',
184 usage=usage)
185
186 ## config
187 group = parser.add_argument_group('config')
188 group.add_argument('--apikey', help='api access key')
189 group.add_argument('--apihost', help='api host')
190 group.add_argument('--config', help='config file')
191
192 group = parser.add_argument_group('API')
193 group.add_argument('method', metavar='METHOD', type=str,
194 help='API method name to call followed by key:value attributes',
195 )
196 group.add_argument('--format', dest='format', type=str,
197 help='output format default: `pretty` can '
198 'be also `%s`' % FORMAT_JSON,
199 default=FORMAT_PRETTY
200 )
201 args, other = parser.parse_known_args()
202 return parser, args, other
203
204
205 def main(argv=None):
206 """
207 Main execution function for cli
208
209 :param argv:
210 :type argv:
211 """
212 if argv is None:
213 argv = sys.argv
214
215 conf = None
216 parser, args, other = argparser(argv)
217
218 api_credentials_given = (args.apikey and args.apihost)
219 if args.method == '_create_config':
220 if not api_credentials_given:
221 raise parser.error('_create_config requires --apikey and --apihost')
222 conf = RcConf(config_location=args.config,
223 autocreate=True, config={'apikey': args.apikey,
224 'apihost': args.apihost})
225
226 if not conf:
227 conf = RcConf(config_location=args.config, autoload=True)
228 if not conf:
229 if not api_credentials_given:
230 parser.error('Could not find config file and missing '
231 '--apikey or --apihost in params')
232
233 apikey = args.apikey or conf['apikey']
234 host = args.apihost or conf['apihost']
235 method = args.method
236 if method == '_create_config':
237 sys.exit()
238
239 try:
240 margs = dict(map(lambda s: s.split(':', 1), other))
241 except:
242 sys.stderr.write('Error parsing arguments \n')
243 sys.exit()
244
245 api_call(apikey, host, args.format, method, **margs)
246 return 0
247
248 if __name__ == '__main__':
249 sys.exit(main(sys.argv))
@@ -0,0 +1,31 b''
1 #!/usr/bin/env python
2 import os
3 import sys
4
5 try:
6 import rhodecode
7 RC_HOOK_VER = '_TMPL_'
8 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
9 from rhodecode.lib.hooks import handle_git_post_receive
10 except ImportError:
11 rhodecode = None
12
13
14 def main():
15 if rhodecode is None:
16 # exit with success if we cannot import rhodecode !!
17 # this allows simply push to this repo even without
18 # rhodecode
19 sys.exit(0)
20
21 repo_path = os.path.abspath('.')
22 push_data = sys.stdin.readlines()
23 # os.environ is modified here by a subprocess call that
24 # runs git and later git executes this hook.
25 # Environ get's some additional info from rhodecode system
26 # like IP or username from basic-auth
27 handle_git_post_receive(repo_path, push_data, os.environ)
28 sys.exit(0)
29
30 if __name__ == '__main__':
31 main()
@@ -0,0 +1,31 b''
1 #!/usr/bin/env python
2 import os
3 import sys
4
5 try:
6 import rhodecode
7 RC_HOOK_VER = '_TMPL_'
8 os.environ['RC_HOOK_VER'] = RC_HOOK_VER
9 from rhodecode.lib.hooks import handle_git_pre_receive
10 except ImportError:
11 rhodecode = None
12
13
14 def main():
15 if rhodecode is None:
16 # exit with success if we cannot import rhodecode !!
17 # this allows simply push to this repo even without
18 # rhodecode
19 sys.exit(0)
20
21 repo_path = os.path.abspath('.')
22 push_data = sys.stdin.readlines()
23 # os.environ is modified here by a subprocess call that
24 # runs git and later git executes this hook.
25 # Environ get's some additional info from rhodecode system
26 # like IP or username from basic-auth
27 handle_git_pre_receive(repo_path, push_data, os.environ)
28 sys.exit(0)
29
30 if __name__ == '__main__':
31 main()
@@ -0,0 +1,133 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.controllers.compare
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 compare controller for pylons showoing differences between two
7 repos, branches, bookmarks or tips
8
9 :created_on: May 6, 2012
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
13 """
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import logging
27 import traceback
28
29 from webob.exc import HTTPNotFound
30 from pylons import request, response, session, tmpl_context as c, url
31 from pylons.controllers.util import abort, redirect
32 from pylons.i18n.translation import _
33
34 from rhodecode.lib.vcs.exceptions import EmptyRepositoryError, RepositoryError
35 from rhodecode.lib import helpers as h
36 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 from rhodecode.lib import diffs
39
40 from rhodecode.model.db import Repository
41 from rhodecode.model.pull_request import PullRequestModel
42
43 log = logging.getLogger(__name__)
44
45
46 class CompareController(BaseRepoController):
47
48 @LoginRequired()
49 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
50 'repository.admin')
51 def __before__(self):
52 super(CompareController, self).__before__()
53
54 def __get_cs_or_redirect(self, rev, repo, redirect_after=True):
55 """
56 Safe way to get changeset if error occur it redirects to changeset with
57 proper message
58
59 :param rev: revision to fetch
60 :param repo: repo instance
61 """
62
63 try:
64 type_, rev = rev
65 return repo.scm_instance.get_changeset(rev)
66 except EmptyRepositoryError, e:
67 if not redirect_after:
68 return None
69 h.flash(h.literal(_('There are no changesets yet')),
70 category='warning')
71 redirect(url('summary_home', repo_name=repo.repo_name))
72
73 except RepositoryError, e:
74 log.error(traceback.format_exc())
75 h.flash(str(e), category='warning')
76 redirect(h.url('summary_home', repo_name=repo.repo_name))
77
78 def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
79
80 org_repo = c.rhodecode_db_repo.repo_name
81 org_ref = (org_ref_type, org_ref)
82 other_ref = (other_ref_type, other_ref)
83 other_repo = request.GET.get('repo', org_repo)
84
85 c.swap_url = h.url('compare_url', repo_name=other_repo,
86 org_ref_type=other_ref[0], org_ref=other_ref[1],
87 other_ref_type=org_ref[0], other_ref=org_ref[1],
88 repo=org_repo)
89
90 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
91 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
92
93 if c.org_repo is None or c.other_repo is None:
94 log.error('Could not found repo %s or %s' % (org_repo, other_repo))
95 raise HTTPNotFound
96
97 if c.org_repo.scm_instance.alias != 'hg':
98 log.error('Review not available for GIT REPOS')
99 raise HTTPNotFound
100
101 self.__get_cs_or_redirect(rev=org_ref, repo=org_repo)
102 self.__get_cs_or_redirect(rev=other_ref, repo=other_repo)
103
104 c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
105 org_repo, org_ref, other_repo, other_ref
106 )
107
108 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
109 c.cs_ranges])
110 c.target_repo = c.repo_name
111 # defines that we need hidden inputs with changesets
112 c.as_form = request.GET.get('as_form', False)
113 if request.environ.get('HTTP_X_PARTIAL_XHR'):
114 return render('compare/compare_cs.html')
115
116 c.org_ref = org_ref[1]
117 c.other_ref = other_ref[1]
118 # diff needs to have swapped org with other to generate proper diff
119 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
120 discovery_data)
121 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
122 _parsed = diff_processor.prepare()
123
124 c.files = []
125 c.changes = {}
126
127 for f in _parsed:
128 fid = h.FID('', f['filename'])
129 c.files.append([fid, f['operation'], f['filename'], f['stats']])
130 diff = diff_processor.as_html(enable_comments=False, diff_lines=[f])
131 c.changes[fid] = [f['operation'], f['filename'], diff]
132
133 return render('compare/compare_diff.html')
@@ -0,0 +1,404 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.controllers.pullrequests
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 pull requests controller for rhodecode for initializing pull requests
7
8 :created_on: May 7, 2012
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
26 import traceback
27 import formencode
28
29 from webob.exc import HTTPNotFound, HTTPForbidden
30 from collections import defaultdict
31 from itertools import groupby
32
33 from pylons import request, response, session, tmpl_context as c, url
34 from pylons.controllers.util import abort, redirect
35 from pylons.i18n.translation import _
36 from pylons.decorators import jsonify
37
38 from rhodecode.lib.compat import json
39 from rhodecode.lib.base import BaseRepoController, render
40 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
41 NotAnonymous
42 from rhodecode.lib import helpers as h
43 from rhodecode.lib import diffs
44 from rhodecode.lib.utils import action_logger
45 from rhodecode.model.db import User, PullRequest, ChangesetStatus,\
46 ChangesetComment
47 from rhodecode.model.pull_request import PullRequestModel
48 from rhodecode.model.meta import Session
49 from rhodecode.model.repo import RepoModel
50 from rhodecode.model.comment import ChangesetCommentsModel
51 from rhodecode.model.changeset_status import ChangesetStatusModel
52 from rhodecode.model.forms import PullRequestForm
53
54 log = logging.getLogger(__name__)
55
56
57 class PullrequestsController(BaseRepoController):
58
59 @LoginRequired()
60 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
61 'repository.admin')
62 def __before__(self):
63 super(PullrequestsController, self).__before__()
64 repo_model = RepoModel()
65 c.users_array = repo_model.get_users_js()
66 c.users_groups_array = repo_model.get_users_groups_js()
67
68 def _get_repo_refs(self, repo):
69 hist_l = []
70
71 branches_group = ([('branch:%s:%s' % (k, v), k) for
72 k, v in repo.branches.iteritems()], _("Branches"))
73 bookmarks_group = ([('book:%s:%s' % (k, v), k) for
74 k, v in repo.bookmarks.iteritems()], _("Bookmarks"))
75 tags_group = ([('tag:%s:%s' % (k, v), k) for
76 k, v in repo.tags.iteritems()], _("Tags"))
77
78 hist_l.append(bookmarks_group)
79 hist_l.append(branches_group)
80 hist_l.append(tags_group)
81
82 return hist_l
83
84 def show_all(self, repo_name):
85 c.pull_requests = PullRequestModel().get_all(repo_name)
86 c.repo_name = repo_name
87 return render('/pullrequests/pullrequest_show_all.html')
88
89 @NotAnonymous()
90 def index(self):
91 org_repo = c.rhodecode_db_repo
92
93 if org_repo.scm_instance.alias != 'hg':
94 log.error('Review not available for GIT REPOS')
95 raise HTTPNotFound
96
97 other_repos_info = {}
98
99 c.org_refs = self._get_repo_refs(c.rhodecode_repo)
100 c.org_repos = []
101 c.other_repos = []
102 c.org_repos.append((org_repo.repo_name, '%s/%s' % (
103 org_repo.user.username, c.repo_name))
104 )
105
106 # add org repo to other so we can open pull request agains itself
107 c.other_repos.extend(c.org_repos)
108
109 c.default_pull_request = org_repo.repo_name
110 c.default_revs = self._get_repo_refs(org_repo.scm_instance)
111 #add orginal repo
112 other_repos_info[org_repo.repo_name] = {
113 'gravatar': h.gravatar_url(org_repo.user.email, 24),
114 'description': org_repo.description,
115 'revs': h.select('other_ref', '', c.default_revs, class_='refs')
116 }
117
118 #gather forks and add to this list
119 for fork in org_repo.forks:
120 c.other_repos.append((fork.repo_name, '%s/%s' % (
121 fork.user.username, fork.repo_name))
122 )
123 other_repos_info[fork.repo_name] = {
124 'gravatar': h.gravatar_url(fork.user.email, 24),
125 'description': fork.description,
126 'revs': h.select('other_ref', '',
127 self._get_repo_refs(fork.scm_instance),
128 class_='refs')
129 }
130 #add parents of this fork also
131 if org_repo.parent:
132 c.default_pull_request = org_repo.parent.repo_name
133 c.other_repos.append((org_repo.parent.repo_name, '%s/%s' % (
134 org_repo.parent.user.username,
135 org_repo.parent.repo_name))
136 )
137 other_repos_info[org_repo.parent.repo_name] = {
138 'gravatar': h.gravatar_url(org_repo.parent.user.email, 24),
139 'description': org_repo.parent.description,
140 'revs': h.select('other_ref', '',
141 self._get_repo_refs(org_repo.parent.scm_instance),
142 class_='refs')
143 }
144
145 c.other_repos_info = json.dumps(other_repos_info)
146 c.review_members = [org_repo.user]
147 return render('/pullrequests/pullrequest.html')
148
149 @NotAnonymous()
150 def create(self, repo_name):
151 try:
152 _form = PullRequestForm()().to_python(request.POST)
153 except formencode.Invalid, errors:
154 log.error(traceback.format_exc())
155 if errors.error_dict.get('revisions'):
156 msg = 'Revisions: %s' % errors.error_dict['revisions']
157 elif errors.error_dict.get('pullrequest_title'):
158 msg = _('Pull request requires a title with min. 3 chars')
159 else:
160 msg = _('error during creation of pull request')
161
162 h.flash(msg, 'error')
163 return redirect(url('pullrequest_home', repo_name=repo_name))
164
165 org_repo = _form['org_repo']
166 org_ref = _form['org_ref']
167 other_repo = _form['other_repo']
168 other_ref = _form['other_ref']
169 revisions = _form['revisions']
170 reviewers = _form['review_members']
171
172 title = _form['pullrequest_title']
173 description = _form['pullrequest_desc']
174
175 try:
176 pull_request = PullRequestModel().create(
177 self.rhodecode_user.user_id, org_repo, org_ref, other_repo,
178 other_ref, revisions, reviewers, title, description
179 )
180 Session().commit()
181 h.flash(_('Successfully opened new pull request'),
182 category='success')
183 except Exception:
184 h.flash(_('Error occurred during sending pull request'),
185 category='error')
186 log.error(traceback.format_exc())
187 return redirect(url('pullrequest_home', repo_name=repo_name))
188
189 return redirect(url('pullrequest_show', repo_name=other_repo,
190 pull_request_id=pull_request.pull_request_id))
191
192 @NotAnonymous()
193 @jsonify
194 def update(self, repo_name, pull_request_id):
195 pull_request = PullRequest.get_or_404(pull_request_id)
196 if pull_request.is_closed():
197 raise HTTPForbidden()
198 #only owner or admin can update it
199 owner = pull_request.author.user_id == c.rhodecode_user.user_id
200 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
201 reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
202 request.POST.get('reviewers_ids', '').split(',')))
203
204 PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
205 Session.commit()
206 return True
207 raise HTTPForbidden()
208
209 @NotAnonymous()
210 @jsonify
211 def delete(self, repo_name, pull_request_id):
212 pull_request = PullRequest.get_or_404(pull_request_id)
213 #only owner can delete it !
214 if pull_request.author.user_id == c.rhodecode_user.user_id:
215 PullRequestModel().delete(pull_request)
216 Session().commit()
217 h.flash(_('Successfully deleted pull request'),
218 category='success')
219 return redirect(url('admin_settings_my_account'))
220 raise HTTPForbidden()
221
222 def _load_compare_data(self, pull_request, enable_comments=True):
223 """
224 Load context data needed for generating compare diff
225
226 :param pull_request:
227 :type pull_request:
228 """
229
230 org_repo = pull_request.org_repo
231 (org_ref_type,
232 org_ref_name,
233 org_ref_rev) = pull_request.org_ref.split(':')
234
235 other_repo = pull_request.other_repo
236 (other_ref_type,
237 other_ref_name,
238 other_ref_rev) = pull_request.other_ref.split(':')
239
240 # despite opening revisions for bookmarks/branches/tags, we always
241 # convert this to rev to prevent changes after book or branch change
242 org_ref = ('rev', org_ref_rev)
243 other_ref = ('rev', other_ref_rev)
244
245 c.org_repo = org_repo
246 c.other_repo = other_repo
247
248 c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
249 org_repo, org_ref, other_repo, other_ref
250 )
251
252 c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
253 c.cs_ranges])
254 # defines that we need hidden inputs with changesets
255 c.as_form = request.GET.get('as_form', False)
256
257 c.org_ref = org_ref[1]
258 c.other_ref = other_ref[1]
259 # diff needs to have swapped org with other to generate proper diff
260 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
261 discovery_data)
262 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
263 _parsed = diff_processor.prepare()
264
265 c.files = []
266 c.changes = {}
267
268 for f in _parsed:
269 fid = h.FID('', f['filename'])
270 c.files.append([fid, f['operation'], f['filename'], f['stats']])
271 diff = diff_processor.as_html(enable_comments=enable_comments,
272 diff_lines=[f])
273 c.changes[fid] = [f['operation'], f['filename'], diff]
274
275 def show(self, repo_name, pull_request_id):
276 repo_model = RepoModel()
277 c.users_array = repo_model.get_users_js()
278 c.users_groups_array = repo_model.get_users_groups_js()
279 c.pull_request = PullRequest.get_or_404(pull_request_id)
280
281 cc_model = ChangesetCommentsModel()
282 cs_model = ChangesetStatusModel()
283 _cs_statuses = cs_model.get_statuses(c.pull_request.org_repo,
284 pull_request=c.pull_request,
285 with_revisions=True)
286
287 cs_statuses = defaultdict(list)
288 for st in _cs_statuses:
289 cs_statuses[st.author.username] += [st]
290
291 c.pull_request_reviewers = []
292 c.pull_request_pending_reviewers = []
293 for o in c.pull_request.reviewers:
294 st = cs_statuses.get(o.user.username, None)
295 if st:
296 sorter = lambda k: k.version
297 st = [(x, list(y)[0])
298 for x, y in (groupby(sorted(st, key=sorter), sorter))]
299 else:
300 c.pull_request_pending_reviewers.append(o.user)
301 c.pull_request_reviewers.append([o.user, st])
302
303 # pull_requests repo_name we opened it against
304 # ie. other_repo must match
305 if repo_name != c.pull_request.other_repo.repo_name:
306 raise HTTPNotFound
307
308 # load compare data into template context
309 enable_comments = not c.pull_request.is_closed()
310 self._load_compare_data(c.pull_request, enable_comments=enable_comments)
311
312 # inline comments
313 c.inline_cnt = 0
314 c.inline_comments = cc_model.get_inline_comments(
315 c.rhodecode_db_repo.repo_id,
316 pull_request=pull_request_id)
317 # count inline comments
318 for __, lines in c.inline_comments:
319 for comments in lines.values():
320 c.inline_cnt += len(comments)
321 # comments
322 c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id,
323 pull_request=pull_request_id)
324
325 # changeset(pull-request) status
326 c.current_changeset_status = cs_model.calculate_status(
327 c.pull_request_reviewers
328 )
329 c.changeset_statuses = ChangesetStatus.STATUSES
330 c.target_repo = c.pull_request.org_repo.repo_name
331 return render('/pullrequests/pullrequest_show.html')
332
333 @NotAnonymous()
334 @jsonify
335 def comment(self, repo_name, pull_request_id):
336 pull_request = PullRequest.get_or_404(pull_request_id)
337 if pull_request.is_closed():
338 raise HTTPForbidden()
339
340 status = request.POST.get('changeset_status')
341 change_status = request.POST.get('change_changeset_status')
342
343 comm = ChangesetCommentsModel().create(
344 text=request.POST.get('text'),
345 repo=c.rhodecode_db_repo.repo_id,
346 user=c.rhodecode_user.user_id,
347 pull_request=pull_request_id,
348 f_path=request.POST.get('f_path'),
349 line_no=request.POST.get('line'),
350 status_change=(ChangesetStatus.get_status_lbl(status)
351 if status and change_status else None)
352 )
353
354 # get status if set !
355 if status and change_status:
356 ChangesetStatusModel().set_status(
357 c.rhodecode_db_repo.repo_id,
358 status,
359 c.rhodecode_user.user_id,
360 comm,
361 pull_request=pull_request_id
362 )
363 action_logger(self.rhodecode_user,
364 'user_commented_pull_request:%s' % pull_request_id,
365 c.rhodecode_db_repo, self.ip_addr, self.sa)
366
367 if request.POST.get('save_close'):
368 PullRequestModel().close_pull_request(pull_request_id)
369 action_logger(self.rhodecode_user,
370 'user_closed_pull_request:%s' % pull_request_id,
371 c.rhodecode_db_repo, self.ip_addr, self.sa)
372
373 Session().commit()
374
375 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
376 return redirect(h.url('pullrequest_show', repo_name=repo_name,
377 pull_request_id=pull_request_id))
378
379 data = {
380 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
381 }
382 if comm:
383 c.co = comm
384 data.update(comm.get_dict())
385 data.update({'rendered_text':
386 render('changeset/changeset_comment_block.html')})
387
388 return data
389
390 @NotAnonymous()
391 @jsonify
392 def delete_comment(self, repo_name, comment_id):
393 co = ChangesetComment.get(comment_id)
394 if co.pull_request.is_closed():
395 #don't allow deleting comments on closed pull request
396 raise HTTPForbidden()
397
398 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
399 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
400 ChangesetCommentsModel().delete(comment=co)
401 Session().commit()
402 return True
403 else:
404 raise HTTPForbidden()
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100755
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -2,6 +2,7 b' syntax: glob'
2 2 *.pyc
3 3 *.swp
4 4 *.sqlite
5 *.tox
5 6 *.egg-info
6 7 *.egg
7 8
@@ -20,3 +21,4 b' syntax: regexp'
20 21 ^RhodeCode\.egg-info$
21 22 ^rc\.ini$
22 23 ^fabfile.py
24 ^\.rhodecode$
@@ -18,4 +18,9 b' List of contributors to RhodeCode projec'
18 18 Aras Pranckevicius <aras@unity3d.com>
19 19 Tony Bussieres <t.bussieres@gmail.com>
20 20 Erwin Kroon <e.kroon@smartmetersolutions.nl>
21 nansenat16 <nansenat16@null.tw> No newline at end of file
21 nansenat16 <nansenat16@null.tw>
22 Vincent Duvert <vincent@duvert.net>
23 Takumi IINO <trot.thunder@gmail.com>
24 Indra Talip <indra.talip@gmail.com>
25 James Rhodes <jrhodes@redpointsoftware.com.au>
26 Dominik Ruf <dominikruf@gmail.com> No newline at end of file
@@ -72,25 +72,26 b' RhodeCode Features'
72 72 Each request can be logged and authenticated.
73 73 - Runs on threads unlike hgweb. You can make multiple pulls/pushes simultaneous.
74 74 Supports http/https and LDAP
75 - Full permissions (private/read/write/admin) and authentication per project.
76 One account for web interface and mercurial_ push/pull/clone operations.
75 - Full permissions (private/read/write/admin) for each repository, additional
76 explicit forking and repository permissions.
77 77 - Have built in users groups for easier permission management
78 78 - Repository groups let you group repos and manage them easier.
79 79 - Users can fork other users repo. RhodeCode have also compare view to see
80 80 combined changeset for all changeset made within single push.
81 81 - Build in commit-api let's you add, edit and commit files right from RhodeCode
82 82 interface using simple editor or upload form for binaries.
83 - Powerfull pull-request driven review system with inline commenting, and
84 changeset statuses, notification system.
85 - Importing SVN repositories from remote locations into RhodeCode.
83 86 - Mako templates let's you customize the look and feel of the application.
84 87 - Beautiful diffs, annotations and source code browsing all colored by pygments.
85 Raw diffs are made in git-diff format, including git_ binary-patches
88 Raw diffs are made in git-diff format, including GIT_ binary-patches
86 89 - Mercurial_ branch graph and yui-flot powered graphs with zooming and statistics
87 90 - Admin interface with user/permission management. Admin activity journal, logs
88 91 pulls, pushes, forks, registrations and other actions made by all users.
89 92 - Server side forks. It is possible to fork a project and modify it freely
90 93 without breaking the main repository. You can even write Your own hooks
91 94 and install them
92 - code review with notification system, inline commenting, all parsed using
93 rst syntax
94 95 - rst and markdown README support for repositories
95 96 - Full text search powered by Whoosh on the source files, and file names.
96 97 Build in indexing daemons, with optional incremental index build
@@ -110,8 +111,9 b' Incoming / Plans'
110 111 ----------------
111 112
112 113 - Finer granular permissions per branch, repo group or subrepo
113 - pull requests and web based merges
114 - per line file history
114 - Pull requests with web based merges
115 - Per line file history
116 - Simple issue tracker
115 117 - SSH based authentication with server side key management
116 118 - Commit based built in wiki system
117 119 - More statistics and graph (global annotation + some more statistics)
@@ -131,7 +133,8 b' Listed bellow are various support resour'
131 133
132 134 .. note::
133 135
134 Please try to read the documentation before posting any issues
136 Please try to read the documentation before posting any issues, especially
137 the **troubleshooting section**
135 138
136 139 - Join the `Google group <http://groups.google.com/group/rhodecode>`_ and ask
137 140 any questions.
@@ -30,22 +30,31 b' pdebug = false'
30 30
31 31 [server:main]
32 32 ##nr of threads to spawn
33 threadpool_workers = 5
33 #threadpool_workers = 5
34 34
35 35 ##max request before thread respawn
36 threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37 37
38 38 ##option to use threads of process
39 use_threadpool = true
39 #use_threadpool = true
40 40
41 use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 43 host = 0.0.0.0
43 44 port = 5000
44 45
46 [filter:proxy-prefix]
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
50
45 51 [app:main]
46 52 use = egg:rhodecode
53 #filter-with = proxy-prefix
47 54 full_stack = true
48 55 static_files = true
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
49 58 lang = en
50 59 cache_dir = %(here)s/data
51 60 index_dir = %(here)s/data/index
@@ -54,6 +63,15 b' cut_off_limit = 256000'
54 63 force_https = false
55 64 commit_parse_limit = 25
56 65 use_gravatar = true
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
72 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
73 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
74
57 75 container_auth_enabled = false
58 76 proxypass_auth_enabled = false
59 77 default_encoding = utf8
@@ -78,7 +96,8 b' default_encoding = utf8'
78 96 issue_pat = (?:\s*#)(\d+)
79 97
80 98 ## server url to the issue, each {id} will be replaced with match
81 ## fetched from the regex and {repo} is replaced with repository name
99 ## fetched from the regex and {repo} is replaced with full repository name
100 ## including groups {repo_name} is replaced with just name of repo
82 101
83 102 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
84 103
@@ -165,30 +184,34 b' beaker.cache.sql_cache_long.key_length ='
165 184 ## The storage uses the Container API
166 185 ## that is also used by the cache system.
167 186
168 ## db session example
169
187 ## db session ##
170 188 #beaker.session.type = ext:database
171 189 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
172 190 #beaker.session.table_name = db_session
173 191
174 ## encrypted cookie session, good for many instances
192 ## encrypted cookie client side session, good for many instances ##
175 193 #beaker.session.type = cookie
176 194
177 beaker.session.type = file
195 ## file based cookies (default) ##
196 #beaker.session.type = file
197
198
178 199 beaker.session.key = rhodecode
179 # secure cookie requires AES python libraries
200 ## secure cookie requires AES python libraries ##
180 201 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
181 202 #beaker.session.validate_key = 9712sds2212c--zxc123
182 beaker.session.timeout = 36000
203 ## sets session as invalid if it haven't been accessed for given amount of time
204 beaker.session.timeout = 2592000
183 205 beaker.session.httponly = true
206 #beaker.session.cookie_path = /<your-prefix>
184 207
185 ## uncomment for https secure cookie
208 ## uncomment for https secure cookie ##
186 209 beaker.session.secure = false
187 210
188 ##auto save the session to not to use .save()
211 ## auto save the session to not to use .save() ##
189 212 beaker.session.auto = False
190 213
191 ##true exire at browser close
214 ## default cookie expiration time in seconds `true` expire at browser close ##
192 215 #beaker.session.cookie_expires = 3600
193 216
194 217
@@ -7,7 +7,7 b' API'
7 7
8 8 Starting from RhodeCode version 1.2 a simple API was implemented.
9 9 There's a single schema for calling all api methods. API is implemented
10 with JSON protocol both ways. An url to send API request in RhodeCode is
10 with JSON protocol both ways. An url to send API request to RhodeCode is
11 11 <your_server>/_admin/api
12 12
13 13 API ACCESS FOR WEB VIEWS
@@ -59,6 +59,47 b' All responses from API will be `HTTP/1.0'
59 59 calling api *error* key from response will contain failure description
60 60 and result will be null.
61 61
62
63 API CLIENT
64 ++++++++++
65
66 From version 1.4 RhodeCode adds a script that allows to easily
67 communicate with API. After installing RhodeCode a `rhodecode-api` script
68 will be available.
69
70 To get started quickly simply run::
71
72 rhodecode-api _create_config --apikey=<youapikey> --apihost=<rhodecode host>
73
74 This will create a file named .config in the directory you executed it storing
75 json config file with credentials. You can skip this step and always provide
76 both of the arguments to be able to communicate with server
77
78
79 after that simply run any api command for example get_repo::
80
81 rhodecode-api get_repo
82
83 calling {"api_key": "<apikey>", "id": 75, "args": {}, "method": "get_repo"} to http://127.0.0.1:5000
84 rhodecode said:
85 {'error': 'Missing non optional `repoid` arg in JSON DATA',
86 'id': 75,
87 'result': None}
88
89 Ups looks like we forgot to add an argument
90
91 Let's try again now giving the repoid as parameters::
92
93 rhodecode-api get_repo repoid:rhodecode
94
95 calling {"api_key": "<apikey>", "id": 39, "args": {"repoid": "rhodecode"}, "method": "get_repo"} to http://127.0.0.1:5000
96 rhodecode said:
97 {'error': None,
98 'id': 39,
99 'result': <json data...>}
100
101
102
62 103 API METHODS
63 104 +++++++++++
64 105
@@ -76,12 +117,64 b' INPUT::'
76 117 api_key : "<api_key>"
77 118 method : "pull"
78 119 args : {
79 "repo_name" : "<reponame>"
120 "repoid" : "<reponame or repo_id>"
121 }
122
123 OUTPUT::
124
125 id : <id_given_in_input>
126 result : "Pulled from `<reponame>`"
127 error : null
128
129
130 rescan_repos
131 ------------
132
133 Dispatch rescan repositories action. If remove_obsolete is set
134 RhodeCode will delete repos that are in database but not in the filesystem.
135 This command can be executed only using api_key belonging to user with admin
136 rights.
137
138 INPUT::
139
140 id : <id_for_response>
141 api_key : "<api_key>"
142 method : "rescan_repos"
143 args : {
144 "remove_obsolete" : "<boolean = Optional(False)>"
80 145 }
81 146
82 147 OUTPUT::
83 148
84 result : "Pulled from <reponame>"
149 id : <id_given_in_input>
150 result : "{'added': [<list of names of added repos>],
151 'removed': [<list of names of removed repos>]}"
152 error : null
153
154
155 lock
156 ----
157
158 Set locking state on given repository by given user.
159 This command can be executed only using api_key belonging to user with admin
160 rights.
161
162 INPUT::
163
164 id : <id_for_response>
165 api_key : "<api_key>"
166 method : "lock"
167 args : {
168 "repoid" : "<reponame or repo_id>"
169 "userid" : "<user_id or username>",
170 "locked" : "<bool true|false>"
171
172 }
173
174 OUTPUT::
175
176 id : <id_given_in_input>
177 result : "User `<username>` set lock state for repo `<reponame>` to `true|false`"
85 178 error : null
86 179
87 180
@@ -104,13 +197,15 b' INPUT::'
104 197
105 198 OUTPUT::
106 199
200 id : <id_given_in_input>
107 201 result: None if user does not exist or
108 202 {
109 "id" : "<id>",
203 "user_id" : "<user_id>",
110 204 "username" : "<username>",
111 205 "firstname": "<firstname>",
112 206 "lastname" : "<lastname>",
113 207 "email" : "<email>",
208 "emails": "<list_of_all_additional_emails>",
114 209 "active" : "<bool>",
115 210 "admin" :  "<bool>",
116 211 "ldap_dn" : "<ldap_dn>",
@@ -143,13 +238,15 b' INPUT::'
143 238
144 239 OUTPUT::
145 240
241 id : <id_given_in_input>
146 242 result: [
147 243 {
148 "id" : "<id>",
244 "user_id" : "<user_id>",
149 245 "username" : "<username>",
150 246 "firstname": "<firstname>",
151 247 "lastname" : "<lastname>",
152 248 "email" : "<email>",
249 "emails": "<list_of_all_additional_emails>",
153 250 "active" : "<bool>",
154 251 "admin" :  "<bool>",
155 252 "ldap_dn" : "<ldap_dn>",
@@ -174,20 +271,32 b' INPUT::'
174 271 method : "create_user"
175 272 args : {
176 273 "username" : "<username>",
274 "email" : "<useremail>",
177 275 "password" : "<password>",
178 "email" : "<useremail>",
179 "firstname" : "<firstname> = None",
180 "lastname" : "<lastname> = None",
181 "active" : "<bool> = True",
182 "admin" : "<bool> = False",
183 "ldap_dn" : "<ldap_dn> = None"
276 "firstname" : "<firstname> = Optional(None)",
277 "lastname" : "<lastname> = Optional(None)",
278 "active" : "<bool> = Optional(True)",
279 "admin" : "<bool> = Optional(False)",
280 "ldap_dn" : "<ldap_dn> = Optional(None)"
184 281 }
185 282
186 283 OUTPUT::
187 284
285 id : <id_given_in_input>
188 286 result: {
189 "id" : "<new_user_id>",
190 "msg" : "created new user <username>"
287 "msg" : "created new user `<username>`",
288 "user": {
289 "user_id" : "<user_id>",
290 "username" : "<username>",
291 "firstname": "<firstname>",
292 "lastname" : "<lastname>",
293 "email" : "<email>",
294 "emails": "<list_of_all_additional_emails>",
295 "active" : "<bool>",
296 "admin" :  "<bool>",
297 "ldap_dn" : "<ldap_dn>",
298 "last_login": "<last_login>",
299 },
191 300 }
192 301 error: null
193 302
@@ -195,7 +304,7 b' OUTPUT::'
195 304 update_user
196 305 -----------
197 306
198 updates current one if such user exists. This command can
307 updates given user if such user exists. This command can
199 308 be executed only using api_key belonging to user with admin rights.
200 309
201 310
@@ -206,21 +315,60 b' INPUT::'
206 315 method : "update_user"
207 316 args : {
208 317 "userid" : "<user_id or username>",
209 "username" : "<username>",
210 "password" : "<password>",
211 "email" : "<useremail>",
212 "firstname" : "<firstname>",
213 "lastname" : "<lastname>",
214 "active" : "<bool>",
215 "admin" : "<bool>",
216 "ldap_dn" : "<ldap_dn>"
318 "username" : "<username> = Optional",
319 "email" : "<useremail> = Optional",
320 "password" : "<password> = Optional",
321 "firstname" : "<firstname> = Optional",
322 "lastname" : "<lastname> = Optional",
323 "active" : "<bool> = Optional",
324 "admin" : "<bool> = Optional",
325 "ldap_dn" : "<ldap_dn> = Optional"
217 326 }
218 327
219 328 OUTPUT::
220 329
330 id : <id_given_in_input>
221 331 result: {
222 "id" : "<edited_user_id>",
223 "msg" : "updated user <username>"
332 "msg" : "updated user ID:<userid> <username>",
333 "user": {
334 "user_id" : "<user_id>",
335 "username" : "<username>",
336 "firstname": "<firstname>",
337 "lastname" : "<lastname>",
338 "email" : "<email>",
339 "emails": "<list_of_all_additional_emails>",
340 "active" : "<bool>",
341 "admin" :  "<bool>",
342 "ldap_dn" : "<ldap_dn>",
343 "last_login": "<last_login>",
344 },
345 }
346 error: null
347
348
349 delete_user
350 -----------
351
352
353 deletes givenuser if such user exists. This command can
354 be executed only using api_key belonging to user with admin rights.
355
356
357 INPUT::
358
359 id : <id_for_response>
360 api_key : "<api_key>"
361 method : "delete_user"
362 args : {
363 "userid" : "<user_id or username>",
364 }
365
366 OUTPUT::
367
368 id : <id_given_in_input>
369 result: {
370 "msg" : "deleted user ID:<userid> <username>",
371 "user": null
224 372 }
225 373 error: null
226 374
@@ -238,25 +386,29 b' INPUT::'
238 386 api_key : "<api_key>"
239 387 method : "get_users_group"
240 388 args : {
241 "group_name" : "<name>"
389 "usersgroupid" : "<users group id or name>"
242 390 }
243 391
244 392 OUTPUT::
245 393
394 id : <id_given_in_input>
246 395 result : None if group not exist
247 396 {
248 "id" : "<id>",
249 "group_name" : "<groupname>",
250 "active": "<bool>",
397 "users_group_id" : "<id>",
398 "group_name" : "<groupname>",
399 "active": "<bool>",
251 400 "members" : [
252 { "id" : "<userid>",
401 {
402 "user_id" : "<user_id>",
253 403 "username" : "<username>",
254 404 "firstname": "<firstname>",
255 405 "lastname" : "<lastname>",
256 406 "email" : "<email>",
407 "emails": "<list_of_all_additional_emails>",
257 408 "active" : "<bool>",
258 409 "admin" :  "<bool>",
259 "ldap" : "<ldap_dn>"
410 "ldap_dn" : "<ldap_dn>",
411 "last_login": "<last_login>",
260 412 },
261 413
262 414 ]
@@ -280,25 +432,29 b' INPUT::'
280 432
281 433 OUTPUT::
282 434
435 id : <id_given_in_input>
283 436 result : [
284 437 {
285 "id" : "<id>",
286 "group_name" : "<groupname>",
287 "active": "<bool>",
288 "members" : [
289 {
290 "id" : "<userid>",
291 "username" : "<username>",
292 "firstname": "<firstname>",
293 "lastname" : "<lastname>",
294 "email" : "<email>",
295 "active" : "<bool>",
296 "admin" :  "<bool>",
297 "ldap" : "<ldap_dn>"
298 },
299
300 ]
301 }
438 "users_group_id" : "<id>",
439 "group_name" : "<groupname>",
440 "active": "<bool>",
441 "members" : [
442 {
443 "user_id" : "<user_id>",
444 "username" : "<username>",
445 "firstname": "<firstname>",
446 "lastname" : "<lastname>",
447 "email" : "<email>",
448 "emails": "<list_of_all_additional_emails>",
449 "active" : "<bool>",
450 "admin" :  "<bool>",
451 "ldap_dn" : "<ldap_dn>",
452 "last_login": "<last_login>",
453 },
454
455 ]
456 },
457
302 458 ]
303 459 error : null
304 460
@@ -317,14 +473,34 b' INPUT::'
317 473 method : "create_users_group"
318 474 args: {
319 475 "group_name": "<groupname>",
320 "active":"<bool> = True"
476 "active":"<bool> = Optional(True)"
321 477 }
322 478
323 479 OUTPUT::
324 480
481 id : <id_given_in_input>
325 482 result: {
326 "id": "<newusersgroupid>",
327 "msg": "created new users group <groupname>"
483 "msg": "created new users group `<groupname>`",
484 "users_group": {
485 "users_group_id" : "<id>",
486 "group_name" : "<groupname>",
487 "active": "<bool>",
488 "members" : [
489 {
490 "user_id" : "<user_id>",
491 "username" : "<username>",
492 "firstname": "<firstname>",
493 "lastname" : "<lastname>",
494 "email" : "<email>",
495 "emails": "<list_of_all_additional_emails>",
496 "active" : "<bool>",
497 "admin" :  "<bool>",
498 "ldap_dn" : "<ldap_dn>",
499 "last_login": "<last_login>",
500 },
501
502 ]
503 },
328 504 }
329 505 error: null
330 506
@@ -343,16 +519,16 b' INPUT::'
343 519 api_key : "<api_key>"
344 520 method : "add_user_users_group"
345 521 args: {
346 "group_name" : "<groupname>",
347 "username" : "<username>"
522 "usersgroupid" : "<users group id or name>",
523 "userid" : "<user_id or username>",
348 524 }
349 525
350 526 OUTPUT::
351 527
528 id : <id_given_in_input>
352 529 result: {
353 "id": "<newusersgroupmemberid>",
354 530 "success": True|False # depends on if member is in group
355 "msg": "added member <username> to users group <groupname> |
531 "msg": "added member `<username>` to users group `<groupname>` |
356 532 User is already in that group"
357 533 }
358 534 error: null
@@ -372,12 +548,13 b' INPUT::'
372 548 api_key : "<api_key>"
373 549 method : "remove_user_from_users_group"
374 550 args: {
375 "group_name" : "<groupname>",
376 "username" : "<username>"
551 "usersgroupid" : "<users group id or name>",
552 "userid" : "<user_id or username>",
377 553 }
378 554
379 555 OUTPUT::
380 556
557 id : <id_given_in_input>
381 558 result: {
382 559 "success": True|False, # depends on if member is in group
383 560 "msg": "removed member <username> from users group <groupname> |
@@ -405,23 +582,32 b' INPUT::'
405 582
406 583 OUTPUT::
407 584
585 id : <id_given_in_input>
408 586 result: None if repository does not exist or
409 587 {
410 "id" : "<id>",
588 "repo_id" : "<repo_id>",
411 589 "repo_name" : "<reponame>"
412 "type" : "<type>",
590 "repo_type" : "<repo_type>",
591 "clone_uri" : "<clone_uri>",
592 "private": : "<bool>",
593 "created_on" : "<datetimecreated>",
413 594 "description" : "<description>",
595 "landing_rev": "<landing_rev>",
596 "owner": "<repo_owner>",
597 "fork_of": "<name_of_fork_parent>",
414 598 "members" : [
415 599 {
416 600 "type": "user",
417 "id" : "<userid>",
418 "username" : "<username>",
419 "firstname": "<firstname>",
420 "lastname" : "<lastname>",
421 "email" : "<email>",
422 "active" : "<bool>",
423 "admin" :  "<bool>",
424 "ldap" : "<ldap_dn>",
601 "user_id" : "<user_id>",
602 "username" : "<username>",
603 "firstname": "<firstname>",
604 "lastname" : "<lastname>",
605 "email" : "<email>",
606 "emails": "<list_of_all_additional_emails>",
607 "active" : "<bool>",
608 "admin" :  "<bool>",
609 "ldap_dn" : "<ldap_dn>",
610 "last_login": "<last_login>",
425 611 "permission" : "repository.(read|write|admin)"
426 612 },
427 613
@@ -454,12 +640,19 b' INPUT::'
454 640
455 641 OUTPUT::
456 642
643 id : <id_given_in_input>
457 644 result: [
458 645 {
459 "id" : "<id>",
646 "repo_id" : "<repo_id>",
460 647 "repo_name" : "<reponame>"
461 "type" : "<type>",
462 "description" : "<description>"
648 "repo_type" : "<repo_type>",
649 "clone_uri" : "<clone_uri>",
650 "private": : "<bool>",
651 "created_on" : "<datetimecreated>",
652 "description" : "<description>",
653 "landing_rev": "<landing_rev>",
654 "owner": "<repo_owner>",
655 "fork_of": "<name_of_fork_parent>",
463 656 },
464 657
465 658 ]
@@ -481,14 +674,15 b' INPUT::'
481 674 api_key : "<api_key>"
482 675 method : "get_repo_nodes"
483 676 args: {
484 "repo_name" : "<reponame>",
677 "repoid" : "<reponame or repo_id>"
485 678 "revision" : "<revision>",
486 679 "root_path" : "<root_path>",
487 "ret_type" : "<ret_type>" = 'all'
680 "ret_type" : "<ret_type> = Optional('all')"
488 681 }
489 682
490 683 OUTPUT::
491 684
685 id : <id_given_in_input>
492 686 result: [
493 687 {
494 688 "name" : "<name>"
@@ -516,18 +710,31 b' INPUT::'
516 710 method : "create_repo"
517 711 args: {
518 712 "repo_name" : "<reponame>",
519 "owner_name" : "<ownername>",
520 "description" : "<description> = ''",
521 "repo_type" : "<type> = 'hg'",
522 "private" : "<bool> = False",
523 "clone_uri" : "<clone_uri> = None",
713 "owner" : "<onwer_name_or_id>",
714 "repo_type" : "<repo_type>",
715 "description" : "<description> = Optional('')",
716 "private" : "<bool> = Optional(False)",
717 "clone_uri" : "<clone_uri> = Optional(None)",
718 "landing_rev" : "<landing_rev> = Optional('tip')",
524 719 }
525 720
526 721 OUTPUT::
527 722
723 id : <id_given_in_input>
528 724 result: {
529 "id": "<newrepoid>",
530 "msg": "Created new repository <reponame>",
725 "msg": "Created new repository `<reponame>`",
726 "repo": {
727 "repo_id" : "<repo_id>",
728 "repo_name" : "<reponame>"
729 "repo_type" : "<repo_type>",
730 "clone_uri" : "<clone_uri>",
731 "private": : "<bool>",
732 "created_on" : "<datetimecreated>",
733 "description" : "<description>",
734 "landing_rev": "<landing_rev>",
735 "owner": "<repo_owner>",
736 "fork_of": "<name_of_fork_parent>",
737 },
531 738 }
532 739 error: null
533 740
@@ -545,13 +752,15 b' INPUT::'
545 752 api_key : "<api_key>"
546 753 method : "delete_repo"
547 754 args: {
548 "repo_name" : "<reponame>",
755 "repoid" : "<reponame or repo_id>"
549 756 }
550 757
551 758 OUTPUT::
552 759
760 id : <id_given_in_input>
553 761 result: {
554 "msg": "Deleted repository <reponame>",
762 "msg": "Deleted repository `<reponame>`",
763 "success": true
555 764 }
556 765 error: null
557 766
@@ -570,15 +779,17 b' INPUT::'
570 779 api_key : "<api_key>"
571 780 method : "grant_user_permission"
572 781 args: {
573 "repo_name" : "<reponame>",
574 "username" : "<username>",
782 "repoid" : "<reponame or repo_id>"
783 "userid" : "<username or user_id>"
575 784 "perm" : "(repository.(none|read|write|admin))",
576 785 }
577 786
578 787 OUTPUT::
579 788
789 id : <id_given_in_input>
580 790 result: {
581 "msg" : "Granted perm: <perm> for user: <username> in repo: <reponame>"
791 "msg" : "Granted perm: `<perm>` for user: `<username>` in repo: `<reponame>`",
792 "success": true
582 793 }
583 794 error: null
584 795
@@ -596,14 +807,16 b' INPUT::'
596 807 api_key : "<api_key>"
597 808 method : "revoke_user_permission"
598 809 args: {
599 "repo_name" : "<reponame>",
600 "username" : "<username>",
810 "repoid" : "<reponame or repo_id>"
811 "userid" : "<username or user_id>"
601 812 }
602 813
603 814 OUTPUT::
604 815
816 id : <id_given_in_input>
605 817 result: {
606 "msg" : "Revoked perm for user: <suername> in repo: <reponame>"
818 "msg" : "Revoked perm for user: `<username>` in repo: `<reponame>`",
819 "success": true
607 820 }
608 821 error: null
609 822
@@ -622,15 +835,17 b' INPUT::'
622 835 api_key : "<api_key>"
623 836 method : "grant_users_group_permission"
624 837 args: {
625 "repo_name" : "<reponame>",
626 "group_name" : "<usersgroupname>",
838 "repoid" : "<reponame or repo_id>"
839 "usersgroupid" : "<users group id or name>"
627 840 "perm" : "(repository.(none|read|write|admin))",
628 841 }
629 842
630 843 OUTPUT::
631 844
845 id : <id_given_in_input>
632 846 result: {
633 "msg" : "Granted perm: <perm> for group: <usersgroupname> in repo: <reponame>"
847 "msg" : "Granted perm: `<perm>` for group: `<usersgroupname>` in repo: `<reponame>`",
848 "success": true
634 849 }
635 850 error: null
636 851
@@ -647,13 +862,15 b' INPUT::'
647 862 api_key : "<api_key>"
648 863 method : "revoke_users_group_permission"
649 864 args: {
650 "repo_name" : "<reponame>",
651 "users_group" : "<usersgroupname>",
865 "repoid" : "<reponame or repo_id>"
866 "usersgroupid" : "<users group id or name>"
652 867 }
653 868
654 869 OUTPUT::
655 870
871 id : <id_given_in_input>
656 872 result: {
657 "msg" : "Revoked perm for group: <usersgroupname> in repo: <reponame>"
873 "msg" : "Revoked perm for group: `<usersgroupname>` in repo: `<reponame>`",
874 "success": true
658 875 }
659 876 error: null No newline at end of file
@@ -4,6 +4,66 b''
4 4 Changelog
5 5 =========
6 6
7 1.4.0 (**2012-09-03**)
8 ----------------------
9
10 news
11 ++++
12
13 - new codereview system
14 - email map, allowing users to have multiple email addresses mapped into
15 their accounts
16 - improved git-hook system. Now all actions for git are logged into journal
17 including pushed revisions, user and IP address
18 - changed setup-app into setup-rhodecode and added default options to it.
19 - new git repos are created as bare now by default
20 - #464 added links to groups in permission box
21 - #465 mentions autocomplete inside comments boxes
22 - #469 added --update-only option to whoosh to re-index only given list
23 of repos in index
24 - rhodecode-api CLI client
25 - new git http protocol replaced buggy dulwich implementation.
26 Now based on pygrack & gitweb
27 - Improved RSS/ATOM feeds. Discoverable by browsers using proper headers, and
28 reformated based on user suggestions. Additional rss/atom feeds for user
29 journal
30 - various i18n improvements
31 - #478 permissions overview for admin in user edit view
32 - File view now displays small gravatars off all authors of given file
33 - Implemented landing revisions. Each repository will get landing_rev attribute
34 that defines 'default' revision/branch for generating readme files
35 - Implemented #509, RhodeCode enforces SSL for push/pulling if requested at
36 earliest possible call.
37 - Import remote svn repositories to mercurial using hgsubversion.
38 - Fixed #508 RhodeCode now has a option to explicitly set forking permissions
39 - RhodeCode can use alternative server for generating avatar icons
40 - implemented repositories locking. Pull locks, push unlocks. Also can be done
41 via API calls
42 - #538 form for permissions can handle multiple users at once
43
44 fixes
45 +++++
46
47 - improved translations
48 - fixes issue #455 Creating an archive generates an exception on Windows
49 - fixes #448 Download ZIP archive keeps file in /tmp open and results
50 in out of disk space
51 - fixes issue #454 Search results under Windows include proceeding
52 backslash
53 - fixed issue #450. Rhodecode no longer will crash when bad revision is
54 present in journal data.
55 - fix for issue #417, git execution was broken on windows for certain
56 commands.
57 - fixed #413. Don't disable .git directory for bare repos on deleting
58 - fixed issue #459. Changed the way of obtaining logger in reindex task.
59 - fixed #453 added ID field in whoosh SCHEMA that solves the issue of
60 reindexing modified files
61 - fixed #481 rhodecode emails are sent without Date header
62 - fixed #458 wrong count when no repos are present
63 - fixed issue #492 missing `\ No newline at end of file` test at the end of
64 new chunk in html diff
65 - full text search now works also for commit messages
66
7 67 1.3.6 (**2012-05-17**)
8 68 ----------------------
9 69
@@ -54,8 +54,8 b" copyright = u'%s, Marcin Kuzminski' % (d"
54 54 # The short X.Y version.
55 55 root = os.path.dirname(os.path.dirname(__file__))
56 56 sys.path.append(root)
57 from rhodecode import get_version, __version__
58 version = get_version()
57 from rhodecode import __version__
58 version = __version__
59 59 # The full version, including alpha/beta/rc tags.
60 60 release = __version__
61 61
@@ -27,7 +27,8 b' enviroment.'
27 27
28 28
29 29 After finishing your changes make sure all tests passes ok. You can run
30 the testsuite running nosetest from the project root.
30 the testsuite running ``nosetest`` from the project root, or if you use tox
31 run tox for python2.5-2.7 with multiple database test.
31 32
32 33 | Thank you for any contributions!
33 34 | Marcin
@@ -21,9 +21,12 b' Users Guide'
21 21
22 22 usage/general
23 23 usage/git_support
24 usage/performance
25 usage/locking
24 26 usage/statistics
25 27 usage/backup
26 28 usage/debugging
29 usage/troubleshooting
27 30
28 31 **Develop**
29 32
@@ -25,13 +25,18 b' Or::'
25 25 pip install rhodecode
26 26
27 27 If you prefer to install RhodeCode manually simply grab latest release from
28 http://pypi.python.org/pypi/rhodecode, decompress the archive and run::
28 http://pypi.python.org/pypi/RhodeCode, decompress the archive and run::
29 29
30 30 python setup.py install
31 31
32 Step by step installation example for Windows
33 ---------------------------------------------
32 34
33 Step by step installation example
34 ---------------------------------
35 :ref:`installation_win`
36
37
38 Step by step installation example for Linux
39 -------------------------------------------
35 40
36 41
37 42 For installing RhodeCode i highly recommend using separate virtualenv_. This
@@ -41,7 +46,7 b' python and making things less problemati'
41 46 - Assuming you have installed virtualenv_ create a new virtual environment
42 47 using virtualenv command::
43 48
44 virtualenv --no-site-packages /var/www/rhodecode-venv
49 virtualenv --no-site-packages /opt/rhodecode-venv
45 50
46 51
47 52 .. note:: Using ``--no-site-packages`` when generating your
@@ -54,10 +59,10 b' python and making things less problemati'
54 59 Python's "main" site-packages dir.
55 60
56 61
57 - this will install new virtualenv_ into `/var/www/rhodecode-venv`.
62 - this will install new virtualenv_ into `/opt/rhodecode-venv`.
58 63 - Activate the virtualenv_ by running::
59 64
60 source /var/www/rhodecode-venv/bin/activate
65 source /opt/rhodecode-venv/bin/activate
61 66
62 67 .. note:: If you're using UNIX, *do not* use ``sudo`` to run the
63 68 ``virtualenv`` script. It's perfectly acceptable (and desirable)
@@ -66,7 +71,7 b' python and making things less problemati'
66 71 - Make a folder for rhodecode data files, and configuration somewhere on the
67 72 filesystem. For example::
68 73
69 mkdir /var/www/rhodecode
74 mkdir /opt/rhodecode
70 75
71 76
72 77 - Go into the created directory run this command to install rhodecode::
@@ -34,6 +34,11 b' entering this "root" path ``setup-rhodec'
34 34 and password for the initial admin account which ``setup-rhodecode`` sets
35 35 up for you.
36 36
37 setup process can be fully automated, example for lazy::
38
39 paster setup-rhodecode production.ini --user=marcink --password=secret --email=marcin@rhodecode.org --repos=/home/marcink/my_repos
40
41
37 42 - The ``setup-rhodecode`` command will create all of the needed tables and an
38 43 admin account. When choosing a root path you can either use a new empty
39 44 location, or a location which already contains existing repositories. If you
@@ -527,6 +532,18 b' Sample config for nginx using proxy::'
527 532 access_log /var/log/nginx/rhodecode.access.log;
528 533 error_log /var/log/nginx/rhodecode.error.log;
529 534
535 # uncomment if you have nginx with chunking module compiled
536 # fixes the issues of having to put postBuffer data for large git
537 # pushes
538 #chunkin on;
539 #error_page 411 = @my_411_error;
540 #location @my_411_error {
541 # chunkin_resume;
542 #}
543
544 # uncomment if you want to serve static files by nginx
545 #root /path/to/installation/rhodecode/public;
546
530 547 location / {
531 548 try_files $uri @rhode;
532 549 }
@@ -682,43 +699,9 b' environment.'
682 699 Other configuration files
683 700 -------------------------
684 701
685 Some example init.d scripts can be found here, for debian and gentoo:
686
687 https://rhodecode.org/rhodecode/files/tip/init.d
688
689
690 Troubleshooting
691 ---------------
692
693 :Q: **Missing static files?**
694 :A: Make sure either to set the `static_files = true` in the .ini file or
695 double check the root path for your http setup. It should point to
696 for example:
697 /home/my-virtual-python/lib/python2.6/site-packages/rhodecode/public
698
699 |
700
701 :Q: **Can't install celery/rabbitmq**
702 :A: Don't worry RhodeCode works without them too. No extra setup is required.
702 Some example init.d scripts can be found in init.d directory::
703 703
704 |
705
706 :Q: **Long lasting push timeouts?**
707 :A: Make sure you set a longer timeouts in your proxy/fcgi settings, timeouts
708 are caused by https server and not RhodeCode.
709
710 |
711
712 :Q: **Large pushes timeouts?**
713 :A: Make sure you set a proper max_body_size for the http server.
714
715 |
716
717 :Q: **Apache doesn't pass basicAuth on pull/push?**
718 :A: Make sure you added `WSGIPassAuthorization true`.
719
720 For further questions search the `Issues tracker`_, or post a message in the
721 `google group rhodecode`_
704 https://secure.rhodecode.org/rhodecode/files/beta/init.d
722 705
723 706 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
724 707 .. _python: http://www.python.org/
@@ -729,4 +712,4 b' For further questions search the `Issues'
729 712 .. _mercurial-server: http://www.lshift.net/mercurial-server.html
730 713 .. _PublishingRepositories: http://mercurial.selenic.com/wiki/PublishingRepositories
731 714 .. _Issues tracker: https://bitbucket.org/marcinkuzminski/rhodecode/issues
732 .. _google group rhodecode: http://groups.google.com/group/rhodecode
715 .. _google group rhodecode: http://groups.google.com/group/rhodecode No newline at end of file
@@ -62,7 +62,6 b' the _<ID> syntax can be used anywhere in'
62 62 for changelogs, files and other can be exchanged with _<ID> syntax.
63 63
64 64
65
66 65 Mailing
67 66 -------
68 67
@@ -82,4 +81,27 b' Trending source files'
82 81 Trending source files are calculated based on pre defined dict of known
83 82 types and extensions. If You miss some extension or Would like to scan some
84 83 custom files it's possible to add new types in `LANGUAGES_EXTENSIONS_MAP` dict
85 located in `/rhodecode/lib/celerylib/tasks.py` No newline at end of file
84 located in `/rhodecode/lib/celerylib/tasks.py`
85
86
87 Cloning remote repositories
88 ---------------------------
89
90 RhodeCode has an ability to clone remote repos from given remote locations.
91 Currently it support following options:
92
93 - hg -> hg clone
94 - svn -> hg clone
95 - git -> git clone
96
97
98 .. note::
99
100 - *`svn -> hg` cloning requires `hgsubversion` library to be installed.*
101
102 If you need to clone repositories that are protected via basic auth, you
103 might pass the url with stored credentials inside eg.
104 `http://user:passw@remote.server/repo, RhodeCode will try to login and clone
105 using given credentials. Please take a note that they will be stored as
106 plaintext inside the database. RhodeCode will remove auth info when showing the
107 clone url in summary page.
@@ -5,11 +5,13 b' GIT support'
5 5 ===========
6 6
7 7
8 Git support in RhodeCode 1.3 was enabled by default.
8 Git support in RhodeCode 1.3 was enabled by default. You need to have a git
9 client installed on the machine to make git fully work.
10
9 11 Although There are some limitations on git usage.
10 12
11 - No hooks are runned for git push/pull actions.
12 - logs in action journals don't have git operations
13 - hooks that are executed on pull/push are not *real* hooks, they are
14 just emulating the behavior, and are executed **BEFORE** action takes place.
13 15 - large pushes needs http server with chunked encoding support.
14 16
15 17 if you plan to use git you need to run RhodeCode with some
@@ -17,14 +19,19 b' http server that supports chunked encodi'
17 19 i recommend using waitress_ or gunicorn_ (linux only) for `paste` wsgi app
18 20 replacement.
19 21
20 To use waitress simply change change the following in the .ini file::
22 To use, simply change change the following in the .ini file::
21 23
22 24 use = egg:Paste#http
23 25
24 To::
26 to::
25 27
26 28 use = egg:waitress#main
27 29
30 or::
31
32 use = egg:gunicorn#main
33
34
28 35 And comment out bellow options::
29 36
30 37 threadpool_workers =
@@ -30,22 +30,31 b' pdebug = false'
30 30
31 31 [server:main]
32 32 ##nr of threads to spawn
33 threadpool_workers = 5
33 #threadpool_workers = 5
34 34
35 35 ##max request before thread respawn
36 threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37 37
38 38 ##option to use threads of process
39 use_threadpool = true
39 #use_threadpool = true
40 40
41 use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 43 host = 127.0.0.1
43 44 port = 8001
44 45
46 [filter:proxy-prefix]
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
50
45 51 [app:main]
46 52 use = egg:rhodecode
53 #filter-with = proxy-prefix
47 54 full_stack = true
48 55 static_files = true
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
49 58 lang = en
50 59 cache_dir = %(here)s/data
51 60 index_dir = %(here)s/data/index
@@ -54,6 +63,15 b' cut_off_limit = 256000'
54 63 force_https = false
55 64 commit_parse_limit = 50
56 65 use_gravatar = true
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
72 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
73 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
74
57 75 container_auth_enabled = false
58 76 proxypass_auth_enabled = false
59 77 default_encoding = utf8
@@ -78,7 +96,8 b' default_encoding = utf8'
78 96 issue_pat = (?:\s*#)(\d+)
79 97
80 98 ## server url to the issue, each {id} will be replaced with match
81 ## fetched from the regex and {repo} is replaced with repository name
99 ## fetched from the regex and {repo} is replaced with full repository name
100 ## including groups {repo_name} is replaced with just name of repo
82 101
83 102 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
84 103
@@ -165,30 +184,34 b' beaker.cache.sql_cache_long.key_length ='
165 184 ## The storage uses the Container API
166 185 ## that is also used by the cache system.
167 186
168 ## db session example
169
187 ## db session ##
170 188 #beaker.session.type = ext:database
171 189 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
172 190 #beaker.session.table_name = db_session
173 191
174 ## encrypted cookie session, good for many instances
192 ## encrypted cookie client side session, good for many instances ##
175 193 #beaker.session.type = cookie
176 194
177 beaker.session.type = file
195 ## file based cookies (default) ##
196 #beaker.session.type = file
197
198
178 199 beaker.session.key = rhodecode
179 # secure cookie requires AES python libraries
200 ## secure cookie requires AES python libraries ##
180 201 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
181 202 #beaker.session.validate_key = 9712sds2212c--zxc123
182 beaker.session.timeout = 36000
203 ## sets session as invalid if it haven't been accessed for given amount of time
204 beaker.session.timeout = 2592000
183 205 beaker.session.httponly = true
206 #beaker.session.cookie_path = /<your-prefix>
184 207
185 ## uncomment for https secure cookie
208 ## uncomment for https secure cookie ##
186 209 beaker.session.secure = false
187 210
188 ##auto save the session to not to use .save()
211 ## auto save the session to not to use .save() ##
189 212 beaker.session.auto = False
190 213
191 ##true exire at browser close
214 ## default cookie expiration time in seconds `true` expire at browser close ##
192 215 #beaker.session.cookie_expires = 3600
193 216
194 217
@@ -1,18 +1,20 b''
1 waitress==0.8.1
2 webob==1.0.8
1 3 Pylons==1.0.0
2 Beaker==1.6.3
4 Beaker==1.6.4
3 5 WebHelpers==1.3
4 6 formencode==1.2.4
5 SQLAlchemy==0.7.6
6 Mako==0.7.0
7 pygments>=1.4
7 SQLAlchemy==0.7.8
8 Mako==0.7.2
9 pygments>=1.5
8 10 whoosh>=2.4.0,<2.5
9 11 celery>=2.2.5,<2.3
10 12 babel
11 13 python-dateutil>=1.5.0,<2.0.0
12 14 dulwich>=0.8.5,<0.9.0
13 webob==1.0.8
14 15 markdown==2.1.1
15 16 docutils==0.8.1
16 17 simplejson==2.5.2
18 mock
17 19 py-bcrypt
18 mercurial>=2.2.1,<2.3 No newline at end of file
20 mercurial>=2.3.0,<2.4 No newline at end of file
@@ -26,7 +26,7 b''
26 26 import sys
27 27 import platform
28 28
29 VERSION = (1, 3, 6)
29 VERSION = (1, 4, 0)
30 30
31 31 try:
32 32 from rhodecode.lib import get_current_revision
@@ -38,50 +38,19 b' except ImportError:'
38 38
39 39 __version__ = ('.'.join((str(each) for each in VERSION[:3])) +
40 40 '.'.join(VERSION[3:]))
41 __dbversion__ = 5 # defines current db version for migrations
41 __dbversion__ = 6 # defines current db version for migrations
42 42 __platform__ = platform.system()
43 43 __license__ = 'GPLv3'
44 44 __py_version__ = sys.version_info
45 __author__ = 'Marcin Kuzminski'
46 __url__ = 'http://rhodecode.org'
45 47
46 48 PLATFORM_WIN = ('Windows')
47 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
49 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS') #depracated
48 50
49 51 is_windows = __platform__ in PLATFORM_WIN
50 is_unix = __platform__ in PLATFORM_OTHERS
52 is_unix = not is_windows
51 53
52 requirements = [
53 "Pylons==1.0.0",
54 "Beaker==1.6.3",
55 "WebHelpers==1.3",
56 "formencode==1.2.4",
57 "SQLAlchemy==0.7.6",
58 "Mako==0.7.0",
59 "pygments>=1.4",
60 "whoosh>=2.4.0,<2.5",
61 "celery>=2.2.5,<2.3",
62 "babel",
63 "python-dateutil>=1.5.0,<2.0.0",
64 "dulwich>=0.8.5,<0.9.0",
65 "webob==1.0.8",
66 "markdown==2.1.1",
67 "docutils==0.8.1",
68 "simplejson==2.5.2",
69 ]
70
71 if __py_version__ < (2, 6):
72 requirements.append("pysqlite")
73
74 if is_windows:
75 requirements.append("mercurial>=2.2.1,<2.3")
76 else:
77 requirements.append("py-bcrypt")
78 requirements.append("mercurial>=2.2.1,<2.3")
79
80
81 def get_version():
82 """Returns shorter version (digit parts only) as string."""
83
84 return '.'.join((str(each) for each in VERSION[:3]))
85 54
86 55 BACKENDS = {
87 56 'hg': 'Mercurial repository',
@@ -1,9 +1,9 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 rhodecode.lib.backup_manager
3 rhodecode.bin.backup_manager
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 Mercurial repositories backup manager, it allows to backups all
6 Repositories backup manager, it allows to backups all
7 7 repositories and send it to backup server using RSA key via ssh.
8 8
9 9 :created_on: Feb 28, 2010
@@ -39,7 +39,7 b' logging.basicConfig(level=logging.DEBUG,'
39 39 class BackupManager(object):
40 40 def __init__(self, repos_location, rsa_key, backup_server):
41 41 today = datetime.datetime.now().weekday() + 1
42 self.backup_file_name = "mercurial_repos.%s.tar.gz" % today
42 self.backup_file_name = "rhodecode_repos.%s.tar.gz" % today
43 43
44 44 self.id_rsa_path = self.get_id_rsa(rsa_key)
45 45 self.repos_path = self.get_repos_path(repos_location)
@@ -30,22 +30,31 b' pdebug = false'
30 30
31 31 [server:main]
32 32 ##nr of threads to spawn
33 threadpool_workers = 5
33 #threadpool_workers = 5
34 34
35 35 ##max request before thread respawn
36 threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37 37
38 38 ##option to use threads of process
39 use_threadpool = true
39 #use_threadpool = true
40 40
41 use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 43 host = 127.0.0.1
43 44 port = 5000
44 45
46 [filter:proxy-prefix]
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
50
45 51 [app:main]
46 52 use = egg:rhodecode
53 #filter-with = proxy-prefix
47 54 full_stack = true
48 55 static_files = true
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
49 58 lang = en
50 59 cache_dir = %(here)s/data
51 60 index_dir = %(here)s/data/index
@@ -54,6 +63,15 b' cut_off_limit = 256000'
54 63 force_https = false
55 64 commit_parse_limit = 50
56 65 use_gravatar = true
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
72 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
73 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
74
57 75 container_auth_enabled = false
58 76 proxypass_auth_enabled = false
59 77 default_encoding = utf8
@@ -78,7 +96,8 b' default_encoding = utf8'
78 96 issue_pat = (?:\s*#)(\d+)
79 97
80 98 ## server url to the issue, each {id} will be replaced with match
81 ## fetched from the regex and {repo} is replaced with repository name
99 ## fetched from the regex and {repo} is replaced with full repository name
100 ## including groups {repo_name} is replaced with just name of repo
82 101
83 102 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
84 103
@@ -165,30 +184,34 b' beaker.cache.sql_cache_long.key_length ='
165 184 ## The storage uses the Container API
166 185 ## that is also used by the cache system.
167 186
168 ## db session example
169
187 ## db session ##
170 188 #beaker.session.type = ext:database
171 189 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
172 190 #beaker.session.table_name = db_session
173 191
174 ## encrypted cookie session, good for many instances
192 ## encrypted cookie client side session, good for many instances ##
175 193 #beaker.session.type = cookie
176 194
177 beaker.session.type = file
195 ## file based cookies (default) ##
196 #beaker.session.type = file
197
198
178 199 beaker.session.key = rhodecode
179 # secure cookie requires AES python libraries
180 #beaker.session.encrypt_key = ${app_instance_secret}
181 #beaker.session.validate_key = ${app_instance_secret}
182 beaker.session.timeout = 36000
200 ## secure cookie requires AES python libraries ##
201 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
202 #beaker.session.validate_key = 9712sds2212c--zxc123
203 ## sets session as invalid if it haven't been accessed for given amount of time
204 beaker.session.timeout = 2592000
183 205 beaker.session.httponly = true
206 #beaker.session.cookie_path = /<your-prefix>
184 207
185 ## uncomment for https secure cookie
208 ## uncomment for https secure cookie ##
186 209 beaker.session.secure = false
187 210
188 ##auto save the session to not to use .save()
211 ## auto save the session to not to use .save() ##
189 212 beaker.session.auto = False
190 213
191 ##true exire at browser close
214 ## default cookie expiration time in seconds `true` expire at browser close ##
192 215 #beaker.session.cookie_expires = 3600
193 216
194 217
@@ -72,19 +72,28 b' def load_environment(global_conf, app_co'
72 72 config['pylons.strict_tmpl_context'] = True
73 73 test = os.path.split(config['__file__'])[-1] == 'test.ini'
74 74 if test:
75 if os.environ.get('TEST_DB'):
76 # swap config if we pass enviroment variable
77 config['sqlalchemy.db1.url'] = os.environ.get('TEST_DB')
78
75 79 from rhodecode.lib.utils import create_test_env, create_test_index
76 80 from rhodecode.tests import TESTS_TMP_PATH
77 create_test_env(TESTS_TMP_PATH, config)
78 create_test_index(TESTS_TMP_PATH, config, True)
81 # set RC_NO_TMP_PATH=1 to disable re-creating the database and
82 # test repos
83 if not int(os.environ.get('RC_NO_TMP_PATH', 0)):
84 create_test_env(TESTS_TMP_PATH, config)
85 # set RC_WHOOSH_TEST_DISABLE=1 to disable whoosh index during tests
86 if not int(os.environ.get('RC_WHOOSH_TEST_DISABLE', 0)):
87 create_test_index(TESTS_TMP_PATH, config, True)
79 88
80 89 # MULTIPLE DB configs
81 90 # Setup the SQLAlchemy database engine
82 91 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
83
84 92 init_model(sa_engine_db1)
85 93
86 94 repos_path = make_ui('db').configitems('paths')[0][1]
87 repo2db_mapper(ScmModel().repo_scan(repos_path))
95 repo2db_mapper(ScmModel().repo_scan(repos_path),
96 remove_obsolete=False, install_git_hook=False)
88 97 set_available_permissions(config)
89 98 config['base_path'] = repos_path
90 99 set_rhodecode_config(config)
@@ -1,6 +1,7 b''
1 1 # Additional mappings that are not present in the pygments lexers
2 2 # used for building stats
3 # format is {'ext':'Name'} eg. {'py':'Python'}
3 # format is {'ext':['Names']} eg. {'py':['Python']} note: there can be
4 # more than one name for extension
4 5 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
5 6 # build by pygments
6 7 EXTRA_MAPPINGS = {}
@@ -39,6 +40,7 b' def _crhook(*args, **kwargs):'
39 40 :param group_id:
40 41 :param created_by:
41 42 """
43
42 44 return 0
43 45 CREATE_REPO_HOOK = _crhook
44 46
@@ -54,7 +54,7 b' class MakeRcExt(BasePasterCommand):'
54 54 logging.config.fileConfig(self.path_to_ini_file)
55 55 from pylons import config
56 56
57 def _make_file(ext_file):
57 def _make_file(ext_file, tmpl):
58 58 bdir = os.path.split(ext_file)[0]
59 59 if not os.path.isdir(bdir):
60 60 os.makedirs(bdir)
@@ -71,11 +71,11 b' class MakeRcExt(BasePasterCommand):'
71 71 msg = ('Extension file already exists, do you want '
72 72 'to overwrite it ? [y/n]')
73 73 if ask_ok(msg):
74 _make_file(ext_file)
74 _make_file(ext_file, tmpl)
75 75 else:
76 76 log.info('nothing done...')
77 77 else:
78 _make_file(ext_file)
78 _make_file(ext_file, tmpl)
79 79
80 80 def update_parser(self):
81 81 pass
@@ -69,7 +69,7 b' def make_map(config):'
69 69 rmap.connect('home', '/', controller='home', action='index')
70 70 rmap.connect('repo_switcher', '/repos', controller='home',
71 71 action='repo_switcher')
72 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}',
72 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
73 73 controller='home', action='branch_tag_switcher')
74 74 rmap.connect('bugtracker',
75 75 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
@@ -93,52 +93,54 b' def make_map(config):'
93 93 action="new", conditions=dict(method=["GET"]))
94 94 m.connect("formatted_new_repo", "/repos/new.{format}",
95 95 action="new", conditions=dict(method=["GET"]))
96 m.connect("/repos/{repo_name:.*}",
96 m.connect("/repos/{repo_name:.*?}",
97 97 action="update", conditions=dict(method=["PUT"],
98 98 function=check_repo))
99 m.connect("/repos/{repo_name:.*}",
99 m.connect("/repos/{repo_name:.*?}",
100 100 action="delete", conditions=dict(method=["DELETE"],
101 101 function=check_repo))
102 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
102 m.connect("edit_repo", "/repos/{repo_name:.*?}/edit",
103 103 action="edit", conditions=dict(method=["GET"],
104 104 function=check_repo))
105 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
105 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
106 106 action="edit", conditions=dict(method=["GET"],
107 107 function=check_repo))
108 m.connect("repo", "/repos/{repo_name:.*}",
108 m.connect("repo", "/repos/{repo_name:.*?}",
109 109 action="show", conditions=dict(method=["GET"],
110 110 function=check_repo))
111 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
111 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
112 112 action="show", conditions=dict(method=["GET"],
113 113 function=check_repo))
114 114 #ajax delete repo perm user
115 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
115 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*?}",
116 116 action="delete_perm_user",
117 117 conditions=dict(method=["DELETE"], function=check_repo))
118 118
119 119 #ajax delete repo perm users_group
120 120 m.connect('delete_repo_users_group',
121 "/repos_delete_users_group/{repo_name:.*}",
121 "/repos_delete_users_group/{repo_name:.*?}",
122 122 action="delete_perm_users_group",
123 123 conditions=dict(method=["DELETE"], function=check_repo))
124 124
125 125 #settings actions
126 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
126 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
127 127 action="repo_stats", conditions=dict(method=["DELETE"],
128 128 function=check_repo))
129 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
129 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
130 130 action="repo_cache", conditions=dict(method=["DELETE"],
131 131 function=check_repo))
132 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}",
132 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
133 133 action="repo_public_journal", conditions=dict(method=["PUT"],
134 134 function=check_repo))
135 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
135 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
136 136 action="repo_pull", conditions=dict(method=["PUT"],
137 137 function=check_repo))
138 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}",
138 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
139 139 action="repo_as_fork", conditions=dict(method=["PUT"],
140 140 function=check_repo))
141
141 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
142 action="repo_locking", conditions=dict(method=["PUT"],
143 function=check_repo))
142 144 with rmap.submapper(path_prefix=ADMIN_PREFIX,
143 145 controller='admin/repos_groups') as m:
144 146 m.connect("repos_groups", "/repos_groups",
@@ -157,9 +159,8 b' def make_map(config):'
157 159 m.connect("delete_repos_group", "/repos_groups/{id}",
158 160 action="delete", conditions=dict(method=["DELETE"],
159 161 function=check_int))
160 m.connect("edit_repos_group", "/repos_groups/{id}/edit",
161 action="edit", conditions=dict(method=["GET"],
162 function=check_int))
162 m.connect("edit_repos_group", "/repos_groups/{id:.*?}/edit",
163 action="edit", conditions=dict(method=["GET"],))
163 164 m.connect("formatted_edit_repos_group",
164 165 "/repos_groups/{id}.{format}/edit",
165 166 action="edit", conditions=dict(method=["GET"],
@@ -212,8 +213,12 b' def make_map(config):'
212 213 #EXTRAS USER ROUTES
213 214 m.connect("user_perm", "/users_perm/{id}",
214 215 action="update_perm", conditions=dict(method=["PUT"]))
216 m.connect("user_emails", "/users_emails/{id}",
217 action="add_email", conditions=dict(method=["PUT"]))
218 m.connect("user_emails_delete", "/users_emails/{id}",
219 action="delete_email", conditions=dict(method=["DELETE"]))
215 220
216 #ADMIN USERS REST ROUTES
221 #ADMIN USERS GROUPS REST ROUTES
217 222 with rmap.submapper(path_prefix=ADMIN_PREFIX,
218 223 controller='admin/users_groups') as m:
219 224 m.connect("users_groups", "/users_groups",
@@ -292,6 +297,10 b' def make_map(config):'
292 297 action="my_account_update", conditions=dict(method=["PUT"]))
293 298 m.connect("admin_settings_create_repository", "/create_repository",
294 299 action="create_repository", conditions=dict(method=["GET"]))
300 m.connect("admin_settings_my_repos", "/my_account/repos",
301 action="my_account_my_repos", conditions=dict(method=["GET"]))
302 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
303 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
295 304
296 305 #NOTIFICATION REST ROUTES
297 306 with rmap.submapper(path_prefix=ADMIN_PREFIX,
@@ -337,15 +346,27 b' def make_map(config):'
337 346 m.connect('api', '/api')
338 347
339 348 #USER JOURNAL
340 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, controller='journal')
349 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
350 controller='journal', action='index')
351 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
352 controller='journal', action='journal_rss')
353 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
354 controller='journal', action='journal_atom')
341 355
342 356 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
343 357 controller='journal', action="public_journal")
344 358
345 rmap.connect('public_journal_rss', '%s/public_journal_rss' % ADMIN_PREFIX,
359 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
360 controller='journal', action="public_journal_rss")
361
362 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
346 363 controller='journal', action="public_journal_rss")
347 364
348 365 rmap.connect('public_journal_atom',
366 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
367 action="public_journal_atom")
368
369 rmap.connect('public_journal_atom_old',
349 370 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
350 371 action="public_journal_atom")
351 372
@@ -374,18 +395,18 b' def make_map(config):'
374 395 controller='login', action='password_reset_confirmation')
375 396
376 397 #FEEDS
377 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
398 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
378 399 controller='feed', action='rss',
379 400 conditions=dict(function=check_repo))
380 401
381 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
402 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
382 403 controller='feed', action='atom',
383 404 conditions=dict(function=check_repo))
384 405
385 406 #==========================================================================
386 407 # REPOSITORY ROUTES
387 408 #==========================================================================
388 rmap.connect('summary_home', '/{repo_name:.*}',
409 rmap.connect('summary_home', '/{repo_name:.*?}',
389 410 controller='summary',
390 411 conditions=dict(function=check_repo))
391 412
@@ -393,114 +414,166 b' def make_map(config):'
393 414 controller='admin/repos_groups', action="show_by_name",
394 415 conditions=dict(function=check_group))
395 416
396 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
417 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
397 418 controller='changeset', revision='tip',
398 419 conditions=dict(function=check_repo))
399 420
400 421 rmap.connect('changeset_comment',
401 '/{repo_name:.*}/changeset/{revision}/comment',
422 '/{repo_name:.*?}/changeset/{revision}/comment',
402 423 controller='changeset', revision='tip', action='comment',
403 424 conditions=dict(function=check_repo))
404 425
405 426 rmap.connect('changeset_comment_delete',
406 '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
427 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
407 428 controller='changeset', action='delete_comment',
408 429 conditions=dict(function=check_repo, method=["DELETE"]))
409 430
410 431 rmap.connect('raw_changeset_home',
411 '/{repo_name:.*}/raw-changeset/{revision}',
432 '/{repo_name:.*?}/raw-changeset/{revision}',
412 433 controller='changeset', action='raw_changeset',
413 434 revision='tip', conditions=dict(function=check_repo))
414 435
415 rmap.connect('summary_home', '/{repo_name:.*}/summary',
436 rmap.connect('compare_url',
437 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref}...{other_ref_type}@{other_ref}',
438 controller='compare', action='index',
439 conditions=dict(function=check_repo),
440 requirements=dict(
441 org_ref_type='(branch|book|tag|rev|org_ref_type)',
442 other_ref_type='(branch|book|tag|rev|other_ref_type)')
443 )
444
445 rmap.connect('pullrequest_home',
446 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
447 action='index', conditions=dict(function=check_repo,
448 method=["GET"]))
449
450 rmap.connect('pullrequest',
451 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
452 action='create', conditions=dict(function=check_repo,
453 method=["POST"]))
454
455 rmap.connect('pullrequest_show',
456 '/{repo_name:.*?}/pull-request/{pull_request_id}',
457 controller='pullrequests',
458 action='show', conditions=dict(function=check_repo,
459 method=["GET"]))
460 rmap.connect('pullrequest_update',
461 '/{repo_name:.*?}/pull-request/{pull_request_id}',
462 controller='pullrequests',
463 action='update', conditions=dict(function=check_repo,
464 method=["PUT"]))
465 rmap.connect('pullrequest_delete',
466 '/{repo_name:.*?}/pull-request/{pull_request_id}',
467 controller='pullrequests',
468 action='delete', conditions=dict(function=check_repo,
469 method=["DELETE"]))
470
471 rmap.connect('pullrequest_show_all',
472 '/{repo_name:.*?}/pull-request',
473 controller='pullrequests',
474 action='show_all', conditions=dict(function=check_repo,
475 method=["GET"]))
476
477 rmap.connect('pullrequest_comment',
478 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
479 controller='pullrequests',
480 action='comment', conditions=dict(function=check_repo,
481 method=["POST"]))
482
483 rmap.connect('pullrequest_comment_delete',
484 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
485 controller='pullrequests', action='delete_comment',
486 conditions=dict(function=check_repo, method=["DELETE"]))
487
488 rmap.connect('summary_home', '/{repo_name:.*?}/summary',
416 489 controller='summary', conditions=dict(function=check_repo))
417 490
418 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
491 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
419 492 controller='shortlog', conditions=dict(function=check_repo))
420 493
421 rmap.connect('branches_home', '/{repo_name:.*}/branches',
494 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
422 495 controller='branches', conditions=dict(function=check_repo))
423 496
424 rmap.connect('tags_home', '/{repo_name:.*}/tags',
497 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
425 498 controller='tags', conditions=dict(function=check_repo))
426 499
427 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
500 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
428 501 controller='bookmarks', conditions=dict(function=check_repo))
429 502
430 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
503 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
431 504 controller='changelog', conditions=dict(function=check_repo))
432 505
433 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
506 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
434 507 controller='changelog', action='changelog_details',
435 508 conditions=dict(function=check_repo))
436 509
437 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
510 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
438 511 controller='files', revision='tip', f_path='',
439 512 conditions=dict(function=check_repo))
440 513
441 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
514 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
442 515 controller='files', action='diff', revision='tip', f_path='',
443 516 conditions=dict(function=check_repo))
444 517
445 518 rmap.connect('files_rawfile_home',
446 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
519 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
447 520 controller='files', action='rawfile', revision='tip',
448 521 f_path='', conditions=dict(function=check_repo))
449 522
450 523 rmap.connect('files_raw_home',
451 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
524 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
452 525 controller='files', action='raw', revision='tip', f_path='',
453 526 conditions=dict(function=check_repo))
454 527
455 528 rmap.connect('files_annotate_home',
456 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
529 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
457 530 controller='files', action='index', revision='tip',
458 531 f_path='', annotate=True, conditions=dict(function=check_repo))
459 532
460 533 rmap.connect('files_edit_home',
461 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
534 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
462 535 controller='files', action='edit', revision='tip',
463 536 f_path='', conditions=dict(function=check_repo))
464 537
465 538 rmap.connect('files_add_home',
466 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
539 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
467 540 controller='files', action='add', revision='tip',
468 541 f_path='', conditions=dict(function=check_repo))
469 542
470 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
543 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
471 544 controller='files', action='archivefile',
472 545 conditions=dict(function=check_repo))
473 546
474 547 rmap.connect('files_nodelist_home',
475 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
548 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
476 549 controller='files', action='nodelist',
477 550 conditions=dict(function=check_repo))
478 551
479 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
552 rmap.connect('repo_settings_delete', '/{repo_name:.*?}/settings',
480 553 controller='settings', action="delete",
481 554 conditions=dict(method=["DELETE"], function=check_repo))
482 555
483 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
556 rmap.connect('repo_settings_update', '/{repo_name:.*?}/settings',
484 557 controller='settings', action="update",
485 558 conditions=dict(method=["PUT"], function=check_repo))
486 559
487 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
560 rmap.connect('repo_settings_home', '/{repo_name:.*?}/settings',
488 561 controller='settings', action='index',
489 562 conditions=dict(function=check_repo))
490 563
491 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
564 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
492 565 controller='forks', action='fork_create',
493 566 conditions=dict(function=check_repo, method=["POST"]))
494 567
495 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
568 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
496 569 controller='forks', action='fork',
497 570 conditions=dict(function=check_repo))
498 571
499 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
572 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
500 573 controller='forks', action='forks',
501 574 conditions=dict(function=check_repo))
502 575
503 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
576 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
504 577 controller='followers', action='followers',
505 578 conditions=dict(function=check_repo))
506 579
@@ -45,7 +45,7 b' class AdminController(BaseController):'
45 45 @HasPermissionAllDecorator('hg.admin')
46 46 def index(self):
47 47
48 users_log = self.sa.query(UserLog)\
48 users_log = UserLog.query()\
49 49 .options(joinedload(UserLog.user))\
50 50 .options(joinedload(UserLog.repository))\
51 51 .order_by(UserLog.action_date.desc())
@@ -40,6 +40,7 b' from rhodecode.lib.auth import LoginRequ'
40 40 from rhodecode.lib.exceptions import LdapImportError
41 41 from rhodecode.model.forms import LdapSettingsForm
42 42 from rhodecode.model.db import RhodeCodeSetting
43 from rhodecode.model.meta import Session
43 44
44 45 log = logging.getLogger(__name__)
45 46
@@ -119,9 +120,9 b' class LdapSettingsController(BaseControl'
119 120 v = ldap_active
120 121 setting = RhodeCodeSetting.get_by_name(k)
121 122 setting.app_settings_value = v
122 self.sa.add(setting)
123 Session().add(setting)
123 124
124 self.sa.commit()
125 Session().commit()
125 126 h.flash(_('Ldap settings updated successfully'),
126 127 category='success')
127 128 if not ldap_active:
@@ -60,19 +60,33 b' class NotificationsController(BaseContro'
60 60 """GET /_admin/notifications: All items in the collection"""
61 61 # url('notifications')
62 62 c.user = self.rhodecode_user
63 notif = NotificationModel().get_for_user(self.rhodecode_user.user_id)
63 notif = NotificationModel().get_for_user(self.rhodecode_user.user_id,
64 filter_=request.GET.getall('type'))
64 65 p = int(request.params.get('page', 1))
65 66 c.notifications = Page(notif, page=p, items_per_page=10)
67 c.pull_request_type = Notification.TYPE_PULL_REQUEST
68 c.comment_type = [Notification.TYPE_CHANGESET_COMMENT,
69 Notification.TYPE_PULL_REQUEST_COMMENT]
70
71 _current_filter = request.GET.getall('type')
72 c.current_filter = 'all'
73 if _current_filter == [c.pull_request_type]:
74 c.current_filter = 'pull_request'
75 elif _current_filter == c.comment_type:
76 c.current_filter = 'comment'
77
66 78 return render('admin/notifications/notifications.html')
67 79
68 80 def mark_all_read(self):
69 81 if request.environ.get('HTTP_X_PARTIAL_XHR'):
70 82 nm = NotificationModel()
71 83 # mark all read
72 nm.mark_all_read_for_user(self.rhodecode_user.user_id)
73 Session.commit()
84 nm.mark_all_read_for_user(self.rhodecode_user.user_id,
85 filter_=request.GET.getall('type'))
86 Session().commit()
74 87 c.user = self.rhodecode_user
75 notif = nm.get_for_user(self.rhodecode_user.user_id)
88 notif = nm.get_for_user(self.rhodecode_user.user_id,
89 filter_=request.GET.getall('type'))
76 90 c.notifications = Page(notif, page=1, items_per_page=10)
77 91 return render('admin/notifications/notifications_data.html')
78 92
@@ -92,6 +106,18 b' class NotificationsController(BaseContro'
92 106 # h.form(url('notification', notification_id=ID),
93 107 # method='put')
94 108 # url('notification', notification_id=ID)
109 try:
110 no = Notification.get(notification_id)
111 owner = lambda: (no.notifications_to_users.user.user_id
112 == c.rhodecode_user.user_id)
113 if h.HasPermissionAny('hg.admin')() or owner:
114 NotificationModel().mark_read(c.rhodecode_user.user_id, no)
115 Session().commit()
116 return 'ok'
117 except Exception:
118 Session.rollback()
119 log.error(traceback.format_exc())
120 return 'fail'
95 121
96 122 def delete(self, notification_id):
97 123 """DELETE /_admin/notifications/id: Delete an existing item"""
@@ -106,9 +132,9 b' class NotificationsController(BaseContro'
106 132 no = Notification.get(notification_id)
107 133 owner = lambda: (no.notifications_to_users.user.user_id
108 134 == c.rhodecode_user.user_id)
109 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
135 if h.HasPermissionAny('hg.admin')() or owner:
110 136 NotificationModel().delete(c.rhodecode_user.user_id, no)
111 Session.commit()
137 Session().commit()
112 138 return 'ok'
113 139 except Exception:
114 140 Session.rollback()
@@ -132,7 +158,7 b' class NotificationsController(BaseContro'
132 158 if unotification:
133 159 if unotification.read is False:
134 160 unotification.mark_as_read()
135 Session.commit()
161 Session().commit()
136 162 c.notification = no
137 163
138 164 return render('admin/notifications/show_notification.html')
@@ -71,6 +71,15 b' class PermissionsController(BaseControll'
71 71 self.create_choices = [('hg.create.none', _('Disabled')),
72 72 ('hg.create.repository', _('Enabled'))]
73 73
74 self.fork_choices = [('hg.fork.none', _('Disabled')),
75 ('hg.fork.repository', _('Enabled'))]
76
77 # set the global template variables
78 c.perms_choices = self.perms_choices
79 c.register_choices = self.register_choices
80 c.create_choices = self.create_choices
81 c.fork_choices = self.fork_choices
82
74 83 def index(self, format='html'):
75 84 """GET /permissions: All items in the collection"""
76 85 # url('permissions')
@@ -96,20 +105,18 b' class PermissionsController(BaseControll'
96 105
97 106 _form = DefaultPermissionsForm([x[0] for x in self.perms_choices],
98 107 [x[0] for x in self.register_choices],
99 [x[0] for x in self.create_choices])()
108 [x[0] for x in self.create_choices],
109 [x[0] for x in self.fork_choices])()
100 110
101 111 try:
102 112 form_result = _form.to_python(dict(request.POST))
103 113 form_result.update({'perm_user_name': id})
104 114 permission_model.update(form_result)
105 Session.commit()
115 Session().commit()
106 116 h.flash(_('Default permissions updated successfully'),
107 117 category='success')
108 118
109 119 except formencode.Invalid, errors:
110 c.perms_choices = self.perms_choices
111 c.register_choices = self.register_choices
112 c.create_choices = self.create_choices
113 120 defaults = errors.value
114 121
115 122 return htmlfill.render(
@@ -141,10 +148,8 b' class PermissionsController(BaseControll'
141 148 def edit(self, id, format='html'):
142 149 """GET /permissions/id/edit: Form to edit an existing item"""
143 150 #url('edit_permission', id=ID)
144 c.perms_choices = self.perms_choices
145 c.register_choices = self.register_choices
146 c.create_choices = self.create_choices
147 151
152 #this form can only edit default user permissions
148 153 if id == 'default':
149 154 default_user = User.get_by_username('default')
150 155 defaults = {'_method': 'put',
@@ -160,10 +165,14 b' class PermissionsController(BaseControll'
160 165 if p.permission.permission_name.startswith('hg.create.'):
161 166 defaults['default_create'] = p.permission.permission_name
162 167
168 if p.permission.permission_name.startswith('hg.fork.'):
169 defaults['default_fork'] = p.permission.permission_name
170
163 171 return htmlfill.render(
164 render('admin/permissions/permissions.html'),
165 defaults=defaults,
166 encoding="UTF-8",
167 force_defaults=True,)
172 render('admin/permissions/permissions.html'),
173 defaults=defaults,
174 encoding="UTF-8",
175 force_defaults=True,
176 )
168 177 else:
169 178 return redirect(url('admin_home'))
@@ -28,12 +28,13 b' import traceback'
28 28 import formencode
29 29 from formencode import htmlfill
30 30
31 from paste.httpexceptions import HTTPInternalServerError
31 from webob.exc import HTTPInternalServerError
32 32 from pylons import request, session, tmpl_context as c, url
33 33 from pylons.controllers.util import redirect
34 34 from pylons.i18n.translation import _
35 35 from sqlalchemy.exc import IntegrityError
36 36
37 import rhodecode
37 38 from rhodecode.lib import helpers as h
38 39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
39 40 HasPermissionAnyDecorator, HasRepoPermissionAllDecorator
@@ -45,6 +46,7 b' from rhodecode.model.db import User, Rep'
45 46 from rhodecode.model.forms import RepoForm
46 47 from rhodecode.model.scm import ScmModel
47 48 from rhodecode.model.repo import RepoModel
49 from rhodecode.lib.compat import json
48 50
49 51 log = logging.getLogger(__name__)
50 52
@@ -70,6 +72,8 b' class ReposController(BaseController):'
70 72 repo_model = RepoModel()
71 73 c.users_array = repo_model.get_users_js()
72 74 c.users_groups_array = repo_model.get_users_groups_js()
75 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
76 c.landing_revs_choices = choices
73 77
74 78 def __load_data(self, repo_name=None):
75 79 """
@@ -91,6 +95,9 b' class ReposController(BaseController):'
91 95
92 96 return redirect(url('repos'))
93 97
98 choices, c.landing_revs = ScmModel().get_repo_landing_revs(c.repo_info)
99 c.landing_revs_choices = choices
100
94 101 c.default_user_id = User.get_by_username('default').user_id
95 102 c.in_public_journal = UserFollowing.query()\
96 103 .filter(UserFollowing.user_id == c.default_user_id)\
@@ -115,7 +122,10 b' class ReposController(BaseController):'
115 122
116 123 c.repos_list = [('', _('--REMOVE FORK--'))]
117 124 c.repos_list += [(x.repo_id, x.repo_name) for x in
118 Repository.query().order_by(Repository.repo_name).all()]
125 Repository.query().order_by(Repository.repo_name).all()
126 if x.repo_id != c.repo_info.repo_id]
127
128 defaults['id_fork_of'] = db_repo.fork.repo_id if db_repo.fork else ''
119 129 return defaults
120 130
121 131 @HasPermissionAllDecorator('hg.admin')
@@ -123,9 +133,45 b' class ReposController(BaseController):'
123 133 """GET /repos: All items in the collection"""
124 134 # url('repos')
125 135
126 c.repos_list = ScmModel().get_repos(Repository.query()
127 .order_by(Repository.repo_name)
128 .all(), sort_key='name_sort')
136 c.repos_list = Repository.query()\
137 .order_by(Repository.repo_name)\
138 .all()
139
140 repos_data = []
141 total_records = len(c.repos_list)
142
143 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
144 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
145
146 quick_menu = lambda repo_name: (template.get_def("quick_menu")
147 .render(repo_name, _=_, h=h, c=c))
148 repo_lnk = lambda name, rtype, private, fork_of: (
149 template.get_def("repo_name")
150 .render(name, rtype, private, fork_of, short_name=False,
151 admin=True, _=_, h=h, c=c))
152
153 repo_actions = lambda repo_name: (template.get_def("repo_actions")
154 .render(repo_name, _=_, h=h, c=c))
155
156 for repo in c.repos_list:
157 repos_data.append({
158 "menu": quick_menu(repo.repo_name),
159 "raw_name": repo.repo_name,
160 "name": repo_lnk(repo.repo_name, repo.repo_type,
161 repo.private, repo.fork),
162 "desc": repo.description,
163 "owner": repo.user.username,
164 "action": repo_actions(repo.repo_name),
165 })
166
167 c.data = json.dumps({
168 "totalRecords": total_records,
169 "startIndex": 0,
170 "sort": "name",
171 "dir": "asc",
172 "records": repos_data
173 })
174
129 175 return render('admin/repos/repos.html')
130 176
131 177 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
@@ -137,9 +183,11 b' class ReposController(BaseController):'
137 183 self.__load_defaults()
138 184 form_result = {}
139 185 try:
140 form_result = RepoForm(repo_groups=c.repo_groups_choices)()\
186 form_result = RepoForm(repo_groups=c.repo_groups_choices,
187 landing_revs=c.landing_revs_choices)()\
141 188 .to_python(dict(request.POST))
142 RepoModel().create(form_result, self.rhodecode_user)
189 new_repo = RepoModel().create(form_result,
190 self.rhodecode_user.user_id)
143 191 if form_result['clone_uri']:
144 192 h.flash(_('created repository %s from %s') \
145 193 % (form_result['repo_name'], form_result['clone_uri']),
@@ -151,11 +199,13 b' class ReposController(BaseController):'
151 199 if request.POST.get('user_created'):
152 200 # created by regular non admin user
153 201 action_logger(self.rhodecode_user, 'user_created_repo',
154 form_result['repo_name_full'], '', self.sa)
202 form_result['repo_name_full'], self.ip_addr,
203 self.sa)
155 204 else:
156 205 action_logger(self.rhodecode_user, 'admin_created_repo',
157 form_result['repo_name_full'], '', self.sa)
158 Session.commit()
206 form_result['repo_name_full'], self.ip_addr,
207 self.sa)
208 Session().commit()
159 209 except formencode.Invalid, errors:
160 210
161 211 c.new_repo = errors.value['repo_name']
@@ -177,9 +227,9 b' class ReposController(BaseController):'
177 227 msg = _('error occurred during creation of repository %s') \
178 228 % form_result.get('repo_name')
179 229 h.flash(msg, category='error')
180 if request.POST.get('user_created'):
181 return redirect(url('home'))
182 return redirect(url('repos'))
230 return redirect(url('repos'))
231 #redirect to our new repo !
232 return redirect(url('summary_home', repo_name=new_repo.repo_name))
183 233
184 234 @HasPermissionAllDecorator('hg.admin')
185 235 def new(self, format='html'):
@@ -202,18 +252,23 b' class ReposController(BaseController):'
202 252 self.__load_defaults()
203 253 repo_model = RepoModel()
204 254 changed_name = repo_name
255 #override the choices with extracted revisions !
256 choices, c.landing_revs = ScmModel().get_repo_landing_revs(repo_name)
257 c.landing_revs_choices = choices
258
205 259 _form = RepoForm(edit=True, old_data={'repo_name': repo_name},
206 repo_groups=c.repo_groups_choices)()
260 repo_groups=c.repo_groups_choices,
261 landing_revs=c.landing_revs_choices)()
207 262 try:
208 263 form_result = _form.to_python(dict(request.POST))
209 264 repo = repo_model.update(repo_name, form_result)
210 265 invalidate_cache('get_repo_cached_%s' % repo_name)
211 h.flash(_('Repository %s updated successfully' % repo_name),
266 h.flash(_('Repository %s updated successfully') % repo_name,
212 267 category='success')
213 268 changed_name = repo.repo_name
214 269 action_logger(self.rhodecode_user, 'admin_updated_repo',
215 changed_name, '', self.sa)
216 Session.commit()
270 changed_name, self.ip_addr, self.sa)
271 Session().commit()
217 272 except formencode.Invalid, errors:
218 273 defaults = self.__load_data(repo_name)
219 274 defaults.update(errors.value)
@@ -253,11 +308,11 b' class ReposController(BaseController):'
253 308 return redirect(url('repos'))
254 309 try:
255 310 action_logger(self.rhodecode_user, 'admin_deleted_repo',
256 repo_name, '', self.sa)
311 repo_name, self.ip_addr, self.sa)
257 312 repo_model.delete(repo)
258 313 invalidate_cache('get_repo_cached_%s' % repo_name)
259 314 h.flash(_('deleted repository %s') % repo_name, category='success')
260 Session.commit()
315 Session().commit()
261 316 except IntegrityError, e:
262 317 if e.message.find('repositories_fork_id_fkey') != -1:
263 318 log.error(traceback.format_exc())
@@ -287,7 +342,7 b' class ReposController(BaseController):'
287 342 try:
288 343 RepoModel().revoke_user_permission(repo=repo_name,
289 344 user=request.POST['user_id'])
290 Session.commit()
345 Session().commit()
291 346 except Exception:
292 347 log.error(traceback.format_exc())
293 348 h.flash(_('An error occurred during deletion of repository user'),
@@ -306,7 +361,7 b' class ReposController(BaseController):'
306 361 RepoModel().revoke_users_group_permission(
307 362 repo=repo_name, group_name=request.POST['users_group_id']
308 363 )
309 Session.commit()
364 Session().commit()
310 365 except Exception:
311 366 log.error(traceback.format_exc())
312 367 h.flash(_('An error occurred during deletion of repository'
@@ -324,8 +379,9 b' class ReposController(BaseController):'
324 379
325 380 try:
326 381 RepoModel().delete_stats(repo_name)
327 Session.commit()
382 Session().commit()
328 383 except Exception, e:
384 log.error(traceback.format_exc())
329 385 h.flash(_('An error occurred during deletion of repository stats'),
330 386 category='error')
331 387 return redirect(url('edit_repo', repo_name=repo_name))
@@ -340,13 +396,34 b' class ReposController(BaseController):'
340 396
341 397 try:
342 398 ScmModel().mark_for_invalidation(repo_name)
343 Session.commit()
399 Session().commit()
344 400 except Exception, e:
401 log.error(traceback.format_exc())
345 402 h.flash(_('An error occurred during cache invalidation'),
346 403 category='error')
347 404 return redirect(url('edit_repo', repo_name=repo_name))
348 405
349 406 @HasPermissionAllDecorator('hg.admin')
407 def repo_locking(self, repo_name):
408 """
409 Unlock repository when it is locked !
410
411 :param repo_name:
412 """
413
414 try:
415 repo = Repository.get_by_repo_name(repo_name)
416 if request.POST.get('set_lock'):
417 Repository.lock(repo, c.rhodecode_user.user_id)
418 elif request.POST.get('set_unlock'):
419 Repository.unlock(repo)
420 except Exception, e:
421 log.error(traceback.format_exc())
422 h.flash(_('An error occurred during unlocking'),
423 category='error')
424 return redirect(url('edit_repo', repo_name=repo_name))
425
426 @HasPermissionAllDecorator('hg.admin')
350 427 def repo_public_journal(self, repo_name):
351 428 """
352 429 Set's this repository to be visible in public journal,
@@ -364,7 +441,7 b' class ReposController(BaseController):'
364 441 self.scm_model.toggle_following_repo(repo_id, user_id)
365 442 h.flash(_('Updated repository visibility in public journal'),
366 443 category='success')
367 Session.commit()
444 Session().commit()
368 445 except:
369 446 h.flash(_('An error occurred during setting this'
370 447 ' repository in public journal'),
@@ -403,11 +480,11 b' class ReposController(BaseController):'
403 480 repo = ScmModel().mark_as_fork(repo_name, fork_id,
404 481 self.rhodecode_user.username)
405 482 fork = repo.fork.repo_name if repo.fork else _('Nothing')
406 Session.commit()
407 h.flash(_('Marked repo %s as fork of %s' % (repo_name,fork)),
483 Session().commit()
484 h.flash(_('Marked repo %s as fork of %s') % (repo_name, fork),
408 485 category='success')
409 486 except Exception, e:
410 raise
487 log.error(traceback.format_exc())
411 488 h.flash(_('An error occurred during this operation'),
412 489 category='error')
413 490
@@ -44,7 +44,7 b' from rhodecode.model.repos_group import '
44 44 from rhodecode.model.forms import ReposGroupForm
45 45 from rhodecode.model.meta import Session
46 46 from rhodecode.model.repo import RepoModel
47 from webob.exc import HTTPInternalServerError
47 from webob.exc import HTTPInternalServerError, HTTPNotFound
48 48
49 49 log = logging.getLogger(__name__)
50 50
@@ -74,11 +74,8 b' class ReposGroupsController(BaseControll'
74 74 :param group_id:
75 75 """
76 76 self.__load_defaults()
77
78 repo_group = RepoGroup.get(group_id)
79
77 repo_group = RepoGroup.get_or_404(group_id)
80 78 data = repo_group.get_dict()
81
82 79 data['group_name'] = repo_group.name
83 80
84 81 # fill repository users
@@ -115,7 +112,7 b' class ReposGroupsController(BaseControll'
115 112 group_description=form_result['group_description'],
116 113 parent=form_result['group_parent_id']
117 114 )
118 Session.commit()
115 Session().commit()
119 116 h.flash(_('created repos group %s') \
120 117 % form_result['group_name'], category='success')
121 118 #TODO: in futureaction_logger(, '', '', '', self.sa)
@@ -162,7 +159,7 b' class ReposGroupsController(BaseControll'
162 159 try:
163 160 form_result = repos_group_form.to_python(dict(request.POST))
164 161 ReposGroupModel().update(id, form_result)
165 Session.commit()
162 Session().commit()
166 163 h.flash(_('updated repos group %s') \
167 164 % form_result['group_name'], category='success')
168 165 #TODO: in futureaction_logger(, '', '', '', self.sa)
@@ -179,7 +176,7 b' class ReposGroupsController(BaseControll'
179 176 h.flash(_('error occurred during update of repos group %s') \
180 177 % request.POST.get('group_name'), category='error')
181 178
182 return redirect(url('repos_groups'))
179 return redirect(url('edit_repos_group', id=id))
183 180
184 181 @HasPermissionAnyDecorator('hg.admin')
185 182 def delete(self, id):
@@ -195,17 +192,18 b' class ReposGroupsController(BaseControll'
195 192 repos = gr.repositories.all()
196 193 if repos:
197 194 h.flash(_('This group contains %s repositores and cannot be '
198 'deleted' % len(repos)),
195 'deleted') % len(repos),
199 196 category='error')
200 197 return redirect(url('repos_groups'))
201 198
202 199 try:
203 200 ReposGroupModel().delete(id)
204 Session.commit()
205 h.flash(_('removed repos group %s' % gr.group_name), category='success')
201 Session().commit()
202 h.flash(_('removed repos group %s') % gr.group_name,
203 category='success')
206 204 #TODO: in future action_logger(, '', '', '', self.sa)
207 205 except IntegrityError, e:
208 if e.message.find('groups_group_parent_id_fkey') != -1:
206 if str(e.message).find('groups_group_parent_id_fkey') != -1:
209 207 log.error(traceback.format_exc())
210 208 h.flash(_('Cannot delete this group it still contains '
211 209 'subgroups'),
@@ -213,12 +211,12 b' class ReposGroupsController(BaseControll'
213 211 else:
214 212 log.error(traceback.format_exc())
215 213 h.flash(_('error occurred during deletion of repos '
216 'group %s' % gr.group_name), category='error')
214 'group %s') % gr.group_name, category='error')
217 215
218 216 except Exception:
219 217 log.error(traceback.format_exc())
220 218 h.flash(_('error occurred during deletion of repos '
221 'group %s' % gr.group_name), category='error')
219 'group %s') % gr.group_name, category='error')
222 220
223 221 return redirect(url('repos_groups'))
224 222
@@ -234,7 +232,7 b' class ReposGroupsController(BaseControll'
234 232 ReposGroupModel().revoke_user_permission(
235 233 repos_group=group_name, user=request.POST['user_id']
236 234 )
237 Session.commit()
235 Session().commit()
238 236 except Exception:
239 237 log.error(traceback.format_exc())
240 238 h.flash(_('An error occurred during deletion of group user'),
@@ -254,7 +252,7 b' class ReposGroupsController(BaseControll'
254 252 repos_group=group_name,
255 253 group_name=request.POST['users_group_id']
256 254 )
257 Session.commit()
255 Session().commit()
258 256 except Exception:
259 257 log.error(traceback.format_exc())
260 258 h.flash(_('An error occurred during deletion of group'
@@ -268,8 +266,10 b' class ReposGroupsController(BaseControll'
268 266 the group by id view instead
269 267 """
270 268 group_name = group_name.rstrip('/')
271 id_ = RepoGroup.get_by_group_name(group_name).group_id
272 return self.show(id_)
269 id_ = RepoGroup.get_by_group_name(group_name)
270 if id_:
271 return self.show(id_.group_id)
272 raise HTTPNotFound
273 273
274 274 @HasReposGroupPermissionAnyDecorator('group.read', 'group.write',
275 275 'group.admin')
@@ -277,12 +277,9 b' class ReposGroupsController(BaseControll'
277 277 """GET /repos_groups/id: Show a specific item"""
278 278 # url('repos_group', id=ID)
279 279
280 c.group = RepoGroup.get(id)
280 c.group = RepoGroup.get_or_404(id)
281 281
282 if c.group:
283 c.group_repos = c.group.repositories.all()
284 else:
285 return redirect(url('home'))
282 c.group_repos = c.group.repositories.all()
286 283
287 284 #overwrite our cached list with current filter
288 285 gr_filter = c.group_repos
@@ -292,7 +289,7 b' class ReposGroupsController(BaseControll'
292 289
293 290 c.repo_cnt = 0
294 291
295 c.groups = self.sa.query(RepoGroup).order_by(RepoGroup.group_name)\
292 c.groups = RepoGroup.query().order_by(RepoGroup.group_name)\
296 293 .filter(RepoGroup.group_parent_id == id).all()
297 294
298 295 return render('admin/repos_groups/repos_groups.html')
@@ -302,13 +299,12 b' class ReposGroupsController(BaseControll'
302 299 """GET /repos_groups/id/edit: Form to edit an existing item"""
303 300 # url('edit_repos_group', id=ID)
304 301
305 id_ = int(id)
306
307 c.repos_group = RepoGroup.get(id_)
308 defaults = self.__load_data(id_)
302 c.repos_group = ReposGroupModel()._get_repos_group(id)
303 defaults = self.__load_data(c.repos_group.group_id)
309 304
310 305 # we need to exclude this group from the group list for editing
311 c.repo_groups = filter(lambda x: x[0] != id_, c.repo_groups)
306 c.repo_groups = filter(lambda x: x[0] != c.repos_group.group_id,
307 c.repo_groups)
312 308
313 309 return htmlfill.render(
314 310 render('admin/repos_groups/repos_groups_edit.html'),
@@ -43,9 +43,9 b' from rhodecode.lib.celerylib import task'
43 43 from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
44 44 set_rhodecode_config, repo_name_slug
45 45 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
46 RhodeCodeSetting
46 RhodeCodeSetting, PullRequest, PullRequestReviewers
47 47 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
48 ApplicationUiSettingsForm
48 ApplicationUiSettingsForm, ApplicationVisualisationForm
49 49 from rhodecode.model.scm import ScmModel
50 50 from rhodecode.model.user import UserModel
51 51 from rhodecode.model.db import User
@@ -79,7 +79,7 b' class SettingsController(BaseController)'
79 79 # url('admin_settings')
80 80
81 81 defaults = RhodeCodeSetting.get_app_settings()
82 defaults.update(self.get_hg_ui_settings())
82 defaults.update(self._get_hg_ui_settings())
83 83
84 84 return htmlfill.render(
85 85 render('admin/settings/settings.html'),
@@ -107,6 +107,7 b' class SettingsController(BaseController)'
107 107 # h.form(url('admin_setting', setting_id=ID),
108 108 # method='put')
109 109 # url('admin_setting', setting_id=ID)
110
110 111 if setting_id == 'mapping':
111 112 rm_obsolete = request.POST.get('destroy', False)
112 113 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
@@ -119,122 +120,160 b' class SettingsController(BaseController)'
119 120
120 121 h.flash(_('Repositories successfully'
121 122 ' rescanned added: %s,removed: %s') % (added, removed),
122 category='success')
123 category='success')
123 124
124 125 if setting_id == 'whoosh':
125 repo_location = self.get_hg_ui_settings()['paths_root_path']
126 repo_location = self._get_hg_ui_settings()['paths_root_path']
126 127 full_index = request.POST.get('full_index', False)
127 128 run_task(tasks.whoosh_index, repo_location, full_index)
129 h.flash(_('Whoosh reindex task scheduled'), category='success')
128 130
129 h.flash(_('Whoosh reindex task scheduled'), category='success')
130 131 if setting_id == 'global':
131 132
132 133 application_form = ApplicationSettingsForm()()
133 134 try:
134 135 form_result = application_form.to_python(dict(request.POST))
135
136 try:
137 hgsettings1 = RhodeCodeSetting.get_by_name('title')
138 hgsettings1.app_settings_value = \
139 form_result['rhodecode_title']
136 except formencode.Invalid, errors:
137 return htmlfill.render(
138 render('admin/settings/settings.html'),
139 defaults=errors.value,
140 errors=errors.error_dict or {},
141 prefix_error=False,
142 encoding="UTF-8"
143 )
140 144
141 hgsettings2 = RhodeCodeSetting.get_by_name('realm')
142 hgsettings2.app_settings_value = \
143 form_result['rhodecode_realm']
145 try:
146 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
147 sett1.app_settings_value = form_result['rhodecode_title']
148 Session().add(sett1)
144 149
145 hgsettings3 = RhodeCodeSetting.get_by_name('ga_code')
146 hgsettings3.app_settings_value = \
147 form_result['rhodecode_ga_code']
150 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
151 sett2.app_settings_value = form_result['rhodecode_realm']
152 Session().add(sett2)
148 153
149 self.sa.add(hgsettings1)
150 self.sa.add(hgsettings2)
151 self.sa.add(hgsettings3)
152 self.sa.commit()
153 set_rhodecode_config(config)
154 h.flash(_('Updated application settings'),
155 category='success')
154 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
155 sett3.app_settings_value = form_result['rhodecode_ga_code']
156 Session().add(sett3)
157
158 Session().commit()
159 set_rhodecode_config(config)
160 h.flash(_('Updated application settings'), category='success')
156 161
157 except Exception:
158 log.error(traceback.format_exc())
159 h.flash(_('error occurred during updating '
160 'application settings'),
161 category='error')
162 except Exception:
163 log.error(traceback.format_exc())
164 h.flash(_('error occurred during updating '
165 'application settings'),
166 category='error')
162 167
163 self.sa.rollback()
168 if setting_id == 'visual':
164 169
170 application_form = ApplicationVisualisationForm()()
171 try:
172 form_result = application_form.to_python(dict(request.POST))
165 173 except formencode.Invalid, errors:
166 174 return htmlfill.render(
167 175 render('admin/settings/settings.html'),
168 176 defaults=errors.value,
169 177 errors=errors.error_dict or {},
170 178 prefix_error=False,
171 encoding="UTF-8")
179 encoding="UTF-8"
180 )
181
182 try:
183 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
184 sett1.app_settings_value = \
185 form_result['rhodecode_show_public_icon']
186
187 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
188 sett2.app_settings_value = \
189 form_result['rhodecode_show_private_icon']
190
191 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
192 sett3.app_settings_value = \
193 form_result['rhodecode_stylify_metatags']
172 194
173 if setting_id == 'mercurial':
195 Session().add(sett1)
196 Session().add(sett2)
197 Session().add(sett3)
198 Session().commit()
199 set_rhodecode_config(config)
200 h.flash(_('Updated visualisation settings'),
201 category='success')
202
203 except Exception:
204 log.error(traceback.format_exc())
205 h.flash(_('error occurred during updating '
206 'visualisation settings'),
207 category='error')
208
209 if setting_id == 'vcs':
174 210 application_form = ApplicationUiSettingsForm()()
175 211 try:
176 212 form_result = application_form.to_python(dict(request.POST))
177
178 try:
179
180 hgsettings1 = self.sa.query(RhodeCodeUi)\
181 .filter(RhodeCodeUi.ui_key == 'push_ssl').one()
182 hgsettings1.ui_value = form_result['web_push_ssl']
183
184 hgsettings2 = self.sa.query(RhodeCodeUi)\
185 .filter(RhodeCodeUi.ui_key == '/').one()
186 hgsettings2.ui_value = form_result['paths_root_path']
187
188 #HOOKS
189 hgsettings3 = self.sa.query(RhodeCodeUi)\
190 .filter(RhodeCodeUi.ui_key == 'changegroup.update').one()
191 hgsettings3.ui_active = \
192 bool(form_result['hooks_changegroup_update'])
193
194 hgsettings4 = self.sa.query(RhodeCodeUi)\
195 .filter(RhodeCodeUi.ui_key ==
196 'changegroup.repo_size').one()
197 hgsettings4.ui_active = \
198 bool(form_result['hooks_changegroup_repo_size'])
199
200 hgsettings5 = self.sa.query(RhodeCodeUi)\
201 .filter(RhodeCodeUi.ui_key ==
202 'pretxnchangegroup.push_logger').one()
203 hgsettings5.ui_active = \
204 bool(form_result['hooks_pretxnchangegroup'
205 '_push_logger'])
206
207 hgsettings6 = self.sa.query(RhodeCodeUi)\
208 .filter(RhodeCodeUi.ui_key ==
209 'preoutgoing.pull_logger').one()
210 hgsettings6.ui_active = \
211 bool(form_result['hooks_preoutgoing_pull_logger'])
212
213 self.sa.add(hgsettings1)
214 self.sa.add(hgsettings2)
215 self.sa.add(hgsettings3)
216 self.sa.add(hgsettings4)
217 self.sa.add(hgsettings5)
218 self.sa.add(hgsettings6)
219 self.sa.commit()
220
221 h.flash(_('Updated mercurial settings'),
222 category='success')
223
224 except:
225 log.error(traceback.format_exc())
226 h.flash(_('error occurred during updating '
227 'application settings'), category='error')
228
229 self.sa.rollback()
230
231 213 except formencode.Invalid, errors:
232 214 return htmlfill.render(
233 215 render('admin/settings/settings.html'),
234 216 defaults=errors.value,
235 217 errors=errors.error_dict or {},
236 218 prefix_error=False,
237 encoding="UTF-8")
219 encoding="UTF-8"
220 )
221
222 try:
223 # fix namespaces for hooks and extensions
224 _f = lambda s: s.replace('.', '_')
225
226 sett = RhodeCodeUi.get_by_key('push_ssl')
227 sett.ui_value = form_result['web_push_ssl']
228 Session().add(sett)
229
230 sett = RhodeCodeUi.get_by_key('/')
231 sett.ui_value = form_result['paths_root_path']
232 Session().add(sett)
233
234 #HOOKS
235 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
236 sett.ui_active = form_result[_f('hooks_%s' %
237 RhodeCodeUi.HOOK_UPDATE)]
238 Session().add(sett)
239
240 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
241 sett.ui_active = form_result[_f('hooks_%s' %
242 RhodeCodeUi.HOOK_REPO_SIZE)]
243 Session().add(sett)
244
245 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
246 sett.ui_active = form_result[_f('hooks_%s' %
247 RhodeCodeUi.HOOK_PUSH)]
248 Session().add(sett)
249
250 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
251 sett.ui_active = form_result[_f('hooks_%s' %
252 RhodeCodeUi.HOOK_PULL)]
253
254 Session().add(sett)
255
256 ## EXTENSIONS
257 sett = RhodeCodeUi.get_by_key('largefiles')
258 sett.ui_active = form_result[_f('extensions_largefiles')]
259 Session().add(sett)
260
261 sett = RhodeCodeUi.get_by_key('hgsubversion')
262 sett.ui_active = form_result[_f('extensions_hgsubversion')]
263 Session().add(sett)
264
265 # sett = RhodeCodeUi.get_by_key('hggit')
266 # sett.ui_active = form_result[_f('extensions_hggit')]
267 # Session().add(sett)
268
269 Session().commit()
270
271 h.flash(_('Updated VCS settings'), category='success')
272
273 except Exception:
274 log.error(traceback.format_exc())
275 h.flash(_('error occurred during updating '
276 'application settings'), category='error')
238 277
239 278 if setting_id == 'hooks':
240 279 ui_key = request.POST.get('new_hook_ui_key')
@@ -256,8 +295,8 b' class SettingsController(BaseController)'
256 295
257 296 if update:
258 297 h.flash(_('Updated hooks'), category='success')
259 self.sa.commit()
260 except:
298 Session().commit()
299 except Exception:
261 300 log.error(traceback.format_exc())
262 301 h.flash(_('error occurred during hook creation'),
263 302 category='error')
@@ -293,7 +332,7 b' class SettingsController(BaseController)'
293 332 if setting_id == 'hooks':
294 333 hook_id = request.POST.get('hook_id')
295 334 RhodeCodeUi.delete(hook_id)
296 self.sa.commit()
335 Session().commit()
297 336
298 337 @HasPermissionAllDecorator('hg.admin')
299 338 def show(self, setting_id, format='html'):
@@ -326,7 +365,7 b' class SettingsController(BaseController)'
326 365 # url('admin_settings_my_account')
327 366
328 367 c.user = User.get(self.rhodecode_user.user_id)
329 all_repos = self.sa.query(Repository)\
368 all_repos = Session().query(Repository)\
330 369 .filter(Repository.user_id == c.user.user_id)\
331 370 .order_by(func.lower(Repository.repo_name)).all()
332 371
@@ -338,13 +377,16 b' class SettingsController(BaseController)'
338 377 return redirect(url('users'))
339 378
340 379 defaults = c.user.get_dict()
341 return htmlfill.render(
342 render('admin/users/user_edit_my_account.html'),
380
381 c.form = htmlfill.render(
382 render('admin/users/user_edit_my_account_form.html'),
343 383 defaults=defaults,
344 384 encoding="UTF-8",
345 385 force_defaults=False
346 386 )
387 return render('admin/users/user_edit_my_account.html')
347 388
389 @NotAnonymous()
348 390 def my_account_update(self):
349 391 """PUT /_admin/my_account_update: Update an existing item"""
350 392 # Forms posted to this method should contain a hidden field:
@@ -353,32 +395,27 b' class SettingsController(BaseController)'
353 395 # h.form(url('admin_settings_my_account_update'),
354 396 # method='put')
355 397 # url('admin_settings_my_account_update', id=ID)
356 user_model = UserModel()
357 398 uid = self.rhodecode_user.user_id
399 email = self.rhodecode_user.email
358 400 _form = UserForm(edit=True,
359 old_data={'user_id': uid,
360 'email': self.rhodecode_user.email})()
401 old_data={'user_id': uid, 'email': email})()
361 402 form_result = {}
362 403 try:
363 404 form_result = _form.to_python(dict(request.POST))
364 user_model.update_my_account(uid, form_result)
405 UserModel().update_my_account(uid, form_result)
365 406 h.flash(_('Your account was updated successfully'),
366 407 category='success')
367 Session.commit()
408 Session().commit()
368 409 except formencode.Invalid, errors:
369 410 c.user = User.get(self.rhodecode_user.user_id)
370 all_repos = self.sa.query(Repository)\
371 .filter(Repository.user_id == c.user.user_id)\
372 .order_by(func.lower(Repository.repo_name))\
373 .all()
374 c.user_repos = ScmModel().get_repos(all_repos)
375 411
376 return htmlfill.render(
377 render('admin/users/user_edit_my_account.html'),
412 c.form = htmlfill.render(
413 render('admin/users/user_edit_my_account_form.html'),
378 414 defaults=errors.value,
379 415 errors=errors.error_dict or {},
380 416 prefix_error=False,
381 417 encoding="UTF-8")
418 return render('admin/users/user_edit_my_account.html')
382 419 except Exception:
383 420 log.error(traceback.format_exc())
384 421 h.flash(_('error occurred during update of user %s') \
@@ -387,20 +424,43 b' class SettingsController(BaseController)'
387 424 return redirect(url('my_account'))
388 425
389 426 @NotAnonymous()
427 def my_account_my_repos(self):
428 all_repos = Session().query(Repository)\
429 .filter(Repository.user_id == self.rhodecode_user.user_id)\
430 .order_by(func.lower(Repository.repo_name))\
431 .all()
432 c.user_repos = ScmModel().get_repos(all_repos)
433 return render('admin/users/user_edit_my_account_repos.html')
434
435 @NotAnonymous()
436 def my_account_my_pullrequests(self):
437 c.my_pull_requests = PullRequest.query()\
438 .filter(PullRequest.user_id==
439 self.rhodecode_user.user_id)\
440 .all()
441 c.participate_in_pull_requests = \
442 [x.pull_request for x in PullRequestReviewers.query()\
443 .filter(PullRequestReviewers.user_id==
444 self.rhodecode_user.user_id)\
445 .all()]
446 return render('admin/users/user_edit_my_account_pullrequests.html')
447
448 @NotAnonymous()
390 449 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
391 450 def create_repository(self):
392 451 """GET /_admin/create_repository: Form to create a new item"""
393 452
394 453 c.repo_groups = RepoGroup.groups_choices()
395 454 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
455 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
396 456
397 457 new_repo = request.GET.get('repo', '')
398 458 c.new_repo = repo_name_slug(new_repo)
399 459
400 460 return render('admin/repos/repo_add_create_repository.html')
401 461
402 def get_hg_ui_settings(self):
403 ret = self.sa.query(RhodeCodeUi).all()
462 def _get_hg_ui_settings(self):
463 ret = RhodeCodeUi.query().all()
404 464
405 465 if not ret:
406 466 raise Exception('Could not get application ui settings !')
@@ -414,7 +474,7 b' class SettingsController(BaseController)'
414 474 if k.find('.') != -1:
415 475 k = k.replace('.', '_')
416 476
417 if each.ui_section == 'hooks':
477 if each.ui_section in ['hooks', 'extensions']:
418 478 v = each.ui_active
419 479
420 480 settings[each.ui_section + '_' + k] = v
@@ -26,22 +26,28 b''
26 26 import logging
27 27 import traceback
28 28 import formencode
29 from pylons import response
29 30
30 31 from formencode import htmlfill
31 32 from pylons import request, session, tmpl_context as c, url, config
32 33 from pylons.controllers.util import redirect
33 34 from pylons.i18n.translation import _
34 35
36 import rhodecode
35 37 from rhodecode.lib.exceptions import DefaultUserException, \
36 38 UserOwnsReposException
37 39 from rhodecode.lib import helpers as h
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
40 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
41 AuthUser
39 42 from rhodecode.lib.base import BaseController, render
40 43
41 from rhodecode.model.db import User, Permission
44 from rhodecode.model.db import User, UserEmailMap
42 45 from rhodecode.model.forms import UserForm
43 46 from rhodecode.model.user import UserModel
44 47 from rhodecode.model.meta import Session
48 from rhodecode.lib.utils import action_logger
49 from rhodecode.lib.compat import json
50 from rhodecode.lib.utils2 import datetime_to_time, str2bool
45 51
46 52 log = logging.getLogger(__name__)
47 53
@@ -64,7 +70,49 b' class UsersController(BaseController):'
64 70 """GET /users: All items in the collection"""
65 71 # url('users')
66 72
67 c.users_list = self.sa.query(User).all()
73 c.users_list = User.query().order_by(User.username).all()
74
75 users_data = []
76 total_records = len(c.users_list)
77 _tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
78 template = _tmpl_lookup.get_template('data_table/_dt_elements.html')
79
80 grav_tmpl = lambda user_email, size: (
81 template.get_def("user_gravatar")
82 .render(user_email, size, _=_, h=h, c=c))
83
84 user_lnk = lambda user_id, username: (
85 template.get_def("user_name")
86 .render(user_id, username, _=_, h=h, c=c))
87
88 user_actions = lambda user_id, username: (
89 template.get_def("user_actions")
90 .render(user_id, username, _=_, h=h, c=c))
91
92 for user in c.users_list:
93
94 users_data.append({
95 "gravatar": grav_tmpl(user. email, 24),
96 "raw_username": user.username,
97 "username": user_lnk(user.user_id, user.username),
98 "firstname": user.name,
99 "lastname": user.lastname,
100 "last_login": h.fmt_date(user.last_login),
101 "last_login_raw": datetime_to_time(user.last_login),
102 "active": h.bool2icon(user.active),
103 "admin": h.bool2icon(user.admin),
104 "ldap": h.bool2icon(bool(user.ldap_dn)),
105 "action": user_actions(user.user_id, user.username),
106 })
107
108 c.data = json.dumps({
109 "totalRecords": total_records,
110 "startIndex": 0,
111 "sort": None,
112 "dir": "asc",
113 "records": users_data
114 })
115
68 116 return render('admin/users/users.html')
69 117
70 118 def create(self):
@@ -76,10 +124,12 b' class UsersController(BaseController):'
76 124 try:
77 125 form_result = user_form.to_python(dict(request.POST))
78 126 user_model.create(form_result)
79 h.flash(_('created user %s') % form_result['username'],
127 usr = form_result['username']
128 action_logger(self.rhodecode_user, 'admin_created_user:%s' % usr,
129 None, self.ip_addr, self.sa)
130 h.flash(_('created user %s') % usr,
80 131 category='success')
81 Session.commit()
82 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
132 Session().commit()
83 133 except formencode.Invalid, errors:
84 134 return htmlfill.render(
85 135 render('admin/users/user_add.html'),
@@ -108,22 +158,31 b' class UsersController(BaseController):'
108 158 # url('user', id=ID)
109 159 user_model = UserModel()
110 160 c.user = user_model.get(id)
111
161 c.perm_user = AuthUser(user_id=id)
112 162 _form = UserForm(edit=True, old_data={'user_id': id,
113 163 'email': c.user.email})()
114 164 form_result = {}
115 165 try:
116 166 form_result = _form.to_python(dict(request.POST))
117 167 user_model.update(id, form_result)
168 usr = form_result['username']
169 action_logger(self.rhodecode_user, 'admin_updated_user:%s' % usr,
170 None, self.ip_addr, self.sa)
118 171 h.flash(_('User updated successfully'), category='success')
119 Session.commit()
172 Session().commit()
120 173 except formencode.Invalid, errors:
174 c.user_email_map = UserEmailMap.query()\
175 .filter(UserEmailMap.user == c.user).all()
176 defaults = errors.value
121 177 e = errors.error_dict or {}
122 perm = Permission.get_by_key('hg.create.repository')
123 e.update({'create_repo_perm': user_model.has_perm(id, perm)})
178 defaults.update({
179 'create_repo_perm': user_model.has_perm(id, 'hg.create.repository'),
180 'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'),
181 '_method': 'put'
182 })
124 183 return htmlfill.render(
125 184 render('admin/users/user_edit.html'),
126 defaults=errors.value,
185 defaults=defaults,
127 186 errors=e,
128 187 prefix_error=False,
129 188 encoding="UTF-8")
@@ -131,8 +190,7 b' class UsersController(BaseController):'
131 190 log.error(traceback.format_exc())
132 191 h.flash(_('error occurred during update of user %s') \
133 192 % form_result.get('username'), category='error')
134
135 return redirect(url('users'))
193 return redirect(url('edit_user', id=id))
136 194
137 195 def delete(self, id):
138 196 """DELETE /users/id: Delete an existing item"""
@@ -142,10 +200,10 b' class UsersController(BaseController):'
142 200 # h.form(url('delete_user', id=ID),
143 201 # method='delete')
144 202 # url('user', id=ID)
145 user_model = UserModel()
203 usr = User.get_or_404(id)
146 204 try:
147 user_model.delete(id)
148 Session.commit()
205 UserModel().delete(usr)
206 Session().commit()
149 207 h.flash(_('successfully deleted user'), category='success')
150 208 except (UserOwnsReposException, DefaultUserException), e:
151 209 h.flash(e, category='warning')
@@ -162,19 +220,24 b' class UsersController(BaseController):'
162 220 def edit(self, id, format='html'):
163 221 """GET /users/id/edit: Form to edit an existing item"""
164 222 # url('edit_user', id=ID)
165 c.user = User.get(id)
166 if not c.user:
167 return redirect(url('users'))
223 c.user = User.get_or_404(id)
224
168 225 if c.user.username == 'default':
169 226 h.flash(_("You can't edit this user"), category='warning')
170 227 return redirect(url('users'))
228
229 c.perm_user = AuthUser(user_id=id)
171 230 c.user.permissions = {}
172 231 c.granted_permissions = UserModel().fill_perms(c.user)\
173 232 .permissions['global']
174
233 c.user_email_map = UserEmailMap.query()\
234 .filter(UserEmailMap.user == c.user).all()
235 user_model = UserModel()
175 236 defaults = c.user.get_dict()
176 perm = Permission.get_by_key('hg.create.repository')
177 defaults.update({'create_repo_perm': UserModel().has_perm(id, perm)})
237 defaults.update({
238 'create_repo_perm': user_model.has_perm(id, 'hg.create.repository'),
239 'fork_repo_perm': user_model.has_perm(id, 'hg.fork.repository'),
240 })
178 241
179 242 return htmlfill.render(
180 243 render('admin/users/user_edit.html'),
@@ -186,26 +249,72 b' class UsersController(BaseController):'
186 249 def update_perm(self, id):
187 250 """PUT /users_perm/id: Update an existing item"""
188 251 # url('user_perm', id=ID, method='put')
252 usr = User.get_or_404(id)
253 grant_create_perm = str2bool(request.POST.get('create_repo_perm'))
254 grant_fork_perm = str2bool(request.POST.get('fork_repo_perm'))
255 inherit_perms = str2bool(request.POST.get('inherit_default_permissions'))
189 256
190 grant_perm = request.POST.get('create_repo_perm', False)
191 257 user_model = UserModel()
192 258
193 if grant_perm:
194 perm = Permission.get_by_key('hg.create.none')
195 user_model.revoke_perm(id, perm)
259 try:
260 usr.inherit_default_permissions = inherit_perms
261 Session().add(usr)
262
263 if grant_create_perm:
264 user_model.revoke_perm(usr, 'hg.create.none')
265 user_model.grant_perm(usr, 'hg.create.repository')
266 h.flash(_("Granted 'repository create' permission to user"),
267 category='success')
268 else:
269 user_model.revoke_perm(usr, 'hg.create.repository')
270 user_model.grant_perm(usr, 'hg.create.none')
271 h.flash(_("Revoked 'repository create' permission to user"),
272 category='success')
273
274 if grant_fork_perm:
275 user_model.revoke_perm(usr, 'hg.fork.none')
276 user_model.grant_perm(usr, 'hg.fork.repository')
277 h.flash(_("Granted 'repository fork' permission to user"),
278 category='success')
279 else:
280 user_model.revoke_perm(usr, 'hg.fork.repository')
281 user_model.grant_perm(usr, 'hg.fork.none')
282 h.flash(_("Revoked 'repository fork' permission to user"),
283 category='success')
196 284
197 perm = Permission.get_by_key('hg.create.repository')
198 user_model.grant_perm(id, perm)
199 h.flash(_("Granted 'repository create' permission to user"),
200 category='success')
201 Session.commit()
202 else:
203 perm = Permission.get_by_key('hg.create.repository')
204 user_model.revoke_perm(id, perm)
285 Session().commit()
286 except Exception:
287 log.error(traceback.format_exc())
288 h.flash(_('An error occurred during permissions saving'),
289 category='error')
290 return redirect(url('edit_user', id=id))
291
292 def add_email(self, id):
293 """POST /user_emails:Add an existing item"""
294 # url('user_emails', id=ID, method='put')
295
296 #TODO: validation and form !!!
297 email = request.POST.get('new_email')
298 user_model = UserModel()
205 299
206 perm = Permission.get_by_key('hg.create.none')
207 user_model.grant_perm(id, perm)
208 h.flash(_("Revoked 'repository create' permission to user"),
209 category='success')
210 Session.commit()
300 try:
301 user_model.add_extra_email(id, email)
302 Session().commit()
303 h.flash(_("Added email %s to user") % email, category='success')
304 except formencode.Invalid, error:
305 msg = error.error_dict['email']
306 h.flash(msg, category='error')
307 except Exception:
308 log.error(traceback.format_exc())
309 h.flash(_('An error occurred during email saving'),
310 category='error')
211 311 return redirect(url('edit_user', id=id))
312
313 def delete_email(self, id):
314 """DELETE /user_emails_delete/id: Delete an existing item"""
315 # url('user_emails_delete', id=ID, method='delete')
316 user_model = UserModel()
317 user_model.delete_extra_email(id, request.POST.get('del_email'))
318 Session().commit()
319 h.flash(_("Removed email from user"), category='success')
320 return redirect(url('edit_user', id=id))
@@ -34,15 +34,16 b' from pylons.i18n.translation import _'
34 34
35 35 from rhodecode.lib import helpers as h
36 36 from rhodecode.lib.exceptions import UsersGroupsAssignedException
37 from rhodecode.lib.utils2 import safe_unicode
37 from rhodecode.lib.utils2 import safe_unicode, str2bool
38 38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
39 39 from rhodecode.lib.base import BaseController, render
40 40
41 41 from rhodecode.model.users_group import UsersGroupModel
42 42
43 from rhodecode.model.db import User, UsersGroup, Permission, UsersGroupToPerm
43 from rhodecode.model.db import User, UsersGroup
44 44 from rhodecode.model.forms import UsersGroupForm
45 45 from rhodecode.model.meta import Session
46 from rhodecode.lib.utils import action_logger
46 47
47 48 log = logging.getLogger(__name__)
48 49
@@ -64,7 +65,7 b' class UsersGroupsController(BaseControll'
64 65 def index(self, format='html'):
65 66 """GET /users_groups: All items in the collection"""
66 67 # url('users_groups')
67 c.users_groups_list = self.sa.query(UsersGroup).all()
68 c.users_groups_list = UsersGroup().query().all()
68 69 return render('admin/users_groups/users_groups.html')
69 70
70 71 def create(self):
@@ -76,10 +77,12 b' class UsersGroupsController(BaseControll'
76 77 form_result = users_group_form.to_python(dict(request.POST))
77 78 UsersGroupModel().create(name=form_result['users_group_name'],
78 79 active=form_result['users_group_active'])
79 h.flash(_('created users group %s') \
80 % form_result['users_group_name'], category='success')
81 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
82 Session.commit()
80 gr = form_result['users_group_name']
81 action_logger(self.rhodecode_user,
82 'admin_created_users_group:%s' % gr,
83 None, self.ip_addr, self.sa)
84 h.flash(_('created users group %s') % gr, category='success')
85 Session().commit()
83 86 except formencode.Invalid, errors:
84 87 return htmlfill.render(
85 88 render('admin/users_groups/users_group_add.html'),
@@ -114,7 +117,7 b' class UsersGroupsController(BaseControll'
114 117 c.group_members_obj]
115 118
116 119 c.available_members = [(x.user_id, x.username) for x in
117 self.sa.query(User).all()]
120 User.query().all()]
118 121
119 122 available_members = [safe_unicode(x[0]) for x in c.available_members]
120 123
@@ -125,21 +128,27 b' class UsersGroupsController(BaseControll'
125 128 try:
126 129 form_result = users_group_form.to_python(request.POST)
127 130 UsersGroupModel().update(c.users_group, form_result)
128 h.flash(_('updated users group %s') \
129 % form_result['users_group_name'],
130 category='success')
131 #action_logger(self.rhodecode_user, 'new_user', '', '', self.sa)
132 Session.commit()
131 gr = form_result['users_group_name']
132 action_logger(self.rhodecode_user,
133 'admin_updated_users_group:%s' % gr,
134 None, self.ip_addr, self.sa)
135 h.flash(_('updated users group %s') % gr, category='success')
136 Session().commit()
133 137 except formencode.Invalid, errors:
138 ug_model = UsersGroupModel()
139 defaults = errors.value
134 140 e = errors.error_dict or {}
135
136 perm = Permission.get_by_key('hg.create.repository')
137 e.update({'create_repo_perm':
138 UsersGroupModel().has_perm(id, perm)})
141 defaults.update({
142 'create_repo_perm': ug_model.has_perm(id,
143 'hg.create.repository'),
144 'fork_repo_perm': ug_model.has_perm(id,
145 'hg.fork.repository'),
146 '_method': 'put'
147 })
139 148
140 149 return htmlfill.render(
141 150 render('admin/users_groups/users_group_edit.html'),
142 defaults=errors.value,
151 defaults=defaults,
143 152 errors=e,
144 153 prefix_error=False,
145 154 encoding="UTF-8")
@@ -148,7 +157,7 b' class UsersGroupsController(BaseControll'
148 157 h.flash(_('error occurred during update of users group %s') \
149 158 % request.POST.get('users_group_name'), category='error')
150 159
151 return redirect(url('users_groups'))
160 return redirect(url('edit_users_group', id=id))
152 161
153 162 def delete(self, id):
154 163 """DELETE /users_groups/id: Delete an existing item"""
@@ -158,10 +167,10 b' class UsersGroupsController(BaseControll'
158 167 # h.form(url('users_group', id=ID),
159 168 # method='delete')
160 169 # url('users_group', id=ID)
161
170 usr_gr = UsersGroup.get_or_404(id)
162 171 try:
163 UsersGroupModel().delete(id)
164 Session.commit()
172 UsersGroupModel().delete(usr_gr)
173 Session().commit()
165 174 h.flash(_('successfully deleted users group'), category='success')
166 175 except UsersGroupsAssignedException, e:
167 176 h.flash(e, category='error')
@@ -179,20 +188,23 b' class UsersGroupsController(BaseControll'
179 188 """GET /users_groups/id/edit: Form to edit an existing item"""
180 189 # url('edit_users_group', id=ID)
181 190
182 c.users_group = self.sa.query(UsersGroup).get(id)
183 if not c.users_group:
184 return redirect(url('users_groups'))
191 c.users_group = UsersGroup.get_or_404(id)
185 192
186 193 c.users_group.permissions = {}
187 194 c.group_members_obj = [x.user for x in c.users_group.members]
188 195 c.group_members = [(x.user_id, x.username) for x in
189 196 c.group_members_obj]
190 197 c.available_members = [(x.user_id, x.username) for x in
191 self.sa.query(User).all()]
198 User.query().all()]
199 ug_model = UsersGroupModel()
192 200 defaults = c.users_group.get_dict()
193 perm = Permission.get_by_key('hg.create.repository')
194 defaults.update({'create_repo_perm':
195 UsersGroupModel().has_perm(c.users_group, perm)})
201 defaults.update({
202 'create_repo_perm': ug_model.has_perm(c.users_group,
203 'hg.create.repository'),
204 'fork_repo_perm': ug_model.has_perm(c.users_group,
205 'hg.fork.repository'),
206 })
207
196 208 return htmlfill.render(
197 209 render('admin/users_groups/users_group_edit.html'),
198 210 defaults=defaults,
@@ -204,25 +216,43 b' class UsersGroupsController(BaseControll'
204 216 """PUT /users_perm/id: Update an existing item"""
205 217 # url('users_group_perm', id=ID, method='put')
206 218
207 grant_perm = request.POST.get('create_repo_perm', False)
219 users_group = UsersGroup.get_or_404(id)
220 grant_create_perm = str2bool(request.POST.get('create_repo_perm'))
221 grant_fork_perm = str2bool(request.POST.get('fork_repo_perm'))
222 inherit_perms = str2bool(request.POST.get('inherit_default_permissions'))
208 223
209 if grant_perm:
210 perm = Permission.get_by_key('hg.create.none')
211 UsersGroupModel().revoke_perm(id, perm)
224 usersgroup_model = UsersGroupModel()
212 225
213 perm = Permission.get_by_key('hg.create.repository')
214 UsersGroupModel().grant_perm(id, perm)
215 h.flash(_("Granted 'repository create' permission to user"),
216 category='success')
226 try:
227 users_group.inherit_default_permissions = inherit_perms
228 Session().add(users_group)
217 229
218 Session.commit()
219 else:
220 perm = Permission.get_by_key('hg.create.repository')
221 UsersGroupModel().revoke_perm(id, perm)
230 if grant_create_perm:
231 usersgroup_model.revoke_perm(id, 'hg.create.none')
232 usersgroup_model.grant_perm(id, 'hg.create.repository')
233 h.flash(_("Granted 'repository create' permission to users group"),
234 category='success')
235 else:
236 usersgroup_model.revoke_perm(id, 'hg.create.repository')
237 usersgroup_model.grant_perm(id, 'hg.create.none')
238 h.flash(_("Revoked 'repository create' permission to users group"),
239 category='success')
222 240
223 perm = Permission.get_by_key('hg.create.none')
224 UsersGroupModel().grant_perm(id, perm)
225 h.flash(_("Revoked 'repository create' permission to user"),
226 category='success')
227 Session.commit()
241 if grant_fork_perm:
242 usersgroup_model.revoke_perm(id, 'hg.fork.none')
243 usersgroup_model.grant_perm(id, 'hg.fork.repository')
244 h.flash(_("Granted 'repository fork' permission to users group"),
245 category='success')
246 else:
247 usersgroup_model.revoke_perm(id, 'hg.fork.repository')
248 usersgroup_model.grant_perm(id, 'hg.fork.none')
249 h.flash(_("Revoked 'repository fork' permission to users group"),
250 category='success')
251
252 Session().commit()
253 except Exception:
254 log.error(traceback.format_exc())
255 h.flash(_('An error occurred during permissions saving'),
256 category='error')
257
228 258 return redirect(url('edit_users_group', id=id))
@@ -30,6 +30,7 b' import logging'
30 30 import types
31 31 import urllib
32 32 import traceback
33 import time
33 34
34 35 from rhodecode.lib.compat import izip_longest, json
35 36
@@ -43,6 +44,8 b' HTTPBadRequest, HTTPError'
43 44
44 45 from rhodecode.model.db import User
45 46 from rhodecode.lib.auth import AuthUser
47 from rhodecode.lib.base import _get_ip_addr, _get_access_path
48 from rhodecode.lib.utils2 import safe_unicode
46 49
47 50 log = logging.getLogger('JSONRPC')
48 51
@@ -57,15 +60,16 b' class JSONRPCError(BaseException):'
57 60 return str(self.message)
58 61
59 62
60 def jsonrpc_error(message, code=None):
63 def jsonrpc_error(message, retid=None, code=None):
61 64 """
62 65 Generate a Response object with a JSON-RPC error body
63 66 """
64 67 from pylons.controllers.util import Response
65 resp = Response(body=json.dumps(dict(id=None, result=None, error=message)),
66 status=code,
67 content_type='application/json')
68 return resp
68 return Response(
69 body=json.dumps(dict(id=retid, result=None, error=message)),
70 status=code,
71 content_type='application/json'
72 )
69 73
70 74
71 75 class JSONRPCController(WSGIController):
@@ -94,9 +98,12 b' class JSONRPCController(WSGIController):'
94 98 Parse the request body as JSON, look up the method on the
95 99 controller and if it exists, dispatch to it.
96 100 """
101 start = time.time()
102 self._req_id = None
97 103 if 'CONTENT_LENGTH' not in environ:
98 104 log.debug("No Content-Length")
99 return jsonrpc_error(message="No Content-Length in request")
105 return jsonrpc_error(retid=self._req_id,
106 message="No Content-Length in request")
100 107 else:
101 108 length = environ['CONTENT_LENGTH'] or 0
102 109 length = int(environ['CONTENT_LENGTH'])
@@ -104,7 +111,8 b' class JSONRPCController(WSGIController):'
104 111
105 112 if length == 0:
106 113 log.debug("Content-Length is 0")
107 return jsonrpc_error(message="Content-Length is 0")
114 return jsonrpc_error(retid=self._req_id,
115 message="Content-Length is 0")
108 116
109 117 raw_body = environ['wsgi.input'].read(length)
110 118
@@ -112,7 +120,8 b' class JSONRPCController(WSGIController):'
112 120 json_body = json.loads(urllib.unquote_plus(raw_body))
113 121 except ValueError, e:
114 122 # catch JSON errors Here
115 return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \
123 return jsonrpc_error(retid=self._req_id,
124 message="JSON parse error ERR:%s RAW:%r" \
116 125 % (e, urllib.unquote_plus(raw_body)))
117 126
118 127 # check AUTH based on API KEY
@@ -126,22 +135,26 b' class JSONRPCController(WSGIController):'
126 135 self._request_params)
127 136 )
128 137 except KeyError, e:
129 return jsonrpc_error(message='Incorrect JSON query missing %s' % e)
138 return jsonrpc_error(retid=self._req_id,
139 message='Incorrect JSON query missing %s' % e)
130 140
131 141 # check if we can find this session using api_key
132 142 try:
133 143 u = User.get_by_api_key(self._req_api_key)
134 144 if u is None:
135 return jsonrpc_error(message='Invalid API KEY')
145 return jsonrpc_error(retid=self._req_id,
146 message='Invalid API KEY')
136 147 auth_u = AuthUser(u.user_id, self._req_api_key)
137 148 except Exception, e:
138 return jsonrpc_error(message='Invalid API KEY')
149 return jsonrpc_error(retid=self._req_id,
150 message='Invalid API KEY')
139 151
140 152 self._error = None
141 153 try:
142 154 self._func = self._find_method()
143 155 except AttributeError, e:
144 return jsonrpc_error(message=str(e))
156 return jsonrpc_error(retid=self._req_id,
157 message=str(e))
145 158
146 159 # now that we have a method, add self._req_params to
147 160 # self.kargs and dispatch control to WGIController
@@ -164,9 +177,12 b' class JSONRPCController(WSGIController):'
164 177 USER_SESSION_ATTR = 'apiuser'
165 178
166 179 if USER_SESSION_ATTR not in arglist:
167 return jsonrpc_error(message='This method [%s] does not support '
168 'authentication (missing %s param)' %
169 (self._func.__name__, USER_SESSION_ATTR))
180 return jsonrpc_error(
181 retid=self._req_id,
182 message='This method [%s] does not support '
183 'authentication (missing %s param)' % (
184 self._func.__name__, USER_SESSION_ATTR)
185 )
170 186
171 187 # get our arglist and check if we provided them as args
172 188 for arg, default in func_kwargs.iteritems():
@@ -179,6 +195,7 b' class JSONRPCController(WSGIController):'
179 195 # NotImplementedType (default_empty)
180 196 if (default == default_empty and arg not in self._request_params):
181 197 return jsonrpc_error(
198 retid=self._req_id,
182 199 message=(
183 200 'Missing non optional `%s` arg in JSON DATA' % arg
184 201 )
@@ -205,7 +222,10 b' class JSONRPCController(WSGIController):'
205 222 headers.append(('Content-Length', str(len(output[0]))))
206 223 replace_header(headers, 'Content-Type', 'application/json')
207 224 start_response(status[0], headers, exc_info[0])
208
225 log.info('IP: %s Request to %s time: %.3fs' % (
226 _get_ip_addr(environ),
227 safe_unicode(_get_access_path(environ)), time.time() - start)
228 )
209 229 return output
210 230
211 231 def _dispatch_call(self):
This diff has been collapsed as it changes many lines, (785 lines changed) Show them Hide them
@@ -31,18 +31,100 b' import logging'
31 31 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
32 32 from rhodecode.lib.auth import HasPermissionAllDecorator, \
33 33 HasPermissionAnyDecorator, PasswordGenerator, AuthUser
34
34 from rhodecode.lib.utils import map_groups, repo2db_mapper
35 35 from rhodecode.model.meta import Session
36 36 from rhodecode.model.scm import ScmModel
37 from rhodecode.model.db import User, UsersGroup, Repository
38 37 from rhodecode.model.repo import RepoModel
39 38 from rhodecode.model.user import UserModel
40 39 from rhodecode.model.users_group import UsersGroupModel
41 from rhodecode.lib.utils import map_groups
40 from rhodecode.model.permission import PermissionModel
41 from rhodecode.model.db import Repository
42 42
43 43 log = logging.getLogger(__name__)
44 44
45 45
46 class Optional(object):
47 """
48 Defines an optional parameter::
49
50 param = param.getval() if isinstance(param, Optional) else param
51 param = param() if isinstance(param, Optional) else param
52
53 is equivalent of::
54
55 param = Optional.extract(param)
56
57 """
58 def __init__(self, type_):
59 self.type_ = type_
60
61 def __repr__(self):
62 return '<Optional:%s>' % self.type_.__repr__()
63
64 def __call__(self):
65 return self.getval()
66
67 def getval(self):
68 """
69 returns value from this Optional instance
70 """
71 return self.type_
72
73 @classmethod
74 def extract(cls, val):
75 if isinstance(val, cls):
76 return val.getval()
77 return val
78
79
80 def get_user_or_error(userid):
81 """
82 Get user by id or name or return JsonRPCError if not found
83
84 :param userid:
85 """
86 user = UserModel().get_user(userid)
87 if user is None:
88 raise JSONRPCError("user `%s` does not exist" % userid)
89 return user
90
91
92 def get_repo_or_error(repoid):
93 """
94 Get repo by id or name or return JsonRPCError if not found
95
96 :param userid:
97 """
98 repo = RepoModel().get_repo(repoid)
99 if repo is None:
100 raise JSONRPCError('repository `%s` does not exist' % (repoid))
101 return repo
102
103
104 def get_users_group_or_error(usersgroupid):
105 """
106 Get users group by id or name or return JsonRPCError if not found
107
108 :param userid:
109 """
110 users_group = UsersGroupModel().get_group(usersgroupid)
111 if users_group is None:
112 raise JSONRPCError('users group `%s` does not exist' % usersgroupid)
113 return users_group
114
115
116 def get_perm_or_error(permid):
117 """
118 Get permission by id or name or return JsonRPCError if not found
119
120 :param userid:
121 """
122 perm = PermissionModel().get_permission_by_name(permid)
123 if perm is None:
124 raise JSONRPCError('permission `%s` does not exist' % (permid))
125 return perm
126
127
46 128 class ApiController(JSONRPCController):
47 129 """
48 130 API Controller
@@ -60,23 +142,74 b' class ApiController(JSONRPCController):'
60 142 """
61 143
62 144 @HasPermissionAllDecorator('hg.admin')
63 def pull(self, apiuser, repo_name):
145 def pull(self, apiuser, repoid):
64 146 """
65 147 Dispatch pull action on given repo
66 148
149 :param apiuser:
150 :param repoid:
151 """
67 152
68 :param user:
69 :param repo_name:
153 repo = get_repo_or_error(repoid)
154
155 try:
156 ScmModel().pull_changes(repo.repo_name,
157 self.rhodecode_user.username)
158 return 'Pulled from `%s`' % repo.repo_name
159 except Exception:
160 log.error(traceback.format_exc())
161 raise JSONRPCError(
162 'Unable to pull changes from `%s`' % repo.repo_name
163 )
164
165 @HasPermissionAllDecorator('hg.admin')
166 def rescan_repos(self, apiuser, remove_obsolete=Optional(False)):
167 """
168 Dispatch rescan repositories action. If remove_obsolete is set
169 than also delete repos that are in database but not in the filesystem.
170 aka "clean zombies"
171
172 :param apiuser:
173 :param remove_obsolete:
70 174 """
71 175
72 if Repository.is_valid(repo_name) is False:
73 raise JSONRPCError('Unknown repo "%s"' % repo_name)
74
75 176 try:
76 ScmModel().pull_changes(repo_name, self.rhodecode_user.username)
77 return 'Pulled from %s' % repo_name
177 rm_obsolete = Optional.extract(remove_obsolete)
178 added, removed = repo2db_mapper(ScmModel().repo_scan(),
179 remove_obsolete=rm_obsolete)
180 return {'added': added, 'removed': removed}
78 181 except Exception:
79 raise JSONRPCError('Unable to pull changes from "%s"' % repo_name)
182 log.error(traceback.format_exc())
183 raise JSONRPCError(
184 'Error occurred during rescan repositories action'
185 )
186
187 @HasPermissionAllDecorator('hg.admin')
188 def lock(self, apiuser, repoid, userid, locked):
189 """
190 Set locking state on particular repository by given user
191
192 :param apiuser:
193 :param repoid:
194 :param userid:
195 :param locked:
196 """
197 repo = get_repo_or_error(repoid)
198 user = get_user_or_error(userid)
199 locked = bool(locked)
200 try:
201 if locked:
202 Repository.lock(repo, user.user_id)
203 else:
204 Repository.unlock(repo)
205
206 return ('User `%s` set lock state for repo `%s` to `%s`'
207 % (user.username, repo.repo_name, locked))
208 except Exception:
209 log.error(traceback.format_exc())
210 raise JSONRPCError(
211 'Error occurred locking repository `%s`' % repo.repo_name
212 )
80 213
81 214 @HasPermissionAllDecorator('hg.admin')
82 215 def get_user(self, apiuser, userid):
@@ -84,25 +217,13 b' class ApiController(JSONRPCController):'
84 217 Get a user by username
85 218
86 219 :param apiuser:
87 :param username:
220 :param userid:
88 221 """
89 222
90 user = UserModel().get_user(userid)
91 if user is None:
92 return user
93
94 return dict(
95 id=user.user_id,
96 username=user.username,
97 firstname=user.name,
98 lastname=user.lastname,
99 email=user.email,
100 active=user.active,
101 admin=user.admin,
102 ldap_dn=user.ldap_dn,
103 last_login=user.last_login,
104 permissions=AuthUser(user_id=user.user_id).permissions
105 )
223 user = get_user_or_error(userid)
224 data = user.get_api_data()
225 data['permissions'] = AuthUser(user_id=user.user_id).permissions
226 return data
106 227
107 228 @HasPermissionAllDecorator('hg.admin')
108 229 def get_users(self, apiuser):
@@ -113,124 +234,150 b' class ApiController(JSONRPCController):'
113 234 """
114 235
115 236 result = []
116 for user in User.getAll():
117 result.append(
118 dict(
119 id=user.user_id,
120 username=user.username,
121 firstname=user.name,
122 lastname=user.lastname,
123 email=user.email,
124 active=user.active,
125 admin=user.admin,
126 ldap_dn=user.ldap_dn,
127 last_login=user.last_login,
128 )
129 )
237 for user in UserModel().get_all():
238 result.append(user.get_api_data())
130 239 return result
131 240
132 241 @HasPermissionAllDecorator('hg.admin')
133 def create_user(self, apiuser, username, email, password, firstname=None,
134 lastname=None, active=True, admin=False, ldap_dn=None):
242 def create_user(self, apiuser, username, email, password,
243 firstname=Optional(None), lastname=Optional(None),
244 active=Optional(True), admin=Optional(False),
245 ldap_dn=Optional(None)):
135 246 """
136 247 Create new user
137 248
138 249 :param apiuser:
139 250 :param username:
251 :param email:
140 252 :param password:
141 :param email:
142 :param name:
253 :param firstname:
143 254 :param lastname:
144 255 :param active:
145 256 :param admin:
146 257 :param ldap_dn:
147 258 """
148 if User.get_by_username(username):
149 raise JSONRPCError("user %s already exist" % username)
259
260 if UserModel().get_by_username(username):
261 raise JSONRPCError("user `%s` already exist" % username)
150 262
151 if User.get_by_email(email, case_insensitive=True):
152 raise JSONRPCError("email %s already exist" % email)
263 if UserModel().get_by_email(email, case_insensitive=True):
264 raise JSONRPCError("email `%s` already exist" % email)
153 265
154 if ldap_dn:
266 if Optional.extract(ldap_dn):
155 267 # generate temporary password if ldap_dn
156 268 password = PasswordGenerator().gen_password(length=8)
157 269
158 270 try:
159 usr = UserModel().create_or_update(
160 username, password, email, firstname,
161 lastname, active, admin, ldap_dn
271 user = UserModel().create_or_update(
272 username=Optional.extract(username),
273 password=Optional.extract(password),
274 email=Optional.extract(email),
275 firstname=Optional.extract(firstname),
276 lastname=Optional.extract(lastname),
277 active=Optional.extract(active),
278 admin=Optional.extract(admin),
279 ldap_dn=Optional.extract(ldap_dn)
162 280 )
163 Session.commit()
281 Session().commit()
164 282 return dict(
165 id=usr.user_id,
166 msg='created new user %s' % username
283 msg='created new user `%s`' % username,
284 user=user.get_api_data()
167 285 )
168 286 except Exception:
169 287 log.error(traceback.format_exc())
170 raise JSONRPCError('failed to create user %s' % username)
288 raise JSONRPCError('failed to create user `%s`' % username)
171 289
172 290 @HasPermissionAllDecorator('hg.admin')
173 def update_user(self, apiuser, userid, username, password, email,
174 firstname, lastname, active, admin, ldap_dn):
291 def update_user(self, apiuser, userid, username=Optional(None),
292 email=Optional(None), firstname=Optional(None),
293 lastname=Optional(None), active=Optional(None),
294 admin=Optional(None), ldap_dn=Optional(None),
295 password=Optional(None)):
175 296 """
176 297 Updates given user
177 298
178 299 :param apiuser:
300 :param userid:
179 301 :param username:
180 :param password:
181 302 :param email:
182 :param name:
303 :param firstname:
183 304 :param lastname:
184 305 :param active:
185 306 :param admin:
186 307 :param ldap_dn:
308 :param password:
187 309 """
188 if not UserModel().get_user(userid):
189 raise JSONRPCError("user %s does not exist" % username)
310
311 user = get_user_or_error(userid)
312
313 # call function and store only updated arguments
314 updates = {}
315
316 def store_update(attr, name):
317 if not isinstance(attr, Optional):
318 updates[name] = attr
190 319
191 320 try:
192 usr = UserModel().create_or_update(
193 username, password, email, firstname,
194 lastname, active, admin, ldap_dn
195 )
196 Session.commit()
321
322 store_update(username, 'username')
323 store_update(password, 'password')
324 store_update(email, 'email')
325 store_update(firstname, 'name')
326 store_update(lastname, 'lastname')
327 store_update(active, 'active')
328 store_update(admin, 'admin')
329 store_update(ldap_dn, 'ldap_dn')
330
331 user = UserModel().update_user(user, **updates)
332 Session().commit()
197 333 return dict(
198 id=usr.user_id,
199 msg='updated user %s' % username
334 msg='updated user ID:%s %s' % (user.user_id, user.username),
335 user=user.get_api_data()
200 336 )
201 337 except Exception:
202 338 log.error(traceback.format_exc())
203 raise JSONRPCError('failed to update user %s' % username)
339 raise JSONRPCError('failed to update user `%s`' % userid)
204 340
205 341 @HasPermissionAllDecorator('hg.admin')
206 def get_users_group(self, apiuser, group_name):
342 def delete_user(self, apiuser, userid):
207 343 """"
208 Get users group by name
344 Deletes an user
209 345
210 346 :param apiuser:
211 :param group_name:
347 :param userid:
212 348 """
349 user = get_user_or_error(userid)
213 350
214 users_group = UsersGroup.get_by_group_name(group_name)
215 if not users_group:
216 return None
351 try:
352 UserModel().delete(userid)
353 Session().commit()
354 return dict(
355 msg='deleted user ID:%s %s' % (user.user_id, user.username),
356 user=None
357 )
358 except Exception:
359 log.error(traceback.format_exc())
360 raise JSONRPCError('failed to delete ID:%s %s' % (user.user_id,
361 user.username))
362
363 @HasPermissionAllDecorator('hg.admin')
364 def get_users_group(self, apiuser, usersgroupid):
365 """"
366 Get users group by name or id
367
368 :param apiuser:
369 :param usersgroupid:
370 """
371 users_group = get_users_group_or_error(usersgroupid)
372
373 data = users_group.get_api_data()
217 374
218 375 members = []
219 376 for user in users_group.members:
220 377 user = user.user
221 members.append(dict(id=user.user_id,
222 username=user.username,
223 firstname=user.name,
224 lastname=user.lastname,
225 email=user.email,
226 active=user.active,
227 admin=user.admin,
228 ldap=user.ldap_dn))
229
230 return dict(id=users_group.users_group_id,
231 group_name=users_group.users_group_name,
232 active=users_group.users_group_active,
233 members=members)
378 members.append(user.get_api_data())
379 data['members'] = members
380 return data
234 381
235 382 @HasPermissionAllDecorator('hg.admin')
236 383 def get_users_groups(self, apiuser):
@@ -241,107 +388,96 b' class ApiController(JSONRPCController):'
241 388 """
242 389
243 390 result = []
244 for users_group in UsersGroup.getAll():
245 members = []
246 for user in users_group.members:
247 user = user.user
248 members.append(dict(id=user.user_id,
249 username=user.username,
250 firstname=user.name,
251 lastname=user.lastname,
252 email=user.email,
253 active=user.active,
254 admin=user.admin,
255 ldap=user.ldap_dn))
256
257 result.append(dict(id=users_group.users_group_id,
258 group_name=users_group.users_group_name,
259 active=users_group.users_group_active,
260 members=members))
391 for users_group in UsersGroupModel().get_all():
392 result.append(users_group.get_api_data())
261 393 return result
262 394
263 395 @HasPermissionAllDecorator('hg.admin')
264 def create_users_group(self, apiuser, group_name, active=True):
396 def create_users_group(self, apiuser, group_name, active=Optional(True)):
265 397 """
266 398 Creates an new usergroup
267 399
400 :param apiuser:
268 401 :param group_name:
269 402 :param active:
270 403 """
271 404
272 if self.get_users_group(apiuser, group_name):
273 raise JSONRPCError("users group %s already exist" % group_name)
405 if UsersGroupModel().get_by_name(group_name):
406 raise JSONRPCError("users group `%s` already exist" % group_name)
274 407
275 408 try:
409 active = Optional.extract(active)
276 410 ug = UsersGroupModel().create(name=group_name, active=active)
277 Session.commit()
278 return dict(id=ug.users_group_id,
279 msg='created new users group %s' % group_name)
411 Session().commit()
412 return dict(
413 msg='created new users group `%s`' % group_name,
414 users_group=ug.get_api_data()
415 )
280 416 except Exception:
281 417 log.error(traceback.format_exc())
282 raise JSONRPCError('failed to create group %s' % group_name)
418 raise JSONRPCError('failed to create group `%s`' % group_name)
283 419
284 420 @HasPermissionAllDecorator('hg.admin')
285 def add_user_to_users_group(self, apiuser, group_name, username):
421 def add_user_to_users_group(self, apiuser, usersgroupid, userid):
286 422 """"
287 423 Add a user to a users group
288 424
289 425 :param apiuser:
290 :param group_name:
291 :param username:
426 :param usersgroupid:
427 :param userid:
292 428 """
429 user = get_user_or_error(userid)
430 users_group = get_users_group_or_error(usersgroupid)
293 431
294 432 try:
295 users_group = UsersGroup.get_by_group_name(group_name)
296 if not users_group:
297 raise JSONRPCError('unknown users group %s' % group_name)
298
299 user = User.get_by_username(username)
300 if user is None:
301 raise JSONRPCError('unknown user %s' % username)
302
303 433 ugm = UsersGroupModel().add_user_to_group(users_group, user)
304 434 success = True if ugm != True else False
305 msg = 'added member %s to users group %s' % (username, group_name)
435 msg = 'added member `%s` to users group `%s`' % (
436 user.username, users_group.users_group_name
437 )
306 438 msg = msg if success else 'User is already in that group'
307 Session.commit()
439 Session().commit()
308 440
309 441 return dict(
310 id=ugm.users_group_member_id if ugm != True else None,
311 442 success=success,
312 443 msg=msg
313 444 )
314 445 except Exception:
315 446 log.error(traceback.format_exc())
316 raise JSONRPCError('failed to add users group member')
447 raise JSONRPCError(
448 'failed to add member to users group `%s`' % (
449 users_group.users_group_name
450 )
451 )
317 452
318 453 @HasPermissionAllDecorator('hg.admin')
319 def remove_user_from_users_group(self, apiuser, group_name, username):
454 def remove_user_from_users_group(self, apiuser, usersgroupid, userid):
320 455 """
321 456 Remove user from a group
322 457
323 :param apiuser
324 :param group_name
325 :param username
458 :param apiuser:
459 :param usersgroupid:
460 :param userid:
326 461 """
462 user = get_user_or_error(userid)
463 users_group = get_users_group_or_error(usersgroupid)
327 464
328 465 try:
329 users_group = UsersGroup.get_by_group_name(group_name)
330 if not users_group:
331 raise JSONRPCError('unknown users group %s' % group_name)
332
333 user = User.get_by_username(username)
334 if user is None:
335 raise JSONRPCError('unknown user %s' % username)
336
337 success = UsersGroupModel().remove_user_from_group(users_group, user)
338 msg = 'removed member %s from users group %s' % (username, group_name)
466 success = UsersGroupModel().remove_user_from_group(users_group,
467 user)
468 msg = 'removed member `%s` from users group `%s`' % (
469 user.username, users_group.users_group_name
470 )
339 471 msg = msg if success else "User wasn't in group"
340 Session.commit()
472 Session().commit()
341 473 return dict(success=success, msg=msg)
342 474 except Exception:
343 475 log.error(traceback.format_exc())
344 raise JSONRPCError('failed to remove user from group')
476 raise JSONRPCError(
477 'failed to remove member from users group `%s`' % (
478 users_group.users_group_name
479 )
480 )
345 481
346 482 @HasPermissionAnyDecorator('hg.admin')
347 483 def get_repo(self, apiuser, repoid):
@@ -349,51 +485,30 b' class ApiController(JSONRPCController):'
349 485 Get repository by name
350 486
351 487 :param apiuser:
352 :param repo_name:
488 :param repoid:
353 489 """
354
355 repo = RepoModel().get_repo(repoid)
356 if repo is None:
357 raise JSONRPCError('unknown repository %s' % repo)
490 repo = get_repo_or_error(repoid)
358 491
359 492 members = []
360 493 for user in repo.repo_to_perm:
361 494 perm = user.permission.permission_name
362 495 user = user.user
363 members.append(
364 dict(
365 type="user",
366 id=user.user_id,
367 username=user.username,
368 firstname=user.name,
369 lastname=user.lastname,
370 email=user.email,
371 active=user.active,
372 admin=user.admin,
373 ldap=user.ldap_dn,
374 permission=perm
375 )
376 )
496 user_data = user.get_api_data()
497 user_data['type'] = "user"
498 user_data['permission'] = perm
499 members.append(user_data)
500
377 501 for users_group in repo.users_group_to_perm:
378 502 perm = users_group.permission.permission_name
379 503 users_group = users_group.users_group
380 members.append(
381 dict(
382 type="users_group",
383 id=users_group.users_group_id,
384 name=users_group.users_group_name,
385 active=users_group.users_group_active,
386 permission=perm
387 )
388 )
504 users_group_data = users_group.get_api_data()
505 users_group_data['type'] = "users_group"
506 users_group_data['permission'] = perm
507 members.append(users_group_data)
389 508
390 return dict(
391 id=repo.repo_id,
392 repo_name=repo.repo_name,
393 type=repo.repo_type,
394 description=repo.description,
395 members=members
396 )
509 data = repo.get_api_data()
510 data['members'] = members
511 return data
397 512
398 513 @HasPermissionAnyDecorator('hg.admin')
399 514 def get_repos(self, apiuser):
@@ -404,19 +519,12 b' class ApiController(JSONRPCController):'
404 519 """
405 520
406 521 result = []
407 for repository in Repository.getAll():
408 result.append(
409 dict(
410 id=repository.repo_id,
411 repo_name=repository.repo_name,
412 type=repository.repo_type,
413 description=repository.description
414 )
415 )
522 for repo in RepoModel().get_all():
523 result.append(repo.get_api_data())
416 524 return result
417 525
418 526 @HasPermissionAnyDecorator('hg.admin')
419 def get_repo_nodes(self, apiuser, repo_name, revision, root_path,
527 def get_repo_nodes(self, apiuser, repoid, revision, root_path,
420 528 ret_type='all'):
421 529 """
422 530 returns a list of nodes and it's children
@@ -424,13 +532,14 b' class ApiController(JSONRPCController):'
424 532 to show only files or dirs
425 533
426 534 :param apiuser:
427 :param repo_name: name of repository
535 :param repoid: name or id of repository
428 536 :param revision: revision for which listing should be done
429 537 :param root_path: path from which start displaying
430 538 :param ret_type: return type 'all|files|dirs' nodes
431 539 """
540 repo = get_repo_or_error(repoid)
432 541 try:
433 _d, _f = ScmModel().get_nodes(repo_name, revision, root_path,
542 _d, _f = ScmModel().get_nodes(repo, revision, root_path,
434 543 flat=False)
435 544 _map = {
436 545 'all': _d + _f,
@@ -440,218 +549,264 b' class ApiController(JSONRPCController):'
440 549 return _map[ret_type]
441 550 except KeyError:
442 551 raise JSONRPCError('ret_type must be one of %s' % _map.keys())
443 except Exception, e:
444 raise JSONRPCError(e)
552 except Exception:
553 log.error(traceback.format_exc())
554 raise JSONRPCError(
555 'failed to get repo: `%s` nodes' % repo.repo_name
556 )
445 557
446 558 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
447 def create_repo(self, apiuser, repo_name, owner_name, description='',
448 repo_type='hg', private=False, clone_uri=None):
559 def create_repo(self, apiuser, repo_name, owner, repo_type,
560 description=Optional(''), private=Optional(False),
561 clone_uri=Optional(None), landing_rev=Optional('tip')):
449 562 """
450 563 Create repository, if clone_url is given it makes a remote clone
564 if repo_name is withina group name the groups will be created
565 automatically if they aren't present
451 566
452 567 :param apiuser:
453 568 :param repo_name:
454 :param owner_name:
569 :param onwer:
570 :param repo_type:
455 571 :param description:
456 :param repo_type:
457 572 :param private:
458 573 :param clone_uri:
574 :param landing_rev:
459 575 """
576 owner = get_user_or_error(owner)
577
578 if RepoModel().get_by_repo_name(repo_name):
579 raise JSONRPCError("repo `%s` already exist" % repo_name)
580
581 private = Optional.extract(private)
582 clone_uri = Optional.extract(clone_uri)
583 description = Optional.extract(description)
584 landing_rev = Optional.extract(landing_rev)
460 585
461 586 try:
462 owner = User.get_by_username(owner_name)
463 if owner is None:
464 raise JSONRPCError('unknown user %s' % owner_name)
465
466 if Repository.get_by_repo_name(repo_name):
467 raise JSONRPCError("repo %s already exist" % repo_name)
468
469 groups = repo_name.split(Repository.url_sep())
470 real_name = groups[-1]
471 # create structure of groups
587 # create structure of groups and return the last group
472 588 group = map_groups(repo_name)
473 589
474 repo = RepoModel().create(
475 dict(
476 repo_name=real_name,
477 repo_name_full=repo_name,
478 description=description,
479 private=private,
480 repo_type=repo_type,
481 repo_group=group.group_id if group else None,
482 clone_uri=clone_uri
483 ),
484 owner
590 repo = RepoModel().create_repo(
591 repo_name=repo_name,
592 repo_type=repo_type,
593 description=description,
594 owner=owner,
595 private=private,
596 clone_uri=clone_uri,
597 repos_group=group,
598 landing_rev=landing_rev,
485 599 )
486 Session.commit()
600
601 Session().commit()
487 602
488 603 return dict(
489 id=repo.repo_id,
490 msg="Created new repository %s" % repo.repo_name
604 msg="Created new repository `%s`" % (repo.repo_name),
605 repo=repo.get_api_data()
491 606 )
492 607
493 608 except Exception:
494 609 log.error(traceback.format_exc())
495 raise JSONRPCError('failed to create repository %s' % repo_name)
610 raise JSONRPCError('failed to create repository `%s`' % repo_name)
496 611
497 612 @HasPermissionAnyDecorator('hg.admin')
498 def delete_repo(self, apiuser, repo_name):
499 """
500 Deletes a given repository
613 def fork_repo(self, apiuser, repoid, fork_name, owner,
614 description=Optional(''), copy_permissions=Optional(False),
615 private=Optional(False), landing_rev=Optional('tip')):
616 repo = get_repo_or_error(repoid)
617 repo_name = repo.repo_name
618 owner = get_user_or_error(owner)
619
620 _repo = RepoModel().get_by_repo_name(fork_name)
621 if _repo:
622 type_ = 'fork' if _repo.fork else 'repo'
623 raise JSONRPCError("%s `%s` already exist" % (type_, fork_name))
624
625 try:
626 # create structure of groups and return the last group
627 group = map_groups(fork_name)
501 628
502 :param repo_name:
503 """
504 if not Repository.get_by_repo_name(repo_name):
505 raise JSONRPCError("repo %s does not exist" % repo_name)
506 try:
507 RepoModel().delete(repo_name)
508 Session.commit()
629 form_data = dict(
630 repo_name=fork_name,
631 repo_name_full=fork_name,
632 repo_group=group,
633 repo_type=repo.repo_type,
634 description=Optional.extract(description),
635 private=Optional.extract(private),
636 copy_permissions=Optional.extract(copy_permissions),
637 landing_rev=Optional.extract(landing_rev),
638 update_after_clone=False,
639 fork_parent_id=repo.repo_id,
640 )
641 RepoModel().create_fork(form_data, cur_user=owner)
509 642 return dict(
510 msg='Deleted repository %s' % repo_name
643 msg='Created fork of `%s` as `%s`' % (repo.repo_name,
644 fork_name),
645 success=True # cannot return the repo data here since fork
646 # cann be done async
511 647 )
512 648 except Exception:
513 649 log.error(traceback.format_exc())
514 raise JSONRPCError('failed to delete repository %s' % repo_name)
650 raise JSONRPCError(
651 'failed to fork repository `%s` as `%s`' % (repo_name,
652 fork_name)
653 )
515 654
516 655 @HasPermissionAnyDecorator('hg.admin')
517 def grant_user_permission(self, apiuser, repo_name, username, perm):
656 def delete_repo(self, apiuser, repoid):
518 657 """
519 Grant permission for user on given repository, or update existing one
520 if found
658 Deletes a given repository
521 659
522 :param repo_name:
523 :param username:
524 :param perm:
660 :param apiuser:
661 :param repoid:
525 662 """
663 repo = get_repo_or_error(repoid)
526 664
527 665 try:
528 repo = Repository.get_by_repo_name(repo_name)
529 if repo is None:
530 raise JSONRPCError('unknown repository %s' % repo)
531
532 user = User.get_by_username(username)
533 if user is None:
534 raise JSONRPCError('unknown user %s' % username)
535
536 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
537
538 Session.commit()
666 RepoModel().delete(repo)
667 Session().commit()
539 668 return dict(
540 msg='Granted perm: %s for user: %s in repo: %s' % (
541 perm, username, repo_name
542 )
669 msg='Deleted repository `%s`' % repo.repo_name,
670 success=True
543 671 )
544 672 except Exception:
545 673 log.error(traceback.format_exc())
546 674 raise JSONRPCError(
547 'failed to edit permission %(repo)s for %(user)s' % dict(
548 user=username, repo=repo_name
675 'failed to delete repository `%s`' % repo.repo_name
676 )
677
678 @HasPermissionAnyDecorator('hg.admin')
679 def grant_user_permission(self, apiuser, repoid, userid, perm):
680 """
681 Grant permission for user on given repository, or update existing one
682 if found
683
684 :param repoid:
685 :param userid:
686 :param perm:
687 """
688 repo = get_repo_or_error(repoid)
689 user = get_user_or_error(userid)
690 perm = get_perm_or_error(perm)
691
692 try:
693
694 RepoModel().grant_user_permission(repo=repo, user=user, perm=perm)
695
696 Session().commit()
697 return dict(
698 msg='Granted perm: `%s` for user: `%s` in repo: `%s`' % (
699 perm.permission_name, user.username, repo.repo_name
700 ),
701 success=True
702 )
703 except Exception:
704 log.error(traceback.format_exc())
705 raise JSONRPCError(
706 'failed to edit permission for user: `%s` in repo: `%s`' % (
707 userid, repoid
549 708 )
550 709 )
551 710
552 711 @HasPermissionAnyDecorator('hg.admin')
553 def revoke_user_permission(self, apiuser, repo_name, username):
712 def revoke_user_permission(self, apiuser, repoid, userid):
554 713 """
555 714 Revoke permission for user on given repository
556 715
557 :param repo_name:
558 :param username:
716 :param apiuser:
717 :param repoid:
718 :param userid:
559 719 """
560 720
721 repo = get_repo_or_error(repoid)
722 user = get_user_or_error(userid)
561 723 try:
562 repo = Repository.get_by_repo_name(repo_name)
563 if repo is None:
564 raise JSONRPCError('unknown repository %s' % repo)
724
725 RepoModel().revoke_user_permission(repo=repo, user=user)
565 726
566 user = User.get_by_username(username)
567 if user is None:
568 raise JSONRPCError('unknown user %s' % username)
569
570 RepoModel().revoke_user_permission(repo=repo_name, user=username)
571
572 Session.commit()
727 Session().commit()
573 728 return dict(
574 msg='Revoked perm for user: %s in repo: %s' % (
575 username, repo_name
576 )
729 msg='Revoked perm for user: `%s` in repo: `%s`' % (
730 user.username, repo.repo_name
731 ),
732 success=True
577 733 )
578 734 except Exception:
579 735 log.error(traceback.format_exc())
580 736 raise JSONRPCError(
581 'failed to edit permission %(repo)s for %(user)s' % dict(
582 user=username, repo=repo_name
737 'failed to edit permission for user: `%s` in repo: `%s`' % (
738 userid, repoid
583 739 )
584 740 )
585 741
586 742 @HasPermissionAnyDecorator('hg.admin')
587 def grant_users_group_permission(self, apiuser, repo_name, group_name, perm):
743 def grant_users_group_permission(self, apiuser, repoid, usersgroupid,
744 perm):
588 745 """
589 746 Grant permission for users group on given repository, or update
590 747 existing one if found
591 748
592 :param repo_name:
593 :param group_name:
749 :param apiuser:
750 :param repoid:
751 :param usersgroupid:
594 752 :param perm:
595 753 """
754 repo = get_repo_or_error(repoid)
755 perm = get_perm_or_error(perm)
756 users_group = get_users_group_or_error(usersgroupid)
596 757
597 758 try:
598 repo = Repository.get_by_repo_name(repo_name)
599 if repo is None:
600 raise JSONRPCError('unknown repository %s' % repo)
601
602 user_group = UsersGroup.get_by_group_name(group_name)
603 if user_group is None:
604 raise JSONRPCError('unknown users group %s' % user_group)
605
606 RepoModel().grant_users_group_permission(repo=repo_name,
607 group_name=group_name,
759 RepoModel().grant_users_group_permission(repo=repo,
760 group_name=users_group,
608 761 perm=perm)
609 762
610 Session.commit()
763 Session().commit()
611 764 return dict(
612 msg='Granted perm: %s for group: %s in repo: %s' % (
613 perm, group_name, repo_name
614 )
765 msg='Granted perm: `%s` for users group: `%s` in '
766 'repo: `%s`' % (
767 perm.permission_name, users_group.users_group_name,
768 repo.repo_name
769 ),
770 success=True
615 771 )
616 772 except Exception:
773 print traceback.format_exc()
617 774 log.error(traceback.format_exc())
618 775 raise JSONRPCError(
619 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
620 usersgr=group_name, repo=repo_name
776 'failed to edit permission for users group: `%s` in '
777 'repo: `%s`' % (
778 usersgroupid, repo.repo_name
621 779 )
622 780 )
623 781
624 782 @HasPermissionAnyDecorator('hg.admin')
625 def revoke_users_group_permission(self, apiuser, repo_name, group_name):
783 def revoke_users_group_permission(self, apiuser, repoid, usersgroupid):
626 784 """
627 785 Revoke permission for users group on given repository
628 786
629 :param repo_name:
630 :param group_name:
787 :param apiuser:
788 :param repoid:
789 :param usersgroupid:
631 790 """
791 repo = get_repo_or_error(repoid)
792 users_group = get_users_group_or_error(usersgroupid)
632 793
633 794 try:
634 repo = Repository.get_by_repo_name(repo_name)
635 if repo is None:
636 raise JSONRPCError('unknown repository %s' % repo)
637
638 user_group = UsersGroup.get_by_group_name(group_name)
639 if user_group is None:
640 raise JSONRPCError('unknown users group %s' % user_group)
795 RepoModel().revoke_users_group_permission(repo=repo,
796 group_name=users_group)
641 797
642 RepoModel().revoke_users_group_permission(repo=repo_name,
643 group_name=group_name)
644
645 Session.commit()
798 Session().commit()
646 799 return dict(
647 msg='Revoked perm for group: %s in repo: %s' % (
648 group_name, repo_name
649 )
800 msg='Revoked perm for users group: `%s` in repo: `%s`' % (
801 users_group.users_group_name, repo.repo_name
802 ),
803 success=True
650 804 )
651 805 except Exception:
652 806 log.error(traceback.format_exc())
653 807 raise JSONRPCError(
654 'failed to edit permission %(repo)s for %(usersgr)s' % dict(
655 usersgr=group_name, repo=repo_name
808 'failed to edit permission for users group: `%s` in '
809 'repo: `%s`' % (
810 users_group.users_group_name, repo.repo_name
656 811 )
657 812 )
@@ -24,14 +24,15 b''
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 import binascii
27 28
28 29 from pylons import tmpl_context as c
29 import binascii
30 30
31 31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
32 32 from rhodecode.lib.base import BaseRepoController, render
33 33 from rhodecode.lib.compat import OrderedDict
34 34 from rhodecode.lib.utils2 import safe_unicode
35
35 36 log = logging.getLogger(__name__)
36 37
37 38
@@ -26,7 +26,6 b''
26 26 import logging
27 27 import traceback
28 28
29 from mercurial import graphmod
30 29 from pylons import request, url, session, tmpl_context as c
31 30 from pylons.controllers.util import redirect
32 31 from pylons.i18n.translation import _
@@ -36,9 +35,8 b' from rhodecode.lib.auth import LoginRequ'
36 35 from rhodecode.lib.base import BaseRepoController, render
37 36 from rhodecode.lib.helpers import RepoPage
38 37 from rhodecode.lib.compat import json
39
38 from rhodecode.lib.graphmod import _colored, _dagwalker
40 39 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError
41 from rhodecode.model.db import Repository
42 40
43 41 log = logging.getLogger(__name__)
44 42
@@ -60,13 +58,13 b' class ChangelogController(BaseRepoContro'
60 58 int_size = int(request.params.get('size'))
61 59 except ValueError:
62 60 int_size = default
63 int_size = int_size if int_size <= limit else limit
64 c.size = int_size
61 c.size = max(min(int_size, limit), 1)
65 62 session['changelog_size'] = c.size
66 63 session.save()
67 64 else:
68 65 c.size = int(session.get('changelog_size', default))
69
66 # min size must be 1
67 c.size = max(c.size, 1)
70 68 p = int(request.params.get('page', 1))
71 69 branch_name = request.params.get('branch', None)
72 70 try:
@@ -83,8 +81,8 b' class ChangelogController(BaseRepoContro'
83 81 items_per_page=c.size, branch=branch_name)
84 82 collection = list(c.pagination)
85 83 page_revisions = [x.raw_id for x in collection]
86 c.comments = c.rhodecode_db_repo.comments(page_revisions)
87
84 c.comments = c.rhodecode_db_repo.get_comments(page_revisions)
85 c.statuses = c.rhodecode_db_repo.statuses(page_revisions)
88 86 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
89 87 log.error(traceback.format_exc())
90 88 h.flash(str(e), category='warning')
@@ -118,18 +116,9 b' class ChangelogController(BaseRepoContro'
118 116 data = []
119 117 revs = [x.revision for x in collection]
120 118
121 if repo.alias == 'git':
122 for _ in revs:
123 vtx = [0, 1]
124 edges = [[0, 0, 1]]
125 data.append(['', vtx, edges])
126
127 elif repo.alias == 'hg':
128 dag = graphmod.dagwalker(repo._repo, revs)
129 c.dag = graphmod.colored(dag, repo._repo)
130 for (id, type, ctx, vtx, edges) in c.dag:
131 if type != graphmod.CHANGESET:
132 continue
133 data.append(['', vtx, edges])
119 dag = _dagwalker(repo, revs, repo.alias)
120 dag = _colored(dag)
121 for (id, type, ctx, vtx, edges) in dag:
122 data.append(['', vtx, edges])
134 123
135 124 c.jsdata = json.dumps(data)
@@ -40,13 +40,17 b' from rhodecode.lib.vcs.nodes import File'
40 40 import rhodecode.lib.helpers as h
41 41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
42 42 from rhodecode.lib.base import BaseRepoController, render
43 from rhodecode.lib.utils import EmptyChangeset
43 from rhodecode.lib.utils import action_logger
44 44 from rhodecode.lib.compat import OrderedDict
45 45 from rhodecode.lib import diffs
46 from rhodecode.model.db import ChangesetComment
46 from rhodecode.model.db import ChangesetComment, ChangesetStatus
47 47 from rhodecode.model.comment import ChangesetCommentsModel
48 from rhodecode.model.changeset_status import ChangesetStatusModel
48 49 from rhodecode.model.meta import Session
49 50 from rhodecode.lib.diffs import wrapped_diff
51 from rhodecode.model.repo import RepoModel
52 from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
53 from rhodecode.lib.vcs.backends.base import EmptyChangeset
50 54
51 55 log = logging.getLogger(__name__)
52 56
@@ -165,6 +169,9 b' class ChangesetController(BaseRepoContro'
165 169 def __before__(self):
166 170 super(ChangesetController, self).__before__()
167 171 c.affected_files_cut_off = 60
172 repo_model = RepoModel()
173 c.users_array = repo_model.get_users_js()
174 c.users_groups_array = repo_model.get_users_groups_js()
168 175
169 176 def index(self, revision):
170 177
@@ -201,18 +208,24 b' class ChangesetController(BaseRepoContro'
201 208
202 209 cumulative_diff = 0
203 210 c.cut_off = False # defines if cut off limit is reached
204
211 c.changeset_statuses = ChangesetStatus.STATUSES
205 212 c.comments = []
213 c.statuses = []
206 214 c.inline_comments = []
207 215 c.inline_cnt = 0
208 216 # Iterate over ranges (default changeset view is always one changeset)
209 217 for changeset in c.cs_ranges:
218
219 c.statuses.extend([ChangesetStatusModel()\
220 .get_status(c.rhodecode_db_repo.repo_id,
221 changeset.raw_id)])
222
210 223 c.comments.extend(ChangesetCommentsModel()\
211 224 .get_comments(c.rhodecode_db_repo.repo_id,
212 changeset.raw_id))
225 revision=changeset.raw_id))
213 226 inlines = ChangesetCommentsModel()\
214 227 .get_inline_comments(c.rhodecode_db_repo.repo_id,
215 changeset.raw_id)
228 revision=changeset.raw_id)
216 229 c.inline_comments.extend(inlines)
217 230 c.changes[changeset.raw_id] = []
218 231 try:
@@ -284,7 +297,7 b' class ChangesetController(BaseRepoContro'
284 297 )
285 298
286 299 # count inline comments
287 for path, lines in c.inline_comments:
300 for __, lines in c.inline_comments:
288 301 for comments in lines.values():
289 302 c.inline_cnt += len(comments)
290 303
@@ -361,15 +374,48 b' class ChangesetController(BaseRepoContro'
361 374
362 375 @jsonify
363 376 def comment(self, repo_name, revision):
377 status = request.POST.get('changeset_status')
378 change_status = request.POST.get('change_changeset_status')
379
364 380 comm = ChangesetCommentsModel().create(
365 381 text=request.POST.get('text'),
366 repo_id=c.rhodecode_db_repo.repo_id,
367 user_id=c.rhodecode_user.user_id,
382 repo=c.rhodecode_db_repo.repo_id,
383 user=c.rhodecode_user.user_id,
368 384 revision=revision,
369 385 f_path=request.POST.get('f_path'),
370 line_no=request.POST.get('line')
386 line_no=request.POST.get('line'),
387 status_change=(ChangesetStatus.get_status_lbl(status)
388 if status and change_status else None)
371 389 )
372 Session.commit()
390
391 # get status if set !
392 if status and change_status:
393 # if latest status was from pull request and it's closed
394 # disallow changing status !
395 # dont_allow_on_closed_pull_request = True !
396
397 try:
398 ChangesetStatusModel().set_status(
399 c.rhodecode_db_repo.repo_id,
400 status,
401 c.rhodecode_user.user_id,
402 comm,
403 revision=revision,
404 dont_allow_on_closed_pull_request=True
405 )
406 except StatusChangeOnClosedPullRequestError:
407 log.error(traceback.format_exc())
408 msg = _('Changing status on a changeset associated with'
409 'a closed pull request is not allowed')
410 h.flash(msg, category='warning')
411 return redirect(h.url('changeset_home', repo_name=repo_name,
412 revision=revision))
413 action_logger(self.rhodecode_user,
414 'user_commented_revision:%s' % revision,
415 c.rhodecode_db_repo, self.ip_addr, self.sa)
416
417 Session().commit()
418
373 419 if not request.environ.get('HTTP_X_PARTIAL_XHR'):
374 420 return redirect(h.url('changeset_home', repo_name=repo_name,
375 421 revision=revision))
@@ -391,7 +437,7 b' class ChangesetController(BaseRepoContro'
391 437 owner = lambda: co.author.user_id == c.rhodecode_user.user_id
392 438 if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
393 439 ChangesetCommentsModel().delete(comment=co)
394 Session.commit()
440 Session().commit()
395 441 return True
396 442 else:
397 443 raise HTTPForbidden()
@@ -28,11 +28,12 b' import logging'
28 28 from pylons import url, response, tmpl_context as c
29 29 from pylons.i18n.translation import _
30 30
31 from rhodecode.lib.utils2 import safe_unicode
31 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32
33 from rhodecode.lib import helpers as h
32 34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
33 35 from rhodecode.lib.base import BaseRepoController
34
35 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
36 from rhodecode.lib.diffs import DiffProcessor
36 37
37 38 log = logging.getLogger(__name__)
38 39
@@ -49,31 +50,36 b' class FeedController(BaseRepoController)'
49 50 self.title = self.title = _('%s %s feed') % (c.rhodecode_name, '%s')
50 51 self.language = 'en-us'
51 52 self.ttl = "5"
52 self.feed_nr = 10
53 self.feed_nr = 20
53 54
54 55 def _get_title(self, cs):
55 return "R%s:%s - %s" % (
56 cs.revision, cs.short_id, cs.message
56 return "%s" % (
57 h.shorter(cs.message, 160)
57 58 )
58 59
59 60 def __changes(self, cs):
60 61 changes = []
61 62
62 a = [safe_unicode(n.path) for n in cs.added]
63 if a:
64 changes.append('\nA ' + '\nA '.join(a))
65
66 m = [safe_unicode(n.path) for n in cs.changed]
67 if m:
68 changes.append('\nM ' + '\nM '.join(m))
63 diffprocessor = DiffProcessor(cs.diff())
64 stats = diffprocessor.prepare(inline_diff=False)
65 for st in stats:
66 st.update({'added': st['stats'][0],
67 'removed': st['stats'][1]})
68 changes.append('\n %(operation)s %(filename)s '
69 '(%(added)s lines added, %(removed)s lines removed)'
70 % st)
71 return changes
69 72
70 d = [safe_unicode(n.path) for n in cs.removed]
71 if d:
72 changes.append('\nD ' + '\nD '.join(d))
73
74 changes.append('</pre>')
75
76 return ''.join(changes)
73 def __get_desc(self, cs):
74 desc_msg = []
75 desc_msg.append('%s %s %s:<br/>' % (cs.author, _('commited on'),
76 h.fmt_date(cs.date)))
77 desc_msg.append('<pre>')
78 desc_msg.append(cs.message)
79 desc_msg.append('\n')
80 desc_msg.extend(self.__changes(cs))
81 desc_msg.append('</pre>')
82 return desc_msg
77 83
78 84 def atom(self, repo_name):
79 85 """Produce an atom-1.0 feed via feedgenerator module"""
@@ -87,15 +93,13 b' class FeedController(BaseRepoController)'
87 93 )
88 94
89 95 for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])):
90 desc_msg = []
91 desc_msg.append('%s - %s<br/><pre>' % (cs.author, cs.date))
92 desc_msg.append(self.__changes(cs))
93
94 96 feed.add_item(title=self._get_title(cs),
95 97 link=url('changeset_home', repo_name=repo_name,
96 98 revision=cs.raw_id, qualified=True),
97 99 author_name=cs.author,
98 description=''.join(desc_msg))
100 description=''.join(self.__get_desc(cs)),
101 pubdate=cs.date,
102 )
99 103
100 104 response.content_type = feed.mime_type
101 105 return feed.writeString('utf-8')
@@ -112,15 +116,12 b' class FeedController(BaseRepoController)'
112 116 )
113 117
114 118 for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])):
115 desc_msg = []
116 desc_msg.append('%s - %s<br/><pre>' % (cs.author, cs.date))
117 desc_msg.append(self.__changes(cs))
118
119 119 feed.add_item(title=self._get_title(cs),
120 120 link=url('changeset_home', repo_name=repo_name,
121 121 revision=cs.raw_id, qualified=True),
122 122 author_name=cs.author,
123 description=''.join(desc_msg),
123 description=''.join(self.__get_desc(cs)),
124 pubdate=cs.date,
124 125 )
125 126
126 127 response.content_type = feed.mime_type
@@ -32,7 +32,6 b' from pylons import request, response, tm'
32 32 from pylons.i18n.translation import _
33 33 from pylons.controllers.util import redirect
34 34 from pylons.decorators import jsonify
35 from paste.fileapp import FileApp, _FileIter
36 35
37 36 from rhodecode.lib import diffs
38 37 from rhodecode.lib import helpers as h
@@ -41,7 +40,7 b' from rhodecode.lib.compat import Ordered'
41 40 from rhodecode.lib.utils2 import convert_line_endings, detect_mode, safe_str
42 41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
43 42 from rhodecode.lib.base import BaseRepoController, render
44 from rhodecode.lib.utils import EmptyChangeset
43 from rhodecode.lib.vcs.backends.base import EmptyChangeset
45 44 from rhodecode.lib.vcs.conf import settings
46 45 from rhodecode.lib.vcs.exceptions import RepositoryError, \
47 46 ChangesetDoesNotExistError, EmptyRepositoryError, \
@@ -61,7 +60,6 b' log = logging.getLogger(__name__)'
61 60
62 61 class FilesController(BaseRepoController):
63 62
64 @LoginRequired()
65 63 def __before__(self):
66 64 super(FilesController, self).__before__()
67 65 c.cut_off_limit = self.cut_off_limit
@@ -83,8 +81,8 b' class FilesController(BaseRepoController'
83 81 url_ = url('files_add_home',
84 82 repo_name=c.repo_name,
85 83 revision=0, f_path='')
86 add_new = '<a href="%s">[%s]</a>' % (url_, _('add new'))
87 h.flash(h.literal(_('There are no files yet %s' % add_new)),
84 add_new = '<a href="%s">[%s]</a>' % (url_, _('click here to add new file'))
85 h.flash(h.literal(_('There are no files yet %s') % add_new),
88 86 category='warning')
89 87 redirect(h.url('summary_home', repo_name=repo_name))
90 88
@@ -113,6 +111,7 b' class FilesController(BaseRepoController'
113 111
114 112 return file_node
115 113
114 @LoginRequired()
116 115 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
117 116 'repository.admin')
118 117 def index(self, repo_name, revision, f_path, annotate=False):
@@ -154,16 +153,25 b' class FilesController(BaseRepoController'
154 153 c.file = c.changeset.get_node(f_path)
155 154
156 155 if c.file.is_file():
157 c.file_history = self._get_node_history(c.changeset, f_path)
156 _hist = c.changeset.get_file_history(f_path)
157 c.file_history = self._get_node_history(c.changeset, f_path,
158 _hist)
159 c.authors = []
160 for a in set([x.author for x in _hist]):
161 c.authors.append((h.email(a), h.person(a)))
158 162 else:
159 c.file_history = []
163 c.authors = c.file_history = []
160 164 except RepositoryError, e:
161 165 h.flash(str(e), category='warning')
162 166 redirect(h.url('files_home', repo_name=repo_name,
163 revision=revision))
167 revision='tip'))
168
169 if request.environ.get('HTTP_X_PARTIAL_XHR'):
170 return render('files/files_ypjax.html')
164 171
165 172 return render('files/files.html')
166 173
174 @LoginRequired()
167 175 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
168 176 'repository.admin')
169 177 def rawfile(self, repo_name, revision, f_path):
@@ -176,6 +184,7 b' class FilesController(BaseRepoController'
176 184 response.content_type = file_node.mimetype
177 185 return file_node.content
178 186
187 @LoginRequired()
179 188 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
180 189 'repository.admin')
181 190 def raw(self, repo_name, revision, f_path):
@@ -222,8 +231,18 b' class FilesController(BaseRepoController'
222 231 response.content_type = mimetype
223 232 return file_node.content
224 233
234 @LoginRequired()
225 235 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
226 236 def edit(self, repo_name, revision, f_path):
237 repo = Repository.get_by_repo_name(repo_name)
238 if repo.enable_locking and repo.locked[0]:
239 h.flash(_('This repository is has been locked by %s on %s')
240 % (h.person_by_id(repo.locked[0]),
241 h.fmt_date(h.time_to_datetime(repo.locked[1]))),
242 'warning')
243 return redirect(h.url('files_home',
244 repo_name=repo_name, revision='tip'))
245
227 246 r_post = request.POST
228 247
229 248 c.cs = self.__get_cs_or_redirect(revision, repo_name)
@@ -260,7 +279,7 b' class FilesController(BaseRepoController'
260 279 user=self.rhodecode_user,
261 280 author=author, message=message,
262 281 content=content, f_path=f_path)
263 h.flash(_('Successfully committed to %s' % f_path),
282 h.flash(_('Successfully committed to %s') % f_path,
264 283 category='success')
265 284
266 285 except Exception:
@@ -271,8 +290,19 b' class FilesController(BaseRepoController'
271 290
272 291 return render('files/files_edit.html')
273 292
293 @LoginRequired()
274 294 @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
275 295 def add(self, repo_name, revision, f_path):
296
297 repo = Repository.get_by_repo_name(repo_name)
298 if repo.enable_locking and repo.locked[0]:
299 h.flash(_('This repository is has been locked by %s on %s')
300 % (h.person_by_id(repo.locked[0]),
301 h.fmt_date(h.time_to_datetime(repo.locked[1]))),
302 'warning')
303 return redirect(h.url('files_home',
304 repo_name=repo_name, revision='tip'))
305
276 306 r_post = request.POST
277 307 c.cs = self.__get_cs_or_redirect(revision, repo_name,
278 308 redirect_after=False)
@@ -313,7 +343,7 b' class FilesController(BaseRepoController'
313 343 user=self.rhodecode_user,
314 344 author=author, message=message,
315 345 content=content, f_path=node_path)
316 h.flash(_('Successfully committed to %s' % node_path),
346 h.flash(_('Successfully committed to %s') % node_path,
317 347 category='success')
318 348 except NodeAlreadyExistsError, e:
319 349 h.flash(_(e), category='error')
@@ -325,6 +355,7 b' class FilesController(BaseRepoController'
325 355
326 356 return render('files/files_add.html')
327 357
358 @LoginRequired()
328 359 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
329 360 'repository.admin')
330 361 def archivefile(self, repo_name, fname):
@@ -361,27 +392,28 b' class FilesController(BaseRepoController'
361 392 except (ImproperArchiveTypeError, KeyError):
362 393 return _('Unknown archive type')
363 394
364 fd, _archive_name = tempfile.mkstemp(suffix='rcarchive')
365 with open(_archive_name, 'wb') as f:
366 cs.fill_archive(stream=f, kind=fileformat, subrepos=subrepos)
367
368 content_disposition = 'attachment; filename=%s-%s%s' \
369 % (repo_name, revision[:12], ext)
370 content_length = os.path.getsize(_archive_name)
395 fd, archive = tempfile.mkstemp()
396 t = open(archive, 'wb')
397 cs.fill_archive(stream=t, kind=fileformat, subrepos=subrepos)
398 t.close()
371 399
372 headers = [('Content-Disposition', str(content_disposition)),
373 ('Content-Type', str(content_type)),
374 ('Content-Length', str(content_length))]
400 def get_chunked_archive(archive):
401 stream = open(archive, 'rb')
402 while True:
403 data = stream.read(16 * 1024)
404 if not data:
405 stream.close()
406 os.close(fd)
407 os.remove(archive)
408 break
409 yield data
375 410
376 class _DestroyingFileWrapper(_FileIter):
377 def close(self):
378 self.file.close
379 os.remove(self.file.name)
411 response.content_disposition = str('attachment; filename=%s-%s%s' \
412 % (repo_name, revision[:12], ext))
413 response.content_type = str(content_type)
414 return get_chunked_archive(archive)
380 415
381 request.environ['wsgi.file_wrapper'] = _DestroyingFileWrapper
382 fapp = FileApp(_archive_name, headers=headers)
383 return fapp(request.environ, self.start_response)
384
416 @LoginRequired()
385 417 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
386 418 'repository.admin')
387 419 def diff(self, repo_name, f_path):
@@ -454,8 +486,9 b' class FilesController(BaseRepoController'
454 486
455 487 return render('files/file_diff.html')
456 488
457 def _get_node_history(self, cs, f_path):
458 changesets = cs.get_file_history(f_path)
489 def _get_node_history(self, cs, f_path, changesets=None):
490 if changesets is None:
491 changesets = cs.get_file_history(f_path)
459 492 hist_l = []
460 493
461 494 changesets_group = ([], _("Changesets"))
@@ -479,12 +512,13 b' class FilesController(BaseRepoController'
479 512
480 513 return hist_l
481 514
482 @jsonify
515 @LoginRequired()
483 516 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
484 517 'repository.admin')
518 @jsonify
485 519 def nodelist(self, repo_name, revision, f_path):
486 520 if request.environ.get('HTTP_X_PARTIAL_XHR'):
487 521 cs = self.__get_cs_or_redirect(revision, repo_name)
488 522 _d, _f = ScmModel().get_nodes(repo_name, cs.raw_id, f_path,
489 523 flat=False)
490 return _d + _f
524 return {'nodes': _d + _f}
@@ -35,11 +35,13 b' import rhodecode.lib.helpers as h'
35 35
36 36 from rhodecode.lib.helpers import Page
37 37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, \
38 NotAnonymous, HasRepoPermissionAny
38 NotAnonymous, HasRepoPermissionAny, HasPermissionAllDecorator,\
39 HasPermissionAnyDecorator
39 40 from rhodecode.lib.base import BaseRepoController, render
40 41 from rhodecode.model.db import Repository, RepoGroup, UserFollowing, User
41 42 from rhodecode.model.repo import RepoModel
42 43 from rhodecode.model.forms import RepoForkForm
44 from rhodecode.model.scm import ScmModel
43 45
44 46 log = logging.getLogger(__name__)
45 47
@@ -53,6 +55,8 b' class ForksController(BaseRepoController'
53 55 def __load_defaults(self):
54 56 c.repo_groups = RepoGroup.groups_choices()
55 57 c.repo_groups_choices = map(lambda k: unicode(k[0]), c.repo_groups)
58 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
59 c.landing_revs_choices = choices
56 60
57 61 def __load_data(self, repo_name=None):
58 62 """
@@ -120,6 +124,7 b' class ForksController(BaseRepoController'
120 124 return render('/forks/forks.html')
121 125
122 126 @NotAnonymous()
127 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
123 128 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
124 129 'repository.admin')
125 130 def fork(self, repo_name):
@@ -142,24 +147,23 b' class ForksController(BaseRepoController'
142 147 force_defaults=False
143 148 )
144 149
145
146 150 @NotAnonymous()
151 @HasPermissionAnyDecorator('hg.admin', 'hg.fork.repository')
147 152 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
148 153 'repository.admin')
149 154 def fork_create(self, repo_name):
150 155 self.__load_defaults()
151 156 c.repo_info = Repository.get_by_repo_name(repo_name)
152 157 _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
153 repo_groups=c.repo_groups_choices,)()
158 repo_groups=c.repo_groups_choices,
159 landing_revs=c.landing_revs_choices)()
154 160 form_result = {}
155 161 try:
156 162 form_result = _form.to_python(dict(request.POST))
157 # add org_path of repo so we can do a clone from it later
158 form_result['org_path'] = c.repo_info.repo_name
159 163
160 164 # create fork is done sometimes async on celery, db transaction
161 165 # management is handled there.
162 RepoModel().create_fork(form_result, self.rhodecode_user)
166 RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
163 167 h.flash(_('forked %s repository as %s') \
164 168 % (repo_name, form_result['repo_name']),
165 169 category='success')
@@ -26,7 +26,7 b''
26 26 import logging
27 27
28 28 from pylons import tmpl_context as c, request
29 from paste.httpexceptions import HTTPBadRequest
29 from webob.exc import HTTPBadRequest
30 30
31 31 from rhodecode.lib.auth import LoginRequired
32 32 from rhodecode.lib.base import BaseController, render
@@ -51,7 +51,8 b' class HomeController(BaseController):'
51 51 if request.is_xhr:
52 52 all_repos = Repository.query().order_by(Repository.repo_name).all()
53 53 c.repos_list = self.scm_model.get_repos(all_repos,
54 sort_key='name_sort')
54 sort_key='name_sort',
55 simple=True)
55 56 return render('/repo_switcher_list.html')
56 57 else:
57 58 return HTTPBadRequest()
@@ -30,7 +30,7 b' from sqlalchemy.orm import joinedload'
30 30 from webhelpers.paginate import Page
31 31 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32 32
33 from paste.httpexceptions import HTTPBadRequest
33 from webob.exc import HTTPBadRequest
34 34 from pylons import request, tmpl_context as c, response, url
35 35 from pylons.i18n.translation import _
36 36
@@ -49,8 +49,6 b' class JournalController(BaseController):'
49 49
50 50 def __before__(self):
51 51 super(JournalController, self).__before__()
52 self.rhodecode_user = self.rhodecode_user
53 self.title = _('%s public journal %s feed') % (c.rhodecode_name, '%s')
54 52 self.language = 'en-us'
55 53 self.ttl = "5"
56 54 self.feed_nr = 20
@@ -84,6 +82,30 b' class JournalController(BaseController):'
84 82 return c.journal_data
85 83 return render('journal/journal.html')
86 84
85 @LoginRequired(api_access=True)
86 @NotAnonymous()
87 def journal_atom(self):
88 """
89 Produce an atom-1.0 feed via feedgenerator module
90 """
91 following = self.sa.query(UserFollowing)\
92 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
93 .options(joinedload(UserFollowing.follows_repository))\
94 .all()
95 return self._atom_feed(following, public=False)
96
97 @LoginRequired(api_access=True)
98 @NotAnonymous()
99 def journal_rss(self):
100 """
101 Produce an rss feed via feedgenerator module
102 """
103 following = self.sa.query(UserFollowing)\
104 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
105 .options(joinedload(UserFollowing.follows_repository))\
106 .all()
107 return self._rss_feed(following, public=False)
108
87 109 def _get_daily_aggregate(self, journal):
88 110 groups = []
89 111 for k, g in groupby(journal, lambda x: x.action_as_day):
@@ -173,6 +195,80 b' class JournalController(BaseController):'
173 195 return c.journal_data
174 196 return render('journal/public_journal.html')
175 197
198 def _atom_feed(self, repos, public=True):
199 journal = self._get_journal_data(repos)
200 if public:
201 _link = url('public_journal_atom', qualified=True)
202 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
203 'atom feed')
204 else:
205 _link = url('journal_atom', qualified=True)
206 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
207
208 feed = Atom1Feed(title=_desc,
209 link=_link,
210 description=_desc,
211 language=self.language,
212 ttl=self.ttl)
213
214 for entry in journal[:self.feed_nr]:
215 action, action_extra, ico = h.action_parser(entry, feed=True)
216 title = "%s - %s %s" % (entry.user.short_contact, action(),
217 entry.repository.repo_name)
218 desc = action_extra()
219 _url = None
220 if entry.repository is not None:
221 _url = url('changelog_home',
222 repo_name=entry.repository.repo_name,
223 qualified=True)
224
225 feed.add_item(title=title,
226 pubdate=entry.action_date,
227 link=_url or url('', qualified=True),
228 author_email=entry.user.email,
229 author_name=entry.user.full_contact,
230 description=desc)
231
232 response.content_type = feed.mime_type
233 return feed.writeString('utf-8')
234
235 def _rss_feed(self, repos, public=True):
236 journal = self._get_journal_data(repos)
237 if public:
238 _link = url('public_journal_atom', qualified=True)
239 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
240 'rss feed')
241 else:
242 _link = url('journal_atom', qualified=True)
243 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
244
245 feed = Rss201rev2Feed(title=_desc,
246 link=_link,
247 description=_desc,
248 language=self.language,
249 ttl=self.ttl)
250
251 for entry in journal[:self.feed_nr]:
252 action, action_extra, ico = h.action_parser(entry, feed=True)
253 title = "%s - %s %s" % (entry.user.short_contact, action(),
254 entry.repository.repo_name)
255 desc = action_extra()
256 _url = None
257 if entry.repository is not None:
258 _url = url('changelog_home',
259 repo_name=entry.repository.repo_name,
260 qualified=True)
261
262 feed.add_item(title=title,
263 pubdate=entry.action_date,
264 link=_url or url('', qualified=True),
265 author_email=entry.user.email,
266 author_name=entry.user.full_contact,
267 description=desc)
268
269 response.content_type = feed.mime_type
270 return feed.writeString('utf-8')
271
176 272 @LoginRequired(api_access=True)
177 273 def public_journal_atom(self):
178 274 """
@@ -183,29 +279,7 b' class JournalController(BaseController):'
183 279 .options(joinedload(UserFollowing.follows_repository))\
184 280 .all()
185 281
186 journal = self._get_journal_data(c.following)
187
188 feed = Atom1Feed(title=self.title % 'atom',
189 link=url('public_journal_atom', qualified=True),
190 description=_('Public journal'),
191 language=self.language,
192 ttl=self.ttl)
193
194 for entry in journal[:self.feed_nr]:
195 #tmpl = h.action_parser(entry)[0]
196 action, action_extra = h.action_parser(entry, feed=True)
197 title = "%s - %s %s" % (entry.user.short_contact, action,
198 entry.repository.repo_name)
199 desc = action_extra()
200 feed.add_item(title=title,
201 pubdate=entry.action_date,
202 link=url('', qualified=True),
203 author_email=entry.user.email,
204 author_name=entry.user.full_contact,
205 description=desc)
206
207 response.content_type = feed.mime_type
208 return feed.writeString('utf-8')
282 return self._atom_feed(c.following)
209 283
210 284 @LoginRequired(api_access=True)
211 285 def public_journal_rss(self):
@@ -217,26 +291,4 b' class JournalController(BaseController):'
217 291 .options(joinedload(UserFollowing.follows_repository))\
218 292 .all()
219 293
220 journal = self._get_journal_data(c.following)
221
222 feed = Rss201rev2Feed(title=self.title % 'rss',
223 link=url('public_journal_rss', qualified=True),
224 description=_('Public journal'),
225 language=self.language,
226 ttl=self.ttl)
227
228 for entry in journal[:self.feed_nr]:
229 #tmpl = h.action_parser(entry)[0]
230 action, action_extra = h.action_parser(entry, feed=True)
231 title = "%s - %s %s" % (entry.user.short_contact, action,
232 entry.repository.repo_name)
233 desc = action_extra()
234 feed.add_item(title=title,
235 pubdate=entry.action_date,
236 link=url('', qualified=True),
237 author_email=entry.user.email,
238 author_name=entry.user.full_contact,
239 description=desc)
240
241 response.content_type = feed.mime_type
242 return feed.writeString('utf-8')
294 return self._rss_feed(c.following)
@@ -25,9 +25,11 b''
25 25
26 26 import logging
27 27 import formencode
28 import datetime
29 import urlparse
28 30
29 31 from formencode import htmlfill
30
32 from webob.exc import HTTPFound
31 33 from pylons.i18n.translation import _
32 34 from pylons.controllers.util import abort, redirect
33 35 from pylons import request, response, session, tmpl_context as c, url
@@ -51,7 +53,7 b' class LoginController(BaseController):'
51 53
52 54 def index(self):
53 55 # redirect if already logged in
54 c.came_from = request.GET.get('came_from', None)
56 c.came_from = request.GET.get('came_from')
55 57
56 58 if self.rhodecode_user.is_authenticated \
57 59 and self.rhodecode_user.username != 'default':
@@ -62,6 +64,7 b' class LoginController(BaseController):'
62 64 # import Login Form validator class
63 65 login_form = LoginForm()
64 66 try:
67 session.invalidate()
65 68 c.form_result = login_form.to_python(dict(request.POST))
66 69 # form checks for username/password, now we're authenticated
67 70 username = c.form_result['username']
@@ -70,22 +73,46 b' class LoginController(BaseController):'
70 73 auth_user.set_authenticated()
71 74 cs = auth_user.get_cookie_store()
72 75 session['rhodecode_user'] = cs
76 user.update_lastlogin()
77 Session().commit()
78
73 79 # If they want to be remembered, update the cookie
74 80 if c.form_result['remember'] is not False:
75 session.cookie_expires = False
76 session._set_cookie_values()
77 session._update_cookie_out()
81 _year = (datetime.datetime.now() +
82 datetime.timedelta(seconds=60 * 60 * 24 * 365))
83 session._set_cookie_expires(_year)
84
78 85 session.save()
79 86
80 87 log.info('user %s is now authenticated and stored in '
81 88 'session, session attrs %s' % (username, cs))
82 user.update_lastlogin()
83 Session.commit()
89
90 # dumps session attrs back to cookie
91 session._update_cookie_out()
84 92
93 # we set new cookie
94 headers = None
95 if session.request['set_cookie']:
96 # send set-cookie headers back to response to update cookie
97 headers = [('Set-Cookie', session.request['cookie_out'])]
98
99 allowed_schemes = ['http', 'https']
85 100 if c.came_from:
86 return redirect(c.came_from)
101 parsed = urlparse.urlparse(c.came_from)
102 server_parsed = urlparse.urlparse(url.current())
103 if parsed.scheme and parsed.scheme not in allowed_schemes:
104 log.error(
105 'Suspicious URL scheme detected %s for url %s' %
106 (parsed.scheme, parsed))
107 c.came_from = url('home')
108 elif server_parsed.netloc != parsed.netloc:
109 log.error('Suspicious NETLOC detected %s for url %s'
110 'server url is: %s' %
111 (parsed.netloc, parsed, server_parsed))
112 c.came_from = url('home')
113 raise HTTPFound(location=c.came_from, headers=headers)
87 114 else:
88 return redirect(url('home'))
115 raise HTTPFound(location=url('home'), headers=headers)
89 116
90 117 except formencode.Invalid, errors:
91 118 return htmlfill.render(
@@ -115,7 +142,7 b' class LoginController(BaseController):'
115 142 UserModel().create_registration(form_result)
116 143 h.flash(_('You have successfully registered into rhodecode'),
117 144 category='success')
118 Session.commit()
145 Session().commit()
119 146 return redirect(url('login_home'))
120 147
121 148 except formencode.Invalid, errors:
@@ -3,7 +3,7 b''
3 3 rhodecode.controllers.search
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 Search controller for rhodecode
6 Search controller for RhodeCode
7 7
8 8 :created_on: Aug 7, 2010
9 9 :author: marcink
@@ -30,7 +30,8 b' from pylons import request, config, tmpl'
30 30
31 31 from rhodecode.lib.auth import LoginRequired
32 32 from rhodecode.lib.base import BaseController, render
33 from rhodecode.lib.indexers import SCHEMA, IDX_NAME, ResultWrapper
33 from rhodecode.lib.indexers import CHGSETS_SCHEMA, SCHEMA, CHGSET_IDX_NAME, \
34 IDX_NAME, WhooshResultWrapper
34 35
35 36 from webhelpers.paginate import Page
36 37 from webhelpers.util import update_params
@@ -38,6 +39,7 b' from webhelpers.util import update_param'
38 39 from whoosh.index import open_dir, EmptyIndexError
39 40 from whoosh.qparser import QueryParser, QueryParserError
40 41 from whoosh.query import Phrase, Wildcard, Term, Prefix
42 from rhodecode.model.repo import RepoModel
41 43
42 44 log = logging.getLogger(__name__)
43 45
@@ -53,25 +55,41 b' class SearchController(BaseController):'
53 55 c.formated_results = []
54 56 c.runtime = ''
55 57 c.cur_query = request.GET.get('q', None)
56 c.cur_type = request.GET.get('type', 'source')
58 c.cur_type = request.GET.get('type', 'content')
57 59 c.cur_search = search_type = {'content': 'content',
58 'commit': 'content',
60 'commit': 'message',
59 61 'path': 'path',
60 'repository': 'repository'}\
61 .get(c.cur_type, 'content')
62 'repository': 'repository'
63 }.get(c.cur_type, 'content')
64
65 index_name = {
66 'content': IDX_NAME,
67 'commit': CHGSET_IDX_NAME,
68 'path': IDX_NAME
69 }.get(c.cur_type, IDX_NAME)
70
71 schema_defn = {
72 'content': SCHEMA,
73 'commit': CHGSETS_SCHEMA,
74 'path': SCHEMA
75 }.get(c.cur_type, SCHEMA)
76
77 log.debug('IDX: %s' % index_name)
78 log.debug('SCHEMA: %s' % schema_defn)
62 79
63 80 if c.cur_query:
64 81 cur_query = c.cur_query.lower()
82 log.debug(cur_query)
65 83
66 84 if c.cur_query:
67 85 p = int(request.params.get('page', 1))
68 86 highlight_items = set()
69 87 try:
70 88 idx = open_dir(config['app_conf']['index_dir'],
71 indexname=IDX_NAME)
89 indexname=index_name)
72 90 searcher = idx.searcher()
73 91
74 qp = QueryParser(search_type, schema=SCHEMA)
92 qp = QueryParser(search_type, schema=schema_defn)
75 93 if c.repo_name:
76 94 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
77 95 try:
@@ -83,13 +101,13 b' class SearchController(BaseController):'
83 101 highlight_items.add(query.text)
84 102 else:
85 103 for i in query.all_terms():
86 if i[0] == 'content':
104 if i[0] in ['content', 'message']:
87 105 highlight_items.add(i[1])
88 106
89 107 matcher = query.matcher(searcher)
90 108
91 log.debug(query)
92 log.debug(highlight_items)
109 log.debug('query: %s' % query)
110 log.debug('hl terms: %s' % highlight_items)
93 111 results = searcher.search(query)
94 112 res_ln = len(results)
95 113 c.runtime = '%s results (%.3f seconds)' % (
@@ -98,11 +116,11 b' class SearchController(BaseController):'
98 116
99 117 def url_generator(**kw):
100 118 return update_params("?q=%s&type=%s" \
101 % (c.cur_query, c.cur_search), **kw)
102
119 % (c.cur_query, c.cur_type), **kw)
120 repo_location = RepoModel().repos_path
103 121 c.formated_results = Page(
104 ResultWrapper(search_type, searcher, matcher,
105 highlight_items),
122 WhooshResultWrapper(search_type, searcher, matcher,
123 highlight_items, repo_location),
106 124 page=p,
107 125 item_count=res_ln,
108 126 items_per_page=10,
@@ -121,6 +139,5 b' class SearchController(BaseController):'
121 139 log.error(traceback.format_exc())
122 140 c.runtime = _('An error occurred during this search operation')
123 141
124
125 142 # Return a rendered template
126 143 return render('/search/search.html')
@@ -43,6 +43,7 b' from rhodecode.model.forms import RepoSe'
43 43 from rhodecode.model.repo import RepoModel
44 44 from rhodecode.model.db import RepoGroup
45 45 from rhodecode.model.meta import Session
46 from rhodecode.model.scm import ScmModel
46 47
47 48 log = logging.getLogger(__name__)
48 49
@@ -60,6 +61,8 b' class SettingsController(BaseRepoControl'
60 61 repo_model = RepoModel()
61 62 c.users_array = repo_model.get_users_js()
62 63 c.users_groups_array = repo_model.get_users_groups_js()
64 choices, c.landing_revs = ScmModel().get_repo_landing_revs()
65 c.landing_revs_choices = choices
63 66
64 67 @HasRepoPermissionAllDecorator('repository.admin')
65 68 def index(self, repo_name):
@@ -94,17 +97,18 b' class SettingsController(BaseRepoControl'
94 97
95 98 _form = RepoSettingsForm(edit=True,
96 99 old_data={'repo_name': repo_name},
97 repo_groups=c.repo_groups_choices)()
100 repo_groups=c.repo_groups_choices,
101 landing_revs=c.landing_revs_choices)()
98 102 try:
99 103 form_result = _form.to_python(dict(request.POST))
100 104
101 105 repo_model.update(repo_name, form_result)
102 106 invalidate_cache('get_repo_cached_%s' % repo_name)
103 h.flash(_('Repository %s updated successfully' % repo_name),
107 h.flash(_('Repository %s updated successfully') % repo_name,
104 108 category='success')
105 109 changed_name = form_result['repo_name_full']
106 110 action_logger(self.rhodecode_user, 'user_updated_repo',
107 changed_name, '', self.sa)
111 changed_name, self.ip_addr, self.sa)
108 112 Session.commit()
109 113 except formencode.Invalid, errors:
110 114 c.repo_info = repo_model.get_by_repo_name(repo_name)
@@ -145,7 +149,7 b' class SettingsController(BaseRepoControl'
145 149 return redirect(url('home'))
146 150 try:
147 151 action_logger(self.rhodecode_user, 'user_deleted_repo',
148 repo_name, '', self.sa)
152 repo_name, self.ip_addr, self.sa)
149 153 repo_model.delete(repo)
150 154 invalidate_cache('get_repo_cached_%s' % repo_name)
151 155 h.flash(_('deleted repository %s') % repo_name, category='success')
@@ -45,12 +45,13 b' from rhodecode.model.db import Statistic'
45 45 from rhodecode.lib.utils2 import safe_unicode
46 46 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
47 47 from rhodecode.lib.base import BaseRepoController, render
48 from rhodecode.lib.utils import EmptyChangeset
48 from rhodecode.lib.vcs.backends.base import EmptyChangeset
49 49 from rhodecode.lib.markup_renderer import MarkupRenderer
50 50 from rhodecode.lib.celerylib import run_task
51 51 from rhodecode.lib.celerylib.tasks import get_commits_stats
52 52 from rhodecode.lib.helpers import RepoPage
53 53 from rhodecode.lib.compat import json, OrderedDict
54 from rhodecode.lib.vcs.nodes import FileNode
54 55
55 56 log = logging.getLogger(__name__)
56 57
@@ -179,27 +180,31 b' class SummaryController(BaseRepoControll'
179 180 if c.enable_downloads:
180 181 c.download_options = self._get_download_links(c.rhodecode_repo)
181 182
182 c.readme_data, c.readme_file = self.__get_readme_data(
183 c.rhodecode_db_repo.repo_name, c.rhodecode_repo
184 )
183 c.readme_data, c.readme_file = \
184 self.__get_readme_data(c.rhodecode_db_repo)
185 185 return render('summary/summary.html')
186 186
187 def __get_readme_data(self, repo_name, repo):
187 def __get_readme_data(self, db_repo):
188 repo_name = db_repo.repo_name
188 189
189 190 @cache_region('long_term')
190 191 def _get_readme_from_cache(key):
191 192 readme_data = None
192 193 readme_file = None
193 log.debug('Fetching readme file')
194 log.debug('Looking for README file')
194 195 try:
195 cs = repo.get_changeset() # fetches TIP
196 # get's the landing revision! or tip if fails
197 cs = db_repo.get_landing_changeset()
196 198 renderer = MarkupRenderer()
197 199 for f in README_FILES:
198 200 try:
199 201 readme = cs.get_node(f)
202 if not isinstance(readme, FileNode):
203 continue
200 204 readme_file = f
205 log.debug('Found README file `%s` rendering...' %
206 readme_file)
201 207 readme_data = renderer.render(readme.content, f)
202 log.debug('Found readme %s' % readme_file)
203 208 break
204 209 except NodeDoesNotExistError:
205 210 continue
This diff has been collapsed as it changes many lines, (3687 lines changed) Show them Hide them
@@ -7,7 +7,7 b' msgid ""'
7 7 msgstr ""
8 8 "Project-Id-Version: rhodecode 0.1\n"
9 9 "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
10 "POT-Creation-Date: 2011-09-14 15:50-0300\n"
10 "POT-Creation-Date: 2012-09-02 20:30+0200\n"
11 11 "PO-Revision-Date: 2011-02-25 19:13+0100\n"
12 12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 13 "Language-Team: en <LL@li.org>\n"
@@ -17,20 +17,36 b' msgstr ""'
17 17 "Content-Transfer-Encoding: 8bit\n"
18 18 "Generated-By: Babel 0.9.6\n"
19 19
20 #: rhodecode/controllers/changeset.py:108
21 #: rhodecode/controllers/changeset.py:149
22 #: rhodecode/controllers/changeset.py:216
23 #: rhodecode/controllers/changeset.py:229
20 #: rhodecode/controllers/changelog.py:94
21 msgid "All Branches"
22 msgstr ""
23
24 #: rhodecode/controllers/changeset.py:83
25 msgid "show white space"
26 msgstr ""
27
28 #: rhodecode/controllers/changeset.py:90 rhodecode/controllers/changeset.py:97
29 msgid "ignore white space"
30 msgstr ""
31
32 #: rhodecode/controllers/changeset.py:157
33 #, python-format
34 msgid "%s line context"
35 msgstr ""
36
37 #: rhodecode/controllers/changeset.py:333
38 #: rhodecode/controllers/changeset.py:348 rhodecode/lib/diffs.py:70
24 39 msgid "binary file"
25 40 msgstr ""
26 41
27 #: rhodecode/controllers/changeset.py:123
28 #: rhodecode/controllers/changeset.py:168
29 msgid "Changeset is to big and was cut off, see raw changeset instead"
30 msgstr ""
31
32 #: rhodecode/controllers/changeset.py:159
33 msgid "Diff is to big and was cut off, see raw diff instead"
42 #: rhodecode/controllers/changeset.py:408
43 msgid ""
44 "Changing status on a changeset associated witha closed pull request is "
45 "not allowed"
46 msgstr ""
47
48 #: rhodecode/controllers/compare.py:69
49 msgid "There are no changesets yet"
34 50 msgstr ""
35 51
36 52 #: rhodecode/controllers/error.py:69
@@ -59,117 +75,107 b' msgid ""'
59 75 "fulfilling the request."
60 76 msgstr ""
61 77
62 #: rhodecode/controllers/feed.py:48
78 #: rhodecode/controllers/feed.py:49
63 79 #, python-format
64 80 msgid "Changes on %s repository"
65 81 msgstr ""
66 82
67 #: rhodecode/controllers/feed.py:49
83 #: rhodecode/controllers/feed.py:50
68 84 #, python-format
69 85 msgid "%s %s feed"
70 86 msgstr ""
71 87
72 #: rhodecode/controllers/files.py:72
73 msgid "There are no files yet"
74 msgstr ""
75
76 #: rhodecode/controllers/files.py:262
88 #: rhodecode/controllers/feed.py:75
89 msgid "commited on"
90 msgstr ""
91
92 #: rhodecode/controllers/files.py:84
93 msgid "click here to add new file"
94 msgstr ""
95
96 #: rhodecode/controllers/files.py:85
97 #, python-format
98 msgid "There are no files yet %s"
99 msgstr ""
100
101 #: rhodecode/controllers/files.py:239 rhodecode/controllers/files.py:299
102 #, python-format
103 msgid "This repository is has been locked by %s on %s"
104 msgstr ""
105
106 #: rhodecode/controllers/files.py:266
77 107 #, python-format
78 108 msgid "Edited %s via RhodeCode"
79 109 msgstr ""
80 110
81 #: rhodecode/controllers/files.py:267
82 #: rhodecode/templates/files/file_diff.html:40
111 #: rhodecode/controllers/files.py:271
83 112 msgid "No changes"
84 113 msgstr ""
85 114
86 #: rhodecode/controllers/files.py:278
115 #: rhodecode/controllers/files.py:282 rhodecode/controllers/files.py:346
87 116 #, python-format
88 117 msgid "Successfully committed to %s"
89 118 msgstr ""
90 119
91 #: rhodecode/controllers/files.py:283
120 #: rhodecode/controllers/files.py:287 rhodecode/controllers/files.py:352
92 121 msgid "Error occurred during commit"
93 122 msgstr ""
94 123
95 #: rhodecode/controllers/files.py:308
124 #: rhodecode/controllers/files.py:318
125 #, python-format
126 msgid "Added %s via RhodeCode"
127 msgstr ""
128
129 #: rhodecode/controllers/files.py:332
130 msgid "No content"
131 msgstr ""
132
133 #: rhodecode/controllers/files.py:336
134 msgid "No filename"
135 msgstr ""
136
137 #: rhodecode/controllers/files.py:378
96 138 msgid "downloads disabled"
97 139 msgstr ""
98 140
99 #: rhodecode/controllers/files.py:313
141 #: rhodecode/controllers/files.py:389
100 142 #, python-format
101 143 msgid "Unknown revision %s"
102 144 msgstr ""
103 145
104 #: rhodecode/controllers/files.py:315
146 #: rhodecode/controllers/files.py:391
105 147 msgid "Empty repository"
106 148 msgstr ""
107 149
108 #: rhodecode/controllers/files.py:317
150 #: rhodecode/controllers/files.py:393
109 151 msgid "Unknown archive type"
110 152 msgstr ""
111 153
112 #: rhodecode/controllers/files.py:385 rhodecode/controllers/files.py:398
113 msgid "Binary file"
114 msgstr ""
115
116 #: rhodecode/controllers/files.py:417
117 #: rhodecode/templates/changeset/changeset_range.html:4
118 #: rhodecode/templates/changeset/changeset_range.html:12
119 #: rhodecode/templates/changeset/changeset_range.html:29
154 #: rhodecode/controllers/files.py:494
155 #: rhodecode/templates/changeset/changeset_range.html:13
156 #: rhodecode/templates/changeset/changeset_range.html:31
120 157 msgid "Changesets"
121 158 msgstr ""
122 159
123 #: rhodecode/controllers/files.py:418 rhodecode/controllers/summary.py:175
124 #: rhodecode/templates/branches/branches.html:5
125 #: rhodecode/templates/summary/summary.html:690
160 #: rhodecode/controllers/files.py:495 rhodecode/controllers/pullrequests.py:72
161 #: rhodecode/controllers/summary.py:232 rhodecode/model/scm.py:543
126 162 msgid "Branches"
127 163 msgstr ""
128 164
129 #: rhodecode/controllers/files.py:419 rhodecode/controllers/summary.py:176
130 #: rhodecode/templates/summary/summary.html:679
131 #: rhodecode/templates/tags/tags.html:5
165 #: rhodecode/controllers/files.py:496 rhodecode/controllers/pullrequests.py:76
166 #: rhodecode/controllers/summary.py:233 rhodecode/model/scm.py:554
132 167 msgid "Tags"
133 168 msgstr ""
134 169
135 #: rhodecode/controllers/journal.py:50
170 #: rhodecode/controllers/forks.py:73 rhodecode/controllers/admin/repos.py:90
136 171 #, python-format
137 msgid "%s public journal %s feed"
138 msgstr ""
139
140 #: rhodecode/controllers/journal.py:178 rhodecode/controllers/journal.py:212
141 #: rhodecode/templates/admin/repos/repo_edit.html:171
142 #: rhodecode/templates/base/base.html:50
143 msgid "Public journal"
144 msgstr ""
145
146 #: rhodecode/controllers/login.py:111
147 msgid "You have successfully registered into rhodecode"
148 msgstr ""
149
150 #: rhodecode/controllers/login.py:133
151 msgid "Your password reset link was sent"
152 msgstr ""
153
154 #: rhodecode/controllers/login.py:155
155 172 msgid ""
156 "Your password reset was successful, new password has been sent to your "
157 "email"
158 msgstr ""
159
160 #: rhodecode/controllers/search.py:109
161 msgid "Invalid search query. Try quoting it."
162 msgstr ""
163
164 #: rhodecode/controllers/search.py:114
165 msgid "There is no index to search in. Please run whoosh indexer"
166 msgstr ""
167
168 #: rhodecode/controllers/search.py:118
169 msgid "An error occurred during this search operation"
170 msgstr ""
171
172 #: rhodecode/controllers/settings.py:61 rhodecode/controllers/settings.py:171
173 "%s repository is not mapped to db perhaps it was created or renamed from "
174 "the filesystem please run the application again in order to rescan "
175 "repositories"
176 msgstr ""
177
178 #: rhodecode/controllers/forks.py:133 rhodecode/controllers/settings.py:72
173 179 #, python-format
174 180 msgid ""
175 181 "%s repository is not mapped to db perhaps it was created or renamed from "
@@ -177,20 +183,89 b' msgid ""'
177 183 "repositories"
178 184 msgstr ""
179 185
180 #: rhodecode/controllers/settings.py:109
181 #: rhodecode/controllers/admin/repos.py:239
186 #: rhodecode/controllers/forks.py:167
187 #, python-format
188 msgid "forked %s repository as %s"
189 msgstr ""
190
191 #: rhodecode/controllers/forks.py:181
192 #, python-format
193 msgid "An error occurred during repository forking %s"
194 msgstr ""
195
196 #: rhodecode/controllers/journal.py:202 rhodecode/controllers/journal.py:239
197 msgid "public journal"
198 msgstr ""
199
200 #: rhodecode/controllers/journal.py:206 rhodecode/controllers/journal.py:243
201 #: rhodecode/templates/base/base.html:220
202 msgid "journal"
203 msgstr ""
204
205 #: rhodecode/controllers/login.py:143
206 msgid "You have successfully registered into rhodecode"
207 msgstr ""
208
209 #: rhodecode/controllers/login.py:164
210 msgid "Your password reset link was sent"
211 msgstr ""
212
213 #: rhodecode/controllers/login.py:184
214 msgid ""
215 "Your password reset was successful, new password has been sent to your "
216 "email"
217 msgstr ""
218
219 #: rhodecode/controllers/pullrequests.py:74 rhodecode/model/scm.py:549
220 msgid "Bookmarks"
221 msgstr ""
222
223 #: rhodecode/controllers/pullrequests.py:158
224 msgid "Pull request requires a title with min. 3 chars"
225 msgstr ""
226
227 #: rhodecode/controllers/pullrequests.py:160
228 msgid "error during creation of pull request"
229 msgstr ""
230
231 #: rhodecode/controllers/pullrequests.py:181
232 msgid "Successfully opened new pull request"
233 msgstr ""
234
235 #: rhodecode/controllers/pullrequests.py:184
236 msgid "Error occurred during sending pull request"
237 msgstr ""
238
239 #: rhodecode/controllers/pullrequests.py:217
240 msgid "Successfully deleted pull request"
241 msgstr ""
242
243 #: rhodecode/controllers/search.py:131
244 msgid "Invalid search query. Try quoting it."
245 msgstr ""
246
247 #: rhodecode/controllers/search.py:136
248 msgid "There is no index to search in. Please run whoosh indexer"
249 msgstr ""
250
251 #: rhodecode/controllers/search.py:140
252 msgid "An error occurred during this search operation"
253 msgstr ""
254
255 #: rhodecode/controllers/settings.py:107
256 #: rhodecode/controllers/admin/repos.py:266
182 257 #, python-format
183 258 msgid "Repository %s updated successfully"
184 259 msgstr ""
185 260
186 #: rhodecode/controllers/settings.py:126
187 #: rhodecode/controllers/admin/repos.py:257
261 #: rhodecode/controllers/settings.py:125
262 #: rhodecode/controllers/admin/repos.py:284
188 263 #, python-format
189 264 msgid "error occurred during update of repository %s"
190 265 msgstr ""
191 266
192 #: rhodecode/controllers/settings.py:144
193 #: rhodecode/controllers/admin/repos.py:275
267 #: rhodecode/controllers/settings.py:143
268 #: rhodecode/controllers/admin/repos.py:302
194 269 #, python-format
195 270 msgid ""
196 271 "%s repository is not mapped to db perhaps it was moved or renamed from "
@@ -198,111 +273,102 b' msgid ""'
198 273 "repositories"
199 274 msgstr ""
200 275
201 #: rhodecode/controllers/settings.py:156
202 #: rhodecode/controllers/admin/repos.py:287
276 #: rhodecode/controllers/settings.py:155
277 #: rhodecode/controllers/admin/repos.py:314
203 278 #, python-format
204 279 msgid "deleted repository %s"
205 280 msgstr ""
206 281
207 282 #: rhodecode/controllers/settings.py:159
208 #: rhodecode/controllers/admin/repos.py:297
209 #: rhodecode/controllers/admin/repos.py:303
283 #: rhodecode/controllers/admin/repos.py:324
284 #: rhodecode/controllers/admin/repos.py:330
210 285 #, python-format
211 286 msgid "An error occurred during deletion of %s"
212 287 msgstr ""
213 288
214 #: rhodecode/controllers/settings.py:193
215 #, python-format
216 msgid "forked %s repository as %s"
217 msgstr ""
218
219 #: rhodecode/controllers/settings.py:211
220 #, python-format
221 msgid "An error occurred during repository forking %s"
222 msgstr ""
223
224 #: rhodecode/controllers/summary.py:123
289 #: rhodecode/controllers/summary.py:138
225 290 msgid "No data loaded yet"
226 291 msgstr ""
227 292
228 #: rhodecode/controllers/summary.py:126
293 #: rhodecode/controllers/summary.py:142
294 #: rhodecode/templates/summary/summary.html:148
229 295 msgid "Statistics are disabled for this repository"
230 296 msgstr ""
231 297
232 #: rhodecode/controllers/admin/ldap_settings.py:49
233 msgid "BASE"
234 msgstr ""
235
236 298 #: rhodecode/controllers/admin/ldap_settings.py:50
237 msgid "ONELEVEL"
299 msgid "BASE"
238 300 msgstr ""
239 301
240 302 #: rhodecode/controllers/admin/ldap_settings.py:51
303 msgid "ONELEVEL"
304 msgstr ""
305
306 #: rhodecode/controllers/admin/ldap_settings.py:52
241 307 msgid "SUBTREE"
242 308 msgstr ""
243 309
244 #: rhodecode/controllers/admin/ldap_settings.py:55
245 msgid "NEVER"
246 msgstr ""
247
248 310 #: rhodecode/controllers/admin/ldap_settings.py:56
249 msgid "ALLOW"
311 msgid "NEVER"
250 312 msgstr ""
251 313
252 314 #: rhodecode/controllers/admin/ldap_settings.py:57
253 msgid "TRY"
315 msgid "ALLOW"
254 316 msgstr ""
255 317
256 318 #: rhodecode/controllers/admin/ldap_settings.py:58
257 msgid "DEMAND"
319 msgid "TRY"
258 320 msgstr ""
259 321
260 322 #: rhodecode/controllers/admin/ldap_settings.py:59
323 msgid "DEMAND"
324 msgstr ""
325
326 #: rhodecode/controllers/admin/ldap_settings.py:60
261 327 msgid "HARD"
262 328 msgstr ""
263 329
264 #: rhodecode/controllers/admin/ldap_settings.py:63
265 msgid "No encryption"
266 msgstr ""
267
268 330 #: rhodecode/controllers/admin/ldap_settings.py:64
269 msgid "LDAPS connection"
331 msgid "No encryption"
270 332 msgstr ""
271 333
272 334 #: rhodecode/controllers/admin/ldap_settings.py:65
335 msgid "LDAPS connection"
336 msgstr ""
337
338 #: rhodecode/controllers/admin/ldap_settings.py:66
273 339 msgid "START_TLS on LDAP connection"
274 340 msgstr ""
275 341
276 #: rhodecode/controllers/admin/ldap_settings.py:115
342 #: rhodecode/controllers/admin/ldap_settings.py:126
277 343 msgid "Ldap settings updated successfully"
278 344 msgstr ""
279 345
280 #: rhodecode/controllers/admin/ldap_settings.py:120
346 #: rhodecode/controllers/admin/ldap_settings.py:130
281 347 msgid "Unable to activate ldap. The \"python-ldap\" library is missing."
282 348 msgstr ""
283 349
284 #: rhodecode/controllers/admin/ldap_settings.py:134
350 #: rhodecode/controllers/admin/ldap_settings.py:147
285 351 msgid "error occurred during update of ldap settings"
286 352 msgstr ""
287 353
288 #: rhodecode/controllers/admin/permissions.py:56
289 msgid "None"
290 msgstr ""
291
292 #: rhodecode/controllers/admin/permissions.py:57
293 msgid "Read"
294 msgstr ""
295
296 #: rhodecode/controllers/admin/permissions.py:58
297 msgid "Write"
298 msgstr ""
299
300 354 #: rhodecode/controllers/admin/permissions.py:59
355 msgid "None"
356 msgstr ""
357
358 #: rhodecode/controllers/admin/permissions.py:60
359 msgid "Read"
360 msgstr ""
361
362 #: rhodecode/controllers/admin/permissions.py:61
363 msgid "Write"
364 msgstr ""
365
366 #: rhodecode/controllers/admin/permissions.py:62
301 367 #: rhodecode/templates/admin/ldap/ldap.html:9
302 368 #: rhodecode/templates/admin/permissions/permissions.html:9
303 369 #: rhodecode/templates/admin/repos/repo_add.html:9
304 370 #: rhodecode/templates/admin/repos/repo_edit.html:9
305 #: rhodecode/templates/admin/repos/repos.html:10
371 #: rhodecode/templates/admin/repos/repos.html:9
306 372 #: rhodecode/templates/admin/repos_groups/repos_groups_add.html:8
307 373 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:8
308 374 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:10
@@ -310,550 +376,871 b' msgstr ""'
310 376 #: rhodecode/templates/admin/settings/settings.html:9
311 377 #: rhodecode/templates/admin/users/user_add.html:8
312 378 #: rhodecode/templates/admin/users/user_edit.html:9
313 #: rhodecode/templates/admin/users/user_edit.html:110
379 #: rhodecode/templates/admin/users/user_edit.html:122
314 380 #: rhodecode/templates/admin/users/users.html:9
315 381 #: rhodecode/templates/admin/users_groups/users_group_add.html:8
316 382 #: rhodecode/templates/admin/users_groups/users_group_edit.html:9
317 383 #: rhodecode/templates/admin/users_groups/users_groups.html:9
318 #: rhodecode/templates/base/base.html:279
319 #: rhodecode/templates/base/base.html:366
320 #: rhodecode/templates/base/base.html:368
321 #: rhodecode/templates/base/base.html:370
384 #: rhodecode/templates/base/base.html:197
385 #: rhodecode/templates/base/base.html:337
386 #: rhodecode/templates/base/base.html:339
387 #: rhodecode/templates/base/base.html:341
322 388 msgid "Admin"
323 389 msgstr ""
324 390
325 #: rhodecode/controllers/admin/permissions.py:62
391 #: rhodecode/controllers/admin/permissions.py:65
326 392 msgid "disabled"
327 393 msgstr ""
328 394
329 #: rhodecode/controllers/admin/permissions.py:64
395 #: rhodecode/controllers/admin/permissions.py:67
330 396 msgid "allowed with manual account activation"
331 397 msgstr ""
332 398
333 #: rhodecode/controllers/admin/permissions.py:66
334 msgid "allowed with automatic account activation"
335 msgstr ""
336
337 #: rhodecode/controllers/admin/permissions.py:68
338 msgid "Disabled"
339 msgstr ""
340
341 399 #: rhodecode/controllers/admin/permissions.py:69
400 msgid "allowed with automatic account activation"
401 msgstr ""
402
403 #: rhodecode/controllers/admin/permissions.py:71
404 #: rhodecode/controllers/admin/permissions.py:74
405 msgid "Disabled"
406 msgstr ""
407
408 #: rhodecode/controllers/admin/permissions.py:72
409 #: rhodecode/controllers/admin/permissions.py:75
342 410 msgid "Enabled"
343 411 msgstr ""
344 412
345 #: rhodecode/controllers/admin/permissions.py:102
413 #: rhodecode/controllers/admin/permissions.py:116
346 414 msgid "Default permissions updated successfully"
347 415 msgstr ""
348 416
349 #: rhodecode/controllers/admin/permissions.py:119
417 #: rhodecode/controllers/admin/permissions.py:130
350 418 msgid "error occurred during update of permissions"
351 419 msgstr ""
352 420
353 #: rhodecode/controllers/admin/repos.py:96
354 #, python-format
355 msgid ""
356 "%s repository is not mapped to db perhaps it was created or renamed from "
357 "the filesystem please run the application again in order to rescan "
358 "repositories"
359 msgstr ""
360
361 #: rhodecode/controllers/admin/repos.py:172
421 #: rhodecode/controllers/admin/repos.py:123
422 msgid "--REMOVE FORK--"
423 msgstr ""
424
425 #: rhodecode/controllers/admin/repos.py:192
362 426 #, python-format
363 427 msgid "created repository %s from %s"
364 428 msgstr ""
365 429
366 #: rhodecode/controllers/admin/repos.py:176
430 #: rhodecode/controllers/admin/repos.py:196
367 431 #, python-format
368 432 msgid "created repository %s"
369 433 msgstr ""
370 434
371 #: rhodecode/controllers/admin/repos.py:205
435 #: rhodecode/controllers/admin/repos.py:227
372 436 #, python-format
373 437 msgid "error occurred during creation of repository %s"
374 438 msgstr ""
375 439
376 #: rhodecode/controllers/admin/repos.py:292
440 #: rhodecode/controllers/admin/repos.py:319
377 441 #, python-format
378 442 msgid "Cannot delete %s it still contains attached forks"
379 443 msgstr ""
380 444
381 #: rhodecode/controllers/admin/repos.py:320
445 #: rhodecode/controllers/admin/repos.py:348
382 446 msgid "An error occurred during deletion of repository user"
383 447 msgstr ""
384 448
385 #: rhodecode/controllers/admin/repos.py:335
386 msgid "An error occurred during deletion of repository users groups"
387 msgstr ""
388
389 #: rhodecode/controllers/admin/repos.py:352
390 msgid "An error occurred during deletion of repository stats"
391 msgstr ""
392
393 449 #: rhodecode/controllers/admin/repos.py:367
450 msgid "An error occurred during deletion of repository users groups"
451 msgstr ""
452
453 #: rhodecode/controllers/admin/repos.py:385
454 msgid "An error occurred during deletion of repository stats"
455 msgstr ""
456
457 #: rhodecode/controllers/admin/repos.py:402
394 458 msgid "An error occurred during cache invalidation"
395 459 msgstr ""
396 460
397 #: rhodecode/controllers/admin/repos.py:387
461 #: rhodecode/controllers/admin/repos.py:422
462 msgid "An error occurred during unlocking"
463 msgstr ""
464
465 #: rhodecode/controllers/admin/repos.py:442
398 466 msgid "Updated repository visibility in public journal"
399 467 msgstr ""
400 468
401 #: rhodecode/controllers/admin/repos.py:390
469 #: rhodecode/controllers/admin/repos.py:446
402 470 msgid "An error occurred during setting this repository in public journal"
403 471 msgstr ""
404 472
405 #: rhodecode/controllers/admin/repos.py:395 rhodecode/model/forms.py:53
473 #: rhodecode/controllers/admin/repos.py:451 rhodecode/model/validators.py:299
406 474 msgid "Token mismatch"
407 475 msgstr ""
408 476
409 #: rhodecode/controllers/admin/repos.py:408
477 #: rhodecode/controllers/admin/repos.py:464
410 478 msgid "Pulled from remote location"
411 479 msgstr ""
412 480
413 #: rhodecode/controllers/admin/repos.py:410
481 #: rhodecode/controllers/admin/repos.py:466
414 482 msgid "An error occurred during pull from remote location"
415 483 msgstr ""
416 484
417 #: rhodecode/controllers/admin/repos_groups.py:83
485 #: rhodecode/controllers/admin/repos.py:482
486 msgid "Nothing"
487 msgstr ""
488
489 #: rhodecode/controllers/admin/repos.py:484
490 #, python-format
491 msgid "Marked repo %s as fork of %s"
492 msgstr ""
493
494 #: rhodecode/controllers/admin/repos.py:488
495 msgid "An error occurred during this operation"
496 msgstr ""
497
498 #: rhodecode/controllers/admin/repos_groups.py:116
418 499 #, python-format
419 500 msgid "created repos group %s"
420 501 msgstr ""
421 502
422 #: rhodecode/controllers/admin/repos_groups.py:96
503 #: rhodecode/controllers/admin/repos_groups.py:129
423 504 #, python-format
424 505 msgid "error occurred during creation of repos group %s"
425 506 msgstr ""
426 507
427 #: rhodecode/controllers/admin/repos_groups.py:130
508 #: rhodecode/controllers/admin/repos_groups.py:163
428 509 #, python-format
429 510 msgid "updated repos group %s"
430 511 msgstr ""
431 512
432 #: rhodecode/controllers/admin/repos_groups.py:143
513 #: rhodecode/controllers/admin/repos_groups.py:176
433 514 #, python-format
434 515 msgid "error occurred during update of repos group %s"
435 516 msgstr ""
436 517
437 #: rhodecode/controllers/admin/repos_groups.py:164
518 #: rhodecode/controllers/admin/repos_groups.py:194
438 519 #, python-format
439 520 msgid "This group contains %s repositores and cannot be deleted"
440 521 msgstr ""
441 522
442 #: rhodecode/controllers/admin/repos_groups.py:171
523 #: rhodecode/controllers/admin/repos_groups.py:202
443 524 #, python-format
444 525 msgid "removed repos group %s"
445 526 msgstr ""
446 527
447 #: rhodecode/controllers/admin/repos_groups.py:175
528 #: rhodecode/controllers/admin/repos_groups.py:208
529 msgid "Cannot delete this group it still contains subgroups"
530 msgstr ""
531
532 #: rhodecode/controllers/admin/repos_groups.py:213
533 #: rhodecode/controllers/admin/repos_groups.py:218
448 534 #, python-format
449 535 msgid "error occurred during deletion of repos group %s"
450 536 msgstr ""
451 537
452 #: rhodecode/controllers/admin/settings.py:109
538 #: rhodecode/controllers/admin/repos_groups.py:238
539 msgid "An error occurred during deletion of group user"
540 msgstr ""
541
542 #: rhodecode/controllers/admin/repos_groups.py:258
543 msgid "An error occurred during deletion of group users groups"
544 msgstr ""
545
546 #: rhodecode/controllers/admin/settings.py:121
453 547 #, python-format
454 548 msgid "Repositories successfully rescanned added: %s,removed: %s"
455 549 msgstr ""
456 550
457 #: rhodecode/controllers/admin/settings.py:118
551 #: rhodecode/controllers/admin/settings.py:129
458 552 msgid "Whoosh reindex task scheduled"
459 553 msgstr ""
460 554
461 #: rhodecode/controllers/admin/settings.py:143
555 #: rhodecode/controllers/admin/settings.py:160
462 556 msgid "Updated application settings"
463 557 msgstr ""
464 558
465 #: rhodecode/controllers/admin/settings.py:148
466 #: rhodecode/controllers/admin/settings.py:215
559 #: rhodecode/controllers/admin/settings.py:164
560 #: rhodecode/controllers/admin/settings.py:275
467 561 msgid "error occurred during updating application settings"
468 562 msgstr ""
469 563
470 #: rhodecode/controllers/admin/settings.py:210
471 msgid "Updated mercurial settings"
472 msgstr ""
473
474 #: rhodecode/controllers/admin/settings.py:236
564 #: rhodecode/controllers/admin/settings.py:200
565 msgid "Updated visualisation settings"
566 msgstr ""
567
568 #: rhodecode/controllers/admin/settings.py:205
569 msgid "error occurred during updating visualisation settings"
570 msgstr ""
571
572 #: rhodecode/controllers/admin/settings.py:271
573 msgid "Updated VCS settings"
574 msgstr ""
575
576 #: rhodecode/controllers/admin/settings.py:285
475 577 msgid "Added new hook"
476 578 msgstr ""
477 579
478 #: rhodecode/controllers/admin/settings.py:247
580 #: rhodecode/controllers/admin/settings.py:297
479 581 msgid "Updated hooks"
480 582 msgstr ""
481 583
482 #: rhodecode/controllers/admin/settings.py:251
584 #: rhodecode/controllers/admin/settings.py:301
483 585 msgid "error occurred during hook creation"
484 586 msgstr ""
485 587
486 #: rhodecode/controllers/admin/settings.py:310
588 #: rhodecode/controllers/admin/settings.py:320
589 msgid "Email task created"
590 msgstr ""
591
592 #: rhodecode/controllers/admin/settings.py:375
487 593 msgid "You can't edit this user since it's crucial for entire application"
488 594 msgstr ""
489 595
490 #: rhodecode/controllers/admin/settings.py:339
596 #: rhodecode/controllers/admin/settings.py:406
491 597 msgid "Your account was updated successfully"
492 598 msgstr ""
493 599
494 #: rhodecode/controllers/admin/settings.py:359
600 #: rhodecode/controllers/admin/settings.py:421
601 #: rhodecode/controllers/admin/users.py:191
602 #, python-format
603 msgid "error occurred during update of user %s"
604 msgstr ""
605
495 606 #: rhodecode/controllers/admin/users.py:130
496 607 #, python-format
497 msgid "error occurred during update of user %s"
498 msgstr ""
499
500 #: rhodecode/controllers/admin/users.py:78
501 #, python-format
502 608 msgid "created user %s"
503 609 msgstr ""
504 610
505 #: rhodecode/controllers/admin/users.py:90
611 #: rhodecode/controllers/admin/users.py:142
506 612 #, python-format
507 613 msgid "error occurred during creation of user %s"
508 614 msgstr ""
509 615
510 #: rhodecode/controllers/admin/users.py:116
616 #: rhodecode/controllers/admin/users.py:171
511 617 msgid "User updated successfully"
512 618 msgstr ""
513 619
514 #: rhodecode/controllers/admin/users.py:146
620 #: rhodecode/controllers/admin/users.py:207
515 621 msgid "successfully deleted user"
516 622 msgstr ""
517 623
518 #: rhodecode/controllers/admin/users.py:150
624 #: rhodecode/controllers/admin/users.py:212
519 625 msgid "An error occurred during deletion of user"
520 626 msgstr ""
521 627
522 #: rhodecode/controllers/admin/users.py:166
628 #: rhodecode/controllers/admin/users.py:226
523 629 msgid "You can't edit this user"
524 630 msgstr ""
525 631
526 #: rhodecode/controllers/admin/users.py:195
527 #: rhodecode/controllers/admin/users_groups.py:202
632 #: rhodecode/controllers/admin/users.py:266
528 633 msgid "Granted 'repository create' permission to user"
529 634 msgstr ""
530 635
531 #: rhodecode/controllers/admin/users.py:204
532 #: rhodecode/controllers/admin/users_groups.py:211
636 #: rhodecode/controllers/admin/users.py:271
533 637 msgid "Revoked 'repository create' permission to user"
534 638 msgstr ""
535 639
536 #: rhodecode/controllers/admin/users_groups.py:74
640 #: rhodecode/controllers/admin/users.py:277
641 msgid "Granted 'repository fork' permission to user"
642 msgstr ""
643
644 #: rhodecode/controllers/admin/users.py:282
645 msgid "Revoked 'repository fork' permission to user"
646 msgstr ""
647
648 #: rhodecode/controllers/admin/users.py:288
649 #: rhodecode/controllers/admin/users_groups.py:255
650 msgid "An error occurred during permissions saving"
651 msgstr ""
652
653 #: rhodecode/controllers/admin/users.py:303
654 #, python-format
655 msgid "Added email %s to user"
656 msgstr ""
657
658 #: rhodecode/controllers/admin/users.py:309
659 msgid "An error occurred during email saving"
660 msgstr ""
661
662 #: rhodecode/controllers/admin/users.py:319
663 msgid "Removed email from user"
664 msgstr ""
665
666 #: rhodecode/controllers/admin/users_groups.py:84
537 667 #, python-format
538 668 msgid "created users group %s"
539 669 msgstr ""
540 670
541 #: rhodecode/controllers/admin/users_groups.py:86
671 #: rhodecode/controllers/admin/users_groups.py:95
542 672 #, python-format
543 673 msgid "error occurred during creation of users group %s"
544 674 msgstr ""
545 675
546 #: rhodecode/controllers/admin/users_groups.py:119
676 #: rhodecode/controllers/admin/users_groups.py:135
547 677 #, python-format
548 678 msgid "updated users group %s"
549 679 msgstr ""
550 680
551 #: rhodecode/controllers/admin/users_groups.py:138
681 #: rhodecode/controllers/admin/users_groups.py:157
552 682 #, python-format
553 683 msgid "error occurred during update of users group %s"
554 684 msgstr ""
555 685
556 #: rhodecode/controllers/admin/users_groups.py:154
686 #: rhodecode/controllers/admin/users_groups.py:174
557 687 msgid "successfully deleted users group"
558 688 msgstr ""
559 689
560 #: rhodecode/controllers/admin/users_groups.py:158
690 #: rhodecode/controllers/admin/users_groups.py:179
561 691 msgid "An error occurred during deletion of users group"
562 692 msgstr ""
563 693
564 #: rhodecode/lib/__init__.py:279
565 msgid "year"
566 msgstr ""
567
568 #: rhodecode/lib/__init__.py:280
569 msgid "month"
570 msgstr ""
571
572 #: rhodecode/lib/__init__.py:281
573 msgid "day"
574 msgstr ""
575
576 #: rhodecode/lib/__init__.py:282
577 msgid "hour"
578 msgstr ""
579
580 #: rhodecode/lib/__init__.py:283
581 msgid "minute"
582 msgstr ""
583
584 #: rhodecode/lib/__init__.py:284
585 msgid "second"
586 msgstr ""
587
588 #: rhodecode/lib/__init__.py:293
589 msgid "ago"
590 msgstr ""
591
592 #: rhodecode/lib/__init__.py:296
593 msgid "just now"
594 msgstr ""
595
596 #: rhodecode/lib/auth.py:377
694 #: rhodecode/controllers/admin/users_groups.py:233
695 msgid "Granted 'repository create' permission to users group"
696 msgstr ""
697
698 #: rhodecode/controllers/admin/users_groups.py:238
699 msgid "Revoked 'repository create' permission to users group"
700 msgstr ""
701
702 #: rhodecode/controllers/admin/users_groups.py:244
703 msgid "Granted 'repository fork' permission to users group"
704 msgstr ""
705
706 #: rhodecode/controllers/admin/users_groups.py:249
707 msgid "Revoked 'repository fork' permission to users group"
708 msgstr ""
709
710 #: rhodecode/lib/auth.py:499
597 711 msgid "You need to be a registered user to perform this action"
598 712 msgstr ""
599 713
600 #: rhodecode/lib/auth.py:421
714 #: rhodecode/lib/auth.py:540
601 715 msgid "You need to be a signed in to view this page"
602 716 msgstr ""
603 717
604 #: rhodecode/lib/helpers.py:307
718 #: rhodecode/lib/diffs.py:86
719 msgid "Changeset was too big and was cut off, use diff menu to display this diff"
720 msgstr ""
721
722 #: rhodecode/lib/diffs.py:96
723 msgid "No changes detected"
724 msgstr ""
725
726 #: rhodecode/lib/helpers.py:372
727 #, python-format
728 msgid "%a, %d %b %Y %H:%M:%S"
729 msgstr ""
730
731 #: rhodecode/lib/helpers.py:484
605 732 msgid "True"
606 733 msgstr ""
607 734
608 #: rhodecode/lib/helpers.py:311
735 #: rhodecode/lib/helpers.py:488
609 736 msgid "False"
610 737 msgstr ""
611 738
612 #: rhodecode/lib/helpers.py:352
739 #: rhodecode/lib/helpers.py:532
740 msgid "Changeset not found"
741 msgstr ""
742
743 #: rhodecode/lib/helpers.py:555
613 744 #, python-format
614 745 msgid "Show all combined changesets %s->%s"
615 746 msgstr ""
616 747
617 #: rhodecode/lib/helpers.py:356
748 #: rhodecode/lib/helpers.py:561
618 749 msgid "compare view"
619 750 msgstr ""
620 751
621 #: rhodecode/lib/helpers.py:365
622 msgid "and"
623 msgstr ""
624
625 #: rhodecode/lib/helpers.py:365
626 #, python-format
627 msgid "%s more"
628 msgstr ""
629
630 #: rhodecode/lib/helpers.py:367 rhodecode/templates/changelog/changelog.html:14
631 #: rhodecode/templates/changelog/changelog.html:39
632 msgid "revisions"
633 msgstr ""
634
635 #: rhodecode/lib/helpers.py:385
636 msgid "fork name "
637 msgstr ""
638
639 #: rhodecode/lib/helpers.py:388
640 msgid "[deleted] repository"
641 msgstr ""
642
643 #: rhodecode/lib/helpers.py:389 rhodecode/lib/helpers.py:393
644 msgid "[created] repository"
645 msgstr ""
646
647 #: rhodecode/lib/helpers.py:390 rhodecode/lib/helpers.py:394
648 msgid "[forked] repository"
649 msgstr ""
650
651 #: rhodecode/lib/helpers.py:391 rhodecode/lib/helpers.py:395
652 msgid "[updated] repository"
653 msgstr ""
654
655 #: rhodecode/lib/helpers.py:392
656 msgid "[delete] repository"
657 msgstr ""
658
659 #: rhodecode/lib/helpers.py:396
660 msgid "[pushed] into"
661 msgstr ""
662
663 #: rhodecode/lib/helpers.py:397
664 msgid "[committed via RhodeCode] into"
665 msgstr ""
666
667 #: rhodecode/lib/helpers.py:398
668 msgid "[pulled from remote] into"
669 msgstr ""
670
671 #: rhodecode/lib/helpers.py:399
672 msgid "[pulled] from"
673 msgstr ""
674
675 #: rhodecode/lib/helpers.py:400
676 msgid "[started following] repository"
677 msgstr ""
678
679 #: rhodecode/lib/helpers.py:401
680 msgid "[stopped following] repository"
681 msgstr ""
682
683 #: rhodecode/lib/helpers.py:577
684 #, python-format
685 msgid " and %s more"
686 msgstr ""
687
688 752 #: rhodecode/lib/helpers.py:581
753 msgid "and"
754 msgstr ""
755
756 #: rhodecode/lib/helpers.py:582
757 #, python-format
758 msgid "%s more"
759 msgstr ""
760
761 #: rhodecode/lib/helpers.py:583 rhodecode/templates/changelog/changelog.html:48
762 msgid "revisions"
763 msgstr ""
764
765 #: rhodecode/lib/helpers.py:606
766 msgid "fork name "
767 msgstr ""
768
769 #: rhodecode/lib/helpers.py:620
770 #: rhodecode/templates/pullrequests/pullrequest_show.html:4
771 #: rhodecode/templates/pullrequests/pullrequest_show.html:12
772 #, python-format
773 msgid "Pull request #%s"
774 msgstr ""
775
776 #: rhodecode/lib/helpers.py:626
777 msgid "[deleted] repository"
778 msgstr ""
779
780 #: rhodecode/lib/helpers.py:628 rhodecode/lib/helpers.py:638
781 msgid "[created] repository"
782 msgstr ""
783
784 #: rhodecode/lib/helpers.py:630
785 msgid "[created] repository as fork"
786 msgstr ""
787
788 #: rhodecode/lib/helpers.py:632 rhodecode/lib/helpers.py:640
789 msgid "[forked] repository"
790 msgstr ""
791
792 #: rhodecode/lib/helpers.py:634 rhodecode/lib/helpers.py:642
793 msgid "[updated] repository"
794 msgstr ""
795
796 #: rhodecode/lib/helpers.py:636
797 msgid "[delete] repository"
798 msgstr ""
799
800 #: rhodecode/lib/helpers.py:644
801 msgid "[created] user"
802 msgstr ""
803
804 #: rhodecode/lib/helpers.py:646
805 msgid "[updated] user"
806 msgstr ""
807
808 #: rhodecode/lib/helpers.py:648
809 msgid "[created] users group"
810 msgstr ""
811
812 #: rhodecode/lib/helpers.py:650
813 msgid "[updated] users group"
814 msgstr ""
815
816 #: rhodecode/lib/helpers.py:652
817 msgid "[commented] on revision in repository"
818 msgstr ""
819
820 #: rhodecode/lib/helpers.py:654
821 msgid "[commented] on pull request for"
822 msgstr ""
823
824 #: rhodecode/lib/helpers.py:656
825 msgid "[closed] pull request for"
826 msgstr ""
827
828 #: rhodecode/lib/helpers.py:658
829 msgid "[pushed] into"
830 msgstr ""
831
832 #: rhodecode/lib/helpers.py:660
833 msgid "[committed via RhodeCode] into repository"
834 msgstr ""
835
836 #: rhodecode/lib/helpers.py:662
837 msgid "[pulled from remote] into repository"
838 msgstr ""
839
840 #: rhodecode/lib/helpers.py:664
841 msgid "[pulled] from"
842 msgstr ""
843
844 #: rhodecode/lib/helpers.py:666
845 msgid "[started following] repository"
846 msgstr ""
847
848 #: rhodecode/lib/helpers.py:668
849 msgid "[stopped following] repository"
850 msgstr ""
851
852 #: rhodecode/lib/helpers.py:840
853 #, python-format
854 msgid " and %s more"
855 msgstr ""
856
857 #: rhodecode/lib/helpers.py:844
689 858 msgid "No Files"
690 859 msgstr ""
691 860
692 #: rhodecode/model/forms.py:66
693 msgid "Invalid username"
694 msgstr ""
695
696 #: rhodecode/model/forms.py:75
697 msgid "This username already exists"
698 msgstr ""
699
700 #: rhodecode/model/forms.py:79
861 #: rhodecode/lib/utils2.py:335
862 #, python-format
863 msgid "%d year"
864 msgid_plural "%d years"
865 msgstr[0] ""
866 msgstr[1] ""
867
868 #: rhodecode/lib/utils2.py:336
869 #, python-format
870 msgid "%d month"
871 msgid_plural "%d months"
872 msgstr[0] ""
873 msgstr[1] ""
874
875 #: rhodecode/lib/utils2.py:337
876 #, python-format
877 msgid "%d day"
878 msgid_plural "%d days"
879 msgstr[0] ""
880 msgstr[1] ""
881
882 #: rhodecode/lib/utils2.py:338
883 #, python-format
884 msgid "%d hour"
885 msgid_plural "%d hours"
886 msgstr[0] ""
887 msgstr[1] ""
888
889 #: rhodecode/lib/utils2.py:339
890 #, python-format
891 msgid "%d minute"
892 msgid_plural "%d minutes"
893 msgstr[0] ""
894 msgstr[1] ""
895
896 #: rhodecode/lib/utils2.py:340
897 #, python-format
898 msgid "%d second"
899 msgid_plural "%d seconds"
900 msgstr[0] ""
901 msgstr[1] ""
902
903 #: rhodecode/lib/utils2.py:355
904 #, python-format
905 msgid "%s ago"
906 msgstr ""
907
908 #: rhodecode/lib/utils2.py:357
909 #, python-format
910 msgid "%s and %s ago"
911 msgstr ""
912
913 #: rhodecode/lib/utils2.py:360
914 msgid "just now"
915 msgstr ""
916
917 #: rhodecode/lib/celerylib/tasks.py:269
918 msgid "password reset link"
919 msgstr ""
920
921 #: rhodecode/model/comment.py:110
922 #, python-format
923 msgid "on line %s"
924 msgstr ""
925
926 #: rhodecode/model/comment.py:157
927 msgid "[Mention]"
928 msgstr ""
929
930 #: rhodecode/model/db.py:1140
931 msgid "Repository no access"
932 msgstr ""
933
934 #: rhodecode/model/db.py:1141
935 msgid "Repository read access"
936 msgstr ""
937
938 #: rhodecode/model/db.py:1142
939 msgid "Repository write access"
940 msgstr ""
941
942 #: rhodecode/model/db.py:1143
943 msgid "Repository admin access"
944 msgstr ""
945
946 #: rhodecode/model/db.py:1145
947 msgid "Repositories Group no access"
948 msgstr ""
949
950 #: rhodecode/model/db.py:1146
951 msgid "Repositories Group read access"
952 msgstr ""
953
954 #: rhodecode/model/db.py:1147
955 msgid "Repositories Group write access"
956 msgstr ""
957
958 #: rhodecode/model/db.py:1148
959 msgid "Repositories Group admin access"
960 msgstr ""
961
962 #: rhodecode/model/db.py:1150
963 msgid "RhodeCode Administrator"
964 msgstr ""
965
966 #: rhodecode/model/db.py:1151
967 msgid "Repository creation disabled"
968 msgstr ""
969
970 #: rhodecode/model/db.py:1152
971 msgid "Repository creation enabled"
972 msgstr ""
973
974 #: rhodecode/model/db.py:1153
975 msgid "Repository forking disabled"
976 msgstr ""
977
978 #: rhodecode/model/db.py:1154
979 msgid "Repository forking enabled"
980 msgstr ""
981
982 #: rhodecode/model/db.py:1155
983 msgid "Register disabled"
984 msgstr ""
985
986 #: rhodecode/model/db.py:1156
987 msgid "Register new user with RhodeCode with manual activation"
988 msgstr ""
989
990 #: rhodecode/model/db.py:1159
991 msgid "Register new user with RhodeCode with auto activation"
992 msgstr ""
993
994 #: rhodecode/model/db.py:1579
995 msgid "Not Reviewed"
996 msgstr ""
997
998 #: rhodecode/model/db.py:1580
999 msgid "Approved"
1000 msgstr ""
1001
1002 #: rhodecode/model/db.py:1581
1003 msgid "Rejected"
1004 msgstr ""
1005
1006 #: rhodecode/model/db.py:1582
1007 msgid "Under Review"
1008 msgstr ""
1009
1010 #: rhodecode/model/forms.py:43
1011 msgid "Please enter a login"
1012 msgstr ""
1013
1014 #: rhodecode/model/forms.py:44
1015 #, python-format
1016 msgid "Enter a value %(min)i characters long or more"
1017 msgstr ""
1018
1019 #: rhodecode/model/forms.py:52
1020 msgid "Please enter a password"
1021 msgstr ""
1022
1023 #: rhodecode/model/forms.py:53
1024 #, python-format
1025 msgid "Enter %(min)i characters or more"
1026 msgstr ""
1027
1028 #: rhodecode/model/notification.py:220
1029 msgid "commented on commit"
1030 msgstr ""
1031
1032 #: rhodecode/model/notification.py:221
1033 msgid "sent message"
1034 msgstr ""
1035
1036 #: rhodecode/model/notification.py:222
1037 msgid "mentioned you"
1038 msgstr ""
1039
1040 #: rhodecode/model/notification.py:223
1041 msgid "registered in RhodeCode"
1042 msgstr ""
1043
1044 #: rhodecode/model/notification.py:224
1045 msgid "opened new pull request"
1046 msgstr ""
1047
1048 #: rhodecode/model/notification.py:225
1049 msgid "commented on pull request"
1050 msgstr ""
1051
1052 #: rhodecode/model/pull_request.py:84
1053 #, python-format
1054 msgid "%(user)s wants you to review pull request #%(pr_id)s"
1055 msgstr ""
1056
1057 #: rhodecode/model/scm.py:535
1058 msgid "latest tip"
1059 msgstr ""
1060
1061 #: rhodecode/model/user.py:230
1062 msgid "new user registration"
1063 msgstr ""
1064
1065 #: rhodecode/model/user.py:255 rhodecode/model/user.py:277
1066 #: rhodecode/model/user.py:299
1067 msgid "You can't Edit this user since it's crucial for entire application"
1068 msgstr ""
1069
1070 #: rhodecode/model/user.py:323
1071 msgid "You can't remove this user since it's crucial for entire application"
1072 msgstr ""
1073
1074 #: rhodecode/model/user.py:329
1075 #, python-format
1076 msgid ""
1077 "user \"%s\" still owns %s repositories and cannot be removed. Switch "
1078 "owners or remove those repositories. %s"
1079 msgstr ""
1080
1081 #: rhodecode/model/validators.py:35 rhodecode/model/validators.py:36
1082 msgid "Value cannot be an empty list"
1083 msgstr ""
1084
1085 #: rhodecode/model/validators.py:82
1086 #, python-format
1087 msgid "Username \"%(username)s\" already exists"
1088 msgstr ""
1089
1090 #: rhodecode/model/validators.py:84
1091 #, python-format
1092 msgid "Username \"%(username)s\" is forbidden"
1093 msgstr ""
1094
1095 #: rhodecode/model/validators.py:86
701 1096 msgid ""
702 1097 "Username may only contain alphanumeric characters underscores, periods or"
703 1098 " dashes and must begin with alphanumeric character"
704 1099 msgstr ""
705 1100
706 #: rhodecode/model/forms.py:94
707 msgid "Invalid group name"
708 msgstr ""
709
710 #: rhodecode/model/forms.py:104
711 msgid "This users group already exists"
712 msgstr ""
713
714 #: rhodecode/model/forms.py:110
1101 #: rhodecode/model/validators.py:114
1102 #, python-format
1103 msgid "Username %(username)s is not valid"
1104 msgstr ""
1105
1106 #: rhodecode/model/validators.py:133
1107 msgid "Invalid users group name"
1108 msgstr ""
1109
1110 #: rhodecode/model/validators.py:134
1111 #, python-format
1112 msgid "Users group \"%(usersgroup)s\" already exists"
1113 msgstr ""
1114
1115 #: rhodecode/model/validators.py:136
715 1116 msgid ""
716 "Group name may only contain alphanumeric characters underscores, periods "
717 "or dashes and must begin with alphanumeric character"
718 msgstr ""
719
720 #: rhodecode/model/forms.py:132
1117 "users group name may only contain alphanumeric characters underscores, "
1118 "periods or dashes and must begin with alphanumeric character"
1119 msgstr ""
1120
1121 #: rhodecode/model/validators.py:174
721 1122 msgid "Cannot assign this group as parent"
722 1123 msgstr ""
723 1124
724 #: rhodecode/model/forms.py:148
725 msgid "This group already exists"
726 msgstr ""
727
728 #: rhodecode/model/forms.py:164 rhodecode/model/forms.py:172
729 #: rhodecode/model/forms.py:180
730 msgid "Invalid characters in password"
731 msgstr ""
732
733 #: rhodecode/model/forms.py:191
1125 #: rhodecode/model/validators.py:175
1126 #, python-format
1127 msgid "Group \"%(group_name)s\" already exists"
1128 msgstr ""
1129
1130 #: rhodecode/model/validators.py:177
1131 #, python-format
1132 msgid "Repository with name \"%(group_name)s\" already exists"
1133 msgstr ""
1134
1135 #: rhodecode/model/validators.py:235
1136 msgid "Invalid characters (non-ascii) in password"
1137 msgstr ""
1138
1139 #: rhodecode/model/validators.py:250
734 1140 msgid "Passwords do not match"
735 1141 msgstr ""
736 1142
737 #: rhodecode/model/forms.py:196
1143 #: rhodecode/model/validators.py:267
738 1144 msgid "invalid password"
739 1145 msgstr ""
740 1146
741 #: rhodecode/model/forms.py:197
1147 #: rhodecode/model/validators.py:268
742 1148 msgid "invalid user name"
743 1149 msgstr ""
744 1150
745 #: rhodecode/model/forms.py:198
1151 #: rhodecode/model/validators.py:269
746 1152 msgid "Your account is disabled"
747 1153 msgstr ""
748 1154
749 #: rhodecode/model/forms.py:233
750 msgid "This username is not valid"
751 msgstr ""
752
753 #: rhodecode/model/forms.py:245
754 msgid "This repository name is disallowed"
755 msgstr ""
756
757 #: rhodecode/model/forms.py:266
1155 #: rhodecode/model/validators.py:313
1156 #, python-format
1157 msgid "Repository name %(repo)s is disallowed"
1158 msgstr ""
1159
1160 #: rhodecode/model/validators.py:315
758 1161 #, python-format
759 msgid "This repository already exists in group \"%s\""
760 msgstr ""
761
762 #: rhodecode/model/forms.py:274
763 msgid "This repository already exists"
764 msgstr ""
765
766 #: rhodecode/model/forms.py:312 rhodecode/model/forms.py:319
1162 msgid "Repository named %(repo)s already exists"
1163 msgstr ""
1164
1165 #: rhodecode/model/validators.py:316
1166 #, python-format
1167 msgid "Repository \"%(repo)s\" already exists in group \"%(group)s\""
1168 msgstr ""
1169
1170 #: rhodecode/model/validators.py:318
1171 #, python-format
1172 msgid "Repositories group with name \"%(repo)s\" already exists"
1173 msgstr ""
1174
1175 #: rhodecode/model/validators.py:431
767 1176 msgid "invalid clone url"
768 1177 msgstr ""
769 1178
770 #: rhodecode/model/forms.py:322
771 msgid "Invalid clone url, provide a valid clone http\\s url"
772 msgstr ""
773
774 #: rhodecode/model/forms.py:334
775 msgid "Fork have to be the same type as original"
776 msgstr ""
777
778 #: rhodecode/model/forms.py:341
1179 #: rhodecode/model/validators.py:432
1180 msgid "Invalid clone url, provide a valid clone http(s)/svn+http(s) url"
1181 msgstr ""
1182
1183 #: rhodecode/model/validators.py:457
1184 msgid "Fork have to be the same type as parent"
1185 msgstr ""
1186
1187 #: rhodecode/model/validators.py:478
779 1188 msgid "This username or users group name is not valid"
780 1189 msgstr ""
781 1190
782 #: rhodecode/model/forms.py:403
1191 #: rhodecode/model/validators.py:562
783 1192 msgid "This is not a valid path"
784 1193 msgstr ""
785 1194
786 #: rhodecode/model/forms.py:416
1195 #: rhodecode/model/validators.py:577
787 1196 msgid "This e-mail address is already taken"
788 1197 msgstr ""
789 1198
790 #: rhodecode/model/forms.py:427
791 msgid "This e-mail address doesn't exist."
792 msgstr ""
793
794 #: rhodecode/model/forms.py:447
1199 #: rhodecode/model/validators.py:597
1200 #, python-format
1201 msgid "e-mail \"%(email)s\" does not exist."
1202 msgstr ""
1203
1204 #: rhodecode/model/validators.py:634
795 1205 msgid ""
796 1206 "The LDAP Login attribute of the CN must be specified - this is the name "
797 "of the attribute that is equivalent to 'username'"
798 msgstr ""
799
800 #: rhodecode/model/forms.py:466
801 msgid "Please enter a login"
802 msgstr ""
803
804 #: rhodecode/model/forms.py:467
805 #, python-format
806 msgid "Enter a value %(min)i characters long or more"
807 msgstr ""
808
809 #: rhodecode/model/forms.py:475
810 msgid "Please enter a password"
811 msgstr ""
812
813 #: rhodecode/model/forms.py:476
1207 "of the attribute that is equivalent to \"username\""
1208 msgstr ""
1209
1210 #: rhodecode/model/validators.py:653
814 1211 #, python-format
815 msgid "Enter %(min)i characters or more"
816 msgstr ""
817
818 #: rhodecode/model/user.py:145
819 msgid "[RhodeCode] New User registration"
820 msgstr ""
821
822 #: rhodecode/model/user.py:157 rhodecode/model/user.py:179
823 msgid "You can't Edit this user since it's crucial for entire application"
824 msgstr ""
825
826 #: rhodecode/model/user.py:201
827 msgid "You can't remove this user since it's crucial for entire application"
828 msgstr ""
829
830 #: rhodecode/model/user.py:204
831 #, python-format
832 msgid ""
833 "This user still owns %s repositories and cannot be removed. Switch owners"
834 " or remove those repositories"
835 msgstr ""
836
837 #: rhodecode/templates/index.html:4
1212 msgid "Revisions %(revs)s are already part of pull request or have set status"
1213 msgstr ""
1214
1215 #: rhodecode/templates/index.html:3
838 1216 msgid "Dashboard"
839 1217 msgstr ""
840 1218
841 #: rhodecode/templates/index_base.html:22
842 #: rhodecode/templates/admin/users/user_edit_my_account.html:102
1219 #: rhodecode/templates/index_base.html:6
1220 #: rhodecode/templates/repo_switcher_list.html:4
1221 #: rhodecode/templates/admin/repos/repos.html:9
1222 #: rhodecode/templates/admin/users/user_edit_my_account.html:31
1223 #: rhodecode/templates/admin/users/users.html:9
1224 #: rhodecode/templates/bookmarks/bookmarks.html:10
1225 #: rhodecode/templates/branches/branches.html:9
1226 #: rhodecode/templates/journal/journal.html:40
1227 #: rhodecode/templates/tags/tags.html:10
843 1228 msgid "quick filter..."
844 1229 msgstr ""
845 1230
846 #: rhodecode/templates/index_base.html:23
847 #: rhodecode/templates/base/base.html:300
1231 #: rhodecode/templates/index_base.html:6
1232 #: rhodecode/templates/admin/repos/repos.html:9
1233 #: rhodecode/templates/base/base.html:221
848 1234 msgid "repositories"
849 1235 msgstr ""
850 1236
1237 #: rhodecode/templates/index_base.html:13
1238 #: rhodecode/templates/index_base.html:15
1239 #: rhodecode/templates/admin/repos/repos.html:21
1240 msgid "ADD REPOSITORY"
1241 msgstr ""
1242
851 1243 #: rhodecode/templates/index_base.html:29
852 #: rhodecode/templates/admin/repos/repos.html:22
853 msgid "ADD NEW REPOSITORY"
854 msgstr ""
855
856 #: rhodecode/templates/index_base.html:41
857 1244 #: rhodecode/templates/admin/repos_groups/repos_groups_add.html:32
858 1245 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:32
859 1246 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:33
@@ -862,158 +1249,158 b' msgstr ""'
862 1249 msgid "Group name"
863 1250 msgstr ""
864 1251
865 #: rhodecode/templates/index_base.html:42
866 #: rhodecode/templates/index_base.html:73
867 #: rhodecode/templates/admin/repos/repo_add_base.html:44
868 #: rhodecode/templates/admin/repos/repo_edit.html:64
869 #: rhodecode/templates/admin/repos/repos.html:31
1252 #: rhodecode/templates/index_base.html:30
1253 #: rhodecode/templates/index_base.html:71
1254 #: rhodecode/templates/index_base.html:142
1255 #: rhodecode/templates/index_base.html:168
1256 #: rhodecode/templates/admin/repos/repo_add_base.html:56
1257 #: rhodecode/templates/admin/repos/repo_edit.html:75
1258 #: rhodecode/templates/admin/repos/repos.html:72
870 1259 #: rhodecode/templates/admin/repos_groups/repos_groups_add.html:41
871 1260 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:41
872 1261 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:34
873 #: rhodecode/templates/settings/repo_fork.html:40
874 #: rhodecode/templates/settings/repo_settings.html:40
875 #: rhodecode/templates/summary/summary.html:92
1262 #: rhodecode/templates/forks/fork.html:59
1263 #: rhodecode/templates/settings/repo_settings.html:66
1264 #: rhodecode/templates/summary/summary.html:105
876 1265 msgid "Description"
877 1266 msgstr ""
878 1267
879 #: rhodecode/templates/index_base.html:53
1268 #: rhodecode/templates/index_base.html:40
880 1269 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:46
881 1270 msgid "Repositories group"
882 1271 msgstr ""
883 1272
1273 #: rhodecode/templates/index_base.html:70
1274 #: rhodecode/templates/index_base.html:166
1275 #: rhodecode/templates/admin/repos/repo_add_base.html:9
1276 #: rhodecode/templates/admin/repos/repo_edit.html:32
1277 #: rhodecode/templates/admin/repos/repos.html:70
1278 #: rhodecode/templates/admin/users/user_edit.html:192
1279 #: rhodecode/templates/admin/users/user_edit_my_account.html:59
1280 #: rhodecode/templates/admin/users/user_edit_my_account.html:157
1281 #: rhodecode/templates/admin/users/user_edit_my_account.html:193
1282 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:6
1283 #: rhodecode/templates/bookmarks/bookmarks.html:36
1284 #: rhodecode/templates/bookmarks/bookmarks_data.html:6
1285 #: rhodecode/templates/branches/branches.html:51
1286 #: rhodecode/templates/files/files_browser.html:47
1287 #: rhodecode/templates/journal/journal.html:59
1288 #: rhodecode/templates/journal/journal.html:107
1289 #: rhodecode/templates/journal/journal.html:186
1290 #: rhodecode/templates/settings/repo_settings.html:31
1291 #: rhodecode/templates/summary/summary.html:43
1292 #: rhodecode/templates/summary/summary.html:123
1293 #: rhodecode/templates/tags/tags.html:36
1294 #: rhodecode/templates/tags/tags_data.html:6
1295 msgid "Name"
1296 msgstr ""
1297
884 1298 #: rhodecode/templates/index_base.html:72
885 #: rhodecode/templates/admin/repos/repo_add_base.html:9
886 #: rhodecode/templates/admin/repos/repo_edit.html:32
887 #: rhodecode/templates/admin/repos/repos.html:30
888 #: rhodecode/templates/admin/users/user_edit_my_account.html:117
889 #: rhodecode/templates/files/files_browser.html:157
890 #: rhodecode/templates/settings/repo_settings.html:31
891 #: rhodecode/templates/summary/summary.html:31
892 #: rhodecode/templates/summary/summary.html:107
893 msgid "Name"
1299 msgid "Last change"
1300 msgstr ""
1301
1302 #: rhodecode/templates/index_base.html:73
1303 #: rhodecode/templates/index_base.html:171
1304 #: rhodecode/templates/admin/users/user_edit_my_account.html:159
1305 #: rhodecode/templates/journal/journal.html:188
1306 msgid "Tip"
894 1307 msgstr ""
895 1308
896 1309 #: rhodecode/templates/index_base.html:74
897 #: rhodecode/templates/admin/repos/repos.html:32
898 #: rhodecode/templates/summary/summary.html:114
899 msgid "Last change"
1310 #: rhodecode/templates/index_base.html:173
1311 #: rhodecode/templates/admin/repos/repo_edit.html:121
1312 #: rhodecode/templates/admin/repos/repos.html:73
1313 msgid "Owner"
900 1314 msgstr ""
901 1315
902 1316 #: rhodecode/templates/index_base.html:75
903 #: rhodecode/templates/admin/repos/repos.html:33
904 msgid "Tip"
1317 #: rhodecode/templates/summary/summary.html:48
1318 #: rhodecode/templates/summary/summary.html:51
1319 msgid "RSS"
905 1320 msgstr ""
906 1321
907 1322 #: rhodecode/templates/index_base.html:76
908 #: rhodecode/templates/admin/repos/repo_edit.html:97
909 msgid "Owner"
910 msgstr ""
911
912 #: rhodecode/templates/index_base.html:77
913 #: rhodecode/templates/journal/public_journal.html:20
914 #: rhodecode/templates/summary/summary.html:180
915 #: rhodecode/templates/summary/summary.html:183
916 msgid "RSS"
917 msgstr ""
918
919 #: rhodecode/templates/index_base.html:78
920 #: rhodecode/templates/journal/public_journal.html:23
921 #: rhodecode/templates/summary/summary.html:181
922 #: rhodecode/templates/summary/summary.html:184
923 1323 msgid "Atom"
924 1324 msgstr ""
925 1325
926 #: rhodecode/templates/index_base.html:87
927 #: rhodecode/templates/index_base.html:89
928 #: rhodecode/templates/index_base.html:91
929 #: rhodecode/templates/base/base.html:209
930 #: rhodecode/templates/base/base.html:211
931 #: rhodecode/templates/base/base.html:213
932 #: rhodecode/templates/summary/summary.html:4
933 msgid "Summary"
934 msgstr ""
935
936 #: rhodecode/templates/index_base.html:95
937 #: rhodecode/templates/index_base.html:97
938 #: rhodecode/templates/index_base.html:99
939 #: rhodecode/templates/base/base.html:225
940 #: rhodecode/templates/base/base.html:227
941 #: rhodecode/templates/base/base.html:229
942 #: rhodecode/templates/changelog/changelog.html:6
943 #: rhodecode/templates/changelog/changelog.html:14
944 msgid "Changelog"
945 msgstr ""
946
947 #: rhodecode/templates/index_base.html:103
948 #: rhodecode/templates/index_base.html:105
949 #: rhodecode/templates/index_base.html:107
950 #: rhodecode/templates/base/base.html:268
951 #: rhodecode/templates/base/base.html:270
952 #: rhodecode/templates/base/base.html:272
953 #: rhodecode/templates/files/files.html:4
954 msgid "Files"
955 msgstr ""
956
957 #: rhodecode/templates/index_base.html:116
958 #: rhodecode/templates/admin/repos/repos.html:42
959 #: rhodecode/templates/admin/users/user_edit_my_account.html:127
960 #: rhodecode/templates/summary/summary.html:48
961 msgid "Mercurial repository"
962 msgstr ""
963
964 #: rhodecode/templates/index_base.html:118
965 #: rhodecode/templates/admin/repos/repos.html:44
966 #: rhodecode/templates/admin/users/user_edit_my_account.html:129
967 #: rhodecode/templates/summary/summary.html:51
968 msgid "Git repository"
969 msgstr ""
970
971 #: rhodecode/templates/index_base.html:123
972 #: rhodecode/templates/admin/repos/repo_edit_perms.html:16
973 #: rhodecode/templates/journal/journal.html:53
974 #: rhodecode/templates/summary/summary.html:56
975 msgid "private repository"
976 msgstr ""
977
978 #: rhodecode/templates/index_base.html:125
979 #: rhodecode/templates/journal/journal.html:55
980 #: rhodecode/templates/summary/summary.html:58
981 msgid "public repository"
982 msgstr ""
983
984 #: rhodecode/templates/index_base.html:133
985 #: rhodecode/templates/base/base.html:291
986 #: rhodecode/templates/settings/repo_fork.html:13
987 msgid "fork"
988 msgstr ""
989
990 #: rhodecode/templates/index_base.html:134
991 #: rhodecode/templates/admin/repos/repos.html:60
992 #: rhodecode/templates/admin/users/user_edit_my_account.html:143
993 #: rhodecode/templates/summary/summary.html:69
994 #: rhodecode/templates/summary/summary.html:71
995 msgid "Fork of"
996 msgstr ""
997
998 #: rhodecode/templates/index_base.html:155
999 #: rhodecode/templates/admin/repos/repos.html:73
1000 msgid "No changesets yet"
1001 msgstr ""
1002
1003 #: rhodecode/templates/index_base.html:161
1004 #: rhodecode/templates/index_base.html:163
1326 #: rhodecode/templates/index_base.html:110
1327 #: rhodecode/templates/index_base.html:112
1005 1328 #, python-format
1006 1329 msgid "Subscribe to %s rss feed"
1007 1330 msgstr ""
1008 1331
1009 #: rhodecode/templates/index_base.html:168
1010 #: rhodecode/templates/index_base.html:170
1332 #: rhodecode/templates/index_base.html:117
1333 #: rhodecode/templates/index_base.html:119
1011 1334 #, python-format
1012 1335 msgid "Subscribe to %s atom feed"
1013 1336 msgstr ""
1014 1337
1338 #: rhodecode/templates/index_base.html:140
1339 msgid "Group Name"
1340 msgstr ""
1341
1342 #: rhodecode/templates/index_base.html:158
1343 #: rhodecode/templates/index_base.html:198
1344 #: rhodecode/templates/admin/repos/repos.html:94
1345 #: rhodecode/templates/admin/users/user_edit_my_account.html:179
1346 #: rhodecode/templates/admin/users/users.html:107
1347 #: rhodecode/templates/bookmarks/bookmarks.html:60
1348 #: rhodecode/templates/branches/branches.html:77
1349 #: rhodecode/templates/journal/journal.html:211
1350 #: rhodecode/templates/tags/tags.html:60
1351 msgid "Click to sort ascending"
1352 msgstr ""
1353
1354 #: rhodecode/templates/index_base.html:159
1355 #: rhodecode/templates/index_base.html:199
1356 #: rhodecode/templates/admin/repos/repos.html:95
1357 #: rhodecode/templates/admin/users/user_edit_my_account.html:180
1358 #: rhodecode/templates/admin/users/users.html:108
1359 #: rhodecode/templates/bookmarks/bookmarks.html:61
1360 #: rhodecode/templates/branches/branches.html:78
1361 #: rhodecode/templates/journal/journal.html:212
1362 #: rhodecode/templates/tags/tags.html:61
1363 msgid "Click to sort descending"
1364 msgstr ""
1365
1366 #: rhodecode/templates/index_base.html:169
1367 msgid "Last Change"
1368 msgstr ""
1369
1370 #: rhodecode/templates/index_base.html:200
1371 #: rhodecode/templates/admin/repos/repos.html:96
1372 #: rhodecode/templates/admin/users/user_edit_my_account.html:181
1373 #: rhodecode/templates/admin/users/users.html:109
1374 #: rhodecode/templates/bookmarks/bookmarks.html:62
1375 #: rhodecode/templates/branches/branches.html:79
1376 #: rhodecode/templates/journal/journal.html:213
1377 #: rhodecode/templates/tags/tags.html:62
1378 msgid "No records found."
1379 msgstr ""
1380
1381 #: rhodecode/templates/index_base.html:201
1382 #: rhodecode/templates/admin/repos/repos.html:97
1383 #: rhodecode/templates/admin/users/user_edit_my_account.html:182
1384 #: rhodecode/templates/admin/users/users.html:110
1385 #: rhodecode/templates/bookmarks/bookmarks.html:63
1386 #: rhodecode/templates/branches/branches.html:80
1387 #: rhodecode/templates/journal/journal.html:214
1388 #: rhodecode/templates/tags/tags.html:63
1389 msgid "Data error."
1390 msgstr ""
1391
1392 #: rhodecode/templates/index_base.html:202
1393 #: rhodecode/templates/admin/repos/repos.html:98
1394 #: rhodecode/templates/admin/users/user_edit_my_account.html:183
1395 #: rhodecode/templates/admin/users/users.html:111
1396 #: rhodecode/templates/bookmarks/bookmarks.html:64
1397 #: rhodecode/templates/branches/branches.html:81
1398 #: rhodecode/templates/journal/journal.html:215
1399 #: rhodecode/templates/tags/tags.html:64
1400 msgid "Loading..."
1401 msgstr ""
1402
1015 1403 #: rhodecode/templates/login.html:5 rhodecode/templates/login.html:54
1016 #: rhodecode/templates/base/base.html:38
1017 1404 msgid "Sign In"
1018 1405 msgstr ""
1019 1406
@@ -1024,25 +1411,29 b' msgstr ""'
1024 1411 #: rhodecode/templates/login.html:31 rhodecode/templates/register.html:20
1025 1412 #: rhodecode/templates/admin/admin_log.html:5
1026 1413 #: rhodecode/templates/admin/users/user_add.html:32
1027 #: rhodecode/templates/admin/users/user_edit.html:47
1028 #: rhodecode/templates/admin/users/user_edit_my_account.html:45
1029 #: rhodecode/templates/base/base.html:15
1030 #: rhodecode/templates/summary/summary.html:106
1414 #: rhodecode/templates/admin/users/user_edit.html:50
1415 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:26
1416 #: rhodecode/templates/base/base.html:83
1417 #: rhodecode/templates/summary/summary.html:122
1031 1418 msgid "Username"
1032 1419 msgstr ""
1033 1420
1034 1421 #: rhodecode/templates/login.html:40 rhodecode/templates/register.html:29
1035 1422 #: rhodecode/templates/admin/ldap/ldap.html:46
1036 1423 #: rhodecode/templates/admin/users/user_add.html:41
1037 #: rhodecode/templates/base/base.html:24
1424 #: rhodecode/templates/base/base.html:92
1038 1425 msgid "Password"
1039 1426 msgstr ""
1040 1427
1428 #: rhodecode/templates/login.html:50
1429 msgid "Remember me"
1430 msgstr ""
1431
1041 1432 #: rhodecode/templates/login.html:60
1042 1433 msgid "Forgot your password ?"
1043 1434 msgstr ""
1044 1435
1045 #: rhodecode/templates/login.html:63 rhodecode/templates/base/base.html:35
1436 #: rhodecode/templates/login.html:63 rhodecode/templates/base/base.html:103
1046 1437 msgid "Don't have an account ?"
1047 1438 msgstr ""
1048 1439
@@ -1079,24 +1470,24 b' msgid "Re-enter password"'
1079 1470 msgstr ""
1080 1471
1081 1472 #: rhodecode/templates/register.html:47
1082 #: rhodecode/templates/admin/users/user_add.html:50
1083 #: rhodecode/templates/admin/users/user_edit.html:74
1084 #: rhodecode/templates/admin/users/user_edit_my_account.html:63
1473 #: rhodecode/templates/admin/users/user_add.html:59
1474 #: rhodecode/templates/admin/users/user_edit.html:86
1475 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:53
1085 1476 msgid "First Name"
1086 1477 msgstr ""
1087 1478
1088 1479 #: rhodecode/templates/register.html:56
1089 #: rhodecode/templates/admin/users/user_add.html:59
1090 #: rhodecode/templates/admin/users/user_edit.html:83
1091 #: rhodecode/templates/admin/users/user_edit_my_account.html:72
1480 #: rhodecode/templates/admin/users/user_add.html:68
1481 #: rhodecode/templates/admin/users/user_edit.html:95
1482 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:62
1092 1483 msgid "Last Name"
1093 1484 msgstr ""
1094 1485
1095 1486 #: rhodecode/templates/register.html:65
1096 #: rhodecode/templates/admin/users/user_add.html:68
1097 #: rhodecode/templates/admin/users/user_edit.html:92
1098 #: rhodecode/templates/admin/users/user_edit_my_account.html:81
1099 #: rhodecode/templates/summary/summary.html:108
1487 #: rhodecode/templates/admin/users/user_add.html:77
1488 #: rhodecode/templates/admin/users/user_edit.html:104
1489 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:71
1490 #: rhodecode/templates/summary/summary.html:124
1100 1491 msgid "Email"
1101 1492 msgstr ""
1102 1493
@@ -1108,20 +1499,59 b' msgstr ""'
1108 1499 msgid "Your account must wait for activation by administrator"
1109 1500 msgstr ""
1110 1501
1111 #: rhodecode/templates/repo_switcher_list.html:14
1502 #: rhodecode/templates/repo_switcher_list.html:11
1503 #: rhodecode/templates/admin/repos/repo_add_base.html:65
1504 #: rhodecode/templates/admin/repos/repo_edit.html:85
1505 #: rhodecode/templates/settings/repo_settings.html:76
1112 1506 msgid "Private repository"
1113 1507 msgstr ""
1114 1508
1115 #: rhodecode/templates/repo_switcher_list.html:19
1509 #: rhodecode/templates/repo_switcher_list.html:16
1116 1510 msgid "Public repository"
1117 1511 msgstr ""
1118 1512
1513 #: rhodecode/templates/switch_to_list.html:3
1514 #: rhodecode/templates/branches/branches.html:14
1515 msgid "branches"
1516 msgstr ""
1517
1518 #: rhodecode/templates/switch_to_list.html:10
1519 #: rhodecode/templates/branches/branches_data.html:57
1520 msgid "There are no branches yet"
1521 msgstr ""
1522
1523 #: rhodecode/templates/switch_to_list.html:15
1524 #: rhodecode/templates/shortlog/shortlog_data.html:10
1525 #: rhodecode/templates/tags/tags.html:15
1526 msgid "tags"
1527 msgstr ""
1528
1529 #: rhodecode/templates/switch_to_list.html:22
1530 #: rhodecode/templates/tags/tags_data.html:33
1531 msgid "There are no tags yet"
1532 msgstr ""
1533
1534 #: rhodecode/templates/switch_to_list.html:28
1535 #: rhodecode/templates/bookmarks/bookmarks.html:15
1536 msgid "bookmarks"
1537 msgstr ""
1538
1539 #: rhodecode/templates/switch_to_list.html:35
1540 #: rhodecode/templates/bookmarks/bookmarks_data.html:32
1541 msgid "There are no bookmarks yet"
1542 msgstr ""
1543
1119 1544 #: rhodecode/templates/admin/admin.html:5
1120 1545 #: rhodecode/templates/admin/admin.html:9
1121 1546 msgid "Admin journal"
1122 1547 msgstr ""
1123 1548
1124 1549 #: rhodecode/templates/admin/admin_log.html:6
1550 #: rhodecode/templates/admin/repos/repos.html:74
1551 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:8
1552 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:9
1553 #: rhodecode/templates/journal/journal.html:61
1554 #: rhodecode/templates/journal/journal.html:62
1125 1555 msgid "Action"
1126 1556 msgstr ""
1127 1557
@@ -1130,6 +1560,11 b' msgid "Repository"'
1130 1560 msgstr ""
1131 1561
1132 1562 #: rhodecode/templates/admin/admin_log.html:8
1563 #: rhodecode/templates/bookmarks/bookmarks.html:37
1564 #: rhodecode/templates/bookmarks/bookmarks_data.html:7
1565 #: rhodecode/templates/branches/branches.html:52
1566 #: rhodecode/templates/tags/tags.html:37
1567 #: rhodecode/templates/tags/tags_data.html:7
1133 1568 msgid "Date"
1134 1569 msgstr ""
1135 1570
@@ -1137,7 +1572,7 b' msgstr ""'
1137 1572 msgid "From IP"
1138 1573 msgstr ""
1139 1574
1140 #: rhodecode/templates/admin/admin_log.html:52
1575 #: rhodecode/templates/admin/admin_log.html:53
1141 1576 msgid "No actions yet"
1142 1577 msgstr ""
1143 1578
@@ -1214,23 +1649,64 b' msgid "E-mail Attribute"'
1214 1649 msgstr ""
1215 1650
1216 1651 #: rhodecode/templates/admin/ldap/ldap.html:89
1652 #: rhodecode/templates/admin/repos/repo_edit.html:141
1653 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:74
1217 1654 #: rhodecode/templates/admin/settings/hooks.html:73
1218 #: rhodecode/templates/admin/users/user_edit.html:117
1219 #: rhodecode/templates/admin/users/user_edit.html:142
1220 #: rhodecode/templates/admin/users/user_edit_my_account.html:89
1221 #: rhodecode/templates/admin/users_groups/users_group_edit.html:263
1655 #: rhodecode/templates/admin/users/user_edit.html:129
1656 #: rhodecode/templates/admin/users/user_edit.html:174
1657 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:79
1658 #: rhodecode/templates/admin/users_groups/users_group_edit.html:135
1659 #: rhodecode/templates/settings/repo_settings.html:93
1222 1660 msgid "Save"
1223 1661 msgstr ""
1224 1662
1663 #: rhodecode/templates/admin/notifications/notifications.html:5
1664 #: rhodecode/templates/admin/notifications/notifications.html:9
1665 msgid "My Notifications"
1666 msgstr ""
1667
1668 #: rhodecode/templates/admin/notifications/notifications.html:29
1669 msgid "All"
1670 msgstr ""
1671
1672 #: rhodecode/templates/admin/notifications/notifications.html:30
1673 #, fuzzy
1674 msgid "Comments"
1675 msgstr ""
1676
1677 #: rhodecode/templates/admin/notifications/notifications.html:31
1678 #: rhodecode/templates/base/base.html:254
1679 #: rhodecode/templates/base/base.html:256
1680 msgid "Pull requests"
1681 msgstr ""
1682
1683 #: rhodecode/templates/admin/notifications/notifications.html:35
1684 msgid "Mark all read"
1685 msgstr ""
1686
1687 #: rhodecode/templates/admin/notifications/notifications_data.html:39
1688 msgid "No notifications here yet"
1689 msgstr ""
1690
1691 #: rhodecode/templates/admin/notifications/show_notification.html:5
1692 #: rhodecode/templates/admin/notifications/show_notification.html:11
1693 msgid "Show notification"
1694 msgstr ""
1695
1696 #: rhodecode/templates/admin/notifications/show_notification.html:9
1697 msgid "Notifications"
1698 msgstr ""
1699
1225 1700 #: rhodecode/templates/admin/permissions/permissions.html:5
1226 1701 msgid "Permissions administration"
1227 1702 msgstr ""
1228 1703
1229 1704 #: rhodecode/templates/admin/permissions/permissions.html:11
1230 #: rhodecode/templates/admin/repos/repo_edit.html:109
1231 #: rhodecode/templates/admin/users/user_edit.html:127
1232 #: rhodecode/templates/admin/users_groups/users_group_edit.html:248
1233 #: rhodecode/templates/settings/repo_settings.html:58
1705 #: rhodecode/templates/admin/repos/repo_edit.html:134
1706 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:58
1707 #: rhodecode/templates/admin/users/user_edit.html:139
1708 #: rhodecode/templates/admin/users_groups/users_group_edit.html:100
1709 #: rhodecode/templates/settings/repo_settings.html:86
1234 1710 msgid "Permissions"
1235 1711 msgstr ""
1236 1712
@@ -1266,6 +1742,11 b' msgid "Repository creation"'
1266 1742 msgstr ""
1267 1743
1268 1744 #: rhodecode/templates/admin/permissions/permissions.html:71
1745 msgid "Repository forking"
1746 msgstr ""
1747
1748 #: rhodecode/templates/admin/permissions/permissions.html:78
1749 #: rhodecode/templates/admin/repos/repo_edit.html:241
1269 1750 msgid "set"
1270 1751 msgstr ""
1271 1752
@@ -1276,7 +1757,6 b' msgstr ""'
1276 1757
1277 1758 #: rhodecode/templates/admin/repos/repo_add.html:11
1278 1759 #: rhodecode/templates/admin/repos/repo_edit.html:11
1279 #: rhodecode/templates/admin/repos/repos.html:10
1280 1760 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:10
1281 1761 msgid "Repositories"
1282 1762 msgstr ""
@@ -1286,30 +1766,70 b' msgid "add new"'
1286 1766 msgstr ""
1287 1767
1288 1768 #: rhodecode/templates/admin/repos/repo_add_base.html:20
1289 #: rhodecode/templates/summary/summary.html:80
1290 #: rhodecode/templates/summary/summary.html:82
1769 #: rhodecode/templates/summary/summary.html:95
1770 #: rhodecode/templates/summary/summary.html:96
1291 1771 msgid "Clone from"
1292 1772 msgstr ""
1293 1773
1294 #: rhodecode/templates/admin/repos/repo_add_base.html:28
1295 #: rhodecode/templates/admin/repos/repo_edit.html:48
1774 #: rhodecode/templates/admin/repos/repo_add_base.html:24
1775 #: rhodecode/templates/admin/repos/repo_edit.html:44
1776 #: rhodecode/templates/settings/repo_settings.html:43
1777 msgid "Optional http[s] url from which repository should be cloned."
1778 msgstr ""
1779
1780 #: rhodecode/templates/admin/repos/repo_add_base.html:29
1781 #: rhodecode/templates/admin/repos/repo_edit.html:49
1296 1782 #: rhodecode/templates/admin/repos_groups/repos_groups.html:4
1783 #: rhodecode/templates/forks/fork.html:50
1784 #: rhodecode/templates/settings/repo_settings.html:48
1297 1785 msgid "Repository group"
1298 1786 msgstr ""
1299 1787
1300 #: rhodecode/templates/admin/repos/repo_add_base.html:36
1301 #: rhodecode/templates/admin/repos/repo_edit.html:56
1788 #: rhodecode/templates/admin/repos/repo_add_base.html:33
1789 #: rhodecode/templates/forks/fork.html:54
1790 msgid "Optionaly select a group to put this repository into."
1791 msgstr ""
1792
1793 #: rhodecode/templates/admin/repos/repo_add_base.html:38
1794 #: rhodecode/templates/admin/repos/repo_edit.html:58
1302 1795 msgid "Type"
1303 1796 msgstr ""
1304 1797
1305 #: rhodecode/templates/admin/repos/repo_add_base.html:52
1306 #: rhodecode/templates/admin/repos/repo_edit.html:73
1307 #: rhodecode/templates/settings/repo_fork.html:48
1308 #: rhodecode/templates/settings/repo_settings.html:49
1309 msgid "Private"
1310 msgstr ""
1311
1312 #: rhodecode/templates/admin/repos/repo_add_base.html:59
1798 #: rhodecode/templates/admin/repos/repo_add_base.html:42
1799 msgid "Type of repository to create."
1800 msgstr ""
1801
1802 #: rhodecode/templates/admin/repos/repo_add_base.html:47
1803 #: rhodecode/templates/admin/repos/repo_edit.html:66
1804 #: rhodecode/templates/forks/fork.html:41
1805 #: rhodecode/templates/settings/repo_settings.html:57
1806 msgid "Landing revision"
1807 msgstr ""
1808
1809 #: rhodecode/templates/admin/repos/repo_add_base.html:51
1810 #: rhodecode/templates/admin/repos/repo_edit.html:70
1811 #: rhodecode/templates/forks/fork.html:45
1812 #: rhodecode/templates/settings/repo_settings.html:61
1813 msgid "Default revision for files page, downloads, whoosh and readme"
1814 msgstr ""
1815
1816 #: rhodecode/templates/admin/repos/repo_add_base.html:60
1817 #: rhodecode/templates/admin/repos/repo_edit.html:79
1818 #: rhodecode/templates/forks/fork.html:63
1819 #: rhodecode/templates/settings/repo_settings.html:70
1820 msgid "Keep it short and to the point. Use a README file for longer descriptions."
1821 msgstr ""
1822
1823 #: rhodecode/templates/admin/repos/repo_add_base.html:69
1824 #: rhodecode/templates/admin/repos/repo_edit.html:89
1825 #: rhodecode/templates/forks/fork.html:72
1826 #: rhodecode/templates/settings/repo_settings.html:80
1827 msgid ""
1828 "Private repositories are only visible to people explicitly added as "
1829 "collaborators."
1830 msgstr ""
1831
1832 #: rhodecode/templates/admin/repos/repo_add_base.html:73
1313 1833 msgid "add"
1314 1834 msgstr ""
1315 1835
@@ -1323,183 +1843,269 b' msgstr ""'
1323 1843
1324 1844 #: rhodecode/templates/admin/repos/repo_edit.html:13
1325 1845 #: rhodecode/templates/admin/users/user_edit.html:13
1326 #: rhodecode/templates/admin/users/user_edit_my_account.html:148
1846 #: rhodecode/templates/admin/users/user_edit.html:224
1847 #: rhodecode/templates/admin/users/user_edit.html:226
1848 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:28
1327 1849 #: rhodecode/templates/admin/users_groups/users_group_edit.html:13
1328 #: rhodecode/templates/files/files_annotate.html:49
1329 #: rhodecode/templates/files/files_source.html:20
1850 #: rhodecode/templates/files/files_source.html:44
1851 #: rhodecode/templates/journal/journal.html:81
1330 1852 msgid "edit"
1331 1853 msgstr ""
1332 1854
1333 1855 #: rhodecode/templates/admin/repos/repo_edit.html:40
1856 #: rhodecode/templates/settings/repo_settings.html:39
1334 1857 msgid "Clone uri"
1335 1858 msgstr ""
1336 1859
1337 #: rhodecode/templates/admin/repos/repo_edit.html:81
1860 #: rhodecode/templates/admin/repos/repo_edit.html:53
1861 #: rhodecode/templates/settings/repo_settings.html:52
1862 msgid "Optional select a group to put this repository into."
1863 msgstr ""
1864
1865 #: rhodecode/templates/admin/repos/repo_edit.html:94
1338 1866 msgid "Enable statistics"
1339 1867 msgstr ""
1340 1868
1341 #: rhodecode/templates/admin/repos/repo_edit.html:89
1869 #: rhodecode/templates/admin/repos/repo_edit.html:98
1870 msgid "Enable statistics window on summary page."
1871 msgstr ""
1872
1873 #: rhodecode/templates/admin/repos/repo_edit.html:103
1342 1874 msgid "Enable downloads"
1343 1875 msgstr ""
1344 1876
1345 #: rhodecode/templates/admin/repos/repo_edit.html:127
1877 #: rhodecode/templates/admin/repos/repo_edit.html:107
1878 msgid "Enable download menu on summary page."
1879 msgstr ""
1880
1881 #: rhodecode/templates/admin/repos/repo_edit.html:112
1882 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:66
1883 msgid "Enable locking"
1884 msgstr ""
1885
1886 #: rhodecode/templates/admin/repos/repo_edit.html:116
1887 msgid "Enable lock-by-pulling on repository."
1888 msgstr ""
1889
1890 #: rhodecode/templates/admin/repos/repo_edit.html:126
1891 msgid "Change owner of this repository."
1892 msgstr ""
1893
1894 #: rhodecode/templates/admin/repos/repo_edit.html:142
1895 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:75
1896 #: rhodecode/templates/admin/settings/settings.html:113
1897 #: rhodecode/templates/admin/settings/settings.html:168
1898 #: rhodecode/templates/admin/settings/settings.html:258
1899 #: rhodecode/templates/admin/users/user_edit.html:130
1900 #: rhodecode/templates/admin/users/user_edit.html:175
1901 #: rhodecode/templates/admin/users/user_edit.html:278
1902 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:80
1903 #: rhodecode/templates/admin/users_groups/users_group_edit.html:136
1904 #: rhodecode/templates/files/files_add.html:82
1905 #: rhodecode/templates/files/files_edit.html:68
1906 #: rhodecode/templates/pullrequests/pullrequest.html:124
1907 #: rhodecode/templates/settings/repo_settings.html:94
1908 msgid "Reset"
1909 msgstr ""
1910
1911 #: rhodecode/templates/admin/repos/repo_edit.html:152
1346 1912 msgid "Administration"
1347 1913 msgstr ""
1348 1914
1349 #: rhodecode/templates/admin/repos/repo_edit.html:130
1915 #: rhodecode/templates/admin/repos/repo_edit.html:155
1350 1916 msgid "Statistics"
1351 1917 msgstr ""
1352 1918
1353 #: rhodecode/templates/admin/repos/repo_edit.html:134
1919 #: rhodecode/templates/admin/repos/repo_edit.html:159
1354 1920 msgid "Reset current statistics"
1355 1921 msgstr ""
1356 1922
1357 #: rhodecode/templates/admin/repos/repo_edit.html:134
1923 #: rhodecode/templates/admin/repos/repo_edit.html:159
1358 1924 msgid "Confirm to remove current statistics"
1359 1925 msgstr ""
1360 1926
1361 #: rhodecode/templates/admin/repos/repo_edit.html:137
1362 msgid "Fetched to rev"
1363 msgstr ""
1364
1365 #: rhodecode/templates/admin/repos/repo_edit.html:138
1366 msgid "Percentage of stats gathered"
1367 msgstr ""
1368
1369 #: rhodecode/templates/admin/repos/repo_edit.html:147
1370 msgid "Remote"
1371 msgstr ""
1372
1373 #: rhodecode/templates/admin/repos/repo_edit.html:151
1374 msgid "Pull changes from remote location"
1375 msgstr ""
1376
1377 #: rhodecode/templates/admin/repos/repo_edit.html:151
1378 msgid "Confirm to pull changes from remote side"
1379 msgstr ""
1380
1381 1927 #: rhodecode/templates/admin/repos/repo_edit.html:162
1928 msgid "Fetched to rev"
1929 msgstr ""
1930
1931 #: rhodecode/templates/admin/repos/repo_edit.html:163
1932 msgid "Stats gathered"
1933 msgstr ""
1934
1935 #: rhodecode/templates/admin/repos/repo_edit.html:171
1936 msgid "Remote"
1937 msgstr ""
1938
1939 #: rhodecode/templates/admin/repos/repo_edit.html:175
1940 msgid "Pull changes from remote location"
1941 msgstr ""
1942
1943 #: rhodecode/templates/admin/repos/repo_edit.html:175
1944 msgid "Confirm to pull changes from remote side"
1945 msgstr ""
1946
1947 #: rhodecode/templates/admin/repos/repo_edit.html:186
1382 1948 msgid "Cache"
1383 1949 msgstr ""
1384 1950
1385 #: rhodecode/templates/admin/repos/repo_edit.html:166
1951 #: rhodecode/templates/admin/repos/repo_edit.html:190
1386 1952 msgid "Invalidate repository cache"
1387 1953 msgstr ""
1388 1954
1389 #: rhodecode/templates/admin/repos/repo_edit.html:166
1955 #: rhodecode/templates/admin/repos/repo_edit.html:190
1390 1956 msgid "Confirm to invalidate repository cache"
1391 1957 msgstr ""
1392 1958
1393 #: rhodecode/templates/admin/repos/repo_edit.html:177
1959 #: rhodecode/templates/admin/repos/repo_edit.html:195
1960 #: rhodecode/templates/base/base.html:318
1961 #: rhodecode/templates/base/base.html:320
1962 #: rhodecode/templates/base/base.html:322
1963 msgid "Public journal"
1964 msgstr ""
1965
1966 #: rhodecode/templates/admin/repos/repo_edit.html:201
1394 1967 msgid "Remove from public journal"
1395 1968 msgstr ""
1396 1969
1397 #: rhodecode/templates/admin/repos/repo_edit.html:179
1970 #: rhodecode/templates/admin/repos/repo_edit.html:203
1398 1971 msgid "Add to public journal"
1399 1972 msgstr ""
1400 1973
1401 #: rhodecode/templates/admin/repos/repo_edit.html:185
1974 #: rhodecode/templates/admin/repos/repo_edit.html:208
1975 msgid ""
1976 "All actions made on this repository will be accessible to everyone in "
1977 "public journal"
1978 msgstr ""
1979
1980 #: rhodecode/templates/admin/repos/repo_edit.html:215
1981 msgid "Locking"
1982 msgstr ""
1983
1984 #: rhodecode/templates/admin/repos/repo_edit.html:220
1985 msgid "Unlock locked repo"
1986 msgstr ""
1987
1988 #: rhodecode/templates/admin/repos/repo_edit.html:220
1989 msgid "Confirm to unlock repository"
1990 msgstr ""
1991
1992 #: rhodecode/templates/admin/repos/repo_edit.html:223
1993 msgid "lock repo"
1994 msgstr ""
1995
1996 #: rhodecode/templates/admin/repos/repo_edit.html:223
1997 msgid "Confirm to lock repository"
1998 msgstr ""
1999
2000 #: rhodecode/templates/admin/repos/repo_edit.html:224
2001 msgid "Repository is not locked"
2002 msgstr ""
2003
2004 #: rhodecode/templates/admin/repos/repo_edit.html:229
2005 msgid "Force locking on repository. Works only when anonymous access is disabled"
2006 msgstr ""
2007
2008 #: rhodecode/templates/admin/repos/repo_edit.html:236
2009 msgid "Set as fork of"
2010 msgstr ""
2011
2012 #: rhodecode/templates/admin/repos/repo_edit.html:245
2013 msgid "Manually set this repository as a fork of another from the list"
2014 msgstr ""
2015
2016 #: rhodecode/templates/admin/repos/repo_edit.html:251
2017 #: rhodecode/templates/changeset/changeset_file_comment.html:26
1402 2018 msgid "Delete"
1403 2019 msgstr ""
1404 2020
1405 #: rhodecode/templates/admin/repos/repo_edit.html:189
2021 #: rhodecode/templates/admin/repos/repo_edit.html:255
1406 2022 msgid "Remove this repository"
1407 2023 msgstr ""
1408 2024
1409 #: rhodecode/templates/admin/repos/repo_edit.html:189
1410 #: rhodecode/templates/admin/repos/repos.html:79
2025 #: rhodecode/templates/admin/repos/repo_edit.html:255
2026 #: rhodecode/templates/journal/journal.html:84
1411 2027 msgid "Confirm to delete this repository"
1412 2028 msgstr ""
1413 2029
2030 #: rhodecode/templates/admin/repos/repo_edit.html:259
2031 msgid ""
2032 "This repository will be renamed in a special way in order to be "
2033 "unaccesible for RhodeCode and VCS systems.\n"
2034 " If you need fully delete it from filesystem "
2035 "please do it manually"
2036 msgstr ""
2037
1414 2038 #: rhodecode/templates/admin/repos/repo_edit_perms.html:3
2039 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:3
1415 2040 msgid "none"
1416 2041 msgstr ""
1417 2042
1418 2043 #: rhodecode/templates/admin/repos/repo_edit_perms.html:4
2044 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:4
1419 2045 msgid "read"
1420 2046 msgstr ""
1421 2047
1422 2048 #: rhodecode/templates/admin/repos/repo_edit_perms.html:5
2049 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:5
1423 2050 msgid "write"
1424 2051 msgstr ""
1425 2052
1426 2053 #: rhodecode/templates/admin/repos/repo_edit_perms.html:6
1427 #: rhodecode/templates/admin/users/users.html:38
1428 #: rhodecode/templates/base/base.html:296
2054 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:6
2055 #: rhodecode/templates/admin/users/users.html:85
2056 #: rhodecode/templates/base/base.html:217
1429 2057 msgid "admin"
1430 2058 msgstr ""
1431 2059
1432 2060 #: rhodecode/templates/admin/repos/repo_edit_perms.html:7
2061 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:7
1433 2062 msgid "member"
1434 2063 msgstr ""
1435 2064
2065 #: rhodecode/templates/admin/repos/repo_edit_perms.html:16
2066 #: rhodecode/templates/data_table/_dt_elements.html:67
2067 #: rhodecode/templates/journal/journal.html:132
2068 #: rhodecode/templates/summary/summary.html:76
2069 msgid "private repository"
2070 msgstr ""
2071
2072 #: rhodecode/templates/admin/repos/repo_edit_perms.html:19
2073 #: rhodecode/templates/admin/repos/repo_edit_perms.html:28
2074 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:18
2075 msgid "default"
2076 msgstr ""
2077
1436 2078 #: rhodecode/templates/admin/repos/repo_edit_perms.html:33
1437 #: rhodecode/templates/admin/repos/repo_edit_perms.html:53
2079 #: rhodecode/templates/admin/repos/repo_edit_perms.html:58
2080 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:23
2081 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:42
1438 2082 msgid "revoke"
1439 2083 msgstr ""
1440 2084
1441 #: rhodecode/templates/admin/repos/repo_edit_perms.html:75
2085 #: rhodecode/templates/admin/repos/repo_edit_perms.html:83
2086 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:67
1442 2087 msgid "Add another member"
1443 2088 msgstr ""
1444 2089
1445 #: rhodecode/templates/admin/repos/repo_edit_perms.html:89
2090 #: rhodecode/templates/admin/repos/repo_edit_perms.html:97
2091 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:81
1446 2092 msgid "Failed to remove user"
1447 2093 msgstr ""
1448 2094
1449 #: rhodecode/templates/admin/repos/repo_edit_perms.html:104
2095 #: rhodecode/templates/admin/repos/repo_edit_perms.html:112
2096 #: rhodecode/templates/admin/repos_groups/repos_group_edit_perms.html:96
1450 2097 msgid "Failed to remove users group"
1451 2098 msgstr ""
1452 2099
1453 #: rhodecode/templates/admin/repos/repo_edit_perms.html:205
1454 msgid "Group"
1455 msgstr ""
1456
1457 #: rhodecode/templates/admin/repos/repo_edit_perms.html:206
1458 #: rhodecode/templates/admin/users_groups/users_groups.html:33
1459 msgid "members"
1460 msgstr ""
1461
1462 2100 #: rhodecode/templates/admin/repos/repos.html:5
1463 2101 msgid "Repositories administration"
1464 2102 msgstr ""
1465 2103
1466 #: rhodecode/templates/admin/repos/repos.html:34
1467 #: rhodecode/templates/summary/summary.html:100
1468 msgid "Contact"
1469 msgstr ""
1470
1471 #: rhodecode/templates/admin/repos/repos.html:35
1472 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:36
1473 #: rhodecode/templates/admin/users/user_edit_my_account.html:119
1474 #: rhodecode/templates/admin/users/users.html:40
1475 #: rhodecode/templates/admin/users_groups/users_groups.html:35
1476 msgid "action"
1477 msgstr ""
1478
1479 #: rhodecode/templates/admin/repos/repos.html:51
1480 #: rhodecode/templates/admin/users/user_edit_my_account.html:134
1481 #: rhodecode/templates/admin/users/user_edit_my_account.html:148
1482 msgid "private"
1483 msgstr ""
1484
1485 #: rhodecode/templates/admin/repos/repos.html:53
1486 #: rhodecode/templates/admin/repos/repos.html:59
1487 #: rhodecode/templates/admin/users/user_edit_my_account.html:136
1488 #: rhodecode/templates/admin/users/user_edit_my_account.html:142
1489 #: rhodecode/templates/summary/summary.html:68
1490 msgid "public"
1491 msgstr ""
1492
1493 #: rhodecode/templates/admin/repos/repos.html:79
1494 #: rhodecode/templates/admin/users/users.html:55
1495 msgid "delete"
1496 msgstr ""
1497
1498 2104 #: rhodecode/templates/admin/repos_groups/repos_groups.html:8
1499 2105 msgid "Groups"
1500 2106 msgstr ""
1501 2107
1502 #: rhodecode/templates/admin/repos_groups/repos_groups.html:13
2108 #: rhodecode/templates/admin/repos_groups/repos_groups.html:12
1503 2109 msgid "with"
1504 2110 msgstr ""
1505 2111
@@ -1522,10 +2128,10 b' msgid "Group parent"'
1522 2128 msgstr ""
1523 2129
1524 2130 #: rhodecode/templates/admin/repos_groups/repos_groups_add.html:58
1525 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:58
1526 #: rhodecode/templates/admin/users/user_add.html:85
2131 #: rhodecode/templates/admin/users/user_add.html:94
1527 2132 #: rhodecode/templates/admin/users_groups/users_group_add.html:49
1528 2133 #: rhodecode/templates/admin/users_groups/users_group_edit.html:90
2134 #: rhodecode/templates/pullrequests/pullrequest_show.html:113
1529 2135 msgid "save"
1530 2136 msgstr ""
1531 2137
@@ -1537,6 +2143,12 b' msgstr ""'
1537 2143 msgid "edit repos group"
1538 2144 msgstr ""
1539 2145
2146 #: rhodecode/templates/admin/repos_groups/repos_groups_edit.html:70
2147 msgid ""
2148 "Enable lock-by-pulling on group. This option will be applied to all other"
2149 " groups and repositories inside"
2150 msgstr ""
2151
1540 2152 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:5
1541 2153 msgid "Repositories groups administration"
1542 2154 msgstr ""
@@ -1546,11 +2158,26 b' msgid "ADD NEW GROUP"'
1546 2158 msgstr ""
1547 2159
1548 2160 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:35
1549 msgid "Number of repositories"
2161 msgid "Number of toplevel repositories"
2162 msgstr ""
2163
2164 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:36
2165 #: rhodecode/templates/admin/users/users.html:87
2166 #: rhodecode/templates/admin/users_groups/users_groups.html:35
2167 msgid "action"
1550 2168 msgstr ""
1551 2169
1552 2170 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:54
1553 msgid "Confirm to delete this group"
2171 #: rhodecode/templates/admin/users/user_edit.html:255
2172 #: rhodecode/templates/admin/users_groups/users_groups.html:44
2173 #: rhodecode/templates/data_table/_dt_elements.html:7
2174 #: rhodecode/templates/data_table/_dt_elements.html:103
2175 msgid "delete"
2176 msgstr ""
2177
2178 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:54
2179 #, python-format
2180 msgid "Confirm to delete this group: %s"
1554 2181 msgstr ""
1555 2182
1556 2183 #: rhodecode/templates/admin/repos_groups/repos_groups_show.html:62
@@ -1564,7 +2191,6 b' msgstr ""'
1564 2191
1565 2192 #: rhodecode/templates/admin/settings/hooks.html:9
1566 2193 #: rhodecode/templates/admin/settings/settings.html:9
1567 #: rhodecode/templates/settings/repo_settings.html:5
1568 2194 #: rhodecode/templates/settings/repo_settings.html:13
1569 2195 msgid "Settings"
1570 2196 msgstr ""
@@ -1604,115 +2230,185 b' msgstr ""'
1604 2230 msgid "destroy old data"
1605 2231 msgstr ""
1606 2232
1607 #: rhodecode/templates/admin/settings/settings.html:45
2233 #: rhodecode/templates/admin/settings/settings.html:41
2234 msgid ""
2235 "Rescan repositories location for new repositories. Also deletes obsolete "
2236 "if `destroy` flag is checked "
2237 msgstr ""
2238
2239 #: rhodecode/templates/admin/settings/settings.html:46
1608 2240 msgid "Rescan repositories"
1609 2241 msgstr ""
1610 2242
1611 #: rhodecode/templates/admin/settings/settings.html:51
2243 #: rhodecode/templates/admin/settings/settings.html:52
1612 2244 msgid "Whoosh indexing"
1613 2245 msgstr ""
1614 2246
1615 #: rhodecode/templates/admin/settings/settings.html:59
2247 #: rhodecode/templates/admin/settings/settings.html:60
1616 2248 msgid "index build option"
1617 2249 msgstr ""
1618 2250
1619 #: rhodecode/templates/admin/settings/settings.html:64
2251 #: rhodecode/templates/admin/settings/settings.html:65
1620 2252 msgid "build from scratch"
1621 2253 msgstr ""
1622 2254
1623 #: rhodecode/templates/admin/settings/settings.html:70
2255 #: rhodecode/templates/admin/settings/settings.html:71
1624 2256 msgid "Reindex"
1625 2257 msgstr ""
1626 2258
1627 #: rhodecode/templates/admin/settings/settings.html:76
2259 #: rhodecode/templates/admin/settings/settings.html:77
1628 2260 msgid "Global application settings"
1629 2261 msgstr ""
1630 2262
1631 #: rhodecode/templates/admin/settings/settings.html:85
2263 #: rhodecode/templates/admin/settings/settings.html:86
1632 2264 msgid "Application name"
1633 2265 msgstr ""
1634 2266
1635 #: rhodecode/templates/admin/settings/settings.html:94
2267 #: rhodecode/templates/admin/settings/settings.html:95
1636 2268 msgid "Realm text"
1637 2269 msgstr ""
1638 2270
1639 #: rhodecode/templates/admin/settings/settings.html:103
2271 #: rhodecode/templates/admin/settings/settings.html:104
1640 2272 msgid "GA code"
1641 2273 msgstr ""
1642 2274
1643 #: rhodecode/templates/admin/settings/settings.html:111
1644 #: rhodecode/templates/admin/settings/settings.html:177
1645 msgid "Save settings"
1646 msgstr ""
1647
1648 2275 #: rhodecode/templates/admin/settings/settings.html:112
1649 #: rhodecode/templates/admin/settings/settings.html:178
1650 #: rhodecode/templates/admin/users/user_edit.html:118
1651 #: rhodecode/templates/admin/users/user_edit.html:143
1652 #: rhodecode/templates/admin/users/user_edit_my_account.html:90
1653 #: rhodecode/templates/admin/users_groups/users_group_edit.html:264
1654 #: rhodecode/templates/files/files_edit.html:50
1655 msgid "Reset"
1656 msgstr ""
1657
1658 #: rhodecode/templates/admin/settings/settings.html:118
1659 msgid "Mercurial settings"
1660 msgstr ""
1661
1662 #: rhodecode/templates/admin/settings/settings.html:127
2276 #: rhodecode/templates/admin/settings/settings.html:167
2277 #: rhodecode/templates/admin/settings/settings.html:257
2278 msgid "Save settings"
2279 msgstr ""
2280
2281 #: rhodecode/templates/admin/settings/settings.html:119
2282 msgid "Visualisation settings"
2283 msgstr ""
2284
2285 #: rhodecode/templates/admin/settings/settings.html:128
2286 msgid "Icons"
2287 msgstr ""
2288
2289 #: rhodecode/templates/admin/settings/settings.html:133
2290 msgid "Show public repo icon on repositories"
2291 msgstr ""
2292
2293 #: rhodecode/templates/admin/settings/settings.html:137
2294 msgid "Show private repo icon on repositories"
2295 msgstr ""
2296
2297 #: rhodecode/templates/admin/settings/settings.html:144
2298 msgid "Meta-Tagging"
2299 msgstr ""
2300
2301 #: rhodecode/templates/admin/settings/settings.html:149
2302 msgid "Stylify recognised metatags:"
2303 msgstr ""
2304
2305 #: rhodecode/templates/admin/settings/settings.html:176
2306 msgid "VCS settings"
2307 msgstr ""
2308
2309 #: rhodecode/templates/admin/settings/settings.html:185
1663 2310 msgid "Web"
1664 2311 msgstr ""
1665 2312
1666 #: rhodecode/templates/admin/settings/settings.html:132
1667 msgid "require ssl for pushing"
1668 msgstr ""
1669
1670 #: rhodecode/templates/admin/settings/settings.html:139
2313 #: rhodecode/templates/admin/settings/settings.html:190
2314 msgid "require ssl for vcs operations"
2315 msgstr ""
2316
2317 #: rhodecode/templates/admin/settings/settings.html:192
2318 msgid ""
2319 "RhodeCode will require SSL for pushing or pulling. If SSL is missing it "
2320 "will return HTTP Error 406: Not Acceptable"
2321 msgstr ""
2322
2323 #: rhodecode/templates/admin/settings/settings.html:198
1671 2324 msgid "Hooks"
1672 2325 msgstr ""
1673 2326
1674 #: rhodecode/templates/admin/settings/settings.html:142
1675 msgid "advanced setup"
1676 msgstr ""
1677
1678 #: rhodecode/templates/admin/settings/settings.html:147
2327 #: rhodecode/templates/admin/settings/settings.html:203
1679 2328 msgid "Update repository after push (hg update)"
1680 2329 msgstr ""
1681 2330
1682 #: rhodecode/templates/admin/settings/settings.html:151
2331 #: rhodecode/templates/admin/settings/settings.html:207
1683 2332 msgid "Show repository size after push"
1684 2333 msgstr ""
1685 2334
1686 #: rhodecode/templates/admin/settings/settings.html:155
2335 #: rhodecode/templates/admin/settings/settings.html:211
1687 2336 msgid "Log user push commands"
1688 2337 msgstr ""
1689 2338
1690 #: rhodecode/templates/admin/settings/settings.html:159
2339 #: rhodecode/templates/admin/settings/settings.html:215
1691 2340 msgid "Log user pull commands"
1692 2341 msgstr ""
1693 2342
1694 #: rhodecode/templates/admin/settings/settings.html:166
2343 #: rhodecode/templates/admin/settings/settings.html:219
2344 msgid "advanced setup"
2345 msgstr ""
2346
2347 #: rhodecode/templates/admin/settings/settings.html:224
2348 msgid "Mercurial Extensions"
2349 msgstr ""
2350
2351 #: rhodecode/templates/admin/settings/settings.html:229
2352 msgid "largefiles extensions"
2353 msgstr ""
2354
2355 #: rhodecode/templates/admin/settings/settings.html:233
2356 msgid "hgsubversion extensions"
2357 msgstr ""
2358
2359 #: rhodecode/templates/admin/settings/settings.html:235
2360 msgid ""
2361 "Requires hgsubversion library installed. Allows clonning from svn remote "
2362 "locations"
2363 msgstr ""
2364
2365 #: rhodecode/templates/admin/settings/settings.html:245
1695 2366 msgid "Repositories location"
1696 2367 msgstr ""
1697 2368
1698 #: rhodecode/templates/admin/settings/settings.html:171
2369 #: rhodecode/templates/admin/settings/settings.html:250
1699 2370 msgid ""
1700 2371 "This a crucial application setting. If you are really sure you need to "
1701 2372 "change this, you must restart application in order to make this setting "
1702 2373 "take effect. Click this label to unlock."
1703 2374 msgstr ""
1704 2375
1705 #: rhodecode/templates/admin/settings/settings.html:172
2376 #: rhodecode/templates/admin/settings/settings.html:251
1706 2377 msgid "unlock"
1707 2378 msgstr ""
1708 2379
2380 #: rhodecode/templates/admin/settings/settings.html:252
2381 msgid ""
2382 "Location where repositories are stored. After changing this value a "
2383 "restart, and rescan is required"
2384 msgstr ""
2385
2386 #: rhodecode/templates/admin/settings/settings.html:272
2387 msgid "Test Email"
2388 msgstr ""
2389
2390 #: rhodecode/templates/admin/settings/settings.html:280
2391 msgid "Email to"
2392 msgstr ""
2393
2394 #: rhodecode/templates/admin/settings/settings.html:288
2395 msgid "Send"
2396 msgstr ""
2397
2398 #: rhodecode/templates/admin/settings/settings.html:294
2399 msgid "System Info and Packages"
2400 msgstr ""
2401
2402 #: rhodecode/templates/admin/settings/settings.html:297
2403 msgid "show"
2404 msgstr ""
2405
1709 2406 #: rhodecode/templates/admin/users/user_add.html:5
1710 2407 msgid "Add user"
1711 2408 msgstr ""
1712 2409
1713 2410 #: rhodecode/templates/admin/users/user_add.html:10
1714 2411 #: rhodecode/templates/admin/users/user_edit.html:11
1715 #: rhodecode/templates/admin/users/users.html:9
1716 2412 msgid "Users"
1717 2413 msgstr ""
1718 2414
@@ -1720,8 +2416,12 b' msgstr ""'
1720 2416 msgid "add new user"
1721 2417 msgstr ""
1722 2418
1723 #: rhodecode/templates/admin/users/user_add.html:77
1724 #: rhodecode/templates/admin/users/user_edit.html:101
2419 #: rhodecode/templates/admin/users/user_add.html:50
2420 msgid "Password confirmation"
2421 msgstr ""
2422
2423 #: rhodecode/templates/admin/users/user_add.html:86
2424 #: rhodecode/templates/admin/users/user_edit.html:113
1725 2425 #: rhodecode/templates/admin/users_groups/users_group_add.html:41
1726 2426 #: rhodecode/templates/admin/users_groups/users_group_edit.html:42
1727 2427 msgid "Active"
@@ -1731,36 +2431,93 b' msgstr ""'
1731 2431 msgid "Edit user"
1732 2432 msgstr ""
1733 2433
1734 #: rhodecode/templates/admin/users/user_edit.html:33
1735 #: rhodecode/templates/admin/users/user_edit_my_account.html:32
2434 #: rhodecode/templates/admin/users/user_edit.html:34
2435 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:10
1736 2436 msgid "Change your avatar at"
1737 2437 msgstr ""
1738 2438
1739 #: rhodecode/templates/admin/users/user_edit.html:34
1740 #: rhodecode/templates/admin/users/user_edit_my_account.html:33
2439 #: rhodecode/templates/admin/users/user_edit.html:35
2440 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:11
1741 2441 msgid "Using"
1742 2442 msgstr ""
1743 2443
1744 #: rhodecode/templates/admin/users/user_edit.html:40
1745 #: rhodecode/templates/admin/users/user_edit_my_account.html:39
2444 #: rhodecode/templates/admin/users/user_edit.html:43
2445 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:20
1746 2446 msgid "API key"
1747 2447 msgstr ""
1748 2448
1749 #: rhodecode/templates/admin/users/user_edit.html:56
2449 #: rhodecode/templates/admin/users/user_edit.html:59
1750 2450 msgid "LDAP DN"
1751 2451 msgstr ""
1752 2452
1753 #: rhodecode/templates/admin/users/user_edit.html:65
1754 #: rhodecode/templates/admin/users/user_edit_my_account.html:54
2453 #: rhodecode/templates/admin/users/user_edit.html:68
2454 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:35
1755 2455 msgid "New password"
1756 2456 msgstr ""
1757 2457
1758 #: rhodecode/templates/admin/users/user_edit.html:135
1759 #: rhodecode/templates/admin/users_groups/users_group_edit.html:256
2458 #: rhodecode/templates/admin/users/user_edit.html:77
2459 #: rhodecode/templates/admin/users/user_edit_my_account_form.html:44
2460 msgid "New password confirmation"
2461 msgstr ""
2462
2463 #: rhodecode/templates/admin/users/user_edit.html:147
2464 #: rhodecode/templates/admin/users_groups/users_group_edit.html:108
2465 msgid "Inherit default permissions"
2466 msgstr ""
2467
2468 #: rhodecode/templates/admin/users/user_edit.html:152
2469 #: rhodecode/templates/admin/users_groups/users_group_edit.html:113
2470 #, python-format
2471 msgid ""
2472 "Select to inherit permissions from %s settings. With this selected below "
2473 "options does not have any action"
2474 msgstr ""
2475
2476 #: rhodecode/templates/admin/users/user_edit.html:158
2477 #: rhodecode/templates/admin/users_groups/users_group_edit.html:119
1760 2478 msgid "Create repositories"
1761 2479 msgstr ""
1762 2480
2481 #: rhodecode/templates/admin/users/user_edit.html:166
2482 #: rhodecode/templates/admin/users_groups/users_group_edit.html:127
2483 msgid "Fork repositories"
2484 msgstr ""
2485
2486 #: rhodecode/templates/admin/users/user_edit.html:186
2487 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:22
2488 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:39
2489 msgid "Nothing here yet"
2490 msgstr ""
2491
2492 #: rhodecode/templates/admin/users/user_edit.html:193
2493 #: rhodecode/templates/admin/users/user_edit_my_account.html:60
2494 #: rhodecode/templates/admin/users/user_edit_my_account.html:194
2495 msgid "Permission"
2496 msgstr ""
2497
2498 #: rhodecode/templates/admin/users/user_edit.html:194
2499 msgid "Edit Permission"
2500 msgstr ""
2501
2502 #: rhodecode/templates/admin/users/user_edit.html:243
2503 msgid "Email addresses"
2504 msgstr ""
2505
2506 #: rhodecode/templates/admin/users/user_edit.html:256
2507 #, python-format
2508 msgid "Confirm to delete this email: %s"
2509 msgstr ""
2510
2511 #: rhodecode/templates/admin/users/user_edit.html:270
2512 msgid "New email address"
2513 msgstr ""
2514
2515 #: rhodecode/templates/admin/users/user_edit.html:277
2516 msgid "Add"
2517 msgstr ""
2518
1763 2519 #: rhodecode/templates/admin/users/user_edit_my_account.html:5
2520 #: rhodecode/templates/base/base.html:124
1764 2521 msgid "My account"
1765 2522 msgstr ""
1766 2523
@@ -1768,26 +2525,74 b' msgstr ""'
1768 2525 msgid "My Account"
1769 2526 msgstr ""
1770 2527
1771 #: rhodecode/templates/admin/users/user_edit_my_account.html:101
1772 msgid "My repositories"
1773 msgstr ""
1774
1775 #: rhodecode/templates/admin/users/user_edit_my_account.html:107
1776 msgid "ADD REPOSITORY"
1777 msgstr ""
1778
1779 #: rhodecode/templates/admin/users/user_edit_my_account.html:118
1780 #: rhodecode/templates/branches/branches_data.html:7
1781 #: rhodecode/templates/shortlog/shortlog_data.html:8
1782 #: rhodecode/templates/tags/tags_data.html:7
1783 msgid "revision"
1784 msgstr ""
1785
1786 #: rhodecode/templates/admin/users/user_edit_my_account.html:157
2528 #: rhodecode/templates/admin/users/user_edit_my_account.html:35
2529 msgid "My permissions"
2530 msgstr ""
2531
2532 #: rhodecode/templates/admin/users/user_edit_my_account.html:38
2533 #: rhodecode/templates/journal/journal.html:41
2534 msgid "My repos"
2535 msgstr ""
2536
2537 #: rhodecode/templates/admin/users/user_edit_my_account.html:41
2538 msgid "My pull requests"
2539 msgstr ""
2540
2541 #: rhodecode/templates/admin/users/user_edit_my_account.html:45
2542 msgid "Add repo"
2543 msgstr ""
2544
2545 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:2
2546 msgid "Opened by me"
2547 msgstr ""
2548
2549 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:10
2550 #, python-format
2551 msgid "Pull request #%s opened on %s"
2552 msgstr ""
2553
2554 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:15
2555 msgid "Confirm to delete this pull request"
2556 msgstr ""
2557
2558 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:26
2559 msgid "I participate in"
2560 msgstr ""
2561
2562 #: rhodecode/templates/admin/users/user_edit_my_account_pullrequests.html:33
2563 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:30
2564 #, python-format
2565 msgid "Pull request #%s opened by %s on %s"
2566 msgstr ""
2567
2568 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:7
2569 #: rhodecode/templates/bookmarks/bookmarks.html:40
2570 #: rhodecode/templates/bookmarks/bookmarks_data.html:9
2571 #: rhodecode/templates/branches/branches.html:55
2572 #: rhodecode/templates/journal/journal.html:60
2573 #: rhodecode/templates/tags/tags.html:40
2574 #: rhodecode/templates/tags/tags_data.html:9
2575 msgid "Revision"
2576 msgstr ""
2577
2578 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:28
2579 #: rhodecode/templates/journal/journal.html:81
2580 msgid "private"
2581 msgstr ""
2582
2583 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:31
2584 #: rhodecode/templates/data_table/_dt_elements.html:7
2585 #, python-format
2586 msgid "Confirm to delete this repository: %s"
2587 msgstr ""
2588
2589 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:38
2590 #: rhodecode/templates/journal/journal.html:94
1787 2591 msgid "No repositories yet"
1788 2592 msgstr ""
1789 2593
1790 #: rhodecode/templates/admin/users/user_edit_my_account.html:159
2594 #: rhodecode/templates/admin/users/user_edit_my_account_repos.html:40
2595 #: rhodecode/templates/journal/journal.html:96
1791 2596 msgid "create one now"
1792 2597 msgstr ""
1793 2598
@@ -1795,42 +2600,41 b' msgstr ""'
1795 2600 msgid "Users administration"
1796 2601 msgstr ""
1797 2602
2603 #: rhodecode/templates/admin/users/users.html:9
2604 #: rhodecode/templates/base/base.html:223
2605 msgid "users"
2606 msgstr ""
2607
1798 2608 #: rhodecode/templates/admin/users/users.html:23
1799 2609 msgid "ADD NEW USER"
1800 2610 msgstr ""
1801 2611
1802 #: rhodecode/templates/admin/users/users.html:33
2612 #: rhodecode/templates/admin/users/users.html:77
1803 2613 msgid "username"
1804 2614 msgstr ""
1805 2615
1806 #: rhodecode/templates/admin/users/users.html:34
1807 #: rhodecode/templates/branches/branches_data.html:5
1808 #: rhodecode/templates/tags/tags_data.html:5
1809 msgid "name"
1810 msgstr ""
1811
1812 #: rhodecode/templates/admin/users/users.html:35
2616 #: rhodecode/templates/admin/users/users.html:80
2617 msgid "firstname"
2618 msgstr ""
2619
2620 #: rhodecode/templates/admin/users/users.html:81
1813 2621 msgid "lastname"
1814 2622 msgstr ""
1815 2623
1816 #: rhodecode/templates/admin/users/users.html:36
2624 #: rhodecode/templates/admin/users/users.html:82
1817 2625 msgid "last login"
1818 2626 msgstr ""
1819 2627
1820 #: rhodecode/templates/admin/users/users.html:37
2628 #: rhodecode/templates/admin/users/users.html:84
1821 2629 #: rhodecode/templates/admin/users_groups/users_groups.html:34
1822 2630 msgid "active"
1823 2631 msgstr ""
1824 2632
1825 #: rhodecode/templates/admin/users/users.html:39
1826 #: rhodecode/templates/base/base.html:305
2633 #: rhodecode/templates/admin/users/users.html:86
2634 #: rhodecode/templates/base/base.html:226
1827 2635 msgid "ldap"
1828 2636 msgstr ""
1829 2637
1830 #: rhodecode/templates/admin/users/users.html:56
1831 msgid "Confirm to delete this user"
1832 msgstr ""
1833
1834 2638 #: rhodecode/templates/admin/users_groups/users_group_add.html:5
1835 2639 msgid "Add users group"
1836 2640 msgstr ""
@@ -1872,6 +2676,10 b' msgstr ""'
1872 2676 msgid "Add all elements"
1873 2677 msgstr ""
1874 2678
2679 #: rhodecode/templates/admin/users_groups/users_group_edit.html:146
2680 msgid "Group members"
2681 msgstr ""
2682
1875 2683 #: rhodecode/templates/admin/users_groups/users_groups.html:5
1876 2684 msgid "Users groups administration"
1877 2685 msgstr ""
@@ -1884,396 +2692,616 b' msgstr ""'
1884 2692 msgid "group name"
1885 2693 msgstr ""
1886 2694
1887 #: rhodecode/templates/base/base.html:32
2695 #: rhodecode/templates/admin/users_groups/users_groups.html:33
2696 #: rhodecode/templates/base/root.html:46
2697 msgid "members"
2698 msgstr ""
2699
2700 #: rhodecode/templates/admin/users_groups/users_groups.html:45
2701 #, python-format
2702 msgid "Confirm to delete this users group: %s"
2703 msgstr ""
2704
2705 #: rhodecode/templates/base/base.html:41
2706 msgid "Submit a bug"
2707 msgstr ""
2708
2709 #: rhodecode/templates/base/base.html:77
2710 msgid "Login to your account"
2711 msgstr ""
2712
2713 #: rhodecode/templates/base/base.html:100
1888 2714 msgid "Forgot password ?"
1889 2715 msgstr ""
1890 2716
1891 #: rhodecode/templates/base/base.html:57 rhodecode/templates/base/base.html:338
1892 #: rhodecode/templates/base/base.html:340
1893 #: rhodecode/templates/base/base.html:342
1894 msgid "Home"
1895 msgstr ""
1896
1897 #: rhodecode/templates/base/base.html:61 rhodecode/templates/base/base.html:347
1898 #: rhodecode/templates/base/base.html:349
1899 #: rhodecode/templates/base/base.html:351
1900 #: rhodecode/templates/journal/journal.html:4
1901 #: rhodecode/templates/journal/journal.html:17
1902 #: rhodecode/templates/journal/public_journal.html:4
1903 msgid "Journal"
1904 msgstr ""
1905
1906 #: rhodecode/templates/base/base.html:66
1907 msgid "Login"
1908 msgstr ""
1909
1910 #: rhodecode/templates/base/base.html:68
1911 msgid "Log Out"
1912 msgstr ""
1913
1914 2717 #: rhodecode/templates/base/base.html:107
1915 msgid "Submit a bug"
1916 msgstr ""
1917
1918 #: rhodecode/templates/base/base.html:141
2718 msgid "Log In"
2719 msgstr ""
2720
2721 #: rhodecode/templates/base/base.html:118
2722 msgid "Inbox"
2723 msgstr ""
2724
2725 #: rhodecode/templates/base/base.html:122
2726 #: rhodecode/templates/base/base.html:300
2727 #: rhodecode/templates/base/base.html:302
2728 #: rhodecode/templates/base/base.html:304
2729 #: rhodecode/templates/bookmarks/bookmarks.html:11
2730 #: rhodecode/templates/branches/branches.html:10
2731 #: rhodecode/templates/changelog/changelog.html:10
2732 #: rhodecode/templates/changeset/changeset.html:10
2733 #: rhodecode/templates/changeset/changeset_range.html:9
2734 #: rhodecode/templates/compare/compare_diff.html:9
2735 #: rhodecode/templates/files/file_diff.html:8
2736 #: rhodecode/templates/files/files.html:8
2737 #: rhodecode/templates/files/files_add.html:15
2738 #: rhodecode/templates/files/files_edit.html:15
2739 #: rhodecode/templates/followers/followers.html:9
2740 #: rhodecode/templates/forks/fork.html:9 rhodecode/templates/forks/forks.html:9
2741 #: rhodecode/templates/pullrequests/pullrequest.html:8
2742 #: rhodecode/templates/pullrequests/pullrequest_show.html:8
2743 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:8
2744 #: rhodecode/templates/settings/repo_settings.html:9
2745 #: rhodecode/templates/shortlog/shortlog.html:10
2746 #: rhodecode/templates/summary/summary.html:8
2747 #: rhodecode/templates/tags/tags.html:11
2748 msgid "Home"
2749 msgstr ""
2750
2751 #: rhodecode/templates/base/base.html:123
2752 #: rhodecode/templates/base/base.html:309
2753 #: rhodecode/templates/base/base.html:311
2754 #: rhodecode/templates/base/base.html:313
2755 #: rhodecode/templates/journal/journal.html:4
2756 #: rhodecode/templates/journal/journal.html:21
2757 #: rhodecode/templates/journal/public_journal.html:4
2758 msgid "Journal"
2759 msgstr ""
2760
2761 #: rhodecode/templates/base/base.html:125
2762 msgid "Log Out"
2763 msgstr ""
2764
2765 #: rhodecode/templates/base/base.html:144
1919 2766 msgid "Switch repository"
1920 2767 msgstr ""
1921 2768
1922 #: rhodecode/templates/base/base.html:143
2769 #: rhodecode/templates/base/base.html:146
1923 2770 msgid "Products"
1924 2771 msgstr ""
1925 2772
1926 #: rhodecode/templates/base/base.html:149
2773 #: rhodecode/templates/base/base.html:152
2774 #: rhodecode/templates/base/base.html:182
1927 2775 msgid "loading..."
1928 2776 msgstr ""
1929 2777
1930 #: rhodecode/templates/base/base.html:234
1931 #: rhodecode/templates/base/base.html:236
1932 #: rhodecode/templates/base/base.html:238
2778 #: rhodecode/templates/base/base.html:158
2779 #: rhodecode/templates/base/base.html:160
2780 #: rhodecode/templates/base/base.html:162
2781 #: rhodecode/templates/data_table/_dt_elements.html:15
2782 #: rhodecode/templates/data_table/_dt_elements.html:17
2783 #: rhodecode/templates/data_table/_dt_elements.html:19
2784 msgid "Summary"
2785 msgstr ""
2786
2787 #: rhodecode/templates/base/base.html:166
2788 #: rhodecode/templates/base/base.html:168
2789 #: rhodecode/templates/base/base.html:170
2790 #: rhodecode/templates/changelog/changelog.html:15
2791 #: rhodecode/templates/data_table/_dt_elements.html:23
2792 #: rhodecode/templates/data_table/_dt_elements.html:25
2793 #: rhodecode/templates/data_table/_dt_elements.html:27
2794 msgid "Changelog"
2795 msgstr ""
2796
2797 #: rhodecode/templates/base/base.html:175
2798 #: rhodecode/templates/base/base.html:177
2799 #: rhodecode/templates/base/base.html:179
1933 2800 msgid "Switch to"
1934 2801 msgstr ""
1935 2802
1936 #: rhodecode/templates/base/base.html:242
1937 #: rhodecode/templates/branches/branches.html:13
1938 msgid "branches"
1939 msgstr ""
1940
1941 #: rhodecode/templates/base/base.html:249
1942 #: rhodecode/templates/branches/branches_data.html:52
1943 msgid "There are no branches yet"
1944 msgstr ""
1945
1946 #: rhodecode/templates/base/base.html:254
1947 #: rhodecode/templates/shortlog/shortlog_data.html:10
1948 #: rhodecode/templates/tags/tags.html:14
1949 msgid "tags"
1950 msgstr ""
1951
1952 #: rhodecode/templates/base/base.html:261
1953 #: rhodecode/templates/tags/tags_data.html:32
1954 msgid "There are no tags yet"
1955 msgstr ""
1956
1957 #: rhodecode/templates/base/base.html:277
1958 #: rhodecode/templates/base/base.html:281
1959 #: rhodecode/templates/files/files_annotate.html:40
1960 #: rhodecode/templates/files/files_source.html:11
2803 #: rhodecode/templates/base/base.html:186
2804 #: rhodecode/templates/base/base.html:188
2805 #: rhodecode/templates/base/base.html:190
2806 #: rhodecode/templates/data_table/_dt_elements.html:31
2807 #: rhodecode/templates/data_table/_dt_elements.html:33
2808 #: rhodecode/templates/data_table/_dt_elements.html:35
2809 msgid "Files"
2810 msgstr ""
2811
2812 #: rhodecode/templates/base/base.html:195
2813 #: rhodecode/templates/base/base.html:199
1961 2814 msgid "Options"
1962 2815 msgstr ""
1963 2816
1964 #: rhodecode/templates/base/base.html:286
1965 #: rhodecode/templates/base/base.html:288
1966 #: rhodecode/templates/base/base.html:306
2817 #: rhodecode/templates/base/base.html:204
2818 #: rhodecode/templates/base/base.html:206
2819 #: rhodecode/templates/base/base.html:227
1967 2820 msgid "settings"
1968 2821 msgstr ""
1969 2822
1970 #: rhodecode/templates/base/base.html:292
2823 #: rhodecode/templates/base/base.html:209
2824 #: rhodecode/templates/data_table/_dt_elements.html:80
2825 #: rhodecode/templates/forks/fork.html:13
2826 msgid "fork"
2827 msgstr ""
2828
2829 #: rhodecode/templates/base/base.html:211
2830 #: rhodecode/templates/changelog/changelog.html:40
2831 msgid "Open new pull request"
2832 msgstr ""
2833
2834 #: rhodecode/templates/base/base.html:213
1971 2835 msgid "search"
1972 2836 msgstr ""
1973 2837
1974 #: rhodecode/templates/base/base.html:299
1975 msgid "journal"
1976 msgstr ""
1977
1978 #: rhodecode/templates/base/base.html:301
2838 #: rhodecode/templates/base/base.html:222
1979 2839 msgid "repositories groups"
1980 2840 msgstr ""
1981 2841
1982 #: rhodecode/templates/base/base.html:302
1983 msgid "users"
1984 msgstr ""
1985
1986 #: rhodecode/templates/base/base.html:303
2842 #: rhodecode/templates/base/base.html:224
1987 2843 msgid "users groups"
1988 2844 msgstr ""
1989 2845
1990 #: rhodecode/templates/base/base.html:304
2846 #: rhodecode/templates/base/base.html:225
1991 2847 msgid "permissions"
1992 2848 msgstr ""
1993 2849
1994 #: rhodecode/templates/base/base.html:317
1995 #: rhodecode/templates/base/base.html:319
1996 #: rhodecode/templates/followers/followers.html:5
2850 #: rhodecode/templates/base/base.html:238
2851 #: rhodecode/templates/base/base.html:240
1997 2852 msgid "Followers"
1998 2853 msgstr ""
1999 2854
2000 #: rhodecode/templates/base/base.html:325
2855 #: rhodecode/templates/base/base.html:246
2856 #: rhodecode/templates/base/base.html:248
2857 msgid "Forks"
2858 msgstr ""
2859
2001 2860 #: rhodecode/templates/base/base.html:327
2002 #: rhodecode/templates/forks/forks.html:5
2003 msgid "Forks"
2004 msgstr ""
2005
2006 #: rhodecode/templates/base/base.html:356
2007 #: rhodecode/templates/base/base.html:358
2008 #: rhodecode/templates/base/base.html:360
2009 #: rhodecode/templates/search/search.html:4
2010 #: rhodecode/templates/search/search.html:24
2011 #: rhodecode/templates/search/search.html:46
2861 #: rhodecode/templates/base/base.html:329
2862 #: rhodecode/templates/base/base.html:331
2863 #: rhodecode/templates/search/search.html:52
2012 2864 msgid "Search"
2013 2865 msgstr ""
2014 2866
2015 #: rhodecode/templates/base/root.html:57
2016 #: rhodecode/templates/journal/journal.html:48
2017 #: rhodecode/templates/summary/summary.html:36
2867 #: rhodecode/templates/base/root.html:42
2868 msgid "add another comment"
2869 msgstr ""
2870
2871 #: rhodecode/templates/base/root.html:43
2872 #: rhodecode/templates/journal/journal.html:120
2873 #: rhodecode/templates/summary/summary.html:57
2018 2874 msgid "Stop following this repository"
2019 2875 msgstr ""
2020 2876
2021 #: rhodecode/templates/base/root.html:66
2022 #: rhodecode/templates/summary/summary.html:40
2877 #: rhodecode/templates/base/root.html:44
2878 #: rhodecode/templates/summary/summary.html:61
2023 2879 msgid "Start following this repository"
2024 2880 msgstr ""
2025 2881
2026 #: rhodecode/templates/branches/branches_data.html:4
2027 #: rhodecode/templates/tags/tags_data.html:4
2028 msgid "date"
2882 #: rhodecode/templates/base/root.html:45
2883 msgid "Group"
2884 msgstr ""
2885
2886 #: rhodecode/templates/base/root.html:47
2887 msgid "search truncated"
2888 msgstr ""
2889
2890 #: rhodecode/templates/base/root.html:48
2891 msgid "no matching files"
2892 msgstr ""
2893
2894 #: rhodecode/templates/bookmarks/bookmarks.html:5
2895 #, python-format
2896 msgid "%s Bookmarks"
2897 msgstr ""
2898
2899 #: rhodecode/templates/bookmarks/bookmarks.html:39
2900 #: rhodecode/templates/bookmarks/bookmarks_data.html:8
2901 #: rhodecode/templates/branches/branches.html:54
2902 #: rhodecode/templates/tags/tags.html:39
2903 #: rhodecode/templates/tags/tags_data.html:8
2904 msgid "Author"
2905 msgstr ""
2906
2907 #: rhodecode/templates/branches/branches.html:5
2908 #, python-format
2909 msgid "%s Branches"
2910 msgstr ""
2911
2912 #: rhodecode/templates/branches/branches.html:29
2913 msgid "Compare branches"
2914 msgstr ""
2915
2916 #: rhodecode/templates/branches/branches.html:57
2917 #: rhodecode/templates/compare/compare_diff.html:5
2918 #: rhodecode/templates/compare/compare_diff.html:13
2919 msgid "Compare"
2029 2920 msgstr ""
2030 2921
2031 2922 #: rhodecode/templates/branches/branches_data.html:6
2032 #: rhodecode/templates/shortlog/shortlog_data.html:7
2033 #: rhodecode/templates/tags/tags_data.html:6
2034 msgid "author"
2923 msgid "name"
2924 msgstr ""
2925
2926 #: rhodecode/templates/branches/branches_data.html:7
2927 msgid "date"
2035 2928 msgstr ""
2036 2929
2037 2930 #: rhodecode/templates/branches/branches_data.html:8
2038 #: rhodecode/templates/shortlog/shortlog_data.html:11
2039 #: rhodecode/templates/tags/tags_data.html:8
2040 msgid "links"
2041 msgstr ""
2042
2043 #: rhodecode/templates/branches/branches_data.html:23
2044 #: rhodecode/templates/branches/branches_data.html:43
2045 #: rhodecode/templates/shortlog/shortlog_data.html:39
2046 #: rhodecode/templates/tags/tags_data.html:24
2047 msgid "changeset"
2048 msgstr ""
2049
2050 #: rhodecode/templates/branches/branches_data.html:25
2051 #: rhodecode/templates/branches/branches_data.html:45
2052 #: rhodecode/templates/files/files.html:12
2053 #: rhodecode/templates/shortlog/shortlog_data.html:41
2054 #: rhodecode/templates/summary/summary.html:233
2055 #: rhodecode/templates/tags/tags_data.html:26
2056 msgid "files"
2057 msgstr ""
2058
2059 #: rhodecode/templates/changelog/changelog.html:14
2060 msgid "showing "
2061 msgstr ""
2062
2063 #: rhodecode/templates/changelog/changelog.html:14
2064 msgid "out of"
2931 #: rhodecode/templates/shortlog/shortlog_data.html:8
2932 msgid "author"
2933 msgstr ""
2934
2935 #: rhodecode/templates/branches/branches_data.html:9
2936 #: rhodecode/templates/shortlog/shortlog_data.html:5
2937 msgid "revision"
2938 msgstr ""
2939
2940 #: rhodecode/templates/branches/branches_data.html:10
2941 msgid "compare"
2942 msgstr ""
2943
2944 #: rhodecode/templates/changelog/changelog.html:6
2945 #, python-format
2946 msgid "%s Changelog"
2947 msgstr ""
2948
2949 #: rhodecode/templates/changelog/changelog.html:15
2950 #, python-format
2951 msgid "showing %d out of %d revision"
2952 msgid_plural "showing %d out of %d revisions"
2953 msgstr[0] ""
2954 msgstr[1] ""
2955
2956 #: rhodecode/templates/changelog/changelog.html:37
2957 #: rhodecode/templates/forks/forks_data.html:19
2958 #, python-format
2959 msgid "compare fork with %s"
2065 2960 msgstr ""
2066 2961
2067 2962 #: rhodecode/templates/changelog/changelog.html:37
2963 #: rhodecode/templates/forks/forks_data.html:21
2964 msgid "Compare fork"
2965 msgstr ""
2966
2967 #: rhodecode/templates/changelog/changelog.html:46
2068 2968 msgid "Show"
2069 2969 msgstr ""
2070 2970
2071 #: rhodecode/templates/changelog/changelog.html:50
2072 #: rhodecode/templates/changeset/changeset.html:42
2073 #: rhodecode/templates/summary/summary.html:609
2074 msgid "commit"
2075 msgstr ""
2076
2077 #: rhodecode/templates/changelog/changelog.html:63
2078 msgid "Affected number of files, click to show more details"
2079 msgstr ""
2080
2081 #: rhodecode/templates/changelog/changelog.html:67
2082 #: rhodecode/templates/changeset/changeset.html:66
2083 msgid "merge"
2084 msgstr ""
2085
2086 2971 #: rhodecode/templates/changelog/changelog.html:72
2087 #: rhodecode/templates/changeset/changeset.html:72
2972 #: rhodecode/templates/summary/summary.html:364
2973 msgid "show more"
2974 msgstr ""
2975
2976 #: rhodecode/templates/changelog/changelog.html:76
2977 msgid "Affected number of files, click to show more details"
2978 msgstr ""
2979
2980 #: rhodecode/templates/changelog/changelog.html:89
2981 #: rhodecode/templates/changeset/changeset.html:38
2982 #: rhodecode/templates/changeset/changeset_file_comment.html:20
2983 #: rhodecode/templates/changeset/changeset_range.html:46
2984 msgid "Changeset status"
2985 msgstr ""
2986
2987 #: rhodecode/templates/changelog/changelog.html:92
2988 msgid "Click to open associated pull request"
2989 msgstr ""
2990
2991 #: rhodecode/templates/changelog/changelog.html:102
2992 #: rhodecode/templates/changeset/changeset.html:78
2088 2993 msgid "Parent"
2089 2994 msgstr ""
2090 2995
2091 #: rhodecode/templates/changelog/changelog.html:77
2092 #: rhodecode/templates/changeset/changeset.html:77
2996 #: rhodecode/templates/changelog/changelog.html:108
2997 #: rhodecode/templates/changeset/changeset.html:84
2093 2998 msgid "No parents"
2094 2999 msgstr ""
2095 3000
2096 #: rhodecode/templates/changelog/changelog.html:82
2097 #: rhodecode/templates/changeset/changeset.html:80
3001 #: rhodecode/templates/changelog/changelog.html:113
3002 #: rhodecode/templates/changeset/changeset.html:88
3003 msgid "merge"
3004 msgstr ""
3005
3006 #: rhodecode/templates/changelog/changelog.html:116
3007 #: rhodecode/templates/changeset/changeset.html:91
2098 3008 #: rhodecode/templates/files/files.html:29
2099 #: rhodecode/templates/files/files_annotate.html:25
3009 #: rhodecode/templates/files/files_add.html:33
2100 3010 #: rhodecode/templates/files/files_edit.html:33
2101 3011 #: rhodecode/templates/shortlog/shortlog_data.html:9
2102 3012 msgid "branch"
2103 3013 msgstr ""
2104 3014
2105 #: rhodecode/templates/changelog/changelog.html:86
2106 #: rhodecode/templates/changeset/changeset.html:83
3015 #: rhodecode/templates/changelog/changelog.html:122
3016 msgid "bookmark"
3017 msgstr ""
3018
3019 #: rhodecode/templates/changelog/changelog.html:128
3020 #: rhodecode/templates/changeset/changeset.html:96
2107 3021 msgid "tag"
2108 3022 msgstr ""
2109 3023
2110 #: rhodecode/templates/changelog/changelog.html:122
3024 #: rhodecode/templates/changelog/changelog.html:164
2111 3025 msgid "Show selected changes __S -> __E"
2112 3026 msgstr ""
2113 3027
2114 #: rhodecode/templates/changelog/changelog.html:172
2115 #: rhodecode/templates/shortlog/shortlog_data.html:61
3028 #: rhodecode/templates/changelog/changelog.html:255
2116 3029 msgid "There are no changes yet"
2117 3030 msgstr ""
2118 3031
2119 #: rhodecode/templates/changelog/changelog_details.html:2
2120 #: rhodecode/templates/changeset/changeset.html:55
2121 msgid "removed"
2122 msgstr ""
2123
2124 #: rhodecode/templates/changelog/changelog_details.html:3
2125 #: rhodecode/templates/changeset/changeset.html:56
2126 msgid "changed"
2127 msgstr ""
2128
2129 3032 #: rhodecode/templates/changelog/changelog_details.html:4
2130 #: rhodecode/templates/changeset/changeset.html:57
2131 msgid "added"
3033 #: rhodecode/templates/changeset/changeset.html:66
3034 msgid "removed"
3035 msgstr ""
3036
3037 #: rhodecode/templates/changelog/changelog_details.html:5
3038 #: rhodecode/templates/changeset/changeset.html:67
3039 msgid "changed"
2132 3040 msgstr ""
2133 3041
2134 3042 #: rhodecode/templates/changelog/changelog_details.html:6
2135 #: rhodecode/templates/changelog/changelog_details.html:7
3043 #: rhodecode/templates/changeset/changeset.html:68
3044 msgid "added"
3045 msgstr ""
3046
2136 3047 #: rhodecode/templates/changelog/changelog_details.html:8
2137 #: rhodecode/templates/changeset/changeset.html:59
2138 #: rhodecode/templates/changeset/changeset.html:60
2139 #: rhodecode/templates/changeset/changeset.html:61
3048 #: rhodecode/templates/changelog/changelog_details.html:9
3049 #: rhodecode/templates/changelog/changelog_details.html:10
3050 #: rhodecode/templates/changeset/changeset.html:70
3051 #: rhodecode/templates/changeset/changeset.html:71
3052 #: rhodecode/templates/changeset/changeset.html:72
2140 3053 #, python-format
2141 3054 msgid "affected %s files"
2142 3055 msgstr ""
2143 3056
2144 3057 #: rhodecode/templates/changeset/changeset.html:6
3058 #, python-format
3059 msgid "%s Changeset"
3060 msgstr ""
3061
2145 3062 #: rhodecode/templates/changeset/changeset.html:14
2146 #: rhodecode/templates/changeset/changeset.html:31
2147 3063 msgid "Changeset"
2148 3064 msgstr ""
2149 3065
2150 #: rhodecode/templates/changeset/changeset.html:32
2151 #: rhodecode/templates/changeset/changeset.html:121
2152 #: rhodecode/templates/changeset/changeset_range.html:78
2153 #: rhodecode/templates/files/file_diff.html:32
2154 #: rhodecode/templates/files/file_diff.html:42
3066 #: rhodecode/templates/changeset/changeset.html:43
3067 #: rhodecode/templates/changeset/diff_block.html:20
2155 3068 msgid "raw diff"
2156 3069 msgstr ""
2157 3070
2158 #: rhodecode/templates/changeset/changeset.html:34
2159 #: rhodecode/templates/changeset/changeset.html:123
2160 #: rhodecode/templates/changeset/changeset_range.html:80
2161 #: rhodecode/templates/files/file_diff.html:34
3071 #: rhodecode/templates/changeset/changeset.html:44
3072 #: rhodecode/templates/changeset/diff_block.html:21
2162 3073 msgid "download diff"
2163 3074 msgstr ""
2164 3075
2165 #: rhodecode/templates/changeset/changeset.html:90
3076 #: rhodecode/templates/changeset/changeset.html:48
3077 #: rhodecode/templates/changeset/changeset_file_comment.html:82
2166 3078 #, python-format
2167 msgid "%s files affected with %s additions and %s deletions."
2168 msgstr ""
2169
2170 #: rhodecode/templates/changeset/changeset.html:101
2171 msgid "Changeset was too big and was cut off..."
3079 msgid "%d comment"
3080 msgid_plural "%d comments"
3081 msgstr[0] ""
3082 msgstr[1] ""
3083
3084 #: rhodecode/templates/changeset/changeset.html:48
3085 #: rhodecode/templates/changeset/changeset_file_comment.html:82
3086 #, python-format
3087 msgid "(%d inline)"
3088 msgid_plural "(%d inline)"
3089 msgstr[0] ""
3090 msgstr[1] ""
3091
3092 #: rhodecode/templates/changeset/changeset.html:103
3093 #, python-format
3094 msgid "%s files affected with %s insertions and %s deletions:"
2172 3095 msgstr ""
2173 3096
2174 3097 #: rhodecode/templates/changeset/changeset.html:119
2175 #: rhodecode/templates/changeset/changeset_range.html:76
2176 #: rhodecode/templates/files/file_diff.html:30
3098 msgid "Changeset was too big and was cut off..."
3099 msgstr ""
3100
3101 #: rhodecode/templates/changeset/changeset_file_comment.html:42
3102 msgid "Submitting..."
3103 msgstr ""
3104
3105 #: rhodecode/templates/changeset/changeset_file_comment.html:45
3106 msgid "Commenting on line {1}."
3107 msgstr ""
3108
3109 #: rhodecode/templates/changeset/changeset_file_comment.html:46
3110 #: rhodecode/templates/changeset/changeset_file_comment.html:121
3111 #, python-format
3112 msgid "Comments parsed using %s syntax with %s support."
3113 msgstr ""
3114
3115 #: rhodecode/templates/changeset/changeset_file_comment.html:48
3116 #: rhodecode/templates/changeset/changeset_file_comment.html:123
3117 msgid "Use @username inside this text to send notification to this RhodeCode user"
3118 msgstr ""
3119
3120 #: rhodecode/templates/changeset/changeset_file_comment.html:59
3121 #: rhodecode/templates/changeset/changeset_file_comment.html:138
3122 msgid "Comment"
3123 msgstr ""
3124
3125 #: rhodecode/templates/changeset/changeset_file_comment.html:60
3126 #: rhodecode/templates/changeset/changeset_file_comment.html:71
3127 msgid "Hide"
3128 msgstr ""
3129
3130 #: rhodecode/templates/changeset/changeset_file_comment.html:67
3131 msgid "You need to be logged in to comment."
3132 msgstr ""
3133
3134 #: rhodecode/templates/changeset/changeset_file_comment.html:67
3135 msgid "Login now"
3136 msgstr ""
3137
3138 #: rhodecode/templates/changeset/changeset_file_comment.html:118
3139 msgid "Leave a comment"
3140 msgstr ""
3141
3142 #: rhodecode/templates/changeset/changeset_file_comment.html:124
3143 msgid "Check this to change current status of code-review for this changeset"
3144 msgstr ""
3145
3146 #: rhodecode/templates/changeset/changeset_file_comment.html:124
3147 msgid "change status"
3148 msgstr ""
3149
3150 #: rhodecode/templates/changeset/changeset_file_comment.html:140
3151 msgid "Comment and close"
3152 msgstr ""
3153
3154 #: rhodecode/templates/changeset/changeset_range.html:5
3155 #, python-format
3156 msgid "%s Changesets"
3157 msgstr ""
3158
3159 #: rhodecode/templates/changeset/changeset_range.html:29
3160 #: rhodecode/templates/compare/compare_diff.html:29
3161 msgid "Compare View"
3162 msgstr ""
3163
3164 #: rhodecode/templates/changeset/changeset_range.html:54
3165 #: rhodecode/templates/compare/compare_diff.html:41
3166 #: rhodecode/templates/pullrequests/pullrequest_show.html:69
3167 msgid "Files affected"
3168 msgstr ""
3169
3170 #: rhodecode/templates/changeset/diff_block.html:19
2177 3171 msgid "diff"
2178 3172 msgstr ""
2179 3173
2180 #: rhodecode/templates/changeset/changeset.html:132
2181 #: rhodecode/templates/changeset/changeset_range.html:89
2182 msgid "No changes in this file"
2183 msgstr ""
2184
2185 #: rhodecode/templates/changeset/changeset_range.html:30
2186 msgid "Compare View"
2187 msgstr ""
2188
2189 #: rhodecode/templates/changeset/changeset_range.html:52
2190 msgid "Files affected"
2191 msgstr ""
2192
2193 #: rhodecode/templates/errors/error_document.html:44
3174 #: rhodecode/templates/changeset/diff_block.html:27
3175 msgid "show inline comments"
3176 msgstr ""
3177
3178 #: rhodecode/templates/compare/compare_cs.html:5
3179 msgid "No changesets"
3180 msgstr ""
3181
3182 #: rhodecode/templates/compare/compare_diff.html:37
3183 msgid "Outgoing changesets"
3184 msgstr ""
3185
3186 #: rhodecode/templates/data_table/_dt_elements.html:39
3187 #: rhodecode/templates/data_table/_dt_elements.html:41
3188 #: rhodecode/templates/data_table/_dt_elements.html:43
3189 msgid "Fork"
3190 msgstr ""
3191
3192 #: rhodecode/templates/data_table/_dt_elements.html:60
3193 #: rhodecode/templates/journal/journal.html:126
3194 #: rhodecode/templates/summary/summary.html:68
3195 msgid "Mercurial repository"
3196 msgstr ""
3197
3198 #: rhodecode/templates/data_table/_dt_elements.html:62
3199 #: rhodecode/templates/journal/journal.html:128
3200 #: rhodecode/templates/summary/summary.html:71
3201 msgid "Git repository"
3202 msgstr ""
3203
3204 #: rhodecode/templates/data_table/_dt_elements.html:69
3205 #: rhodecode/templates/journal/journal.html:134
3206 #: rhodecode/templates/summary/summary.html:78
3207 msgid "public repository"
3208 msgstr ""
3209
3210 #: rhodecode/templates/data_table/_dt_elements.html:80
3211 #: rhodecode/templates/summary/summary.html:87
3212 #: rhodecode/templates/summary/summary.html:88
3213 msgid "Fork of"
3214 msgstr ""
3215
3216 #: rhodecode/templates/data_table/_dt_elements.html:92
3217 msgid "No changesets yet"
3218 msgstr ""
3219
3220 #: rhodecode/templates/data_table/_dt_elements.html:104
3221 #, python-format
3222 msgid "Confirm to delete this user: %s"
3223 msgstr ""
3224
3225 #: rhodecode/templates/email_templates/main.html:8
3226 msgid "This is an notification from RhodeCode."
3227 msgstr ""
3228
3229 #: rhodecode/templates/errors/error_document.html:46
2194 3230 #, python-format
2195 3231 msgid "You will be redirected to %s in %s seconds"
2196 3232 msgstr ""
2197 3233
2198 3234 #: rhodecode/templates/files/file_diff.html:4
3235 #, python-format
3236 msgid "%s File diff"
3237 msgstr ""
3238
2199 3239 #: rhodecode/templates/files/file_diff.html:12
2200 3240 msgid "File diff"
2201 3241 msgstr ""
2202 3242
2203 #: rhodecode/templates/files/file_diff.html:42
2204 msgid "Diff is to big to display"
2205 msgstr ""
2206
2207 #: rhodecode/templates/files/files.html:37
2208 #: rhodecode/templates/files/files_annotate.html:31
3243 #: rhodecode/templates/files/files.html:4
3244 #: rhodecode/templates/files/files.html:72
3245 #, python-format
3246 msgid "%s files"
3247 msgstr ""
3248
3249 #: rhodecode/templates/files/files.html:12
3250 #: rhodecode/templates/summary/summary.html:340
3251 msgid "files"
3252 msgstr ""
3253
3254 #: rhodecode/templates/files/files_add.html:4
3255 #: rhodecode/templates/files/files_edit.html:4
3256 #, python-format
3257 msgid "%s Edit file"
3258 msgstr ""
3259
3260 #: rhodecode/templates/files/files_add.html:19
3261 msgid "add file"
3262 msgstr ""
3263
3264 #: rhodecode/templates/files/files_add.html:40
3265 msgid "Add new file"
3266 msgstr ""
3267
3268 #: rhodecode/templates/files/files_add.html:45
3269 msgid "File Name"
3270 msgstr ""
3271
3272 #: rhodecode/templates/files/files_add.html:49
3273 #: rhodecode/templates/files/files_add.html:58
3274 msgid "or"
3275 msgstr ""
3276
3277 #: rhodecode/templates/files/files_add.html:49
3278 #: rhodecode/templates/files/files_add.html:54
3279 msgid "Upload file"
3280 msgstr ""
3281
3282 #: rhodecode/templates/files/files_add.html:58
3283 msgid "Create new file"
3284 msgstr ""
3285
3286 #: rhodecode/templates/files/files_add.html:63
2209 3287 #: rhodecode/templates/files/files_edit.html:39
3288 #: rhodecode/templates/files/files_ypjax.html:3
2210 3289 msgid "Location"
2211 3290 msgstr ""
2212 3291
2213 #: rhodecode/templates/files/files.html:46
2214 msgid "Go back"
2215 msgstr ""
2216
2217 #: rhodecode/templates/files/files.html:47
2218 msgid "No files at given path"
2219 msgstr ""
2220
2221 #: rhodecode/templates/files/files_annotate.html:4
2222 msgid "File annotate"
2223 msgstr ""
2224
2225 #: rhodecode/templates/files/files_annotate.html:12
2226 msgid "annotate"
2227 msgstr ""
2228
2229 #: rhodecode/templates/files/files_annotate.html:33
2230 #: rhodecode/templates/files/files_browser.html:160
2231 #: rhodecode/templates/files/files_source.html:2
2232 msgid "Revision"
2233 msgstr ""
2234
2235 #: rhodecode/templates/files/files_annotate.html:36
2236 #: rhodecode/templates/files/files_browser.html:158
2237 #: rhodecode/templates/files/files_source.html:7
2238 msgid "Size"
2239 msgstr ""
2240
2241 #: rhodecode/templates/files/files_annotate.html:38
2242 #: rhodecode/templates/files/files_browser.html:159
2243 #: rhodecode/templates/files/files_source.html:9
2244 msgid "Mimetype"
2245 msgstr ""
2246
2247 #: rhodecode/templates/files/files_annotate.html:41
2248 msgid "show source"
2249 msgstr ""
2250
2251 #: rhodecode/templates/files/files_annotate.html:43
2252 #: rhodecode/templates/files/files_annotate.html:78
2253 #: rhodecode/templates/files/files_source.html:14
2254 #: rhodecode/templates/files/files_source.html:51
2255 msgid "show as raw"
2256 msgstr ""
2257
2258 #: rhodecode/templates/files/files_annotate.html:45
2259 #: rhodecode/templates/files/files_source.html:16
2260 msgid "download as raw"
2261 msgstr ""
2262
2263 #: rhodecode/templates/files/files_annotate.html:54
2264 #: rhodecode/templates/files/files_source.html:25
2265 msgid "History"
2266 msgstr ""
2267
2268 #: rhodecode/templates/files/files_annotate.html:73
2269 #: rhodecode/templates/files/files_source.html:46
2270 #, python-format
2271 msgid "Binary file (%s)"
2272 msgstr ""
2273
2274 #: rhodecode/templates/files/files_annotate.html:78
2275 #: rhodecode/templates/files/files_source.html:51
2276 msgid "File is too big to display"
3292 #: rhodecode/templates/files/files_add.html:67
3293 msgid "use / to separate directories"
3294 msgstr ""
3295
3296 #: rhodecode/templates/files/files_add.html:77
3297 #: rhodecode/templates/files/files_edit.html:63
3298 #: rhodecode/templates/shortlog/shortlog_data.html:6
3299 msgid "commit message"
3300 msgstr ""
3301
3302 #: rhodecode/templates/files/files_add.html:81
3303 #: rhodecode/templates/files/files_edit.html:67
3304 msgid "Commit changes"
2277 3305 msgstr ""
2278 3306
2279 3307 #: rhodecode/templates/files/files_browser.html:13
@@ -2296,57 +3324,161 b' msgstr ""'
2296 3324 msgid "search file list"
2297 3325 msgstr ""
2298 3326
2299 #: rhodecode/templates/files/files_browser.html:32
3327 #: rhodecode/templates/files/files_browser.html:31
3328 #: rhodecode/templates/shortlog/shortlog_data.html:65
3329 msgid "add new file"
3330 msgstr ""
3331
3332 #: rhodecode/templates/files/files_browser.html:35
2300 3333 msgid "Loading file list..."
2301 3334 msgstr ""
2302 3335
2303 #: rhodecode/templates/files/files_browser.html:111
2304 msgid "search truncated"
2305 msgstr ""
2306
2307 #: rhodecode/templates/files/files_browser.html:122
2308 msgid "no matching files"
2309 msgstr ""
2310
2311 #: rhodecode/templates/files/files_browser.html:161
3336 #: rhodecode/templates/files/files_browser.html:48
3337 msgid "Size"
3338 msgstr ""
3339
3340 #: rhodecode/templates/files/files_browser.html:49
3341 msgid "Mimetype"
3342 msgstr ""
3343
3344 #: rhodecode/templates/files/files_browser.html:50
3345 msgid "Last Revision"
3346 msgstr ""
3347
3348 #: rhodecode/templates/files/files_browser.html:51
2312 3349 msgid "Last modified"
2313 3350 msgstr ""
2314 3351
2315 #: rhodecode/templates/files/files_browser.html:162
3352 #: rhodecode/templates/files/files_browser.html:52
2316 3353 msgid "Last commiter"
2317 3354 msgstr ""
2318 3355
2319 #: rhodecode/templates/files/files_edit.html:4
2320 msgid "Edit file"
2321 msgstr ""
2322
2323 3356 #: rhodecode/templates/files/files_edit.html:19
2324 3357 msgid "edit file"
2325 3358 msgstr ""
2326 3359
2327 #: rhodecode/templates/files/files_edit.html:45
2328 #: rhodecode/templates/shortlog/shortlog_data.html:5
2329 msgid "commit message"
3360 #: rhodecode/templates/files/files_edit.html:49
3361 #: rhodecode/templates/files/files_source.html:38
3362 msgid "show annotation"
3363 msgstr ""
3364
3365 #: rhodecode/templates/files/files_edit.html:50
3366 #: rhodecode/templates/files/files_source.html:40
3367 #: rhodecode/templates/files/files_source.html:68
3368 msgid "show as raw"
2330 3369 msgstr ""
2331 3370
2332 3371 #: rhodecode/templates/files/files_edit.html:51
2333 msgid "Commit changes"
2334 msgstr ""
2335
2336 #: rhodecode/templates/files/files_source.html:12
2337 msgid "show annotation"
2338 msgstr ""
2339
2340 #: rhodecode/templates/files/files_source.html:153
3372 #: rhodecode/templates/files/files_source.html:41
3373 msgid "download as raw"
3374 msgstr ""
3375
3376 #: rhodecode/templates/files/files_edit.html:54
3377 msgid "source"
3378 msgstr ""
3379
3380 #: rhodecode/templates/files/files_edit.html:59
3381 msgid "Editing file"
3382 msgstr ""
3383
3384 #: rhodecode/templates/files/files_source.html:2
3385 msgid "History"
3386 msgstr ""
3387
3388 #: rhodecode/templates/files/files_source.html:9
3389 msgid "diff to revision"
3390 msgstr ""
3391
3392 #: rhodecode/templates/files/files_source.html:10
3393 #, fuzzy
3394 msgid "show at revision"
3395 msgstr ""
3396
3397 #: rhodecode/templates/files/files_source.html:14
3398 #, fuzzy, python-format
3399 msgid "%s author"
3400 msgid_plural "%s authors"
3401 msgstr[0] ""
3402 msgstr[1] ""
3403
3404 #: rhodecode/templates/files/files_source.html:36
3405 msgid "show source"
3406 msgstr ""
3407
3408 #: rhodecode/templates/files/files_source.html:59
3409 #, python-format
3410 msgid "Binary file (%s)"
3411 msgstr ""
3412
3413 #: rhodecode/templates/files/files_source.html:68
3414 msgid "File is too big to display"
3415 msgstr ""
3416
3417 #: rhodecode/templates/files/files_source.html:124
2341 3418 msgid "Selection link"
2342 3419 msgstr ""
2343 3420
3421 #: rhodecode/templates/files/files_ypjax.html:5
3422 msgid "annotation"
3423 msgstr ""
3424
3425 #: rhodecode/templates/files/files_ypjax.html:15
3426 msgid "Go back"
3427 msgstr ""
3428
3429 #: rhodecode/templates/files/files_ypjax.html:16
3430 msgid "No files at given path"
3431 msgstr ""
3432
3433 #: rhodecode/templates/followers/followers.html:5
3434 #, python-format
3435 msgid "%s Followers"
3436 msgstr ""
3437
2344 3438 #: rhodecode/templates/followers/followers.html:13
2345 3439 msgid "followers"
2346 3440 msgstr ""
2347 3441
2348 3442 #: rhodecode/templates/followers/followers_data.html:12
2349 msgid "Started following"
3443 msgid "Started following -"
3444 msgstr ""
3445
3446 #: rhodecode/templates/forks/fork.html:5
3447 #, python-format
3448 msgid "%s Fork"
3449 msgstr ""
3450
3451 #: rhodecode/templates/forks/fork.html:31
3452 msgid "Fork name"
3453 msgstr ""
3454
3455 #: rhodecode/templates/forks/fork.html:68
3456 msgid "Private"
3457 msgstr ""
3458
3459 #: rhodecode/templates/forks/fork.html:77
3460 msgid "Copy permissions"
3461 msgstr ""
3462
3463 #: rhodecode/templates/forks/fork.html:81
3464 msgid "Copy permissions from forked repository"
3465 msgstr ""
3466
3467 #: rhodecode/templates/forks/fork.html:86
3468 msgid "Update after clone"
3469 msgstr ""
3470
3471 #: rhodecode/templates/forks/fork.html:90
3472 msgid "Checkout source after making a clone"
3473 msgstr ""
3474
3475 #: rhodecode/templates/forks/fork.html:94
3476 msgid "fork this repository"
3477 msgstr ""
3478
3479 #: rhodecode/templates/forks/forks.html:5
3480 #, python-format
3481 msgid "%s Forks"
2350 3482 msgstr ""
2351 3483
2352 3484 #: rhodecode/templates/forks/forks.html:13
@@ -2357,184 +3489,395 b' msgstr ""'
2357 3489 msgid "forked"
2358 3490 msgstr ""
2359 3491
2360 #: rhodecode/templates/forks/forks_data.html:34
3492 #: rhodecode/templates/forks/forks_data.html:38
2361 3493 msgid "There are no forks yet"
2362 3494 msgstr ""
2363 3495
2364 #: rhodecode/templates/journal/journal.html:34
2365 msgid "Following"
2366 msgstr ""
2367
2368 #: rhodecode/templates/journal/journal.html:41
2369 msgid "following user"
3496 #: rhodecode/templates/journal/journal.html:13
3497 msgid "ATOM journal feed"
3498 msgstr ""
3499
3500 #: rhodecode/templates/journal/journal.html:14
3501 msgid "RSS journal feed"
3502 msgstr ""
3503
3504 #: rhodecode/templates/journal/journal.html:24
3505 #: rhodecode/templates/pullrequests/pullrequest.html:27
3506 msgid "Refresh"
3507 msgstr ""
3508
3509 #: rhodecode/templates/journal/journal.html:27
3510 #: rhodecode/templates/journal/public_journal.html:24
3511 msgid "RSS feed"
3512 msgstr ""
3513
3514 #: rhodecode/templates/journal/journal.html:30
3515 #: rhodecode/templates/journal/public_journal.html:27
3516 msgid "ATOM feed"
2370 3517 msgstr ""
2371 3518
2372 3519 #: rhodecode/templates/journal/journal.html:41
3520 msgid "Watched"
3521 msgstr ""
3522
3523 #: rhodecode/templates/journal/journal.html:46
3524 msgid "ADD"
3525 msgstr ""
3526
3527 #: rhodecode/templates/journal/journal.html:114
3528 msgid "following user"
3529 msgstr ""
3530
3531 #: rhodecode/templates/journal/journal.html:114
2373 3532 msgid "user"
2374 3533 msgstr ""
2375 3534
2376 #: rhodecode/templates/journal/journal.html:65
3535 #: rhodecode/templates/journal/journal.html:147
2377 3536 msgid "You are not following any users or repositories"
2378 3537 msgstr ""
2379 3538
2380 #: rhodecode/templates/journal/journal_data.html:46
3539 #: rhodecode/templates/journal/journal_data.html:47
2381 3540 msgid "No entries yet"
2382 3541 msgstr ""
2383 3542
2384 #: rhodecode/templates/journal/public_journal.html:17
3543 #: rhodecode/templates/journal/public_journal.html:13
3544 msgid "ATOM public journal feed"
3545 msgstr ""
3546
3547 #: rhodecode/templates/journal/public_journal.html:14
3548 msgid "RSS public journal feed"
3549 msgstr ""
3550
3551 #: rhodecode/templates/journal/public_journal.html:21
2385 3552 msgid "Public Journal"
2386 3553 msgstr ""
2387 3554
2388 #: rhodecode/templates/search/search.html:7
2389 #: rhodecode/templates/search/search.html:26
2390 msgid "in repository: "
2391 msgstr ""
2392
2393 #: rhodecode/templates/search/search.html:9
2394 #: rhodecode/templates/search/search.html:28
2395 msgid "in all repositories"
2396 msgstr ""
2397
2398 #: rhodecode/templates/search/search.html:42
3555 #: rhodecode/templates/pullrequests/pullrequest.html:4
3556 #: rhodecode/templates/pullrequests/pullrequest.html:12
3557 msgid "New pull request"
3558 msgstr ""
3559
3560 #: rhodecode/templates/pullrequests/pullrequest.html:28
3561 msgid "refresh overview"
3562 msgstr ""
3563
3564 #: rhodecode/templates/pullrequests/pullrequest.html:66
3565 msgid "Detailed compare view"
3566 msgstr ""
3567
3568 #: rhodecode/templates/pullrequests/pullrequest.html:70
3569 #: rhodecode/templates/pullrequests/pullrequest_show.html:82
3570 msgid "Pull request reviewers"
3571 msgstr ""
3572
3573 #: rhodecode/templates/pullrequests/pullrequest.html:79
3574 #: rhodecode/templates/pullrequests/pullrequest_show.html:94
3575 msgid "owner"
3576 msgstr ""
3577
3578 #: rhodecode/templates/pullrequests/pullrequest.html:91
3579 #: rhodecode/templates/pullrequests/pullrequest_show.html:109
3580 msgid "Add reviewer to this pull request."
3581 msgstr ""
3582
3583 #: rhodecode/templates/pullrequests/pullrequest.html:97
3584 msgid "Create new pull request"
3585 msgstr ""
3586
3587 #: rhodecode/templates/pullrequests/pullrequest.html:106
3588 #: rhodecode/templates/pullrequests/pullrequest_show.html:25
3589 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:33
3590 msgid "Title"
3591 msgstr ""
3592
3593 #: rhodecode/templates/pullrequests/pullrequest.html:115
3594 msgid "description"
3595 msgstr ""
3596
3597 #: rhodecode/templates/pullrequests/pullrequest.html:123
3598 msgid "Send pull request"
3599 msgstr ""
3600
3601 #: rhodecode/templates/pullrequests/pullrequest_show.html:23
3602 #, python-format
3603 msgid "Closed %s"
3604 msgstr ""
3605
3606 #: rhodecode/templates/pullrequests/pullrequest_show.html:31
3607 msgid "Status"
3608 msgstr ""
3609
3610 #: rhodecode/templates/pullrequests/pullrequest_show.html:36
3611 msgid "Pull request status"
3612 msgstr ""
3613
3614 #: rhodecode/templates/pullrequests/pullrequest_show.html:44
3615 msgid "Still not reviewed by"
3616 msgstr ""
3617
3618 #: rhodecode/templates/pullrequests/pullrequest_show.html:47
3619 #, python-format
3620 msgid "%d reviewer"
3621 msgid_plural "%d reviewers"
3622 msgstr[0] ""
3623 msgstr[1] ""
3624
3625 #: rhodecode/templates/pullrequests/pullrequest_show.html:54
3626 msgid "Created on"
3627 msgstr ""
3628
3629 #: rhodecode/templates/pullrequests/pullrequest_show.html:61
3630 msgid "Compare view"
3631 msgstr ""
3632
3633 #: rhodecode/templates/pullrequests/pullrequest_show.html:65
3634 msgid "Incoming changesets"
3635 msgstr ""
3636
3637 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:4
3638 msgid "all pull requests"
3639 msgstr ""
3640
3641 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:12
3642 msgid "All pull requests"
3643 msgstr ""
3644
3645 #: rhodecode/templates/pullrequests/pullrequest_show_all.html:27
3646 msgid "Closed"
3647 msgstr ""
3648
3649 #: rhodecode/templates/search/search.html:6
3650 #, python-format
3651 msgid "Search \"%s\" in repository: %s"
3652 msgstr ""
3653
3654 #: rhodecode/templates/search/search.html:8
3655 #, python-format
3656 msgid "Search \"%s\" in all repositories"
3657 msgstr ""
3658
3659 #: rhodecode/templates/search/search.html:12
3660 #: rhodecode/templates/search/search.html:32
3661 #, python-format
3662 msgid "Search in repository: %s"
3663 msgstr ""
3664
3665 #: rhodecode/templates/search/search.html:14
3666 #: rhodecode/templates/search/search.html:34
3667 msgid "Search in all repositories"
3668 msgstr ""
3669
3670 #: rhodecode/templates/search/search.html:48
2399 3671 msgid "Search term"
2400 3672 msgstr ""
2401 3673
2402 #: rhodecode/templates/search/search.html:54
3674 #: rhodecode/templates/search/search.html:60
2403 3675 msgid "Search in"
2404 3676 msgstr ""
2405 3677
2406 #: rhodecode/templates/search/search.html:57
3678 #: rhodecode/templates/search/search.html:63
2407 3679 msgid "File contents"
2408 3680 msgstr ""
2409 3681
2410 #: rhodecode/templates/search/search.html:59
3682 #: rhodecode/templates/search/search.html:64
3683 msgid "Commit messages"
3684 msgstr ""
3685
3686 #: rhodecode/templates/search/search.html:65
2411 3687 msgid "File names"
2412 3688 msgstr ""
2413 3689
2414 #: rhodecode/templates/search/search_content.html:20
3690 #: rhodecode/templates/search/search_commit.html:35
3691 #: rhodecode/templates/search/search_content.html:21
2415 3692 #: rhodecode/templates/search/search_path.html:15
2416 3693 msgid "Permission denied"
2417 3694 msgstr ""
2418 3695
2419 #: rhodecode/templates/settings/repo_fork.html:5
2420 msgid "Fork"
2421 msgstr ""
2422
2423 #: rhodecode/templates/settings/repo_fork.html:31
2424 msgid "Fork name"
2425 msgstr ""
2426
2427 #: rhodecode/templates/settings/repo_fork.html:55
2428 msgid "fork this repository"
3696 #: rhodecode/templates/settings/repo_settings.html:5
3697 #, python-format
3698 msgid "%s Settings"
2429 3699 msgstr ""
2430 3700
2431 3701 #: rhodecode/templates/shortlog/shortlog.html:5
2432 #: rhodecode/templates/summary/summary.html:666
2433 msgid "Shortlog"
3702 #, python-format
3703 msgid "%s Shortlog"
2434 3704 msgstr ""
2435 3705
2436 3706 #: rhodecode/templates/shortlog/shortlog.html:14
2437 3707 msgid "shortlog"
2438 3708 msgstr ""
2439 3709
2440 #: rhodecode/templates/shortlog/shortlog_data.html:6
3710 #: rhodecode/templates/shortlog/shortlog_data.html:7
2441 3711 msgid "age"
2442 3712 msgstr ""
2443 3713
3714 #: rhodecode/templates/shortlog/shortlog_data.html:18
3715 msgid "No commit message"
3716 msgstr ""
3717
3718 #: rhodecode/templates/shortlog/shortlog_data.html:62
3719 msgid "Add or upload files directly via RhodeCode"
3720 msgstr ""
3721
3722 #: rhodecode/templates/shortlog/shortlog_data.html:71
3723 msgid "Push new repo"
3724 msgstr ""
3725
3726 #: rhodecode/templates/shortlog/shortlog_data.html:79
3727 msgid "Existing repository?"
3728 msgstr ""
3729
3730 #: rhodecode/templates/summary/summary.html:4
3731 #, python-format
3732 msgid "%s Summary"
3733 msgstr ""
3734
2444 3735 #: rhodecode/templates/summary/summary.html:12
2445 3736 msgid "summary"
2446 3737 msgstr ""
2447 3738
2448 #: rhodecode/templates/summary/summary.html:79
3739 #: rhodecode/templates/summary/summary.html:20
3740 #, python-format
3741 msgid "repo %s ATOM feed"
3742 msgstr ""
3743
3744 #: rhodecode/templates/summary/summary.html:21
3745 #, python-format
3746 msgid "repo %s RSS feed"
3747 msgstr ""
3748
3749 #: rhodecode/templates/summary/summary.html:49
3750 #: rhodecode/templates/summary/summary.html:52
3751 msgid "ATOM"
3752 msgstr ""
3753
3754 #: rhodecode/templates/summary/summary.html:82
3755 #, python-format
3756 msgid "Non changable ID %s"
3757 msgstr ""
3758
3759 #: rhodecode/templates/summary/summary.html:87
3760 msgid "public"
3761 msgstr ""
3762
3763 #: rhodecode/templates/summary/summary.html:95
2449 3764 msgid "remote clone"
2450 3765 msgstr ""
2451 3766
2452 #: rhodecode/templates/summary/summary.html:121
2453 msgid "by"
2454 msgstr ""
2455
2456 #: rhodecode/templates/summary/summary.html:128
3767 #: rhodecode/templates/summary/summary.html:116
3768 msgid "Contact"
3769 msgstr ""
3770
3771 #: rhodecode/templates/summary/summary.html:130
2457 3772 msgid "Clone url"
2458 3773 msgstr ""
2459 3774
2460 #: rhodecode/templates/summary/summary.html:137
2461 msgid "Trending source files"
2462 msgstr ""
2463
2464 #: rhodecode/templates/summary/summary.html:146
2465 msgid "Download"
3775 #: rhodecode/templates/summary/summary.html:133
3776 msgid "Show by Name"
3777 msgstr ""
3778
3779 #: rhodecode/templates/summary/summary.html:134
3780 msgid "Show by ID"
3781 msgstr ""
3782
3783 #: rhodecode/templates/summary/summary.html:142
3784 msgid "Trending files"
2466 3785 msgstr ""
2467 3786
2468 3787 #: rhodecode/templates/summary/summary.html:150
2469 msgid "There are no downloads yet"
2470 msgstr ""
2471
2472 #: rhodecode/templates/summary/summary.html:152
2473 msgid "Downloads are disabled for this repository"
2474 msgstr ""
2475
2476 #: rhodecode/templates/summary/summary.html:154
2477 #: rhodecode/templates/summary/summary.html:320
3788 #: rhodecode/templates/summary/summary.html:166
3789 #: rhodecode/templates/summary/summary.html:194
2478 3790 msgid "enable"
2479 3791 msgstr ""
2480 3792
3793 #: rhodecode/templates/summary/summary.html:158
3794 msgid "Download"
3795 msgstr ""
3796
2481 3797 #: rhodecode/templates/summary/summary.html:162
2482 #: rhodecode/templates/summary/summary.html:297
3798 msgid "There are no downloads yet"
3799 msgstr ""
3800
3801 #: rhodecode/templates/summary/summary.html:164
3802 msgid "Downloads are disabled for this repository"
3803 msgstr ""
3804
3805 #: rhodecode/templates/summary/summary.html:170
3806 msgid "Download as zip"
3807 msgstr ""
3808
3809 #: rhodecode/templates/summary/summary.html:173
3810 msgid "Check this to download archive with subrepos"
3811 msgstr ""
3812
3813 #: rhodecode/templates/summary/summary.html:173
3814 msgid "with subrepos"
3815 msgstr ""
3816
3817 #: rhodecode/templates/summary/summary.html:186
3818 msgid "Commit activity by day / author"
3819 msgstr ""
3820
3821 #: rhodecode/templates/summary/summary.html:197
3822 msgid "Stats gathered: "
3823 msgstr ""
3824
3825 #: rhodecode/templates/summary/summary.html:218
3826 msgid "Shortlog"
3827 msgstr ""
3828
3829 #: rhodecode/templates/summary/summary.html:220
3830 msgid "Quick start"
3831 msgstr ""
3832
3833 #: rhodecode/templates/summary/summary.html:233
3834 #, python-format
3835 msgid "Readme file at revision '%s'"
3836 msgstr ""
3837
3838 #: rhodecode/templates/summary/summary.html:236
3839 msgid "Permalink to this readme"
3840 msgstr ""
3841
3842 #: rhodecode/templates/summary/summary.html:293
2483 3843 #, python-format
2484 3844 msgid "Download %s as %s"
2485 3845 msgstr ""
2486 3846
2487 #: rhodecode/templates/summary/summary.html:168
2488 msgid "Check this to download archive with subrepos"
2489 msgstr ""
2490
2491 #: rhodecode/templates/summary/summary.html:168
2492 msgid "with subrepos"
2493 msgstr ""
2494
2495 #: rhodecode/templates/summary/summary.html:176
2496 msgid "Feeds"
2497 msgstr ""
2498
2499 #: rhodecode/templates/summary/summary.html:257
2500 #: rhodecode/templates/summary/summary.html:684
2501 #: rhodecode/templates/summary/summary.html:695
2502 msgid "show more"
2503 msgstr ""
2504
2505 #: rhodecode/templates/summary/summary.html:312
2506 msgid "Commit activity by day / author"
2507 msgstr ""
2508
2509 #: rhodecode/templates/summary/summary.html:324
2510 msgid "Loaded in"
2511 msgstr ""
2512
2513 #: rhodecode/templates/summary/summary.html:603
3847 #: rhodecode/templates/summary/summary.html:650
2514 3848 msgid "commits"
2515 3849 msgstr ""
2516 3850
2517 #: rhodecode/templates/summary/summary.html:604
3851 #: rhodecode/templates/summary/summary.html:651
2518 3852 msgid "files added"
2519 3853 msgstr ""
2520 3854
2521 #: rhodecode/templates/summary/summary.html:605
3855 #: rhodecode/templates/summary/summary.html:652
2522 3856 msgid "files changed"
2523 3857 msgstr ""
2524 3858
2525 #: rhodecode/templates/summary/summary.html:606
3859 #: rhodecode/templates/summary/summary.html:653
2526 3860 msgid "files removed"
2527 3861 msgstr ""
2528 3862
2529 #: rhodecode/templates/summary/summary.html:610
3863 #: rhodecode/templates/summary/summary.html:656
3864 msgid "commit"
3865 msgstr ""
3866
3867 #: rhodecode/templates/summary/summary.html:657
2530 3868 msgid "file added"
2531 3869 msgstr ""
2532 3870
2533 #: rhodecode/templates/summary/summary.html:611
3871 #: rhodecode/templates/summary/summary.html:658
2534 3872 msgid "file changed"
2535 3873 msgstr ""
2536 3874
2537 #: rhodecode/templates/summary/summary.html:612
3875 #: rhodecode/templates/summary/summary.html:659
2538 3876 msgid "file removed"
2539 3877 msgstr ""
2540 3878
3879 #: rhodecode/templates/tags/tags.html:5
3880 #, python-format
3881 msgid "%s Tags"
3882 msgstr ""
3883
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/tests/test_models.py to rhodecode/tests/models/test_notifications.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/tests/mem_watch to rhodecode/tests/scripts/mem_watch
1 NO CONTENT: file renamed from rhodecode/tests/_test_concurency.py to rhodecode/tests/scripts/test_concurency.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/tests/rhodecode_crawler.py to rhodecode/tests/scripts/test_crawler.py
1 NO CONTENT: file renamed from rhodecode/tests/test_hg_operations.py to rhodecode/tests/scripts/test_vcs_operations.py
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now