##// END OF EJS Templates
Added os.sep in models for better win support...
marcink -
r1199:268fa0b6 beta
parent child Browse files
Show More
@@ -1,67 +1,70 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.lib.__init__
4 4 ~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Some simple helper functions
7 7
8 8 :created_on: Jan 5, 2011
9 9 :author: marcink
10 10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27
28 28 def str2bool(s):
29 29 if s is None:
30 30 return False
31 31 if s in (True, False):
32 32 return s
33 33 s = str(s).strip().lower()
34 34 return s in ('t', 'true', 'y', 'yes', 'on', '1')
35 35
36 36 def generate_api_key(username, salt=None):
37 37 """
38 38 Generates uniq API key for given username
39 39
40 40 :param username: username as string
41 41 :param salt: salt to hash generate KEY
42 42 """
43 43 from tempfile import _RandomNameSequence
44 44 import hashlib
45 45
46 46 if salt is None:
47 47 salt = _RandomNameSequence().next()
48 48
49 49 return hashlib.sha1(username + salt).hexdigest()
50 50
51 def safe_unicode(str):
51 def safe_unicode(_str):
52 52 """
53 53 safe unicode function. In case of UnicodeDecode error we try to return
54 54 unicode with errors replace, if this fails we return unicode with
55 55 string_escape decoding
56 56 """
57 57
58 if isinstance(_str, unicode):
59 return _str
60
58 61 try:
59 u_str = unicode(str)
62 u_str = unicode(_str)
60 63 except UnicodeDecodeError:
61 64 try:
62 u_str = unicode(str, 'utf-8', 'replace')
65 u_str = _str.decode('utf-8', 'replace')
63 66 except UnicodeDecodeError:
64 67 #incase we have a decode error just represent as byte string
65 u_str = unicode(str(str).encode('string_escape'))
68 u_str = unicode(_str.encode('string_escape'))
66 69
67 70 return u_str
@@ -1,388 +1,390 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.model.db
4 4 ~~~~~~~~~~~~~~~~~~
5 5
6 6 Database Models for RhodeCode
7 7
8 8 :created_on: Apr 08, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27
28 import os
27 29 import logging
28 30 import datetime
29 31 from datetime import date
30 32
31 33 from sqlalchemy import *
32 34 from sqlalchemy.exc import DatabaseError
33 35 from sqlalchemy.orm import relationship, backref
34 36 from sqlalchemy.orm.interfaces import MapperExtension
35 37
36 38 from rhodecode.model.meta import Base, Session
37 39
38 40 log = logging.getLogger(__name__)
39 41
40 42 #==============================================================================
41 43 # MAPPER EXTENSIONS
42 44 #==============================================================================
43 45
44 46 class RepositoryMapper(MapperExtension):
45 47 def after_update(self, mapper, connection, instance):
46 48 pass
47 49
48 50
49 51 class RhodeCodeSettings(Base):
50 52 __tablename__ = 'rhodecode_settings'
51 53 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
52 54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
53 55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
54 56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
55 57
56 58 def __init__(self, k='', v=''):
57 59 self.app_settings_name = k
58 60 self.app_settings_value = v
59 61
60 62 def __repr__(self):
61 63 return "<%s('%s:%s')>" % (self.__class__.__name__,
62 64 self.app_settings_name, self.app_settings_value)
63 65
64 66 class RhodeCodeUi(Base):
65 67 __tablename__ = 'rhodecode_ui'
66 68 __table_args__ = {'useexisting':True}
67 69 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
68 70 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
69 71 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
70 72 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 73 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
72 74
73 75
74 76 class User(Base):
75 77 __tablename__ = 'users'
76 78 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
77 79 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
78 80 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
79 81 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
80 82 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
81 83 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
82 84 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
83 85 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
84 86 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
85 87 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
86 88 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
87 89 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
88 90
89 91 user_log = relationship('UserLog', cascade='all')
90 92 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
91 93
92 94 repositories = relationship('Repository')
93 95 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
94 96
95 97 group_member = relationship('UsersGroupMember', cascade='all')
96 98
97 99 @property
98 100 def full_contact(self):
99 101 return '%s %s <%s>' % (self.name, self.lastname, self.email)
100 102
101 103 @property
102 104 def short_contact(self):
103 105 return '%s %s' % (self.name, self.lastname)
104 106
105 107
106 108 @property
107 109 def is_admin(self):
108 110 return self.admin
109 111
110 112 def __repr__(self):
111 113 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
112 114 self.user_id, self.username)
113 115
114 116 @classmethod
115 117 def by_username(cls, username):
116 118 return Session.query(cls).filter(cls.username == username).one()
117 119
118 120
119 121 def update_lastlogin(self):
120 122 """Update user lastlogin"""
121 123
122 124 try:
123 125 session = Session.object_session(self)
124 126 self.last_login = datetime.datetime.now()
125 127 session.add(self)
126 128 session.commit()
127 129 log.debug('updated user %s lastlogin', self.username)
128 130 except (DatabaseError,):
129 131 session.rollback()
130 132
131 133
132 134 class UserLog(Base):
133 135 __tablename__ = 'user_logs'
134 136 __table_args__ = {'useexisting':True}
135 137 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
136 138 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
137 139 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
138 140 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
139 141 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
140 142 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
141 143 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
142 144
143 145 @property
144 146 def action_as_day(self):
145 147 return date(*self.action_date.timetuple()[:3])
146 148
147 149 user = relationship('User')
148 150 repository = relationship('Repository')
149 151
150 152
151 153 class UsersGroup(Base):
152 154 __tablename__ = 'users_groups'
153 155 __table_args__ = {'useexisting':True}
154 156
155 157 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
156 158 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
157 159 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
158 160
159 161 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
160 162
161 163 class UsersGroupMember(Base):
162 164 __tablename__ = 'users_groups_members'
163 165 __table_args__ = {'useexisting':True}
164 166
165 167 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
166 168 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
167 169 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
168 170
169 171 user = relationship('User', lazy='joined')
170 172 users_group = relationship('UsersGroup')
171 173
172 174 def __init__(self, gr_id='', u_id=''):
173 175 self.users_group_id = gr_id
174 176 self.user_id = u_id
175 177
176 178 class Repository(Base):
177 179 __tablename__ = 'repositories'
178 180 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
179 181 __mapper_args__ = {'extension':RepositoryMapper()}
180 182
181 183 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
182 184 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
183 185 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
184 186 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
185 187 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
186 188 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
187 189 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
188 190 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
189 191 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
190 192 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
191 193 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
192 194
193 195
194 196 user = relationship('User')
195 197 fork = relationship('Repository', remote_side=repo_id)
196 198 group = relationship('Group')
197 199 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
198 200 users_group_to_perm = relationship('UsersGroupToPerm', cascade='all')
199 201 stats = relationship('Statistics', cascade='all', uselist=False)
200 202
201 203 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
202 204
203 205 logs = relationship('UserLog', cascade='all')
204 206
205 207 def __repr__(self):
206 208 return "<%s('%s:%s')>" % (self.__class__.__name__,
207 209 self.repo_id, self.repo_name)
208 210
209 211 @classmethod
210 212 def by_repo_name(cls, repo_name):
211 213 return Session.query(cls).filter(cls.repo_name == repo_name).one()
212 214
213 215 @property
214 216 def just_name(self):
215 return self.repo_name.split('/')[-1]
217 return self.repo_name.split(os.sep)[-1]
216 218
217 219 @property
218 220 def groups_with_parents(self):
219 221 groups = []
220 222 if self.group is None:
221 223 return groups
222 224
223 225 cur_gr = self.group
224 226 groups.insert(0, cur_gr)
225 227 while 1:
226 228 gr = getattr(cur_gr, 'parent_group', None)
227 229 cur_gr = cur_gr.parent_group
228 230 if gr is None:
229 231 break
230 232 groups.insert(0, gr)
231 233
232 234 return groups
233 235
234 236 @property
235 237 def groups_and_repo(self):
236 238 return self.groups_with_parents, self.just_name
237 239
238 240
239 241 class Group(Base):
240 242 __tablename__ = 'groups'
241 243 __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
242 244
243 245 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
244 246 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
245 247 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
246 248
247 249 parent_group = relationship('Group', remote_side=group_id)
248 250
249 251
250 252 def __init__(self, group_name='', parent_group=None):
251 253 self.group_name = group_name
252 254 self.parent_group = parent_group
253 255
254 256 def __repr__(self):
255 257 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
256 258 self.group_name)
257 259
258 260 @property
259 261 def parents(self):
260 262 groups = []
261 263 if self.parent_group is None:
262 264 return groups
263 265 cur_gr = self.parent_group
264 266 groups.insert(0, cur_gr)
265 267 while 1:
266 268 gr = getattr(cur_gr, 'parent_group', None)
267 269 cur_gr = cur_gr.parent_group
268 270 if gr is None:
269 271 break
270 272 groups.insert(0, gr)
271 273 return groups
272 274
273 275 @property
274 276 def repositories(self):
275 277 return Session.query(Repository).filter(Repository.group == self).all()
276 278
277 279 class Permission(Base):
278 280 __tablename__ = 'permissions'
279 281 __table_args__ = {'useexisting':True}
280 282 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
281 283 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
282 284 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
283 285
284 286 def __repr__(self):
285 287 return "<%s('%s:%s')>" % (self.__class__.__name__,
286 288 self.permission_id, self.permission_name)
287 289
288 290 class RepoToPerm(Base):
289 291 __tablename__ = 'repo_to_perm'
290 292 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
291 293 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
292 294 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
293 295 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
294 296 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
295 297
296 298 user = relationship('User')
297 299 permission = relationship('Permission')
298 300 repository = relationship('Repository')
299 301
300 302 class UserToPerm(Base):
301 303 __tablename__ = 'user_to_perm'
302 304 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
303 305 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
304 306 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
305 307 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
306 308
307 309 user = relationship('User')
308 310 permission = relationship('Permission')
309 311
310 312
311 313 class UsersGroupToPerm(Base):
312 314 __tablename__ = 'users_group_to_perm'
313 315 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
314 316 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
315 317 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
316 318 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
317 319 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
318 320
319 321 users_group = relationship('UsersGroup')
320 322 permission = relationship('Permission')
321 323 repository = relationship('Repository')
322 324
323 325 class GroupToPerm(Base):
324 326 __tablename__ = 'group_to_perm'
325 327 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
326 328
327 329 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
328 330 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
329 331 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
330 332 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
331 333
332 334 user = relationship('User')
333 335 permission = relationship('Permission')
334 336 group = relationship('Group')
335 337
336 338 class Statistics(Base):
337 339 __tablename__ = 'statistics'
338 340 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
339 341 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
340 342 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
341 343 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
342 344 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
343 345 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
344 346 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
345 347
346 348 repository = relationship('Repository', single_parent=True)
347 349
348 350 class UserFollowing(Base):
349 351 __tablename__ = 'user_followings'
350 352 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
351 353 UniqueConstraint('user_id', 'follows_user_id')
352 354 , {'useexisting':True})
353 355
354 356 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
355 357 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
356 358 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
357 359 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
358 360
359 361 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
360 362
361 363 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
362 364 follows_repository = relationship('Repository', order_by='Repository.repo_name')
363 365
364 366 class CacheInvalidation(Base):
365 367 __tablename__ = 'cache_invalidation'
366 368 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
367 369 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
368 370 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
369 371 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
370 372 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
371 373
372 374
373 375 def __init__(self, cache_key, cache_args=''):
374 376 self.cache_key = cache_key
375 377 self.cache_args = cache_args
376 378 self.cache_active = False
377 379
378 380 def __repr__(self):
379 381 return "<%s('%s:%s')>" % (self.__class__.__name__,
380 382 self.cache_id, self.cache_key)
381 383
382 384 class DbMigrateVersion(Base):
383 385 __tablename__ = 'db_migrate_version'
384 386 __table_args__ = {'useexisting':True}
385 387 repository_id = Column('repository_id', String(250), primary_key=True)
386 388 repository_path = Column('repository_path', Text)
387 389 version = Column('version', Integer)
388 390
General Comments 0
You need to be logged in to leave comments. Login now