##// END OF EJS Templates
further cleanup of UsersGroup...
further cleanup of UsersGroup Renaming some names ... but trying not to change API or database scheme.

File last commit:

r3417:fa6ba672 beta
r3417:fa6ba672 beta
Show More
db.py
2042 lines | 75.5 KiB | text/x-python | PythonLexer
Models code cleanups
r759 # -*- coding: utf-8 -*-
"""
new improved models with helper functions for easier data fetching
r832 rhodecode.model.db
~~~~~~~~~~~~~~~~~~
source code cleanup: remove trailing white space, normalize file endings
r1203
added current db version into rhodecode,...
r834 Database Models for RhodeCode
source code cleanup: remove trailing white space, normalize file endings
r1203
Models code cleanups
r759 :created_on: Apr 08, 2010
:author: marcink
2012 copyrights
r1824 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
Models code cleanups
r759 :license: GPLv3, see COPYING for more details.
"""
fixed license issue #149
r1206 # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
Models code cleanups
r759 # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
Models code cleanups
r759 # You should have received a copy of the GNU General Public License
fixed license issue #149
r1206 # along with this program. If not, see <http://www.gnu.org/licenses/>.
Added os.sep in models for better win support...
r1199
import os
Models code cleanups
r759 import logging
import datetime
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 import traceback
typo fix + code garden
r2356 import hashlib
Implemented basic locking functionality....
r2726 import time
Added number of comments in changelog for each changeset...
r1884 from collections import defaultdict
Models code cleanups
r759
fixed imports
r658 from sqlalchemy import *
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546 from sqlalchemy.ext.hybrid import hybrid_property
fixes #288...
r1594 from sqlalchemy.orm import relationship, joinedload, class_mapper, validates
merge with beta
r2357 from sqlalchemy.exc import DatabaseError
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 from beaker.cache import cache_region, region_invalidate
use get_or_404 where possible
r2496 from webob.exc import HTTPNotFound
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
fixed translation function for models
r2218 from pylons.i18n.translation import lazy_ugettext as _
code-review initial
r2215
Added VCS into rhodecode core for faster and easier deployments of new versions
r2007 from rhodecode.lib.vcs import get_backend
from rhodecode.lib.vcs.utils.helpers import get_scm
from rhodecode.lib.vcs.exceptions import VCSError
from rhodecode.lib.vcs.utils.lazy import LazyProperty
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
utils/conf...
r2109 from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \
Implemented #379 defaults settings page for creation of repositories...
r3056 safe_unicode, remove_suffix, remove_prefix
fixed issues with python2.5...
r1514 from rhodecode.lib.compat import json
moved caching query to libs
r1669 from rhodecode.lib.caching_query import FromCache
Extended API...
r1500
typo fix + code garden
r2356 from rhodecode.model.meta import Base, Session
Extended API...
r1500
Added optional repo_name into issue tracker url to get just the name of repo without group prefix
r2339 URL_SEP = '/'
Nicolas VINOT
Correct code style
r1593 log = logging.getLogger(__name__)
renamed project to rhodecode
r547
fixed Session problems in model class functions...
r1081 #==============================================================================
Added basic JsonSerialization into models....
r1388 # BASE CLASSES
fixed Session problems in model class functions...
r1081 #==============================================================================
fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
r2062 _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest()
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class BaseModel(object):
fixed repo_create permission by adding missing commit statements...
r1758 """
Base Model for all classess
Added basic JsonSerialization into models....
r1388 """
@classmethod
Nicolas VINOT
Correct code style
r1593 def _get_keys(cls):
Added basic JsonSerialization into models....
r1388 """return column names for this model """
Nicolas VINOT
Correct code style
r1593 return class_mapper(cls).c.keys()
Added basic JsonSerialization into models....
r1388
get_dict function garden
r1948 def get_dict(self):
fixed repo_create permission by adding missing commit statements...
r1758 """
return dict with keys and values corresponding
get_dict function garden
r1948 to this model data """
Added basic JsonSerialization into models....
r1388
d = {}
for k in self._get_keys():
Nicolas VINOT
Correct code style
r1593 d[k] = getattr(self, k)
pep8ify
r1800
fixed repo_create permission by adding missing commit statements...
r1758 # also use __json__() if present to get additional fields
added status column to pull request + some small refactoring of models
r2588 _json_attr = getattr(self, '__json__', None)
if _json_attr:
# update with attributes from __json__
if callable(_json_attr):
_json_attr = _json_attr()
for k, val in _json_attr.iteritems():
d[k] = val
Added basic JsonSerialization into models....
r1388 return d
Nicolas VINOT
Correct code style
r1593 def get_appstruct(self):
Added basic JsonSerialization into models....
r1388 """return list with keys and values tupples corresponding
to this model data """
l = []
for k in self._get_keys():
Nicolas VINOT
Correct code style
r1593 l.append((k, getattr(self, k),))
Added basic JsonSerialization into models....
r1388 return l
Nicolas VINOT
Correct code style
r1593 def populate_obj(self, populate_dict):
Added basic JsonSerialization into models....
r1388 """populate model with data from given populate_dict"""
for k in self._get_keys():
if k in populate_dict:
Nicolas VINOT
Correct code style
r1593 setattr(self, k, populate_dict[k])
Added basic JsonSerialization into models....
r1388
@classmethod
Nicolas VINOT
Correct code style
r1593 def query(cls):
Fixed calls to Session in db model...
r2520 return Session().query(cls)
Added basic JsonSerialization into models....
r1388
@classmethod
Nicolas VINOT
Correct code style
r1593 def get(cls, id_):
fixes #288...
r1594 if id_:
return cls.query().get(id_)
Code cleanup...
r1466
Added more advanced hook management into rhodecode admin settings
r1460 @classmethod
use get_or_404 where possible
r2496 def get_or_404(cls, id_):
get_or_404 method does validation for ID beeing an INT
r2942 try:
id_ = int(id_)
except (TypeError, ValueError):
raise HTTPNotFound
res = cls.query().get(id_)
if not res:
raise HTTPNotFound
return res
use get_or_404 where possible
r2496
@classmethod
Nicolas VINOT
Correct code style
r1593 def getAll(cls):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 return cls.query().all()
Code cleanup...
r1466
Added more advanced hook management into rhodecode admin settings
r1460 @classmethod
Nicolas VINOT
Correct code style
r1593 def delete(cls, id_):
obj = cls.query().get(id_)
Fixed calls to Session in db model...
r2520 Session().delete(obj)
added hidden fulldiff GET param for disabling big diff cut off limit....
r2161
Use __unicode__ instead of __repr__ in models.
r2156 def __repr__(self):
if hasattr(self, '__unicode__'):
# python repr needs to return str
return safe_str(self.__unicode__())
return '<DB:%s>' % (self.__class__.__name__)
fixed Session problems in model class functions...
r1081
typo fix + code garden
r2356
refactoring of models names for repoGroup permissions
r1633 class RhodeCodeSetting(Base, BaseModel):
renamed hg_app to rhodecode
r548 __tablename__ = 'rhodecode_settings'
renamed repo groups table...
r1958 __table_args__ = (
UniqueConstraint('app_settings_name'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
fixes #288...
r1594 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 app_settings_name = Column("app_settings_name", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
_app_settings_value = Column("app_settings_value", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
renamed project to rhodecode
r547
fixes #288...
r1594 def __init__(self, k='', v=''):
Added settings model, and Exceptions lib....
r704 self.app_settings_name = k
self.app_settings_value = v
Nicolas VINOT
Correct code style
r1593 @validates('_app_settings_value')
def validate_settings_value(self, key, val):
assert type(val) == unicode
added validation of params on settings table
r1561 return val
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546 @hybrid_property
Nicolas VINOT
Correct code style
r1593 def app_settings_value(self):
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546 v = self._app_settings_value
Implemented #379 defaults settings page for creation of repositories...
r3056 if self.app_settings_name in ["ldap_active",
"default_repo_enable_statistics",
"default_repo_enable_locking",
"default_repo_private",
"default_repo_enable_downloads"]:
Nicolas VINOT
Correct code style
r1593 v = str2bool(v)
Nicolas VINOT
Merge with upstream
r1591 return v
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546
@app_settings_value.setter
Nicolas VINOT
Correct code style
r1593 def app_settings_value(self, val):
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546 """
Setter that will always make sure we use unicode in app_settings_value
Nicolas VINOT
Merge with upstream
r1591
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546 :param val:
"""
Nicolas VINOT
Correct code style
r1593 self._app_settings_value = safe_unicode(val)
fixes #265 ldap save fails sometimes on converting attributes to booleans, added getter and setter...
r1546
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u"<%s('%s:%s')>" % (
renamed repo groups table...
r1958 self.__class__.__name__,
self.app_settings_name, self.app_settings_value
)
Added settings model, and Exceptions lib....
r704
Fixed #161 form saves the create repository permission....
r1266 @classmethod
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 def get_by_name(cls, key):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 return cls.query()\
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 .filter(cls.app_settings_name == key).scalar()
@classmethod
def get_by_name_or_create(cls, key):
res = cls.get_by_name(key)
if not res:
res = cls(key)
return res
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292
@classmethod
fixes #288...
r1594 def get_app_settings(cls, cache=False):
Fixed #161 form saves the create repository permission....
r1266
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 ret = cls.query()
Fixed #161 form saves the create repository permission....
r1266
if cache:
Nicolas VINOT
Correct code style
r1593 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
Fixed #161 form saves the create repository permission....
r1266
if not ret:
Nicolas VINOT
Correct code style
r1593 raise Exception('Could not get application settings !')
Fixed #161 form saves the create repository permission....
r1266 settings = {}
for each in ret:
settings['rhodecode_' + each.app_settings_name] = \
each.app_settings_value
return settings
@classmethod
fixes #288...
r1594 def get_ldap_settings(cls, cache=False):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 ret = cls.query()\
Nicolas VINOT
Correct code style
r1593 .filter(cls.app_settings_name.startswith('ldap_')).all()
Fixed #161 form saves the create repository permission....
r1266 fd = {}
for row in ret:
typo fix + code garden
r2356 fd.update({row.app_settings_name: row.app_settings_value})
fixes #204, ldap active checkbox, credits goes to Matt Little.
r1381
Fixed #161 form saves the create repository permission....
r1266 return fd
Implemented #379 defaults settings page for creation of repositories...
r3056 @classmethod
def get_default_repo_settings(cls, cache=False, strip_prefix=False):
ret = cls.query()\
.filter(cls.app_settings_name.startswith('default_')).all()
fd = {}
for row in ret:
key = row.app_settings_name
if strip_prefix:
key = remove_prefix(key, prefix='default_')
fd.update({key: row.app_settings_value})
return fd
Fixed #161 form saves the create repository permission....
r1266
Nicolas VINOT
Correct code style
r1593 class RhodeCodeUi(Base, BaseModel):
renamed hg_app to rhodecode
r548 __tablename__ = 'rhodecode_ui'
renamed repo groups table...
r1958 __table_args__ = (
white space cleanup
r1963 UniqueConstraint('ui_key'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
Added more advanced hook management into rhodecode admin settings
r1460
HOOK_UPDATE = 'changegroup.update'
HOOK_REPO_SIZE = 'changegroup.repo_size'
Change git & hg hooks to post. They shouldn't block as they are used just for logging actions. Futhermore post hooks have access to changesets, so it's much better flexible
r2407 HOOK_PUSH = 'changegroup.push_logger'
Implemented basic locking functionality....
r2726 HOOK_PRE_PUSH = 'prechangegroup.pre_push'
HOOK_PULL = 'outgoing.pull_logger'
HOOK_PRE_PULL = 'preoutgoing.pre_pull'
Added more advanced hook management into rhodecode admin settings
r1460
fixes #288...
r1594 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 ui_section = Column("ui_section", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
ui_key = Column("ui_key", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
ui_value = Column("ui_value", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
fixes #288...
r1594 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
Hacking for git support,and new faster repo scan
r631
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345 @classmethod
Nicolas VINOT
Correct code style
r1593 def get_by_key(cls, key):
Added form for controlling mercurial extensions...
r2708 return cls.query().filter(cls.ui_key == key).scalar()
#47 implemented Adding of new repo_groups+forms+validators. Fixed sorting of repo groups by main names in multiple locations. Removed some unneeded calls to self.sa for exchange to .query() methods....
r1345
Added more advanced hook management into rhodecode admin settings
r1460 @classmethod
Nicolas VINOT
Correct code style
r1593 def get_builtin_hooks(cls):
Added more advanced hook management into rhodecode admin settings
r1460 q = cls.query()
Implemented basic locking functionality....
r2726 q = q.filter(cls.ui_key.in_([cls.HOOK_UPDATE, cls.HOOK_REPO_SIZE,
cls.HOOK_PUSH, cls.HOOK_PRE_PUSH,
cls.HOOK_PULL, cls.HOOK_PRE_PULL]))
Added more advanced hook management into rhodecode admin settings
r1460 return q.all()
@classmethod
Nicolas VINOT
Correct code style
r1593 def get_custom_hooks(cls):
Added more advanced hook management into rhodecode admin settings
r1460 q = cls.query()
Implemented basic locking functionality....
r2726 q = q.filter(~cls.ui_key.in_([cls.HOOK_UPDATE, cls.HOOK_REPO_SIZE,
cls.HOOK_PUSH, cls.HOOK_PRE_PUSH,
cls.HOOK_PULL, cls.HOOK_PRE_PULL]))
Nicolas VINOT
Correct code style
r1593 q = q.filter(cls.ui_section == 'hooks')
Added more advanced hook management into rhodecode admin settings
r1460 return q.all()
@classmethod
Removed hardcoded hooks names from settings....
r2401 def get_repos_location(cls):
Added form for controlling mercurial extensions...
r2708 return cls.get_by_key('/').ui_value
Removed hardcoded hooks names from settings....
r2401
@classmethod
Nicolas VINOT
Correct code style
r1593 def create_or_update_hook(cls, key, val):
Added form for controlling mercurial extensions...
r2708 new_ui = cls.get_by_key(key) or cls()
Added more advanced hook management into rhodecode admin settings
r1460 new_ui.ui_section = 'hooks'
new_ui.ui_active = True
new_ui.ui_key = key
new_ui.ui_value = val
Fixed calls to Session in db model...
r2520 Session().add(new_ui)
Added more advanced hook management into rhodecode admin settings
r1460
fixed issue #560 require push ssl checkbox wasn't shown when option was enabled
r2821 def __repr__(self):
return '<DB:%s[%s:%s]>' % (self.__class__.__name__, self.ui_key,
self.ui_value)
Added more advanced hook management into rhodecode admin settings
r1460
Nicolas VINOT
Correct code style
r1593 class User(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'users'
renamed repo groups table...
r1958 __table_args__ = (
white space cleanup
r1963 UniqueConstraint('username'), UniqueConstraint('email'),
Implemented basic locking functionality....
r2726 Index('u_username_idx', 'username'),
Index('u_email_idx', 'email'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
Implemented basic locking functionality....
r2726 DEFAULT_USER = 'default'
auto-healing of permissions for default user after upgrading from some old versions.
r2798 DEFAULT_PERMISSIONS = [
'hg.register.manual_activate', 'hg.create.repository',
implemented #663 Admin/permission: specify default repogroup perms...
r3052 'hg.fork.repository', 'repository.read', 'group.read'
auto-healing of permissions for default user after upgrading from some old versions.
r2798 ]
fixes #288...
r1594 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 username = Column("username", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
password = Column("password", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
User active flag should be default to True
r2480 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
fixes #288...
r1594 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
added status column to pull request + some small refactoring of models
r2588 name = Column("firstname", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
lastname = Column("lastname", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
_email = Column("email", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
fixes #288...
r1594 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
added status column to pull request + some small refactoring of models
r2588 ldap_dn = Column("ldap_dn", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
api_key = Column("api_key", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
RhodeCode now has a option to explicitly set forking permissions. ref #508...
r2709 inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
Hacking for git support,and new faster repo scan
r631
remove not null from user_id column for users log archiving
r3065 user_log = relationship('UserLog')
fixes #288...
r1594 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
Hacking for git support,and new faster repo scan
r631
Nicolas VINOT
Correct code style
r1593 repositories = relationship('Repository')
fixes #288...
r1594 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
fixed issue with cascade deleting of following entries
r3067 followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all')
refactoring of models names for repoGroup permissions
r1633 repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all')
Mysql fixes...
r2149 repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all')
White space cleanup
r2150
Mads Kiilerich
further cleanup of UsersGroup...
r3417 group_member = relationship('UserGroupMember', cascade='all')
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065
Cascade delete comments and notifications when removing user.
r2157 notifications = relationship('UserNotification', cascade='all')
# notifications assigned to this user
user_created_notifications = relationship('Notification', cascade='all')
# comments created by this user
user_comments = relationship('ChangesetComment', cascade='all')
cascade delete extra emails on user delete
r2562 #extra emails for this user
user_emails = relationship('UserEmailMap', cascade='all')
#302 - basic notification system, models+tests
r1702
fixes #298, ldap email addresses created by rhodecode automatically during first login didn't get converted to lower case, which lead to lookup failures and than wrong checks for uniqueness. Fixed that by putting a setter on db model column that will enforce converting to lowercase.
r1757 @hybrid_property
def email(self):
return self._email
@email.setter
def email(self, val):
self._email = val.lower() if val else None
Models code cleanups
r759 @property
Implemented #532....
r2731 def firstname(self):
# alias for future
return self.name
@property
Add list of all emails that user may have into get_user call
r2506 def emails(self):
other = UserEmailMap.query().filter(UserEmailMap.user==self).all()
return [self.email] + [x.email for x in other]
@property
add ipaddresses to repo data on API calls
r3127 def ip_addresses(self):
ret = UserIpMap.query().filter(UserIpMap.user == self).all()
return [x.ip_addr for x in ret]
@property
Implemented #532....
r2731 def username_and_name(self):
return '%s (%s %s)' % (self.username, self.firstname, self.lastname)
@property
implements #222 registration feedback...
r1731 def full_name(self):
Implemented #532....
r2731 return '%s %s' % (self.firstname, self.lastname)
implements #222 registration feedback...
r1731
@property
#344 optional firstname lastname on user creation...
r1950 def full_name_or_username(self):
Implemented #532....
r2731 return ('%s %s' % (self.firstname, self.lastname)
if (self.firstname and self.lastname) else self.username)
#344 optional firstname lastname on user creation...
r1950
@property
Nicolas VINOT
Correct code style
r1593 def full_contact(self):
Implemented #532....
r2731 return '%s %s <%s>' % (self.firstname, self.lastname, self.email)
Hacking for git support,and new faster repo scan
r631
Added some more details into user edit permissions view
r895 @property
Nicolas VINOT
Correct code style
r1593 def short_contact(self):
Implemented #532....
r2731 return '%s %s' % (self.firstname, self.lastname)
made simple global rss and atom feed
r1088
@property
Nicolas VINOT
Correct code style
r1593 def is_admin(self):
Added some more details into user edit permissions view
r895 return self.admin
fixes #762, LDAP and container created users are now activated based on...
r3370 @property
def AuthUser(self):
"""
Returns instance of AuthUser for this user
"""
from rhodecode.lib.auth import AuthUser
return AuthUser(user_id=self.user_id, api_key=self.api_key,
username=self.username)
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u"<%s('id:%s:%s')>" % (self.__class__.__name__,
Notification system improvements...
r1712 self.user_id, self.username)
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065 @classmethod
Added cache options to some db getters
r1665 def get_by_username(cls, username, case_insensitive=False, cache=False):
Simplified last_login call on user, and changed login to use User model directly
r1400 if case_insensitive:
Added cache options to some db getters
r1665 q = cls.query().filter(cls.username.ilike(username))
Simplified last_login call on user, and changed login to use User model directly
r1400 else:
Added cache options to some db getters
r1665 q = cls.query().filter(cls.username == username)
if cache:
fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
r2062 q = q.options(FromCache(
"sql_cache_short",
"get_user_%s" % _hash_key(username)
)
)
Added cache options to some db getters
r1665 return q.scalar()
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065
fixes #223 improve password reset form
r1417 @classmethod
Added cache options to some db getters
r1665 def get_by_api_key(cls, api_key, cache=False):
q = cls.query().filter(cls.api_key == api_key)
if cache:
q = q.options(FromCache("sql_cache_short",
"get_api_key_%s" % api_key))
fix for api key lookup, reuse same function in user model
r1693 return q.scalar()
fixes #223 improve password reset form
r1417
notification to commit author + gardening
r1716 @classmethod
fixes #298, ldap email addresses created by rhodecode automatically during first login didn't get converted to lower case, which lead to lookup failures and than wrong checks for uniqueness. Fixed that by putting a setter on db model column that will enforce converting to lowercase.
r1757 def get_by_email(cls, email, case_insensitive=False, cache=False):
if case_insensitive:
q = cls.query().filter(cls.email.ilike(email))
else:
q = cls.query().filter(cls.email == email)
notification to commit author + gardening
r1716
if cache:
q = q.options(FromCache("sql_cache_short",
Added email-map for alternative email addresses for users
r2329 "get_email_key_%s" % email))
ret = q.scalar()
if ret is None:
q = UserEmailMap.query()
# try fetching in alternate email map
if case_insensitive:
q = q.filter(UserEmailMap.email.ilike(email))
else:
q = q.filter(UserEmailMap.email == email)
q = q.options(joinedload(UserEmailMap.user))
if cache:
q = q.options(FromCache("sql_cache_short",
"get_email_map_key_%s" % email))
ret = getattr(q.scalar(), 'user', None)
return ret
notification to commit author + gardening
r1716
improved extraction of user from changeset when sending notification....
r3185 @classmethod
def get_from_cs_author(cls, author):
"""
Tries to get User objects out of commit author string
:param author:
"""
from rhodecode.lib.helpers import email, author_name
# Valid email in the attribute passed, see if they're in the system
_email = email(author)
if _email:
user = cls.get_by_email(_email, case_insensitive=True)
if user:
return user
# Maybe we can match by username?
_author = author_name(author)
user = cls.get_by_username(_author, case_insensitive=True)
if user:
return user
Nicolas VINOT
Correct code style
r1593 def update_lastlogin(self):
renamed project to rhodecode
r547 """Update user lastlogin"""
Simplified last_login call on user, and changed login to use User model directly
r1400 self.last_login = datetime.datetime.now()
Fixed calls to Session in db model...
r2520 Session().add(self)
garden...
r1976 log.debug('updated user %s lastlogin' % self.username)
Hacking for git support,and new faster repo scan
r631
Added functions for getting API data to repo and user models
r2508 def get_api_data(self):
"""
Common function for generating user related data for API
"""
user = self
data = dict(
Change return paremeters for get_api_data in user and repo
r2510 user_id=user.user_id,
Added functions for getting API data to repo and user models
r2508 username=user.username,
firstname=user.name,
lastname=user.lastname,
email=user.email,
emails=user.emails,
Change return paremeters for get_api_data in user and repo
r2510 api_key=user.api_key,
Added functions for getting API data to repo and user models
r2508 active=user.active,
admin=user.admin,
ldap_dn=user.ldap_dn,
last_login=user.last_login,
add ipaddresses to repo data on API calls
r3127 ip_addresses=user.ip_addresses
Added functions for getting API data to repo and user models
r2508 )
return data
fixed repo_create permission by adding missing commit statements...
r1758 def __json__(self):
Renamed name to firstname in forms...
r2544 data = dict(
#344 optional firstname lastname on user creation...
r1950 full_name=self.full_name,
full_name_or_username=self.full_name_or_username,
short_contact=self.short_contact,
full_contact=self.full_contact
)
Renamed name to firstname in forms...
r2544 data.update(self.get_api_data())
return data
fixed repo_create permission by adding missing commit statements...
r1758
Added email-map for alternative email addresses for users
r2329 class UserEmailMap(Base, BaseModel):
__tablename__ = 'user_email_map'
__table_args__ = (
Added some DB indexes to optimize queries
r2463 Index('uem_email_idx', 'email'),
Added email-map for alternative email addresses for users
r2329 UniqueConstraint('email'),
Added some DB indexes to optimize queries
r2463 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Added email-map for alternative email addresses for users
r2329 'mysql_charset': 'utf8'}
)
__mapper_args__ = {}
email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
added status column to pull request + some small refactoring of models
r2588 _email = Column("email", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
Added some DB indexes to optimize queries
r2463 user = relationship('User', lazy='joined')
Added email-map for alternative email addresses for users
r2329
@validates('_email')
def validate_email(self, key, email):
# check if this email is not main one
Fixed calls to Session in db model...
r2520 main_email = Session().query(User).filter(User.email == email).scalar()
Added email-map for alternative email addresses for users
r2329 if main_email is not None:
raise AttributeError('email %s is present is user table' % email)
return email
@hybrid_property
def email(self):
return self._email
@email.setter
def email(self, val):
self._email = val.lower() if val else None
Added UserIpMap interface for allowed IP addresses and IP restriction access...
r3125 class UserIpMap(Base, BaseModel):
__tablename__ = 'user_ip_map'
__table_args__ = (
UniqueConstraint('user_id', 'ip_addr'),
{'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'}
)
__mapper_args__ = {}
ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
ip_addr = Column("ip_addr", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
Full IP restrictions enabled...
r3146 active = Column("active", Boolean(), nullable=True, unique=None, default=True)
Added UserIpMap interface for allowed IP addresses and IP restriction access...
r3125 user = relationship('User', lazy='joined')
@classmethod
def _get_ip_range(cls, ip_addr):
from rhodecode.lib import ipaddr
IP restrictions now also enabled for IPv6
r3212 net = ipaddr.IPNetwork(address=ip_addr)
Added UserIpMap interface for allowed IP addresses and IP restriction access...
r3125 return [str(net.network), str(net.broadcast)]
def __json__(self):
return dict(
ip_addr=self.ip_addr,
ip_range=self._get_ip_range(self.ip_addr)
)
Nicolas VINOT
Correct code style
r1593 class UserLog(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'user_logs'
Mysql fixes...
r2149 __table_args__ = (
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
fixes #288...
r1594 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
remove not null from user_id column for users log archiving
r3065 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
Implemented better support for Wildcard queries...
r3063 username = Column("username", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
implements #193 journal stores information about deleting of repos...
r1747 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True)
added status column to pull request + some small refactoring of models
r2588 repository_name = Column("repository_name", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
user_ip = Column("user_ip", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
action = Column("action", UnicodeText(1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
fixes #288...
r1594 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
Hacking for git support,and new faster repo scan
r631
Added grouping by days in journal
r994 @property
Nicolas VINOT
Correct code style
r1593 def action_as_day(self):
- refactoring to overcome poor usage of global pylons config...
r1723 return datetime.date(*self.action_date.timetuple()[:3])
Added grouping by days in journal
r994
Nicolas VINOT
Correct code style
r1593 user = relationship('User')
fixed #373 missing cascade drop on user_group_to_perm table
r2063 repository = relationship('Repository', cascade='')
Hacking for git support,and new faster repo scan
r631
started working on issue #56
r956
Mads Kiilerich
further cleanup of UsersGroup...
r3417 class UserGroup(Base, BaseModel):
started working on issue #56
r956 __tablename__ = 'users_groups'
Mysql fixes...
r2149 __table_args__ = (
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
started working on issue #56
r956
fixes #288...
r1594 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 users_group_name = Column("users_group_name", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
fixes #288...
r1594 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
RhodeCode now has a option to explicitly set forking permissions. ref #508...
r2709 inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True)
started working on issue #56
r956
Mads Kiilerich
further cleanup of UsersGroup...
r3417 members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
users_group_to_perm = relationship('UserGroupToPerm', cascade='all')
users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
started working on issue #56
r956
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u'<userGroup(%s)>' % (self.users_group_name)
Fixed permissions for users groups, group can have create repo permission now....
r1271
@classmethod
- fixes celery sqlalchemy session issues for async forking...
r1728 def get_by_group_name(cls, group_name, cache=False,
case_insensitive=False):
Fixed permissions for users groups, group can have create repo permission now....
r1271 if case_insensitive:
- fixes celery sqlalchemy session issues for async forking...
r1728 q = cls.query().filter(cls.users_group_name.ilike(group_name))
Fixed permissions for users groups, group can have create repo permission now....
r1271 else:
- fixes celery sqlalchemy session issues for async forking...
r1728 q = cls.query().filter(cls.users_group_name == group_name)
Fixed permissions for users groups, group can have create repo permission now....
r1271 if cache:
fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
r2062 q = q.options(FromCache(
"sql_cache_short",
"get_user_%s" % _hash_key(group_name)
)
)
- fixes celery sqlalchemy session issues for async forking...
r1728 return q.scalar()
Fixed permissions for users groups, group can have create repo permission now....
r1271
removed users_group controller in replace for model methods,...
r1436 @classmethod
fixes #288...
r1594 def get(cls, users_group_id, cache=False):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 users_group = cls.query()
removed users_group controller in replace for model methods,...
r1436 if cache:
Nicolas VINOT
Correct code style
r1593 users_group = users_group.options(FromCache("sql_cache_short",
"get_users_group_%s" % users_group_id))
return users_group.get(users_group_id)
removed users_group controller in replace for model methods,...
r1436
added get_api_data into UsersGroup
r2523 def get_api_data(self):
users_group = self
data = dict(
return proper id from users_group...
r2531 users_group_id=users_group.users_group_id,
added get_api_data into UsersGroup
r2523 group_name=users_group.users_group_name,
active=users_group.users_group_active,
)
return data
pep8ify
r1800
Mads Kiilerich
further cleanup of UsersGroup...
r3417 class UserGroupMember(Base, BaseModel):
started working on issue #56
r956 __tablename__ = 'users_groups_members'
Mysql fixes...
r2149 __table_args__ = (
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
started working on issue #56
r956
fixes #288...
r1594 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
started working on issue #56
r956
fixes #288...
r1594 user = relationship('User', lazy='joined')
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group = relationship('UserGroup')
#56 implemented users groups editing,...
r972
fixes #288...
r1594 def __init__(self, gr_id='', u_id=''):
#56 implemented users groups editing,...
r972 self.users_group_id = gr_id
self.user_id = u_id
started working on issue #56
r956
fixed issue with hybrid property for ldap_active...
r2013
repository extra fields implementation...
r3308 class RepositoryField(Base, BaseModel):
__tablename__ = 'repositories_fields'
__table_args__ = (
UniqueConstraint('repository_id', 'field_key'), # no-multi field
{'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'},
)
PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields
repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
mysql indexed keys cannot be larger thatn 256 chars, but 250 is enough for this purpose
r3361 field_key = Column("field_key", String(250, convert_unicode=False, assert_unicode=None))
repository extra fields implementation...
r3308 field_label = Column("field_label", String(1024, convert_unicode=False, assert_unicode=None), nullable=False)
field_value = Column("field_value", String(10000, convert_unicode=False, assert_unicode=None), nullable=False)
field_desc = Column("field_desc", String(1024, convert_unicode=False, assert_unicode=None), nullable=False)
field_type = Column("field_type", String(256), nullable=False, unique=None)
created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
repository = relationship('Repository')
@property
def field_key_prefixed(self):
return 'ex_%s' % self.field_key
@classmethod
def un_prefix_key(cls, key):
if key.startswith(cls.PREFIX):
return key[len(cls.PREFIX):]
return key
@classmethod
def get_by_key_name(cls, key, repo):
row = cls.query()\
.filter(cls.repository == repo)\
.filter(cls.field_key == key).scalar()
return row
Nicolas VINOT
Correct code style
r1593 class Repository(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'repositories'
renamed repo groups table...
r1958 __table_args__ = (
white space cleanup
r1963 UniqueConstraint('repo_name'),
Implemented basic locking functionality....
r2726 Index('r_repo_name_idx', 'repo_name'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
renamed repo groups table...
r1958 )
fixed Session problems in model class functions...
r1081
fixes #288...
r1594 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 repo_name = Column("repo_name", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
clone_uri = Column("clone_uri", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
repo_type = Column("repo_type", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
fixes #288...
r1594 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
private = Column("private", Boolean(), nullable=True, unique=None, default=None)
enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
added status column to pull request + some small refactoring of models
r2588 description = Column("description", String(10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
fixes #288...
r1594 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
Remove null from revision column as for comments inside pull requests to work properly...
r2797 updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
added status column to pull request + some small refactoring of models
r2588 landing_rev = Column("landing_revision", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
Implemented basic locking functionality....
r2726 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
_locked = Column("locked", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
Added full last changeset info to lightweight dashboard
r3147 _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data
Added simple forks page, resolves issue #179
r1301
fixes #288...
r1594 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
Hacking for git support,and new faster repo scan
r631
Nicolas VINOT
Correct code style
r1593 user = relationship('User')
fixes #288...
r1594 fork = relationship('Repository', remote_side=repo_id)
refactoring of models names for repoGroup permissions
r1633 group = relationship('RepoGroup')
repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id')
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all')
fixes #288...
r1594 stats = relationship('Statistics', cascade='all', uselist=False)
fixes #51 deleting a repo didn't delete it's dependent db entries....
r667
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 followers = relationship('UserFollowing',
primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id',
cascade fixes for comments/pull-requests/reviewers...
r2666 cascade='all')
repository extra fields implementation...
r3308 extra_fields = relationship('RepositoryField',
cascade="all, delete, delete-orphan")
implemented user dashboards, and following system.
r734
implements #193 journal stores information about deleting of repos...
r1747 logs = relationship('UserLog')
cascade delete comments when deleting repo, else it's a error preventing deletion
r2665 comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan")
fixees for #106 relation issues on databases different than sqlite
r970
cascade fixes for comments/pull-requests/reviewers...
r2666 pull_requests_org = relationship('PullRequest',
primaryjoin='PullRequest.org_repo_id==Repository.repo_id',
cascade="all, delete, delete-orphan")
pull_requests_other = relationship('PullRequest',
primaryjoin='PullRequest.other_repo_id==Repository.repo_id',
cascade="all, delete, delete-orphan")
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
Initial version of landing revisions ref #483...
r2459 return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id,
Use __unicode__ instead of __repr__ in models.
r2156 self.repo_name)
Extended repo2db mapper with group creation via directory structures...
r878
Implemented basic locking functionality....
r2726 @hybrid_property
def locked(self):
# always should return [user_id, timelocked]
if self._locked:
_lock_info = self._locked.split(':')
return int(_lock_info[0]), _lock_info[1]
return [None, None]
@locked.setter
def locked(self, val):
if val and isinstance(val, (list, tuple)):
self._locked = ':'.join(map(str, val))
else:
self._locked = None
Added full last changeset info to lightweight dashboard
r3147 @hybrid_property
def changeset_cache(self):
from rhodecode.lib.vcs.backends.base import EmptyChangeset
dummy = EmptyChangeset().__json__()
if not self._changeset_cache:
return dummy
try:
return json.loads(self._changeset_cache)
except TypeError:
return dummy
@changeset_cache.setter
def changeset_cache(self, val):
try:
self._changeset_cache = json.dumps(val)
except:
log.error(traceback.format_exc())
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065 @classmethod
Nicolas VINOT
Correct code style
r1593 def url_sep(cls):
Added optional repo_name into issue tracker url to get just the name of repo without group prefix
r2339 return URL_SEP
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065
fixes #245 Rescan of the repositories on Windows
r1554 @classmethod
fixed issues with getting repos by path on windows
r3152 def normalize_repo_name(cls, repo_name):
"""
Normalizes os specific repo_name to the format internally stored inside
dabatabase using URL_SEP
:param cls:
:param repo_name:
"""
return cls.url_sep().join(repo_name.split(os.sep))
@classmethod
Nicolas VINOT
Correct code style
r1593 def get_by_repo_name(cls, repo_name):
Fixed calls to Session in db model...
r2520 q = Session().query(cls).filter(cls.repo_name == repo_name)
Nicolas VINOT
Correct code style
r1593 q = q.options(joinedload(Repository.fork))\
.options(joinedload(Repository.user))\
.options(joinedload(Repository.group))
commit less models...
r1749 return q.scalar()
Added simple forks page, resolves issue #179
r1301
@classmethod
Add method for fetching repos by full path
r2400 def get_by_full_path(cls, repo_full_path):
repo_name = repo_full_path.split(cls.base_path(), 1)[-1]
fixed issues with getting repos by path on windows
r3152 repo_name = cls.normalize_repo_name(repo_name)
Add method for fetching repos by full path
r2400 return cls.get_by_repo_name(repo_name.strip(URL_SEP))
@classmethod
Nicolas VINOT
Correct code style
r1593 def get_repo_forks(cls, repo_id):
return cls.query().filter(Repository.fork_id == repo_id)
Added simple forks page, resolves issue #179
r1301
API added checks for a valid repository on pull command...
r1508 @classmethod
Nicolas VINOT
Correct code style
r1593 def base_path(cls):
API added checks for a valid repository on pull command...
r1508 """
Returns base path when all repos are stored
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
API added checks for a valid repository on pull command...
r1508 :param cls:
"""
Fixed calls to Session in db model...
r2520 q = Session().query(RhodeCodeUi)\
- fixes celery sqlalchemy session issues for async forking...
r1728 .filter(RhodeCodeUi.ui_key == cls.url_sep())
q = q.options(FromCache("sql_cache_short", "repository_repo_path"))
API added checks for a valid repository on pull command...
r1508 return q.one().ui_value
added clone_uri,api_key into models. Fixed models for mysql compatibilty
r1113 @property
created pull-request overview
r2395 def forks(self):
"""
Return forks of this repo
"""
return Repository.get_repo_forks(self.repo_id)
@property
def parent(self):
"""
Returns fork parent
"""
return self.fork
@property
Nicolas VINOT
Correct code style
r1593 def just_name(self):
return self.repo_name.split(Repository.url_sep())[-1]
Added handy methods to Repository model for fetching groups with parents
r1155
@property
Nicolas VINOT
Correct code style
r1593 def groups_with_parents(self):
Added handy methods to Repository model for fetching groups with parents
r1155 groups = []
if self.group is None:
return groups
cur_gr = self.group
Nicolas VINOT
Correct code style
r1593 groups.insert(0, cur_gr)
Added handy methods to Repository model for fetching groups with parents
r1155 while 1:
Nicolas VINOT
Correct code style
r1593 gr = getattr(cur_gr, 'parent_group', None)
Added handy methods to Repository model for fetching groups with parents
r1155 cur_gr = cur_gr.parent_group
if gr is None:
break
Nicolas VINOT
Correct code style
r1593 groups.insert(0, gr)
Added handy methods to Repository model for fetching groups with parents
r1155
return groups
@property
Nicolas VINOT
Correct code style
r1593 def groups_and_repo(self):
Added handy methods to Repository model for fetching groups with parents
r1155 return self.groups_with_parents, self.just_name
added clone_uri,api_key into models. Fixed models for mysql compatibilty
r1113
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 @LazyProperty
Nicolas VINOT
Correct code style
r1593 def repo_path(self):
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 """
Returns base full path for that repository means where it actually
exists on a filesystem
"""
Fixed calls to Session in db model...
r2520 q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key ==
Nicolas VINOT
Correct code style
r1593 Repository.url_sep())
fixed caching query on repos path...
r1727 q = q.options(FromCache("sql_cache_short", "repository_repo_path"))
adde short cache for repo_path
r1368 return q.one().ui_value
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
@property
Nicolas VINOT
Correct code style
r1593 def repo_full_path(self):
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 p = [self.repo_path]
# we need to split the name by / since this is how we store the
# names in the database, but that eventually needs to be converted
# into a valid system path
Nicolas VINOT
Correct code style
r1593 p += self.repo_name.split(Repository.url_sep())
return os.path.join(*p)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Show cache keys in admin settings of repository
r2809 @property
def cache_keys(self):
"""
Returns associated cache keys for that repo
"""
return CacheInvalidation.query()\
.filter(CacheInvalidation.cache_args == self.repo_name)\
.order_by(CacheInvalidation.cache_key)\
.all()
Nicolas VINOT
Correct code style
r1593 def get_new_name(self, repo_name):
fixes #260 Put repo in group, then move group to another group -> repo becomes unavailable
r1539 """
returns new full repository name based on assigned group and new new
Nicolas VINOT
Merge with upstream
r1591
fixes #260 Put repo in group, then move group to another group -> repo becomes unavailable
r1539 :param group_name:
"""
path_prefix = self.group.full_path_splitted if self.group else []
Nicolas VINOT
Correct code style
r1593 return Repository.url_sep().join(path_prefix + [repo_name])
fixes #260 Put repo in group, then move group to another group -> repo becomes unavailable
r1539
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 @property
Nicolas VINOT
Correct code style
r1593 def _ui(self):
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 """
Creates an db based ui object for this repository
"""
remove duplicated code for generating UI objects
r2982 from rhodecode.lib.utils import make_ui
return make_ui('db', clear_session=False)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
API added checks for a valid repository on pull command...
r1508 @classmethod
Fixed calls to Session in db model...
r2520 def inject_ui(cls, repo, extras={}):
from rhodecode.lib.vcs.backends.hg import MercurialRepository
from rhodecode.lib.vcs.backends.git import GitRepository
required = (MercurialRepository, GitRepository)
if not isinstance(repo, required):
raise Exception('repo must be instance of %s' % required)
# inject ui extra param to log this action via push logger
for k, v in extras.items():
repo._repo.ui.setconfig('rhodecode_extras', k, v)
@classmethod
Nicolas VINOT
Correct code style
r1593 def is_valid(cls, repo_name):
API added checks for a valid repository on pull command...
r1508 """
returns True if given repo name is a valid filesystem repository
Nicolas VINOT
Implement all CRUD API operation for repo
r1587
sphinx doc cleanup
r1819 :param cls:
:param repo_name:
API added checks for a valid repository on pull command...
r1508 """
from rhodecode.lib.utils import is_valid_repo
Nicolas VINOT
Correct code style
r1593 return is_valid_repo(repo_name, cls.base_path())
API added checks for a valid repository on pull command...
r1508
Added functions for getting API data to repo and user models
r2508 def get_api_data(self):
"""
Common function for generating repo api data
"""
repo = self
data = dict(
Change return paremeters for get_api_data in user and repo
r2510 repo_id=repo.repo_id,
Added functions for getting API data to repo and user models
r2508 repo_name=repo.repo_name,
repo_type=repo.repo_type,
clone_uri=repo.clone_uri,
private=repo.private,
created_on=repo.created_on,
description=repo.description,
landing_rev=repo.landing_rev,
owner=repo.user.username,
Default parameters are now also used for creating repos using API calls, and initial repo scanner...
r3115 fork_of=repo.fork.repo_name if repo.fork else None,
enable_statistics=repo.enable_statistics,
enable_locking=repo.enable_locking,
added last_changeset information in get_repo API function
r3174 enable_downloads=repo.enable_downloads,
last_changeset=repo.changeset_cache
Added functions for getting API data to repo and user models
r2508 )
repository extra fields implementation...
r3308 rc_config = RhodeCodeSetting.get_app_settings()
repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
if repository_fields:
for f in self.extra_fields:
data[f.field_key_prefixed] = f.field_value
Added functions for getting API data to repo and user models
r2508
return data
Implemented basic locking functionality....
r2726 @classmethod
def lock(cls, repo, user_id):
repo.locked = [user_id, time.time()]
Session().add(repo)
Session().commit()
@classmethod
def unlock(cls, repo):
repo.locked = None
Session().add(repo)
Session().commit()
Added lightweight dashboard option. ref #500
r2936 @property
def last_db_change(self):
return self.updated_on
implemented #725 Pull Request View - Show origin repo URL
r3170 def clone_url(self, **override):
from pylons import url
from urlparse import urlparse
import urllib
parsed_url = urlparse(url('home', qualified=True))
default_clone_uri = '%(scheme)s://%(user)s%(pass)s%(netloc)s%(prefix)s%(path)s'
decoded_path = safe_unicode(urllib.unquote(parsed_url.path))
args = {
'user': '',
'pass': '',
'scheme': parsed_url.scheme,
'netloc': parsed_url.netloc,
'prefix': decoded_path,
'path': self.repo_name
}
args.update(override)
return default_clone_uri % args
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 #==========================================================================
Code cleanup...
r1466 # SCM PROPERTIES
#==========================================================================
fixed issue with getting README files from git repositories
r2251 def get_changeset(self, rev=None):
Nicolas VINOT
Correct code style
r1593 return get_changeset_safe(self.scm_instance, rev)
Code cleanup...
r1466
Readme renderer now uses landing_rev parameter to render the readme based on...
r2603 def get_landing_changeset(self):
"""
Returns landing changeset, or if that doesn't exist returns the tip
"""
cs = self.get_changeset(self.landing_rev) or self.get_changeset()
return cs
Added full last changeset info to lightweight dashboard
r3147 def update_changeset_cache(self, cs_cache=None):
"""
Update cache of last changeset for repository, keys should be::
short_id
raw_id
revision
message
date
author
:param cs_cache:
"""
from rhodecode.lib.vcs.backends.base import BaseChangeset
if cs_cache is None:
cs_cache = self.get_changeset()
if isinstance(cs_cache, BaseChangeset):
cs_cache = cs_cache.__json__()
fixes for issue #731, update-repoinfo sometimes failed to update data when changesets...
r3227 if (cs_cache != self.changeset_cache
or not self.last_change
or not self.changeset_cache):
update repo-info shouldn't allow setting empty values NEVER !
r3226 _default = datetime.datetime.fromtimestamp(0)
last_change = cs_cache.get('date') or self.last_change or _default
Added full last changeset info to lightweight dashboard
r3147 log.debug('updated repo %s with new cs cache %s' % (self, cs_cache))
Update last_change from VCS data on request....
r2937 self.updated_on = last_change
Added full last changeset info to lightweight dashboard
r3147 self.changeset_cache = cs_cache
Update last_change from VCS data on request....
r2937 Session().add(self)
Session().commit()
fixes for issue #731, update-repoinfo sometimes failed to update data when changesets...
r3227 else:
log.debug('Skipping repo:%s already with latest changes' % self)
Update last_change from VCS data on request....
r2937
Code cleanup...
r1466 @property
Nicolas VINOT
Correct code style
r1593 def tip(self):
return self.get_changeset('tip')
Code cleanup...
r1466
@property
Nicolas VINOT
Correct code style
r1593 def author(self):
Code cleanup...
r1466 return self.tip.author
@property
Nicolas VINOT
Correct code style
r1593 def last_change(self):
Code cleanup...
r1466 return self.scm_instance.last_change
Fixed calls to Session in db model...
r2520 def get_comments(self, revisions=None):
Added number of comments in changelog for each changeset...
r1884 """
Returns comments for this repository grouped by revisions
:param revisions: filter query by revisions only
"""
cmts = ChangesetComment.query()\
.filter(ChangesetComment.repo == self)
if revisions:
cmts = cmts.filter(ChangesetComment.revision.in_(revisions))
grouped = defaultdict(list)
for cmt in cmts.all():
grouped[cmt.revision].append(cmt)
return grouped
code-review initial
r2215 def statuses(self, revisions=None):
"""
Returns statuses for this repository
Implemented initial code-review status of changesets
r2217
code-review initial
r2215 :param revisions: list of revisions to get statuses for
:type revisions: list
"""
statuses = ChangesetStatus.query()\
Added simple versioning for changeset status
r2287 .filter(ChangesetStatus.repo == self)\
.filter(ChangesetStatus.version == 0)
code-review initial
r2215 if revisions:
statuses = statuses.filter(ChangesetStatus.revision.in_(revisions))
Implemented initial code-review status of changesets
r2217 grouped = {}
mock changeset status(to under review) if there's opened pull request but not yet with a status
r2542
#maybe we have open new pullrequest without a status ?
stat = ChangesetStatus.STATUS_UNDER_REVIEW
status_lbl = ChangesetStatus.get_status_lbl(stat)
for pr in PullRequest.query().filter(PullRequest.org_repo == self).all():
for rev in pr.revisions:
pr_id = pr.pull_request_id
pr_repo = pr.other_repo.repo_name
grouped[rev] = [stat, status_lbl, pr_id, pr_repo]
code-review initial
r2215 for stat in statuses.all():
- added commenting to pull requests...
r2443 pr_id = pr_repo = None
if stat.pull_request:
pr_id = stat.pull_request.pull_request_id
pr_repo = stat.pull_request.other_repo.repo_name
grouped[stat.revision] = [str(stat.status), stat.status_lbl,
pr_id, pr_repo]
code-review initial
r2215 return grouped
implemented #83 show repo size on summary page
r3246 def _repo_size(self):
from rhodecode.lib import helpers as h
log.debug('calculating repository size...')
return h.format_byte_size(self.scm_instance.size)
Code cleanup...
r1466 #==========================================================================
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 # SCM CACHE INSTANCE
#==========================================================================
@property
Nicolas VINOT
Correct code style
r1593 def invalidate(self):
Cached readme generation...
r1607 return CacheInvalidation.invalidate(self.repo_name)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Nicolas VINOT
Correct code style
r1593 def set_invalidate(self):
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 """
set a cache for invalidation for this instance
"""
Cleaned the way cache keys are invalidated...
r3020 CacheInvalidation.set_invalidate(repo_name=self.repo_name)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Code cleanup...
r1466 @LazyProperty
git hook handler shouldn't ever use cache instances...
r3278 def scm_instance_no_cache(self):
return self.__get_instance()
@LazyProperty
Nicolas VINOT
Correct code style
r1593 def scm_instance(self):
Added option to ini files for controlling full cache of VCS instances....
r3025 import rhodecode
full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache'))
if full_cache:
return self.scm_instance_cached()
Simplified last_login call on user, and changed login to use User model directly
r1400 return self.__get_instance()
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Implemented cache-map on main page to save executing select...
r2352 def scm_instance_cached(self, cache_map=None):
Nicolas VINOT
Correct code style
r1593 @cache_region('long_term')
def _c(repo_name):
Simplified last_login call on user, and changed login to use User model directly
r1400 return self.__get_instance()
Cached readme generation...
r1607 rn = self.repo_name
remove cache from default perms. In some cases of concurrent repo removal it crashed....
r1744 log.debug('Getting cached instance of repo')
Implemented cache-map on main page to save executing select...
r2352
if cache_map:
# get using prefilled cache_map
invalidate_repo = cache_map[self.repo_name]
if invalidate_repo:
typo fix + code garden
r2356 invalidate_repo = (None if invalidate_repo.cache_active
Implemented cache-map on main page to save executing select...
r2352 else invalidate_repo)
else:
# get from invalidate
invalidate_repo = self.invalidate
if invalidate_repo is not None:
Nicolas VINOT
Correct code style
r1593 region_invalidate(_c, None, rn)
fixed some issues with cache invalidation, and simplified invalidation codes
r1428 # update our cache
Implemented cache-map on main page to save executing select...
r2352 CacheInvalidation.set_valid(invalidate_repo.cache_key)
Nicolas VINOT
Correct code style
r1593 return _c(rn)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
Nicolas VINOT
Correct code style
r1593 def __get_instance(self):
adde short cache for repo_path
r1368 repo_full_path = self.repo_full_path
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 try:
Nicolas VINOT
Correct code style
r1593 alias = get_scm(repo_full_path)[0]
garden...
r1976 log.debug('Creating instance of %s repository' % alias)
Nicolas VINOT
Correct code style
r1593 backend = get_backend(alias)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 except VCSError:
Nicolas VINOT
Correct code style
r1593 log.error(traceback.format_exc())
log.error('Perhaps this repository is in db and not in '
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 'filesystem run rescan repositories with '
Nicolas VINOT
Correct code style
r1593 '"destroy old data " option from admin panel')
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 return
if alias == 'hg':
added migrations from 1.2.X to 1.3
r2000
fixes #288...
r1594 repo = backend(safe_str(repo_full_path), create=False,
baseui=self._ui)
Cached readme generation...
r1607 # skip hidden web repository
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366 if repo._get_hidden():
return
else:
fixes #288...
r1594 repo = backend(repo_full_path, create=False)
fixes #200, rewrote the whole caching mechanism to get rid of such problems. Now cached instances are attached...
r1366
return repo
Moved BaseModel into base class for declarative base. Added some handy methods into...
r1065
refactoring of models names for repoGroup permissions
r1633 class RepoGroup(Base, BaseModel):
Extended repo2db mapper with group creation via directory structures...
r878 __tablename__ = 'groups'
renamed repo groups table...
r1958 __table_args__ = (
UniqueConstraint('group_name', 'group_parent_id'),
white space cleanup
r1963 CheckConstraint('group_id != group_parent_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
renamed repo groups table...
r1958 )
__mapper_args__ = {'order_by': 'group_name'}
Extended repo2db mapper with group creation via directory structures...
r878
fixes #288...
r1594 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 group_name = Column("group_name", String(255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
fixes #288...
r1594 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
added status column to pull request + some small refactoring of models
r2588 group_description = Column("group_description", String(10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
Recursive set locking on all children of a group.
r2749 enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False)
Extended repo2db mapper with group creation via directory structures...
r878
#227 Initial version of repository groups permissions system...
r1982 repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id')
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all')
#227 Initial version of repository groups permissions system...
r1982
refactoring of models names for repoGroup permissions
r1633 parent_group = relationship('RepoGroup', remote_side=group_id)
Extended repo2db mapper with group creation via directory structures...
r878
fixes #288...
r1594 def __init__(self, group_name='', parent_group=None):
Extended repo2db mapper with group creation via directory structures...
r878 self.group_name = group_name
self.parent_group = parent_group
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
Nicolas VINOT
Correct code style
r1593 self.group_name)
Hacking for git support,and new faster repo scan
r631
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346 @classmethod
filter out repo groups choices to only ones that you have write+ access to. Before it was read+ access and you got proper...
r3239 def groups_choices(cls, groups=None, show_empty_group=True):
unified generation of repo groups choices...
r1547 from webhelpers.html import literal as _literal
Group management delegation:...
r3222 if not groups:
groups = cls.query().all()
filter out repo groups choices to only ones that you have write+ access to. Before it was read+ access and you got proper...
r3239
Group management delegation:...
r3222 repo_groups = []
if show_empty_group:
repo_groups = [('-1', '-- no parent --')]
unified generation of repo groups choices...
r1547 sep = ' &raquo; '
Nicolas VINOT
Correct code style
r1593 _name = lambda k: _literal(sep.join(k))
unified generation of repo groups choices...
r1547
Nicolas VINOT
Correct code style
r1593 repo_groups.extend([(x.group_id, _name(x.full_path_splitted))
Implemented permissions for writing to repo...
r2835 for x in groups])
Nicolas VINOT
Merge with upstream
r1591
fixes #288...
r1594 repo_groups = sorted(repo_groups, key=lambda t: t[1].split(sep)[0])
unified generation of repo groups choices...
r1547 return repo_groups
Nicolas VINOT
Merge with upstream
r1591
unified generation of repo groups choices...
r1547 @classmethod
Nicolas VINOT
Correct code style
r1593 def url_sep(cls):
Added optional repo_name into issue tracker url to get just the name of repo without group prefix
r2339 return URL_SEP
#47 implemented deleting of empty groups. Fixed problem with full paths on nested groups
r1346
implements #226 repo groups available by path...
r1538 @classmethod
fixes #288...
r1594 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 if case_insensitive:
gr = cls.query()\
Nicolas VINOT
Correct code style
r1593 .filter(cls.group_name.ilike(group_name))
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 else:
gr = cls.query()\
Nicolas VINOT
Correct code style
r1593 .filter(cls.group_name == group_name)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 if cache:
fixes #371 fixed issues with beaker/sqlalchemy and non-ascii cache keys
r2062 gr = gr.options(FromCache(
"sql_cache_short",
"get_group_%s" % _hash_key(group_name)
)
)
Nicolas VINOT
Improve API with user/group/repo CRUD methods
r1584 return gr.scalar()
implements #226 repo groups available by path...
r1538
Changes for repo groups
r1159 @property
Nicolas VINOT
Correct code style
r1593 def parents(self):
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 parents_recursion_limit = 5
Changes for repo groups
r1159 groups = []
if self.parent_group is None:
return groups
cur_gr = self.parent_group
Nicolas VINOT
Correct code style
r1593 groups.insert(0, cur_gr)
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 cnt = 0
Changes for repo groups
r1159 while 1:
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 cnt += 1
Nicolas VINOT
Correct code style
r1593 gr = getattr(cur_gr, 'parent_group', None)
Changes for repo groups
r1159 cur_gr = cur_gr.parent_group
if gr is None:
break
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 if cnt == parents_recursion_limit:
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 # this will prevent accidental infinit loops
Nicolas VINOT
Correct code style
r1593 log.error('group nested more than %s' %
parents_recursion_limit)
#47 added editing of groups, and moving them between. Added check constraint for groups...
r1349 break
Nicolas VINOT
Correct code style
r1593 groups.insert(0, gr)
Changes for repo groups
r1159 return groups
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 @property
Nicolas VINOT
Correct code style
r1593 def children(self):
refactoring of models names for repoGroup permissions
r1633 return RepoGroup.query().filter(RepoGroup.parent_group == self)
fixed saving settings on repositories inside groups, also fixes #187...
r1323
@property
Nicolas VINOT
Correct code style
r1593 def name(self):
refactoring of models names for repoGroup permissions
r1633 return self.group_name.split(RepoGroup.url_sep())[-1]
implements #226 repo groups available by path...
r1538
@property
Nicolas VINOT
Correct code style
r1593 def full_path(self):
fixes #288...
r1594 return self.group_name
implements #226 repo groups available by path...
r1538
@property
Nicolas VINOT
Correct code style
r1593 def full_path_splitted(self):
refactoring of models names for repoGroup permissions
r1633 return self.group_name.split(RepoGroup.url_sep())
fixed saving settings on repositories inside groups, also fixes #187...
r1323
Added repo group page showing what reposiories are inside a group
r1193 @property
Nicolas VINOT
Correct code style
r1593 def repositories(self):
fixed sorting of repos in group
r2079 return Repository.query()\
.filter(Repository.group == self)\
.order_by(Repository.repo_name)
Added repo group page showing what reposiories are inside a group
r1193
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 @property
Nicolas VINOT
Correct code style
r1593 def repositories_recursive_count(self):
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 cnt = self.repositories.count()
Nicolas VINOT
Correct code style
r1593 def children_count(group):
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 cnt = 0
for child in group.children:
cnt += child.repositories.count()
Nicolas VINOT
Correct code style
r1593 cnt += children_count(child)
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385 return cnt
Nicolas VINOT
Correct code style
r1593 return cnt + children_count(self)
#209 Added recursive count on repositories to calculate all repos within all nested groups
r1385
Recursive set locking on all children of a group.
r2749 def recursive_groups_and_repos(self):
"""
Recursive return all groups, with repositories in those groups
"""
all_ = []
def _get_members(root_gr):
for r in root_gr.repositories:
all_.append(r)
childs = root_gr.children.all()
if childs:
for gr in childs:
all_.append(gr)
_get_members(gr)
_get_members(self)
return [self] + all_
Nicolas VINOT
Correct code style
r1593 def get_new_name(self, group_name):
implements #226 repo groups available by path...
r1538 """
returns new full group name based on parent and new name
Nicolas VINOT
Merge with upstream
r1591
implements #226 repo groups available by path...
r1538 :param group_name:
"""
Cached readme generation...
r1607 path_prefix = (self.parent_group.full_path_splitted if
fixes #288...
r1594 self.parent_group else [])
refactoring of models names for repoGroup permissions
r1633 return RepoGroup.url_sep().join(path_prefix + [group_name])
implements #226 repo groups available by path...
r1538
Nicolas VINOT
Correct code style
r1593 class Permission(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'permissions'
Mysql fixes...
r2149 __table_args__ = (
Added some DB indexes to optimize queries
r2463 Index('p_perm_name_idx', 'permission_name'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
Better descriptions of given permission overview in edit user view
r2532 PERMS = [
('repository.none', _('Repository no access')),
('repository.read', _('Repository read access')),
('repository.write', _('Repository write access')),
('repository.admin', _('Repository admin access')),
Mads Kiilerich
follow-up on texts missing from 'users groups'/'repositories group' cleanup
r3416 ('group.none', _('Repository group no access')),
('group.read', _('Repository group read access')),
('group.write', _('Repository group write access')),
('group.admin', _('Repository group admin access')),
Better descriptions of given permission overview in edit user view
r2532
('hg.admin', _('RhodeCode Administrator')),
('hg.create.none', _('Repository creation disabled')),
('hg.create.repository', _('Repository creation enabled')),
RhodeCode now has a option to explicitly set forking permissions. ref #508...
r2709 ('hg.fork.none', _('Repository forking disabled')),
('hg.fork.repository', _('Repository forking enabled')),
Better descriptions of given permission overview in edit user view
r2532 ('hg.register.none', _('Register disabled')),
('hg.register.manual_activate', _('Register new user with RhodeCode '
'with manual activation')),
('hg.register.auto_activate', _('Register new user with RhodeCode '
'with auto activation')),
]
RhodeCode now has a option to explicitly set forking permissions. ref #508...
r2709 # defines which permissions are more important higher the more important
PERM_WEIGHTS = {
'repository.none': 0,
'repository.read': 1,
'repository.write': 3,
'repository.admin': 4,
'group.none': 0,
'group.read': 1,
'group.write': 3,
'group.admin': 4,
'hg.fork.none': 0,
'hg.fork.repository': 1,
'hg.create.none': 0,
'hg.create.repository':1
}
fixes #288...
r1594 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 permission_name = Column("permission_name", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
permission_longname = Column("permission_longname", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
Hacking for git support,and new faster repo scan
r631
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u"<%s('%s:%s')>" % (
#227 Initial version of repository groups permissions system...
r1982 self.__class__.__name__, self.permission_id, self.permission_name
)
renamed project to rhodecode
r547
Fixed #161 form saves the create repository permission....
r1266 @classmethod
Nicolas VINOT
Correct code style
r1593 def get_by_key(cls, key):
return cls.query().filter(cls.permission_name == key).scalar()
Fixed #161 form saves the create repository permission....
r1266
- fixes celery sqlalchemy session issues for async forking...
r1728 @classmethod
remove cache from default perms. In some cases of concurrent repo removal it crashed....
r1744 def get_default_perms(cls, default_user_id):
Fixed calls to Session in db model...
r2520 q = Session().query(UserRepoToPerm, Repository, cls)\
#227 Initial version of repository groups permissions system...
r1982 .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
.join((cls, UserRepoToPerm.permission_id == cls.permission_id))\
.filter(UserRepoToPerm.user_id == default_user_id)
return q.all()
@classmethod
def get_default_group_perms(cls, default_user_id):
Fixed calls to Session in db model...
r2520 q = Session().query(UserRepoGroupToPerm, RepoGroup, cls)\
#227 Initial version of repository groups permissions system...
r1982 .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
.join((cls, UserRepoGroupToPerm.permission_id == cls.permission_id))\
.filter(UserRepoGroupToPerm.user_id == default_user_id)
- fixes celery sqlalchemy session issues for async forking...
r1728
return q.all()
refactoring of models names for repoGroup permissions
r1633 class UserRepoToPerm(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'repo_to_perm'
renamed repo groups table...
r1958 __table_args__ = (
added migrations from 1.2.X to 1.3
r2000 UniqueConstraint('user_id', 'repository_id', 'permission_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
fixes #288...
r1594 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
Hacking for git support,and new faster repo scan
r631
Nicolas VINOT
Correct code style
r1593 user = relationship('User')
added migrations from 1.2.X to 1.3
r2000 repository = relationship('Repository')
Nicolas VINOT
Correct code style
r1593 permission = relationship('Permission')
renamed project to rhodecode
r547
implements #236 forking copy permission option
r1729 @classmethod
def create(cls, user, repository, permission):
n = cls()
n.user = user
n.repository = repository
n.permission = permission
Fixed calls to Session in db model...
r2520 Session().add(n)
implements #236 forking copy permission option
r1729 return n
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u'<user:%s => %s >' % (self.user, self.repository)
implements #236 forking copy permission option
r1729
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class UserToPerm(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'user_to_perm'
db unique constraints fixes
r1988 __table_args__ = (
UniqueConstraint('user_id', 'permission_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
db unique constraints fixes
r1988 )
fixes #288...
r1594 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
Hacking for git support,and new faster repo scan
r631
Nicolas VINOT
Correct code style
r1593 user = relationship('User')
- fixes celery sqlalchemy session issues for async forking...
r1728 permission = relationship('Permission', lazy='joined')
renamed project to rhodecode
r547
#56 added assignments of users groups into repository
r1014
Mads Kiilerich
further cleanup of UsersGroup...
r3417 class UserGroupRepoToPerm(Base, BaseModel):
Fixed permissions for users groups, group can have create repo permission now....
r1271 __tablename__ = 'users_group_repo_to_perm'
renamed repo groups table...
r1958 __table_args__ = (
added migrations from 1.2.X to 1.3
r2000 UniqueConstraint('repository_id', 'users_group_id', 'permission_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
fixes #288...
r1594 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
added user group to perm table
r958
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group = relationship('UserGroup')
Nicolas VINOT
Correct code style
r1593 permission = relationship('Permission')
repository = relationship('Repository')
added user group to perm table
r958
implements #236 forking copy permission option
r1729 @classmethod
def create(cls, users_group, repository, permission):
n = cls()
n.users_group = users_group
n.repository = repository
n.permission = permission
Fixed calls to Session in db model...
r2520 Session().add(n)
implements #236 forking copy permission option
r1729 return n
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u'<userGroup:%s => %s >' % (self.users_group, self.repository)
Fixed permissions for users groups, group can have create repo permission now....
r1271
pep8ify
r1800
Mads Kiilerich
further cleanup of UsersGroup...
r3417 class UserGroupToPerm(Base, BaseModel):
Fixed permissions for users groups, group can have create repo permission now....
r1271 __tablename__ = 'users_group_to_perm'
db unique constraints fixes
r1988 __table_args__ = (
UniqueConstraint('users_group_id', 'permission_id',),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
db unique constraints fixes
r1988 )
fixes #288...
r1594 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
Fixed permissions for users groups, group can have create repo permission now....
r1271
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group = relationship('UserGroup')
Nicolas VINOT
Correct code style
r1593 permission = relationship('Permission')
Fixed permissions for users groups, group can have create repo permission now....
r1271
refactoring of models names for repoGroup permissions
r1633 class UserRepoGroupToPerm(Base, BaseModel):
renamed repo groups table...
r1958 __tablename__ = 'user_repo_group_to_perm'
__table_args__ = (
added migrations from 1.2.X to 1.3
r2000 UniqueConstraint('user_id', 'group_id', 'permission_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
added group to perm mapping table
r879
fixes #288...
r1594 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
renamed repo groups table...
r1958 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
fixes #288...
r1594 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
added group to perm mapping table
r879
Nicolas VINOT
Correct code style
r1593 user = relationship('User')
added migrations from 1.2.X to 1.3
r2000 group = relationship('RepoGroup')
Nicolas VINOT
Correct code style
r1593 permission = relationship('Permission')
refactoring of models names for repoGroup permissions
r1633
pep8ify
r1800
Mads Kiilerich
further cleanup of UsersGroup...
r3417 class UserGroupRepoGroupToPerm(Base, BaseModel):
refactoring of models names for repoGroup permissions
r1633 __tablename__ = 'users_group_repo_group_to_perm'
renamed repo groups table...
r1958 __table_args__ = (
db unique constraints fixes
r1988 UniqueConstraint('users_group_id', 'group_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
refactoring of models names for repoGroup permissions
r1633
users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
db unique constraints fixes
r1988 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
refactoring of models names for repoGroup permissions
r1633 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
Mads Kiilerich
further cleanup of UsersGroup...
r3417 users_group = relationship('UserGroup')
refactoring of models names for repoGroup permissions
r1633 permission = relationship('Permission')
group = relationship('RepoGroup')
added group to perm mapping table
r879
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class Statistics(Base, BaseModel):
renamed project to rhodecode
r547 __tablename__ = 'statistics'
Mysql fixes...
r2149 __table_args__ = (
White space cleanup
r2150 UniqueConstraint('repository_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
)
fixes #288...
r1594 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
Hacking for git support,and new faster repo scan
r631
fixes #288...
r1594 repository = relationship('Repository', single_parent=True)
renamed project to rhodecode
r547
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class UserFollowing(Base, BaseModel):
implemented user dashboards, and following system.
r734 __tablename__ = 'user_followings'
renamed repo groups table...
r1958 __table_args__ = (
UniqueConstraint('user_id', 'follows_repository_id'),
UniqueConstraint('user_id', 'follows_user_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
implemented user dashboards, and following system.
r734
fixes #288...
r1594 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
implemented user dashboards, and following system.
r734
fixes #288...
r1594 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
implemented user dashboards, and following system.
r734
fixes #288...
r1594 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
follows_repository = relationship('Repository', order_by='Repository.repo_name')
implemented user dashboards, and following system.
r734
#179 Added followers page
r1279 @classmethod
Nicolas VINOT
Correct code style
r1593 def get_repo_followers(cls, repo_id):
return cls.query().filter(cls.follows_repo_id == repo_id)
#179 Added followers page
r1279
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class CacheInvalidation(Base, BaseModel):
Adde table for cache invalidation
r670 __tablename__ = 'cache_invalidation'
Mysql fixes...
r2149 __table_args__ = (
UniqueConstraint('cache_key'),
Implemented cache-map on main page to save executing select...
r2352 Index('key_idx', 'cache_key'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
fixes #288...
r1594 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
added status column to pull request + some small refactoring of models
r2588 cache_key = Column("cache_key", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
cache_args = Column("cache_args", String(255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
fixes #288...
r1594 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
Adde table for cache invalidation
r670
fixes #288...
r1594 def __init__(self, cache_key, cache_args=''):
#50 on point cache invalidation changes....
r692 self.cache_key = cache_key
self.cache_args = cache_args
self.cache_active = False
Use __unicode__ instead of __repr__ in models.
r2156 def __unicode__(self):
return u"<%s('%s:%s')>" % (self.__class__.__name__,
Nicolas VINOT
Correct code style
r1593 self.cache_id, self.cache_key)
Implemented cache-map on main page to save executing select...
r2352
Show cache keys in admin settings of repository
r2809 @property
def prefix(self):
_split = self.cache_key.split(self.cache_args, 1)
if _split and len(_split) == 2:
return _split[0]
return ''
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 @classmethod
def clear_cache(cls):
cls.query().delete()
added current db version into rhodecode,...
r834
Cached readme generation...
r1607 @classmethod
fixed issue with hybrid property for ldap_active...
r2013 def _get_key(cls, key):
"""
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 Wrapper for generating a key, together with a prefix
fixed issue with hybrid property for ldap_active...
r2013
:param key:
"""
implements #212 moved default encoding variable into rhodecode-config. It's now possible to change...
r2016 import rhodecode
prefix = ''
Cleaned the way cache keys are invalidated...
r3020 org_key = key
implements #212 moved default encoding variable into rhodecode-config. It's now possible to change...
r2016 iid = rhodecode.CONFIG.get('instance_id')
if iid:
updated CONTRIBUTORS...
r2058 prefix = iid
Cleaned the way cache keys are invalidated...
r3020
return "%s%s" % (prefix, key), prefix, org_key
fixed issue with hybrid property for ldap_active...
r2013
@classmethod
def get_by_key(cls, key):
return cls.query().filter(cls.cache_key == key).scalar()
Mysql fixes...
r2149
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 @classmethod
Cleaned the way cache keys are invalidated...
r3020 def get_by_repo_name(cls, repo_name):
return cls.query().filter(cls.cache_args == repo_name).all()
@classmethod
def _get_or_create_key(cls, key, repo_name, commit=True):
Fixed calls to Session in db model...
r2520 inv_obj = Session().query(cls).filter(cls.cache_key == key).scalar()
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 if not inv_obj:
try:
Cleaned the way cache keys are invalidated...
r3020 inv_obj = CacheInvalidation(key, repo_name)
Fixed calls to Session in db model...
r2520 Session().add(inv_obj)
Fixing issues of cache invalidation for multiple instances running in rhodecode....
r2808 if commit:
Session().commit()
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 except Exception:
log.error(traceback.format_exc())
Fixed calls to Session in db model...
r2520 Session().rollback()
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 return inv_obj
Mysql fixes...
r2149
fixed issue with hybrid property for ldap_active...
r2013 @classmethod
Cached readme generation...
r1607 def invalidate(cls, key):
"""
Returns Invalidation object if this given key should be invalidated
None otherwise. `cache_active = False` means that this cache
state is not valid and needs to be invalidated
auto white-space removal
r1818
Cached readme generation...
r1607 :param key:
"""
Cleaned the way cache keys are invalidated...
r3020 repo_name = key
repo_name = remove_suffix(repo_name, '_README')
repo_name = remove_suffix(repo_name, '_RSS')
repo_name = remove_suffix(repo_name, '_ATOM')
Mysql fixes...
r2149
Cleaned the way cache keys are invalidated...
r3020 # adds instance prefix
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 key, _prefix, _org_key = cls._get_key(key)
Cleaned the way cache keys are invalidated...
r3020 inv = cls._get_or_create_key(key, repo_name)
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147
if inv and inv.cache_active is False:
return inv
Cached readme generation...
r1607
@classmethod
Cleaned the way cache keys are invalidated...
r3020 def set_invalidate(cls, key=None, repo_name=None):
Cached readme generation...
r1607 """
Cleaned the way cache keys are invalidated...
r3020 Mark this Cache key for invalidation, either by key or whole
cache sets based on repo_name
auto white-space removal
r1818
Cached readme generation...
r1607 :param key:
"""
Return a list of invlidated keys on mark_for_invalidation func...
r3234 invalidated_keys = []
Cleaned the way cache keys are invalidated...
r3020 if key:
key, _prefix, _org_key = cls._get_key(key)
inv_objs = Session().query(cls).filter(cls.cache_key == key).all()
elif repo_name:
inv_objs = Session().query(cls).filter(cls.cache_args == repo_name).all()
Cached readme generation...
r1607
- #347 when running multiple RhodeCode instances, properly invalidates cache...
r2147 try:
for inv_obj in inv_objs:
Cleaned the way cache keys are invalidated...
r3020 inv_obj.cache_active = False
Return a list of invlidated keys on mark_for_invalidation func...
r3234 log.debug('marking %s key for invalidation based on key=%s,repo_name=%s'
% (inv_obj, key, repo_name))
invalidated_keys.append(inv_obj.cache_key)
Fixed calls to Session in db model...
r2520 Session().add(inv_obj)
Session().commit()
Cached readme generation...
r1607 except Exception:
log.error(traceback.format_exc())
Fixed calls to Session in db model...
r2520 Session().rollback()
Return a list of invlidated keys on mark_for_invalidation func...
r3234 return invalidated_keys
Cached readme generation...
r1607
@classmethod
def set_valid(cls, key):
"""
Mark this cache key as active and currently cached
auto white-space removal
r1818
Cached readme generation...
r1607 :param key:
"""
fixed issue with hybrid property for ldap_active...
r2013 inv_obj = cls.get_by_key(key)
Cached readme generation...
r1607 inv_obj.cache_active = True
Fixed calls to Session in db model...
r2520 Session().add(inv_obj)
Session().commit()
Cached readme generation...
r1607
Implemented cache-map on main page to save executing select...
r2352 @classmethod
def get_cache_map(cls):
class cachemapdict(dict):
def __init__(self, *args, **kwargs):
fixkey = kwargs.get('fixkey')
if fixkey:
del kwargs['fixkey']
typo fix + code garden
r2356 self.fixkey = fixkey
Implemented cache-map on main page to save executing select...
r2352 super(cachemapdict, self).__init__(*args, **kwargs)
def __getattr__(self, name):
key = name
if self.fixkey:
key, _prefix, _org_key = cls._get_key(key)
if key in self.__dict__:
return self.__dict__[key]
else:
return self[key]
def __getitem__(self, key):
if self.fixkey:
key, _prefix, _org_key = cls._get_key(key)
try:
return super(cachemapdict, self).__getitem__(key)
except KeyError:
return
cache_map = cachemapdict(fixkey=True)
for obj in cls.query().all():
cache_map[obj.cache_key] = cachemapdict(obj.get_dict())
return cache_map
Added cache options to some db getters
r1665
#77 code review...
r1670 class ChangesetComment(Base, BaseModel):
__tablename__ = 'changeset_comments'
Mysql fixes...
r2149 __table_args__ = (
Added some DB indexes to optimize queries
r2463 Index('cc_revision_idx', 'revision'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
#77 code review...
r1670 comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
- pull request generates overview based on it's params...
r2440 revision = Column('revision', String(40), nullable=True)
pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
#71 code-review...
r1677 line_no = Column('line_no', Unicode(10), nullable=True)
added highlight lines field in ChangesetComments, will be used...
r2724 hl_lines = Column('hl_lines', Unicode(512), nullable=True)
#71 code-review...
r1677 f_path = Column('f_path', Unicode(1000), nullable=True)
#77 code review...
r1670 user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
UnicodeText make mysql more happy
r2791 text = Column('text', UnicodeText(25000), nullable=False)
Added created_on column to changeset comments for proper ordering.
r2639 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
#77 code review...
r1670
notification fixes and improvements
r1703 author = relationship('User', lazy='joined')
#77 code review...
r1670 repo = relationship('Repository')
Forbid changing changset status when it is associated with a closed pull request...
r2677 status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
- pull request generates overview based on it's params...
r2440 pull_request = relationship('PullRequest', lazy='joined')
#77 code review...
r1670
notification fixes and improvements
r1703 @classmethod
- added commenting to pull requests...
r2443 def get_users(cls, revision=None, pull_request_id=None):
notification fixes and improvements
r1703 """
- added commenting to pull requests...
r2443 Returns user associated with this ChangesetComment. ie those
notification fixes and improvements
r1703 who actually commented
auto white-space removal
r1818
notification fixes and improvements
r1703 :param cls:
:param revision:
"""
Fixed calls to Session in db model...
r2520 q = Session().query(User)\
- added commenting to pull requests...
r2443 .join(ChangesetComment.author)
if revision:
q = q.filter(cls.revision == revision)
elif pull_request_id:
q = q.filter(cls.pull_request_id == pull_request_id)
return q.all()
code garden
r1886
notification fixes and improvements
r1703
code-review initial
r2215 class ChangesetStatus(Base, BaseModel):
__tablename__ = 'changeset_statuses'
__table_args__ = (
Added some DB indexes to optimize queries
r2463 Index('cs_revision_idx', 'revision'),
Index('cs_version_idx', 'version'),
Added simple versioning for changeset status
r2287 UniqueConstraint('repo_id', 'revision', 'version'),
code-review initial
r2215 {'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'}
)
Adde pull request voting recalculation
r2481 STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed'
STATUS_APPROVED = 'approved'
STATUS_REJECTED = 'rejected'
STATUS_UNDER_REVIEW = 'under_review'
code-review initial
r2215
STATUSES = [
Adde pull request voting recalculation
r2481 (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default
(STATUS_APPROVED, _("Approved")),
(STATUS_REJECTED, _("Rejected")),
(STATUS_UNDER_REVIEW, _("Under Review")),
code-review initial
r2215 ]
changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True)
repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
revision = Column('revision', String(40), nullable=False)
Implemented initial code-review status of changesets
r2217 status = Column('status', String(128), nullable=False, default=DEFAULT)
Show changes of status inside comments...
r2286 changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'))
code-review initial
r2215 modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
Added simple versioning for changeset status
r2287 version = Column('version', Integer(), nullable=False, default=0)
Added basic models for saving open pull requests...
r2434 pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True)
code-review initial
r2215 author = relationship('User', lazy='joined')
repo = relationship('Repository')
Show changes of status inside comments...
r2286 comment = relationship('ChangesetComment', lazy='joined')
Added basic models for saving open pull requests...
r2434 pull_request = relationship('PullRequest', lazy='joined')
code-review initial
r2215
Adde pull request voting recalculation
r2481 def __unicode__(self):
return u"<%s('%s:%s')>" % (
self.__class__.__name__,
self.status, self.author
)
Add changeset status change into emails
r2296 @classmethod
def get_status_lbl(cls, value):
return dict(cls.STATUSES).get(value)
Implemented initial code-review status of changesets
r2217 @property
def status_lbl(self):
Add changeset status change into emails
r2296 return ChangesetStatus.get_status_lbl(self.status)
Implemented initial code-review status of changesets
r2217
code-review initial
r2215
Added basic models for saving open pull requests...
r2434 class PullRequest(Base, BaseModel):
__tablename__ = 'pull_requests'
__table_args__ = (
{'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'},
)
added status column to pull request + some small refactoring of models
r2588 STATUS_NEW = u'new'
STATUS_OPEN = u'open'
STATUS_CLOSED = u'closed'
Added basic models for saving open pull requests...
r2434 pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True)
title = Column('title', Unicode(256), nullable=True)
added status column to pull request + some small refactoring of models
r2588 description = Column('description', UnicodeText(10240), nullable=True)
status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW)
- pull request generates overview based on it's params...
r2440 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
Added option to close pull requests, in future that will be close & merge
r2608 updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
- pull request generates overview based on it's params...
r2440 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None)
Added basic models for saving open pull requests...
r2434 _revisions = Column('revisions', UnicodeText(20500)) # 500 revisions max
org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
org_ref = Column('org_ref', Unicode(256), nullable=False)
other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
other_ref = Column('other_ref', Unicode(256), nullable=False)
@hybrid_property
def revisions(self):
return self._revisions.split(':')
@revisions.setter
def revisions(self, val):
self._revisions = ':'.join(val)
implemented #725 Pull Request View - Show origin repo URL
r3170 @property
def org_ref_parts(self):
return self.org_ref.split(':')
@property
def other_ref_parts(self):
return self.other_ref.split(':')
- pull request generates overview based on it's params...
r2440 author = relationship('User', lazy='joined')
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 reviewers = relationship('PullRequestReviewers',
cascade fixes for comments/pull-requests/reviewers...
r2666 cascade="all, delete, delete-orphan")
Added basic models for saving open pull requests...
r2434 org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id')
other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id')
cascade fixes for comments/pull-requests/reviewers...
r2666 statuses = relationship('ChangesetStatus')
comments = relationship('ChangesetComment',
cascade="all, delete, delete-orphan")
Added basic models for saving open pull requests...
r2434
Added option to close pull requests, in future that will be close & merge
r2608 def is_closed(self):
return self.status == self.STATUS_CLOSED
Add new attr to pull request
r3264 @property
def last_review_status(self):
laste_review status should only return if there are any statuses
r3274 return self.statuses[-1].status if self.statuses else ''
Add new attr to pull request
r3264
Added basic models for saving open pull requests...
r2434 def __json__(self):
return dict(
revisions=self.revisions
)
class PullRequestReviewers(Base, BaseModel):
__tablename__ = 'pull_request_reviewers'
__table_args__ = (
{'extend_existing': True, 'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'},
)
def __init__(self, user=None, pull_request=None):
self.user = user
self.pull_request = pull_request
pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True)
pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False)
user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True)
user = relationship('User')
pull_request = relationship('PullRequest')
code garden
r1886
notification fixes and improvements
r1703
#302 - basic notification system, models+tests
r1702 class Notification(Base, BaseModel):
__tablename__ = 'notifications'
Mysql fixes...
r2149 __table_args__ = (
Added some DB indexes to optimize queries
r2463 Index('notification_type_idx', 'type'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
notification fixes and improvements
r1703
Notification system improvements...
r1712 TYPE_CHANGESET_COMMENT = u'cs_comment'
TYPE_MESSAGE = u'message'
TYPE_MENTION = u'mention'
implements #222 registration feedback...
r1731 TYPE_REGISTRATION = u'registration'
pull requests draft UI
r2244 TYPE_PULL_REQUEST = u'pull_request'
- added commenting to pull requests...
r2443 TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
notification fixes and improvements
r1703
#302 - basic notification system, models+tests
r1702 notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
subject = Column('subject', Unicode(512), nullable=True)
added status column to pull request + some small refactoring of models
r2588 body = Column('body', UnicodeText(50000), nullable=True)
notification fixes and improvements
r1703 created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
#302 - basic notification system, models+tests
r1702 created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
notification fixes and improvements
r1703 type_ = Column('type', Unicode(256))
#302 - basic notification system, models+tests
r1702
Notification system improvements...
r1712 created_by_user = relationship('User')
Notification fixes...
r1717 notifications_to_users = relationship('UserNotification', lazy='joined',
cascade="all, delete, delete-orphan")
#302 - basic notification system, models+tests
r1702
@property
def recipients(self):
return [x.user for x in UserNotification.query()\
fixed issue with empty APIKEYS on registration #438
r2248 .filter(UserNotification.notification == self)\
fixed sorting in recipients query of notifications
r2585 .order_by(UserNotification.user_id.asc()).all()]
#302 - basic notification system, models+tests
r1702
@classmethod
notification fixes and improvements
r1703 def create(cls, created_by, subject, body, recipients, type_=None):
if type_ is None:
type_ = Notification.TYPE_MESSAGE
#302 - basic notification system, models+tests
r1702 notification = cls()
Notification system improvements...
r1712 notification.created_by_user = created_by
#302 - basic notification system, models+tests
r1702 notification.subject = subject
notification.body = body
notification fixes and improvements
r1703 notification.type_ = type_
Notification fixes...
r1717 notification.created_on = datetime.datetime.now()
Tests updates, Session refactoring
r1713
#302 - basic notification system, models+tests
r1702 for u in recipients:
Tests updates, Session refactoring
r1713 assoc = UserNotification()
assoc.notification = notification
u.notifications.append(assoc)
Fixed calls to Session in db model...
r2520 Session().add(notification)
#302 - basic notification system, models+tests
r1702 return notification
Notification system improvements...
r1712 @property
def description(self):
from rhodecode.model.notification import NotificationModel
return NotificationModel().make_description(self)
pep8ify
r1800
#302 - basic notification system, models+tests
r1702 class UserNotification(Base, BaseModel):
__tablename__ = 'user_to_notification'
renamed repo groups table...
r1958 __table_args__ = (
UniqueConstraint('user_id', 'notification_id'),
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'}
renamed repo groups table...
r1958 )
user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True)
Tests updates, Session refactoring
r1713 notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True)
notification fixes and improvements
r1703 read = Column('read', Boolean, default=False)
#302 - basic notification system, models+tests
r1702 sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
Tests updates, Session refactoring
r1713 user = relationship('User', lazy="joined")
Notification fixes...
r1717 notification = relationship('Notification', lazy="joined",
fix typo in db models
r1960 order_by=lambda: Notification.created_on.desc(),)
#302 - basic notification system, models+tests
r1702
Notification system improvements...
r1712 def mark_as_read(self):
self.read = True
Fixed calls to Session in db model...
r2520 Session().add(self)
#302 - basic notification system, models+tests
r1702
pep8ify
r1800
Nicolas VINOT
Correct code style
r1593 class DbMigrateVersion(Base, BaseModel):
added current db version into rhodecode,...
r834 __tablename__ = 'db_migrate_version'
Mysql fixes...
r2149 __table_args__ = (
typo fix + code garden
r2356 {'extend_existing': True, 'mysql_engine': 'InnoDB',
Mysql fixes...
r2149 'mysql_charset': 'utf8'},
)
fixes #288...
r1594 repository_id = Column('repository_id', String(250), primary_key=True)
Nicolas VINOT
Correct code style
r1593 repository_path = Column('repository_path', Text)
version = Column('version', Integer)