##// 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 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 6 browser/management tool with a built in push/pull server and full text search.
7 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 11 RhodeCode is similar in some respects to github or bitbucket_,
11 12 however RhodeCode can be run as standalone hosted application on your own server.
@@ -3,7 +3,8 b''
3 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 10 :status: in-progress
@@ -12,6 +13,18 b' 1.2.0 (**2011-XX-XX**)'
12 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 28 - implemented #47 repository groups
16 29 - implemented #89 Can setup google analytics code from settings menu
17 30 - implemented #91 added nicer looking archive urls with more download options
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
1 NO CONTENT: modified file, binary diff hidden
@@ -25,9 +25,9 b''
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26 import platform
27 27
28 VERSION = (1, 2, 0, 'beta')
28 VERSION = (1, 3, 0, 'beta')
29 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 31 __platform__ = platform.system()
32 32 __license__ = 'GPLv3'
33 33
@@ -26,12 +26,12 b''
26 26 # MA 02110-1301, USA.
27 27
28 28 import inspect
29 import json
30 29 import logging
31 30 import types
32 31 import urllib
33 32 import traceback
34 from itertools import izip_longest
33
34 from rhodecode.lib.compat import izip_longest, json
35 35
36 36 from paste.response import replace_header
37 37
@@ -103,7 +103,7 b' class JSONRPCController(WSGIController):'
103 103
104 104 try:
105 105 json_body = json.loads(urllib.unquote_plus(raw_body))
106 except ValueError as e:
106 except ValueError, e:
107 107 #catch JSON errors Here
108 108 return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \
109 109 % (e, urllib.unquote_plus(raw_body)))
@@ -116,14 +116,14 b' class JSONRPCController(WSGIController):'
116 116 log.debug('method: %s, params: %s',
117 117 self._req_method,
118 118 self._req_params)
119 except KeyError as e:
119 except KeyError, e:
120 120 return jsonrpc_error(message='Incorrect JSON query missing %s' % e)
121 121
122 122 #check if we can find this session using api_key
123 123 try:
124 124 u = User.get_by_api_key(self._req_api_key)
125 125 auth_u = AuthUser(u.user_id, self._req_api_key)
126 except Exception as e:
126 except Exception, e:
127 127 return jsonrpc_error(message='Invalid API KEY')
128 128
129 129 self._error = None
@@ -138,8 +138,8 b' class JSONRPCController(WSGIController):'
138 138 arglist = argspec[0][1:]
139 139 defaults = argspec[3] or []
140 140 default_empty = types.NotImplementedType
141
142 kwarglist = list(izip_longest(reversed(arglist),reversed(defaults),
141
142 kwarglist = list(izip_longest(reversed(arglist), reversed(defaults),
143 143 fillvalue=default_empty))
144 144
145 145 # this is little trick to inject logged in user for
@@ -157,12 +157,12 b' class JSONRPCController(WSGIController):'
157 157 (self._func.__name__, USER_SESSION_ATTR))
158 158
159 159 # get our arglist and check if we provided them as args
160 for arg,default in kwarglist:
160 for arg, default in kwarglist:
161 161 if arg == USER_SESSION_ATTR:
162 162 # USER_SESSION_ATTR is something translated from api key and
163 163 # this is checked before so we don't need validate it
164 164 continue
165
165
166 166 # skip the required param check if it's default value is
167 167 # NotImplementedType (default_empty)
168 168 if not self._req_params or (type(default) == default_empty
@@ -201,10 +201,11 b' class JSONRPCController(WSGIController):'
201 201 raw_response = self._inspect_call(self._func)
202 202 if isinstance(raw_response, HTTPError):
203 203 self._error = str(raw_response)
204 except JSONRPCError as e:
204 except JSONRPCError, e:
205 205 self._error = str(e)
206 except Exception as e:
207 log.error('Encountered unhandled exception: %s' % traceback.format_exc())
206 except Exception, e:
207 log.error('Encountered unhandled exception: %s' \
208 % traceback.format_exc())
208 209 json_exc = JSONRPCError('Internal server error')
209 210 self._error = str(json_exc)
210 211
@@ -30,7 +30,7 b' import binascii'
30 30
31 31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
32 32 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.odict import OrderedDict
33 from rhodecode.lib.compat import OrderedDict
34 34 from rhodecode.lib import safe_unicode
35 35 log = logging.getLogger(__name__)
36 36
@@ -25,18 +25,13 b''
25 25
26 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 28 from mercurial import graphmod
35 29 from pylons import request, session, tmpl_context as c
36 30
37 31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 32 from rhodecode.lib.base import BaseRepoController, render
39 33 from rhodecode.lib.helpers import RepoPage
34 from rhodecode.lib.compat import json
40 35
41 36 log = logging.getLogger(__name__)
42 37
@@ -34,7 +34,7 b' import rhodecode.lib.helpers as h'
34 34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 35 from rhodecode.lib.base import BaseRepoController, render
36 36 from rhodecode.lib.utils import EmptyChangeset
37 from rhodecode.lib.odict import OrderedDict
37 from rhodecode.lib.compat import OrderedDict
38 38
39 39 from vcs.exceptions import RepositoryError, ChangesetError, \
40 40 ChangesetDoesNotExistError
@@ -316,6 +316,13 b' class FilesController(BaseRepoController'
316 316 filename = file_obj.filename
317 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 326 node_path = os.path.join(location, filename)
320 327 author = self.rhodecode_user.full_contact
321 328
@@ -39,19 +39,13 b' from rhodecode.model.repo import RepoMod'
39 39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
40 40 from rhodecode.lib.base import BaseRepoController, render
41 41 from rhodecode.lib.utils import EmptyChangeset
42 from rhodecode.lib.odict import OrderedDict
43 42
44 43 from rhodecode.lib.celerylib import run_task
45 44 from rhodecode.lib.celerylib.tasks import get_commits_stats, \
46 45 LANGUAGES_EXTENSIONS_MAP
47 46 from rhodecode.lib.helpers import RepoPage
47 from rhodecode.lib.compat import json, OrderedDict
48 48
49 try:
50 import json
51 except ImportError:
52 #python 2.5 compatibility
53 import simplejson as json
54
55 49 log = logging.getLogger(__name__)
56 50
57 51
@@ -139,7 +133,7 b' class SummaryController(BaseRepoControll'
139 133 lang_stats_d = json.loads(stats.languages)
140 134 c.commit_data = stats.commit_activity
141 135 c.overview_data = stats.commit_activity_combined
142
136
143 137 lang_stats = ((x, {"count": y,
144 138 "desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
145 139 for x, y in lang_stats_d.items())
@@ -162,7 +156,7 b' class SummaryController(BaseRepoControll'
162 156 c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
163 157 c.trending_languages = json.dumps({})
164 158 c.no_data = True
165
159
166 160 c.enable_downloads = dbrepo.enable_downloads
167 161 if c.enable_downloads:
168 162 c.download_options = self._get_download_links(c.rhodecode_repo)
@@ -28,7 +28,7 b' from pylons import tmpl_context as c'
28 28
29 29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
30 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 33 log = logging.getLogger(__name__)
34 34
@@ -23,14 +23,6 b''
23 23 # You should have received a copy of the GNU General Public License
24 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 26 def __get_lem():
35 27 from pygments import lexers
36 28 from string import lower
@@ -209,14 +201,14 b" def safe_str(unicode_, to_encoding='utf8"
209 201 return unicode_.encode(to_encoding)
210 202 except UnicodeEncodeError:
211 203 pass
212
204
213 205 try:
214 206 import chardet
215 207 encoding = chardet.detect(unicode_)['encoding']
216 208 print encoding
217 209 if encoding is None:
218 210 raise UnicodeEncodeError()
219
211
220 212 return unicode_.encode(encoding)
221 213 except (ImportError, UnicodeEncodeError):
222 214 return unicode_.encode(to_encoding, 'replace')
@@ -386,4 +378,4 b' def get_changeset_safe(repo, rev):'
386 378 except RepositoryError:
387 379 from rhodecode.lib.utils import EmptyChangeset
388 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 43 from rhodecode.lib.helpers import person
44 44 from rhodecode.lib.smtp_mailer import SmtpMailer
45 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 48 from rhodecode.model import init_model
48 49 from rhodecode.model import meta
49 50 from rhodecode.model.db import RhodeCodeUi, Statistics, Repository
@@ -54,11 +55,7 b' from sqlalchemy import engine_from_confi'
54 55
55 56 add_cache(config)
56 57
57 try:
58 import json
59 except ImportError:
60 #python 2.5 compatibility
61 import simplejson as json
58
62 59
63 60 __all__ = ['whoosh_index', 'get_commits_stats',
64 61 'reset_user_password', 'send_email']
@@ -41,9 +41,10 b' from vcs.utils.helpers import get_scm'
41 41 from vcs.exceptions import VCSError
42 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 46 from rhodecode.lib.exceptions import UsersGroupsAssignedException
45 from rhodecode.lib import str2bool, json, safe_str, get_changeset_safe, \
46 generate_api_key
47 from rhodecode.lib.compat import json
47 48
48 49 from rhodecode.model.meta import Base, Session
49 50 from rhodecode.model.caching_query import FromCache
@@ -283,6 +283,19 b' def ValidRepoName(edit, old_data):'
283 283 def ValidForkName():
284 284 class _ValidForkName(formencode.validators.FancyValidator):
285 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 299 return value
287 300 return _ValidForkName
288 301
@@ -192,6 +192,9 b' class RepoModel(BaseModel):'
192 192 if k == 'repo_group':
193 193 k = 'group_id'
194 194
195 if k == 'description':
196 v = v or repo_name
197
195 198 setattr(new_repo, k, v)
196 199
197 200 if fork:
@@ -302,7 +305,7 b' class RepoModel(BaseModel):'
302 305 :param clone_uri:
303 306 """
304 307 from rhodecode.lib.utils import is_valid_repo
305
308
306 309 if new_parent_id:
307 310 paths = Group.get(new_parent_id).full_path.split(Group.url_sep())
308 311 new_parent_path = os.sep.join(paths)
@@ -28,6 +28,7 b' import traceback'
28 28
29 29 from pylons.i18n.translation import _
30 30
31 from rhodecode.lib import safe_unicode
31 32 from rhodecode.model import BaseModel
32 33 from rhodecode.model.caching_query import FromCache
33 34 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \
@@ -111,7 +112,7 b' class UserModel(BaseModel):'
111 112 new_user.api_key = generate_api_key(username)
112 113 new_user.email = attrs['email']
113 114 new_user.active = True
114 new_user.ldap_dn = user_dn
115 new_user.ldap_dn = safe_unicode(user_dn)
115 116 new_user.name = attrs['name']
116 117 new_user.lastname = attrs['lastname']
117 118
@@ -102,7 +102,7 b' def test_files_walk(limit=100):'
102 102
103 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 107 paths_ = OrderedSet([''])
108 108 try:
@@ -23,12 +23,12 b' requirements = ['
23 23 "python-dateutil>=1.5.0,<2.0.0",
24 24 "dulwich>=0.8.0",
25 25 "vcs>=0.2.1.dev",
26 "webob==1.0.8"
26 "webob==1.0.8"
27 27 ]
28 28
29 29 dependency_links = [
30 "https://secure.rhodecode.org/vcs/archive/default.zip#egg=vcs-0.2.1.dev",
31 "https://bitbucket.org/marcinkuzminski/vcs/get/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.2.dev",
32 32 ]
33 33
34 34 classifiers = ['Development Status :: 4 - Beta',
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now