##// END OF EJS Templates
Merge with upstream
Nicolas VINOT -
r1590:10d11754 merge beta
parent child Browse files
Show More
@@ -0,0 +1,360 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.lib.compat
4 ~~~~~~~~~~~~~~~~~~~~
5
6 Python backward compatibility functions and common libs
7
8
9 :created_on: Oct 7, 2011
10 :author: marcink
11 :copyright: (C) 2009-2010 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
27 #==============================================================================
28 # json
29 #==============================================================================
30 try:
31 import json
32 except ImportError:
33 import simplejson as json
34
35
36 #==============================================================================
37 # izip_longest
38 #==============================================================================
39 try:
40 from itertools import izip_longest
41 except ImportError:
42 import itertools
43
44 def izip_longest(*args, **kwds): # noqa
45 fillvalue = kwds.get("fillvalue")
46
47 def sentinel(counter=([fillvalue] * (len(args) - 1)).pop):
48 yield counter() # yields the fillvalue, or raises IndexError
49
50 fillers = itertools.repeat(fillvalue)
51 iters = [itertools.chain(it, sentinel(), fillers)
52 for it in args]
53 try:
54 for tup in itertools.izip(*iters):
55 yield tup
56 except IndexError:
57 pass
58
59
60 #==============================================================================
61 # OrderedDict
62 #==============================================================================
63
64 # Python Software Foundation License
65
66 # XXX: it feels like using the class with "is" and "is not" instead of "==" and
67 # "!=" should be faster.
68 class _Nil(object):
69
70 def __repr__(self):
71 return "nil"
72
73 def __eq__(self, other):
74 if (isinstance(other, _Nil)):
75 return True
76 else:
77 return NotImplemented
78
79 def __ne__(self, other):
80 if (isinstance(other, _Nil)):
81 return False
82 else:
83 return NotImplemented
84
85 _nil = _Nil()
86
87 class _odict(object):
88 """Ordered dict data structure, with O(1) complexity for dict operations
89 that modify one element.
90
91 Overwriting values doesn't change their original sequential order.
92 """
93
94 def _dict_impl(self):
95 return None
96
97 def __init__(self, data=(), **kwds):
98 """This doesn't accept keyword initialization as normal dicts to avoid
99 a trap - inside a function or method the keyword args are accessible
100 only as a dict, without a defined order, so their original order is
101 lost.
102 """
103 if kwds:
104 raise TypeError("__init__() of ordered dict takes no keyword "
105 "arguments to avoid an ordering trap.")
106 self._dict_impl().__init__(self)
107 # If you give a normal dict, then the order of elements is undefined
108 if hasattr(data, "iteritems"):
109 for key, val in data.iteritems():
110 self[key] = val
111 else:
112 for key, val in data:
113 self[key] = val
114
115 # Double-linked list header
116 def _get_lh(self):
117 dict_impl = self._dict_impl()
118 if not hasattr(self, '_lh'):
119 dict_impl.__setattr__(self, '_lh', _nil)
120 return dict_impl.__getattribute__(self, '_lh')
121
122 def _set_lh(self, val):
123 self._dict_impl().__setattr__(self, '_lh', val)
124
125 lh = property(_get_lh, _set_lh)
126
127 # Double-linked list tail
128 def _get_lt(self):
129 dict_impl = self._dict_impl()
130 if not hasattr(self, '_lt'):
131 dict_impl.__setattr__(self, '_lt', _nil)
132 return dict_impl.__getattribute__(self, '_lt')
133
134 def _set_lt(self, val):
135 self._dict_impl().__setattr__(self, '_lt', val)
136
137 lt = property(_get_lt, _set_lt)
138
139 def __getitem__(self, key):
140 return self._dict_impl().__getitem__(self, key)[1]
141
142 def __setitem__(self, key, val):
143 dict_impl = self._dict_impl()
144 try:
145 dict_impl.__getitem__(self, key)[1] = val
146 except KeyError, e:
147 new = [dict_impl.__getattribute__(self, 'lt'), val, _nil]
148 dict_impl.__setitem__(self, key, new)
149 if dict_impl.__getattribute__(self, 'lt') == _nil:
150 dict_impl.__setattr__(self, 'lh', key)
151 else:
152 dict_impl.__getitem__(
153 self, dict_impl.__getattribute__(self, 'lt'))[2] = key
154 dict_impl.__setattr__(self, 'lt', key)
155
156 def __delitem__(self, key):
157 dict_impl = self._dict_impl()
158 pred, _ , succ = self._dict_impl().__getitem__(self, key)
159 if pred == _nil:
160 dict_impl.__setattr__(self, 'lh', succ)
161 else:
162 dict_impl.__getitem__(self, pred)[2] = succ
163 if succ == _nil:
164 dict_impl.__setattr__(self, 'lt', pred)
165 else:
166 dict_impl.__getitem__(self, succ)[0] = pred
167 dict_impl.__delitem__(self, key)
168
169 def __contains__(self, key):
170 return key in self.keys()
171
172 def __len__(self):
173 return len(self.keys())
174
175 def __str__(self):
176 pairs = ("%r: %r" % (k, v) for k, v in self.iteritems())
177 return "{%s}" % ", ".join(pairs)
178
179 def __repr__(self):
180 if self:
181 pairs = ("(%r, %r)" % (k, v) for k, v in self.iteritems())
182 return "odict([%s])" % ", ".join(pairs)
183 else:
184 return "odict()"
185
186 def get(self, k, x=None):
187 if k in self:
188 return self._dict_impl().__getitem__(self, k)[1]
189 else:
190 return x
191
192 def __iter__(self):
193 dict_impl = self._dict_impl()
194 curr_key = dict_impl.__getattribute__(self, 'lh')
195 while curr_key != _nil:
196 yield curr_key
197 curr_key = dict_impl.__getitem__(self, curr_key)[2]
198
199 iterkeys = __iter__
200
201 def keys(self):
202 return list(self.iterkeys())
203
204 def itervalues(self):
205 dict_impl = self._dict_impl()
206 curr_key = dict_impl.__getattribute__(self, 'lh')
207 while curr_key != _nil:
208 _, val, curr_key = dict_impl.__getitem__(self, curr_key)
209 yield val
210
211 def values(self):
212 return list(self.itervalues())
213
214 def iteritems(self):
215 dict_impl = self._dict_impl()
216 curr_key = dict_impl.__getattribute__(self, 'lh')
217 while curr_key != _nil:
218 _, val, next_key = dict_impl.__getitem__(self, curr_key)
219 yield curr_key, val
220 curr_key = next_key
221
222 def items(self):
223 return list(self.iteritems())
224
225 def sort(self, cmp=None, key=None, reverse=False):
226 items = [(k, v) for k, v in self.items()]
227 if cmp is not None:
228 items = sorted(items, cmp=cmp)
229 elif key is not None:
230 items = sorted(items, key=key)
231 else:
232 items = sorted(items, key=lambda x: x[1])
233 if reverse:
234 items.reverse()
235 self.clear()
236 self.__init__(items)
237
238 def clear(self):
239 dict_impl = self._dict_impl()
240 dict_impl.clear(self)
241 dict_impl.__setattr__(self, 'lh', _nil)
242 dict_impl.__setattr__(self, 'lt', _nil)
243
244 def copy(self):
245 return self.__class__(self)
246
247 def update(self, data=(), **kwds):
248 if kwds:
249 raise TypeError("update() of ordered dict takes no keyword "
250 "arguments to avoid an ordering trap.")
251 if hasattr(data, "iteritems"):
252 data = data.iteritems()
253 for key, val in data:
254 self[key] = val
255
256 def setdefault(self, k, x=None):
257 try:
258 return self[k]
259 except KeyError:
260 self[k] = x
261 return x
262
263 def pop(self, k, x=_nil):
264 try:
265 val = self[k]
266 del self[k]
267 return val
268 except KeyError:
269 if x == _nil:
270 raise
271 return x
272
273 def popitem(self):
274 try:
275 dict_impl = self._dict_impl()
276 key = dict_impl.__getattribute__(self, 'lt')
277 return key, self.pop(key)
278 except KeyError:
279 raise KeyError("'popitem(): ordered dictionary is empty'")
280
281 def riterkeys(self):
282 """To iterate on keys in reversed order.
283 """
284 dict_impl = self._dict_impl()
285 curr_key = dict_impl.__getattribute__(self, 'lt')
286 while curr_key != _nil:
287 yield curr_key
288 curr_key = dict_impl.__getitem__(self, curr_key)[0]
289
290 __reversed__ = riterkeys
291
292 def rkeys(self):
293 """List of the keys in reversed order.
294 """
295 return list(self.riterkeys())
296
297 def ritervalues(self):
298 """To iterate on values in reversed order.
299 """
300 dict_impl = self._dict_impl()
301 curr_key = dict_impl.__getattribute__(self, 'lt')
302 while curr_key != _nil:
303 curr_key, val, _ = dict_impl.__getitem__(self, curr_key)
304 yield val
305
306 def rvalues(self):
307 """List of the values in reversed order.
308 """
309 return list(self.ritervalues())
310
311 def riteritems(self):
312 """To iterate on (key, value) in reversed order.
313 """
314 dict_impl = self._dict_impl()
315 curr_key = dict_impl.__getattribute__(self, 'lt')
316 while curr_key != _nil:
317 pred_key, val, _ = dict_impl.__getitem__(self, curr_key)
318 yield curr_key, val
319 curr_key = pred_key
320
321 def ritems(self):
322 """List of the (key, value) in reversed order.
323 """
324 return list(self.riteritems())
325
326 def firstkey(self):
327 if self:
328 return self._dict_impl().__getattribute__(self, 'lh')
329 else:
330 raise KeyError("'firstkey(): ordered dictionary is empty'")
331
332 def lastkey(self):
333 if self:
334 return self._dict_impl().__getattribute__(self, 'lt')
335 else:
336 raise KeyError("'lastkey(): ordered dictionary is empty'")
337
338 def as_dict(self):
339 return self._dict_impl()(self.items())
340
341 def _repr(self):
342 """_repr(): low level repr of the whole data contained in the odict.
343 Useful for debugging.
344 """
345 dict_impl = self._dict_impl()
346 form = "odict low level repr lh,lt,data: %r, %r, %s"
347 return form % (dict_impl.__getattribute__(self, 'lh'),
348 dict_impl.__getattribute__(self, 'lt'),
349 dict_impl.__repr__(self))
350
351 class OrderedDict(_odict, dict):
352
353 def _dict_impl(self):
354 return dict
355
356
357 #==============================================================================
358 # OrderedSet
359 #==============================================================================
360 from sqlalchemy.util import OrderedSet
@@ -2,10 +2,11 b''
2 Welcome to RhodeCode (RhodiumCode) documentation!
2 Welcome to RhodeCode (RhodiumCode) documentation!
3 =================================================
3 =================================================
4
4
5 ``RhodeCode`` (formerly hg-app) is a Pylons framework based Mercurial repository
5 ``RhodeCode`` is a Pylons framework based Mercurial repository
6 browser/management tool with a built in push/pull server and full text search.
6 browser/management tool with a built in push/pull server and full text search.
7 It works on http/https and has a built in permission/authentication system with
7 It works on http/https and has a built in permission/authentication system with
8 the ability to authenticate via LDAP.
8 the ability to authenticate via LDAP or ActiveDirectory. RhodeCode also supports
9 simple API so it's easy integrable with existing systems.
9
10
10 RhodeCode is similar in some respects to github or bitbucket_,
11 RhodeCode is similar in some respects to github or bitbucket_,
11 however RhodeCode can be run as standalone hosted application on your own server.
12 however RhodeCode can be run as standalone hosted application on your own server.
@@ -3,7 +3,8 b''
3 Changelog
3 Changelog
4 =========
4 =========
5
5
6 1.2.0 (**2011-XX-XX**)
6
7 1.3.0 (**XXXX-XX-XX**)
7 ======================
8 ======================
8
9
9 :status: in-progress
10 :status: in-progress
@@ -12,6 +13,18 b' 1.2.0 (**2011-XX-XX**)'
12 news
13 news
13 ----
14 ----
14
15
16 fixes
17 -----
18
19
20
21
22 1.2.0 (**2011-10-07**)
23 ======================
24
25 news
26 ----
27
15 - implemented #47 repository groups
28 - implemented #47 repository groups
16 - implemented #89 Can setup google analytics code from settings menu
29 - implemented #89 Can setup google analytics code from settings menu
17 - implemented #91 added nicer looking archive urls with more download options
30 - implemented #91 added nicer looking archive urls with more download options
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -25,9 +25,9 b''
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import platform
26 import platform
27
27
28 VERSION = (1, 2, 0, 'beta')
28 VERSION = (1, 3, 0, 'beta')
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
30 __dbversion__ = 3 #defines current db version for migrations
30 __dbversion__ = 4 #defines current db version for migrations
31 __platform__ = platform.system()
31 __platform__ = platform.system()
32 __license__ = 'GPLv3'
32 __license__ = 'GPLv3'
33
33
@@ -26,12 +26,12 b''
26 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
27
27
28 import inspect
28 import inspect
29 import json
30 import logging
29 import logging
31 import types
30 import types
32 import urllib
31 import urllib
33 import traceback
32 import traceback
34 from itertools import izip_longest
33
34 from rhodecode.lib.compat import izip_longest, json
35
35
36 from paste.response import replace_header
36 from paste.response import replace_header
37
37
@@ -103,7 +103,7 b' class JSONRPCController(WSGIController):'
103
103
104 try:
104 try:
105 json_body = json.loads(urllib.unquote_plus(raw_body))
105 json_body = json.loads(urllib.unquote_plus(raw_body))
106 except ValueError as e:
106 except ValueError, e:
107 #catch JSON errors Here
107 #catch JSON errors Here
108 return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \
108 return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \
109 % (e, urllib.unquote_plus(raw_body)))
109 % (e, urllib.unquote_plus(raw_body)))
@@ -116,14 +116,14 b' class JSONRPCController(WSGIController):'
116 log.debug('method: %s, params: %s',
116 log.debug('method: %s, params: %s',
117 self._req_method,
117 self._req_method,
118 self._req_params)
118 self._req_params)
119 except KeyError as e:
119 except KeyError, e:
120 return jsonrpc_error(message='Incorrect JSON query missing %s' % e)
120 return jsonrpc_error(message='Incorrect JSON query missing %s' % e)
121
121
122 #check if we can find this session using api_key
122 #check if we can find this session using api_key
123 try:
123 try:
124 u = User.get_by_api_key(self._req_api_key)
124 u = User.get_by_api_key(self._req_api_key)
125 auth_u = AuthUser(u.user_id, self._req_api_key)
125 auth_u = AuthUser(u.user_id, self._req_api_key)
126 except Exception as e:
126 except Exception, e:
127 return jsonrpc_error(message='Invalid API KEY')
127 return jsonrpc_error(message='Invalid API KEY')
128
128
129 self._error = None
129 self._error = None
@@ -201,10 +201,11 b' class JSONRPCController(WSGIController):'
201 raw_response = self._inspect_call(self._func)
201 raw_response = self._inspect_call(self._func)
202 if isinstance(raw_response, HTTPError):
202 if isinstance(raw_response, HTTPError):
203 self._error = str(raw_response)
203 self._error = str(raw_response)
204 except JSONRPCError as e:
204 except JSONRPCError, e:
205 self._error = str(e)
205 self._error = str(e)
206 except Exception as e:
206 except Exception, e:
207 log.error('Encountered unhandled exception: %s' % traceback.format_exc())
207 log.error('Encountered unhandled exception: %s' \
208 % traceback.format_exc())
208 json_exc = JSONRPCError('Internal server error')
209 json_exc = JSONRPCError('Internal server error')
209 self._error = str(json_exc)
210 self._error = str(json_exc)
210
211
@@ -30,7 +30,7 b' import binascii'
30
30
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
32 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.odict import OrderedDict
33 from rhodecode.lib.compat import OrderedDict
34 from rhodecode.lib import safe_unicode
34 from rhodecode.lib import safe_unicode
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
@@ -25,18 +25,13 b''
25
25
26 import logging
26 import logging
27
27
28 try:
29 import json
30 except ImportError:
31 #python 2.5 compatibility
32 import simplejson as json
33
34 from mercurial import graphmod
28 from mercurial import graphmod
35 from pylons import request, session, tmpl_context as c
29 from pylons import request, session, tmpl_context as c
36
30
37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.lib.base import BaseRepoController, render
39 from rhodecode.lib.helpers import RepoPage
33 from rhodecode.lib.helpers import RepoPage
34 from rhodecode.lib.compat import json
40
35
41 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
42
37
@@ -34,7 +34,7 b' import rhodecode.lib.helpers as h'
34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.base import BaseRepoController, render
36 from rhodecode.lib.utils import EmptyChangeset
36 from rhodecode.lib.utils import EmptyChangeset
37 from rhodecode.lib.odict import OrderedDict
37 from rhodecode.lib.compat import OrderedDict
38
38
39 from vcs.exceptions import RepositoryError, ChangesetError, \
39 from vcs.exceptions import RepositoryError, ChangesetError, \
40 ChangesetDoesNotExistError
40 ChangesetDoesNotExistError
@@ -316,6 +316,13 b' class FilesController(BaseRepoController'
316 filename = file_obj.filename
316 filename = file_obj.filename
317 content = file_obj.file
317 content = file_obj.file
318
318
319 #TODO: REMOVE THIS !!
320 ################################
321 import ipdb;ipdb.set_trace()
322 print 'setting ipdb debuggin for rhodecode.controllers.files.FilesController.add'
323 ################################
324
325
319 node_path = os.path.join(location, filename)
326 node_path = os.path.join(location, filename)
320 author = self.rhodecode_user.full_contact
327 author = self.rhodecode_user.full_contact
321
328
@@ -39,18 +39,12 b' from rhodecode.model.repo import RepoMod'
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
40 from rhodecode.lib.base import BaseRepoController, render
40 from rhodecode.lib.base import BaseRepoController, render
41 from rhodecode.lib.utils import EmptyChangeset
41 from rhodecode.lib.utils import EmptyChangeset
42 from rhodecode.lib.odict import OrderedDict
43
42
44 from rhodecode.lib.celerylib import run_task
43 from rhodecode.lib.celerylib import run_task
45 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
44 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
46 LANGUAGES_EXTENSIONS_MAP
45 LANGUAGES_EXTENSIONS_MAP
47 from rhodecode.lib.helpers import RepoPage
46 from rhodecode.lib.helpers import RepoPage
48
47 from rhodecode.lib.compat import json, OrderedDict
49 try:
50 import json
51 except ImportError:
52 #python 2.5 compatibility
53 import simplejson as json
54
48
55 log = logging.getLogger(__name__)
49 log = logging.getLogger(__name__)
56
50
@@ -28,7 +28,7 b' from pylons import tmpl_context as c'
28
28
29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
30 from rhodecode.lib.base import BaseRepoController, render
30 from rhodecode.lib.base import BaseRepoController, render
31 from rhodecode.lib.odict import OrderedDict
31 from rhodecode.lib.compat import OrderedDict
32
32
33 log = logging.getLogger(__name__)
33 log = logging.getLogger(__name__)
34
34
@@ -23,14 +23,6 b''
23 # You should have received a copy of the GNU General Public License
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/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26
27 try:
28 import json
29 except ImportError:
30 #python 2.5 compatibility
31 import simplejson as json
32
33
34 def __get_lem():
26 def __get_lem():
35 from pygments import lexers
27 from pygments import lexers
36 from string import lower
28 from string import lower
@@ -386,4 +378,4 b' def get_changeset_safe(repo, rev):'
386 except RepositoryError:
378 except RepositoryError:
387 from rhodecode.lib.utils import EmptyChangeset
379 from rhodecode.lib.utils import EmptyChangeset
388 cs = EmptyChangeset(requested_revision=rev)
380 cs = EmptyChangeset(requested_revision=rev)
389 return cs No newline at end of file
381 return cs
@@ -43,7 +43,8 b' from rhodecode.lib.celerylib import run_'
43 from rhodecode.lib.helpers import person
43 from rhodecode.lib.helpers import person
44 from rhodecode.lib.smtp_mailer import SmtpMailer
44 from rhodecode.lib.smtp_mailer import SmtpMailer
45 from rhodecode.lib.utils import add_cache
45 from rhodecode.lib.utils import add_cache
46 from rhodecode.lib.odict import OrderedDict
46 from rhodecode.lib.compat import json, OrderedDict
47
47 from rhodecode.model import init_model
48 from rhodecode.model import init_model
48 from rhodecode.model import meta
49 from rhodecode.model import meta
49 from rhodecode.model.db import RhodeCodeUi, Statistics, Repository
50 from rhodecode.model.db import RhodeCodeUi, Statistics, Repository
@@ -54,11 +55,7 b' from sqlalchemy import engine_from_confi'
54
55
55 add_cache(config)
56 add_cache(config)
56
57
57 try:
58
58 import json
59 except ImportError:
60 #python 2.5 compatibility
61 import simplejson as json
62
59
63 __all__ = ['whoosh_index', 'get_commits_stats',
60 __all__ = ['whoosh_index', 'get_commits_stats',
64 'reset_user_password', 'send_email']
61 'reset_user_password', 'send_email']
@@ -41,9 +41,10 b' from vcs.utils.helpers import get_scm'
41 from vcs.exceptions import VCSError
41 from vcs.exceptions import VCSError
42 from vcs.utils.lazy import LazyProperty
42 from vcs.utils.lazy import LazyProperty
43
43
44 from rhodecode.lib import str2bool, safe_str, get_changeset_safe,\
45 generate_api_key
44 from rhodecode.lib.exceptions import UsersGroupsAssignedException
46 from rhodecode.lib.exceptions import UsersGroupsAssignedException
45 from rhodecode.lib import str2bool, json, safe_str, get_changeset_safe, \
47 from rhodecode.lib.compat import json
46 generate_api_key
47
48
48 from rhodecode.model.meta import Base, Session
49 from rhodecode.model.meta import Base, Session
49 from rhodecode.model.caching_query import FromCache
50 from rhodecode.model.caching_query import FromCache
@@ -283,6 +283,19 b' def ValidRepoName(edit, old_data):'
283 def ValidForkName():
283 def ValidForkName():
284 class _ValidForkName(formencode.validators.FancyValidator):
284 class _ValidForkName(formencode.validators.FancyValidator):
285 def to_python(self, value, state):
285 def to_python(self, value, state):
286
287 repo_name = value.get('fork_name')
288
289 slug = repo_name_slug(repo_name)
290 if slug in ['_admin', '']:
291 e_dict = {'repo_name': _('This repository name is disallowed')}
292 raise formencode.Invalid('', value, state, error_dict=e_dict)
293
294 if RepoModel().get_by_repo_name(repo_name):
295 e_dict = {'fork_name':_('This repository '
296 'already exists')}
297 raise formencode.Invalid('', value, state,
298 error_dict=e_dict)
286 return value
299 return value
287 return _ValidForkName
300 return _ValidForkName
288
301
@@ -192,6 +192,9 b' class RepoModel(BaseModel):'
192 if k == 'repo_group':
192 if k == 'repo_group':
193 k = 'group_id'
193 k = 'group_id'
194
194
195 if k == 'description':
196 v = v or repo_name
197
195 setattr(new_repo, k, v)
198 setattr(new_repo, k, v)
196
199
197 if fork:
200 if fork:
@@ -28,6 +28,7 b' import traceback'
28
28
29 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
30
30
31 from rhodecode.lib import safe_unicode
31 from rhodecode.model import BaseModel
32 from rhodecode.model import BaseModel
32 from rhodecode.model.caching_query import FromCache
33 from rhodecode.model.caching_query import FromCache
33 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
34 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
@@ -111,7 +112,7 b' class UserModel(BaseModel):'
111 new_user.api_key = generate_api_key(username)
112 new_user.api_key = generate_api_key(username)
112 new_user.email = attrs['email']
113 new_user.email = attrs['email']
113 new_user.active = True
114 new_user.active = True
114 new_user.ldap_dn = user_dn
115 new_user.ldap_dn = safe_unicode(user_dn)
115 new_user.name = attrs['name']
116 new_user.name = attrs['name']
116 new_user.lastname = attrs['lastname']
117 new_user.lastname = attrs['lastname']
117
118
@@ -102,7 +102,7 b' def test_files_walk(limit=100):'
102
102
103 repo = vcs.get_repo(jn(PROJECT_PATH, PROJECT))
103 repo = vcs.get_repo(jn(PROJECT_PATH, PROJECT))
104
104
105 from rhodecode.lib.oset import OrderedSet
105 from rhodecode.lib.compat import OrderedSet
106
106
107 paths_ = OrderedSet([''])
107 paths_ = OrderedSet([''])
108 try:
108 try:
@@ -27,8 +27,8 b' requirements = ['
27 ]
27 ]
28
28
29 dependency_links = [
29 dependency_links = [
30 "https://secure.rhodecode.org/vcs/archive/default.zip#egg=vcs-0.2.1.dev",
30 "https://secure.rhodecode.org/vcs/archive/default.zip#egg=vcs-0.2.2.dev",
31 "https://bitbucket.org/marcinkuzminski/vcs/get/default.zip#egg=vcs-0.2.1.dev",
31 "https://bitbucket.org/marcinkuzminski/vcs/get/default.zip#egg=vcs-0.2.2.dev",
32 ]
32 ]
33
33
34 classifiers = ['Development Status :: 4 - Beta',
34 classifiers = ['Development Status :: 4 - Beta',
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now