Changeset - dabdc356393b
[Not reviewed]
default
0 56 0
Thomas De Schampheleire - 11 years ago 2015-03-12 21:09:10
thomas.de.schampheleire@gmail.com
lib: trivial typo fixes
56 files changed with 106 insertions and 106 deletions:
0 comments (0 inline, 0 general)
kallithea/lib/annotate.py
Show inline comments
 
@@ -6,25 +6,25 @@
 
#
 
# 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.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.lib.annotate
 
~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Anontation library for usage in kallithea, previously part of vcs
 
Annotation library for usage in Kallithea, previously part of vcs
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Dec 4, 2011
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import StringIO
 

	
 
from kallithea.lib.vcs.exceptions import VCSError
kallithea/lib/auth.py
Show inline comments
 
@@ -227,25 +227,25 @@ def _cached_perms_data(user_id, user_is_
 
        # user groups
 
        for perm in default_user_group_perms:
 
            u_k = perm.UserUserGroupToPerm.user_group.users_group_name
 
            p = 'usergroup.admin'
 
            permissions[UK][u_k] = p
 
        return permissions
 

	
 
    #==================================================================
 
    # SET DEFAULTS GLOBAL, REPOS, REPOSITORY GROUPS
 
    #==================================================================
 
    uid = user_id
 

	
 
    # default global permissions taken fron the default user
 
    # default global permissions taken from the default user
 
    default_global_perms = UserToPerm.query()\
 
        .filter(UserToPerm.user_id == default_user_id)\
 
        .options(joinedload(UserToPerm.permission))
 

	
 
    for perm in default_global_perms:
 
        permissions[GLOBAL].add(perm.permission.permission_name)
 

	
 
    # defaults for repositories, taken from default user
 
    for perm in default_repo_perms:
 
        r_k = perm.UserRepoToPerm.repository.repo_name
 
        if perm.Repository.private and not (perm.Repository.user_id == uid):
 
            # disable defaults for private repos,
 
@@ -545,25 +545,25 @@ class AuthUser(object):
 
            self.username = 'None'
 

	
 
        log.debug('Auth User is now %s' % self)
 

	
 
    def get_perms(self, user, explicit=True, algo='higherwin', cache=False):
 
        """
 
        Fills user permission attribute with permissions taken from database
 
        works for permissions given for repositories, and for permissions that
 
        are granted to groups
 

	
 
        :param user: instance of User object from database
 
        :param explicit: In case there are permissions both for user and a group
 
            that user is part of, explicit flag will defiine if user will
 
            that user is part of, explicit flag will define if user will
 
            explicitly override permissions from group, if it's False it will
 
            make decision based on the algo
 
        :param algo: algorithm to decide what permission should be choose if
 
            it's multiple defined, eg user in two different groups. It also
 
            decides if explicit flag is turned off how to specify the permission
 
            for case when user is in a group + have defined separate permission
 
        """
 
        user_id = user.user_id
 
        user_is_admin = user.is_admin
 
        user_inherit_default_permissions = user.inherit_default_permissions
 

	
 
        log.debug('Getting PERMISSION tree')
kallithea/lib/auth_modules/__init__.py
Show inline comments
 
@@ -58,25 +58,25 @@ class KallitheaAuthPluginBase(object):
 
        "admin": 'True|False defines if user should be Kallithea super admin',
 
        "active": 'True|False defines active state of user internally for Kallithea',
 
        "active_from_extern": "True|False\None, active state from the external auth, "
 
                              "None means use definition from Kallithea extern_type active value"
 
    }
 

	
 
    @property
 
    def validators(self):
 
        """
 
        Exposes Kallithea validators modules
 
        """
 
        # this is a hack to overcome issues with pylons threadlocals and
 
        # translator object _() not beein registered properly.
 
        # translator object _() not being registered properly.
 
        class LazyCaller(object):
 
            def __init__(self, name):
 
                self.validator_name = name
 

	
 
            def __call__(self, *args, **kwargs):
 
                from kallithea.model import validators as v
 
                obj = getattr(v, self.validator_name)
 
                #log.debug('Initializing lazy formencode object: %s' % obj)
 
                return LazyFormencode(obj, *args, **kwargs)
 

	
 

	
 
        class ProxyGet(object):
 
@@ -121,25 +121,25 @@ class KallitheaAuthPluginBase(object):
 
            return False
 

	
 
        if user and user.extern_type and user.extern_type != plugin_name:
 
            log.debug('User %s should authenticate using %s this is %s, skipping'
 
                      % (user, user.extern_type, plugin_name))
 

	
 
            return False
 
        return True
 

	
 
    def get_user(self, username=None, **kwargs):
 
        """
 
        Helper method for user fetching in plugins, by default it's using
 
        simple fetch by username, but this method can be custimized in plugins
 
        simple fetch by username, but this method can be customized in plugins
 
        eg. container auth plugin to fetch user by environ params
 

	
 
        :param username: username if given to fetch from database
 
        :param kwargs: extra arguments needed for user fetching.
 
        """
 
        user = None
 
        log.debug('Trying to fetch user `%s` from Kallithea database'
 
                  % (username))
 
        if username:
 
            user = User.get_by_username(username)
 
            if not user:
 
                log.debug('Fallback to fetch user in case insensitive mode')
 
@@ -254,25 +254,25 @@ class KallitheaExternalAuthPlugin(Kallit
 

	
 
        :returns: boolean
 
        """
 
        raise NotImplementedError("Not implemented in base class")
 

	
 
    def _authenticate(self, userobj, username, passwd, settings, **kwargs):
 
        auth = super(KallitheaExternalAuthPlugin, self)._authenticate(
 
            userobj, username, passwd, settings, **kwargs)
 
        if auth:
 
            # maybe plugin will clean the username ?
 
            # we should use the return value
 
            username = auth['username']
 
            # if user is not active from our extern type we should fail to authe
 
            # if user is not active from our extern type we should fail to auth
 
            # this can prevent from creating users in Kallithea when using
 
            # external authentication, but if it's inactive user we shouldn't
 
            # create that user anyway
 
            if auth['active_from_extern'] is False:
 
                log.warning("User %s authenticated against %s, but is inactive"
 
                            % (username, self.__module__))
 
                return None
 

	
 
            if self.use_fake_password():
 
                # Randomize the PW because we don't need it, but don't want
 
                # them blank either
 
                passwd = PasswordGenerator().gen_password(length=8)
 
@@ -315,47 +315,47 @@ def importplugin(plugin):
 
        parts = plugin.split(u'.lib.auth_modules.auth_', 1)
 
        if len(parts) == 2:
 
            _module, pn = parts
 
            if pn == EXTERN_TYPE_INTERNAL:
 
                pn = "internal"
 
            plugin = u'kallithea.lib.auth_modules.auth_' + pn
 
    PLUGIN_CLASS_NAME = "KallitheaAuthPlugin"
 
    try:
 
        module = importlib.import_module(plugin)
 
    except (ImportError, TypeError):
 
        log.error(traceback.format_exc())
 
        # TODO: make this more error prone, if by some accident we screw up
 
        # the plugin name, the crash is preatty bad and hard to recover
 
        # the plugin name, the crash is pretty bad and hard to recover
 
        raise
 

	
 
    log.debug("Loaded auth plugin from %s (module:%s, file:%s)"
 
              % (plugin, module.__name__, module.__file__))
 

	
 
    pluginclass = getattr(module, PLUGIN_CLASS_NAME)
 
    if not issubclass(pluginclass, KallitheaAuthPluginBase):
 
        raise TypeError("Authentication class %s.KallitheaAuthPlugin is not "
 
                        "a subclass of %s" % (plugin, KallitheaAuthPluginBase))
 
    return pluginclass
 

	
 

	
 
def loadplugin(plugin):
 
    """
 
    Loads and returns an instantiated authentication plugin.
 

	
 
        see: importplugin
 
    """
 
    plugin = importplugin(plugin)()
 
    if plugin.plugin_settings.im_func != KallitheaAuthPluginBase.plugin_settings.im_func:
 
        raise TypeError("Authentication class %s.KallitheaAuthPluginBase "
 
                        "has overriden the plugin_settings method, which is "
 
                        "has overridden the plugin_settings method, which is "
 
                        "forbidden." % plugin)
 
    return plugin
 

	
 

	
 
def authenticate(username, password, environ=None):
 
    """
 
    Authentication function used for access control,
 
    It tries to authenticate based on enabled authentication modules.
 

	
 
    :param username: username can be empty for container auth
 
    :param password: password can be empty for container auth
 
    :param environ: environ headers passed for container auth
 
@@ -390,25 +390,25 @@ def authenticate(username, password, env
 
                               settings=plugin_settings)
 
        log.debug('Plugin %s extracted user is `%s`' % (module, user))
 
        if not plugin.accepts(user):
 
            log.debug('Plugin %s does not accept user `%s` for authentication'
 
                      % (module, user))
 
            continue
 
        else:
 
            log.debug('Plugin %s accepted user `%s` for authentication'
 
                      % (module, user))
 

	
 
        log.info('Authenticating user using %s plugin' % plugin.__module__)
 
        # _authenticate is a wrapper for .auth() method of plugin.
 
        # it checks if .auth() sends proper data. for KallitheaExternalAuthPlugin
 
        # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin
 
        # it also maps users to Database and maps the attributes returned
 
        # from .auth() to Kallithea database. If this function returns data
 
        # then auth is correct.
 
        plugin_user = plugin._authenticate(user, username, password,
 
                                           plugin_settings,
 
                                           environ=environ or {})
 
        log.debug('PLUGIN USER DATA: %s' % plugin_user)
 

	
 
        if plugin_user:
 
            log.debug('Plugin returned proper authentication data')
 
            return plugin_user
 

	
kallithea/lib/auth_modules/auth_container.py
Show inline comments
 
@@ -109,38 +109,38 @@ class KallitheaAuthPlugin(auth_modules.K
 
            username = environ.get(header)
 
            log.debug('extracted %s:%s' % (header, username))
 

	
 
        if username and str2bool(settings.get('clean_username')):
 
            log.debug('Received username %s from container' % username)
 
            username = self._clean_username(username)
 
            log.debug('New cleanup user is: %s' % username)
 
        return username
 

	
 
    def get_user(self, username=None, **kwargs):
 
        """
 
        Helper method for user fetching in plugins, by default it's using
 
        simple fetch by username, but this method can be custimized in plugins
 
        simple fetch by username, but this method can be customized in plugins
 
        eg. container auth plugin to fetch user by environ params
 
        :param username: username if given to fetch
 
        :param kwargs: extra arguments needed for user fetching.
 
        """
 
        environ = kwargs.get('environ') or {}
 
        settings = kwargs.get('settings') or {}
 
        username = self._get_username(environ, settings)
 
        # we got the username, so use default method now
 
        return super(KallitheaAuthPlugin, self).get_user(username)
 

	
 
    def auth(self, userobj, username, password, settings, **kwargs):
 
        """
 
        Get's the container_auth username (or email). It tries to get username
 
        Gets the container_auth username (or email). It tries to get username
 
        from REMOTE_USER if this plugin is enabled, if that fails
 
        it tries to get username from HTTP_X_FORWARDED_USER if fallback header
 
        is set. clean_username extracts the username from this data if it's
 
        having @ in it.
 
        Return None on failure. On success, return a dictionary of the form:
 

	
 
            see: KallitheaAuthPluginBase.auth_func_attrs
 

	
 
        :param userobj:
 
        :param username:
 
        :param password:
 
        :param settings:
 
@@ -152,26 +152,26 @@ class KallitheaAuthPlugin(auth_modules.K
 
            return None
 

	
 
        if not userobj:
 
            userobj = self.get_user('', environ=environ, settings=settings)
 

	
 
        # we don't care passed username/password for container auth plugins.
 
        # only way to log in is using environ
 
        username = None
 
        if userobj:
 
            username = getattr(userobj, 'username')
 

	
 
        if not username:
 
            # we don't have any objects in DB user doesn't exist extrac username
 
            # from environ based on the settings
 
            # we don't have any objects in DB, user doesn't exist, extract
 
            # username from environ based on the settings
 
            username = self._get_username(environ, settings)
 

	
 
        # if cannot fetch username, it's a no-go for this plugin to proceed
 
        if not username:
 
            return None
 

	
 
        # old attrs fetched from Kallithea database
 
        admin = getattr(userobj, 'admin', False)
 
        active = getattr(userobj, 'active', True)
 
        email = getattr(userobj, 'email', '')
 
        firstname = getattr(userobj, 'firstname', '')
 
        lastname = getattr(userobj, 'lastname', '')
kallithea/lib/auth_modules/auth_internal.py
Show inline comments
 
@@ -45,25 +45,25 @@ class KallitheaAuthPlugin(auth_modules.K
 
        return EXTERN_TYPE_INTERNAL
 

	
 
    def settings(self):
 
        return []
 

	
 
    def user_activation_state(self):
 
        def_user_perms = User.get_default_user().AuthUser.permissions['global']
 
        return 'hg.register.auto_activate' in def_user_perms
 

	
 
    def accepts(self, user, accepts_empty=True):
 
        """
 
        Custom accepts for this auth that doesn't accept empty users. We
 
        know that user exisits in database.
 
        know that user exists in database.
 
        """
 
        return super(KallitheaAuthPlugin, self).accepts(user,
 
                                                        accepts_empty=False)
 

	
 
    def auth(self, userobj, username, password, settings, **kwargs):
 
        if not userobj:
 
            log.debug('userobj was:%s skipping' % (userobj, ))
 
            return None
 
        if userobj.extern_type != self.name:
 
            log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`"
 
                     % (userobj, userobj.extern_type, self.name))
 
            return None
kallithea/lib/base.py
Show inline comments
 
@@ -145,41 +145,41 @@ class BaseVCSController(object):
 
        self.basepath = self.config['base_path']
 
        #authenticate this VCS request using authfunc
 
        self.authenticate = BasicAuth('', auth_modules.authenticate,
 
                                      config.get('auth_ret_code'))
 
        self.ip_addr = '0.0.0.0'
 

	
 
    def _handle_request(self, environ, start_response):
 
        raise NotImplementedError()
 

	
 
    def _get_by_id(self, repo_name):
 
        """
 
        Gets a special pattern _<ID> from clone url and tries to replace it
 
        with a repository_name for support of _<ID> non changable urls
 
        with a repository_name for support of _<ID> non changeable urls
 

	
 
        :param repo_name:
 
        """
 

	
 
        data = repo_name.split('/')
 
        if len(data) >= 2:
 
            from kallithea.lib.utils import get_repo_by_id
 
            by_id_match = get_repo_by_id(repo_name)
 
            if by_id_match:
 
                data[1] = by_id_match
 

	
 
        return '/'.join(data)
 

	
 
    def _invalidate_cache(self, repo_name):
 
        """
 
        Set's cache for this repository for invalidation on next access
 
        Sets cache for this repository for invalidation on next access
 

	
 
        :param repo_name: full repo name, also a cache key
 
        """
 
        ScmModel().mark_for_invalidation(repo_name)
 

	
 
    def _check_permission(self, action, user, repo_name, ip_addr=None):
 
        """
 
        Checks permissions using action (push/pull) user and repository
 
        name
 

	
 
        :param action: push or pull action
 
        :param user: user instance
kallithea/lib/caching_query.py
Show inline comments
 
@@ -115,25 +115,25 @@ def query_callable(manager, query_cls=Ca
 

	
 

	
 
def get_cache_region(name, region):
 
    if region not in beaker.cache.cache_regions:
 
        raise BeakerException('Cache region `%s` not configured '
 
            'Check if proper cache settings are in the .ini files' % region)
 
    kw = beaker.cache.cache_regions[region]
 
    return beaker.cache.Cache._get_cache(name, kw)
 

	
 

	
 
def _get_cache_parameters(query):
 
    """For a query with cache_region and cache_namespace configured,
 
    return the correspoinding Cache instance and cache key, based
 
    return the corresponding Cache instance and cache key, based
 
    on this query's current criterion and parameter values.
 

	
 
    """
 
    if not hasattr(query, '_cache_parameters'):
 
        raise ValueError("This Query does not have caching "
 
                         "parameters configured.")
 

	
 
    region, namespace, cache_key = query._cache_parameters
 

	
 
    namespace = _namespace_from_query(namespace, query)
 

	
 
    if cache_key is None:
kallithea/lib/celerylib/tasks.py
Show inline comments
 
@@ -201,25 +201,25 @@ def get_commits_stats(repo_name, ts_min_
 

	
 
        if not co_day_auth_aggr:
 
            co_day_auth_aggr[akc(repo.contact)] = {
 
                "label": akc(repo.contact),
 
                "data": [0, 1],
 
                "schema": ["commits"],
 
            }
 

	
 
        stats = cur_stats if cur_stats else Statistics()
 
        stats.commit_activity = json.dumps(co_day_auth_aggr)
 
        stats.commit_activity_combined = json.dumps(overview_data)
 

	
 
        log.debug('last revison %s' % last_rev)
 
        log.debug('last revision %s' % last_rev)
 
        leftovers = len(repo.revisions[last_rev:])
 
        log.debug('revisions to parse %s' % leftovers)
 

	
 
        if last_rev == 0 or leftovers < parse_limit:
 
            log.debug('getting code trending stats')
 
            stats.languages = json.dumps(__get_codes_stats(repo_name))
 

	
 
        try:
 
            stats.repository = dbrepo
 
            stats.stat_on_revision = last_cs.revision if last_cs else 0
 
            DBS.add(stats)
 
            DBS.commit()
kallithea/lib/compat.py
Show inline comments
 
@@ -421,25 +421,25 @@ except ImportError:
 
try:
 
    from io import BytesIO
 
except ImportError:
 
    from cStringIO import StringIO as BytesIO
 

	
 

	
 
#==============================================================================
 
# bytes
 
#==============================================================================
 
if __py_version__ >= (2, 6):
 
    _bytes = bytes
 
else:
 
    # in py2.6 bytes is a synonim for str
 
    # in py2.6 bytes is a synonym for str
 
    _bytes = str
 

	
 
if __py_version__ >= (2, 6):
 
    _bytearray = bytearray
 
else:
 
    import array
 
    # no idea if this is correct but all integration tests are passing
 
    # i think we never use bytearray anyway
 
    _bytearray = array
 

	
 

	
 
#==============================================================================
kallithea/lib/db_manage.py
Show inline comments
 
@@ -393,25 +393,25 @@ class DbManage(object):
 
            default = UserRepoGroupToPerm.query()\
 
                .filter(UserRepoGroupToPerm.group == g)\
 
                .filter(UserRepoGroupToPerm.user == def_usr)\
 
                .scalar()
 

	
 
            if default is None:
 
                log.debug('missing default permission for group %s adding' % g)
 
                perm_obj = RepoGroupModel()._create_default_perms(g)
 
                self.sa.add(perm_obj)
 

	
 
    def reset_permissions(self, username):
 
        """
 
        Resets permissions to default state, usefull when old systems had
 
        Resets permissions to default state, useful when old systems had
 
        bad permissions, we must clean them up
 

	
 
        :param username:
 
        """
 
        default_user = User.get_by_username(username)
 
        if not default_user:
 
            return
 

	
 
        u2p = UserToPerm.query()\
 
            .filter(UserToPerm.user == default_user).all()
 
        fixed = False
 
        if len(u2p) != len(Permission.DEFAULT_USER_PERMISSIONS):
 
@@ -525,26 +525,26 @@ class DbManage(object):
 
                                     firstname='Kallithea', lastname='Admin',
 
                                     active=True, admin=admin,
 
                                     extern_type=EXTERN_TYPE_INTERNAL)
 

	
 
    def create_default_user(self):
 
        log.info('creating default user')
 
        # create default user for handling default permissions.
 
        user = UserModel().create_or_update(username=User.DEFAULT_USER,
 
                                            password=str(uuid.uuid1())[:20],
 
                                            email='anonymous@kallithea-scm.org',
 
                                            firstname='Anonymous',
 
                                            lastname='User')
 
        # based on configuration options activate/deactive this user which
 
        # controlls anonymous access
 
        # based on configuration options activate/deactivate this user which
 
        # controls anonymous access
 
        if self.cli_args.get('public_access') is False:
 
            log.info('Public access disabled')
 
            user.active = False
 
            Session().add(user)
 
            Session().commit()
 

	
 
    def create_permissions(self):
 
        """
 
        Creates all permissions defined in the system
 
        """
 
        # module.(access|create|change|delete)_[name]
 
        # module.(none|read|write|admin)
kallithea/lib/dbmigrate/migrate/changeset/constraint.py
Show inline comments
 
@@ -29,39 +29,39 @@ class ConstraintChangeset(object):
 
        engine = kw.pop('engine', self.table.bind)
 
        from kallithea.lib.dbmigrate.migrate.changeset.databases.visitor import (get_engine_visitor,
 
                                                                                 run_single_visitor)
 
        visitorcallable = get_engine_visitor(engine, visitor_name)
 
        run_single_visitor(engine, visitorcallable, self, *a, **kw)
 

	
 
    def create(self, *a, **kw):
 
        """Create the constraint in the database.
 

	
 
        :param engine: the database engine to use. If this is \
 
        :keyword:`None` the instance's engine will be used
 
        :type engine: :class:`sqlalchemy.engine.base.Engine`
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 
        """
 
        # TODO: set the parent here instead of in __init__
 
        self.__do_imports('constraintgenerator', *a, **kw)
 

	
 
    def drop(self, *a, **kw):
 
        """Drop the constraint from the database.
 

	
 
        :param engine: the database engine to use. If this is
 
          :keyword:`None` the instance's engine will be used
 
        :param cascade: Issue CASCADE drop if database supports it
 
        :type engine: :class:`sqlalchemy.engine.base.Engine`
 
        :type cascade: bool
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 
        :returns: Instance with cleared columns
 
        """
 
        self.cascade = kw.pop('cascade', False)
 
        self.__do_imports('constraintdropper', *a, **kw)
 
        # the spirit of Constraint objects is that they
 
        # are immutable (just like in a DB.  they're only ADDed
 
        # or DROPped).
 
        #self.columns.clear()
 
        return self
 

	
 

	
kallithea/lib/dbmigrate/migrate/changeset/databases/firebird.py
Show inline comments
 
@@ -60,33 +60,33 @@ class FBSchemaChanger(ansisql.ANSISchema
 
            "Firebird does not support renaming tables.")
 

	
 
    def _visit_column_name(self, table, column, delta):
 
        self.start_alter_table(table)
 
        col_name = self.preparer.quote(delta.current_name, table.quote)
 
        new_name = self.preparer.format_column(delta.result_column)
 
        self.append('ALTER COLUMN %s TO %s' % (col_name, new_name))
 

	
 
    def _visit_column_nullable(self, table, column, delta):
 
        """Changing NULL is not supported"""
 
        # TODO: http://www.firebirdfaq.org/faq103/
 
        raise exceptions.NotSupportedError(
 
            "Firebird does not support altering NULL bevahior.")
 
            "Firebird does not support altering NULL behavior.")
 

	
 

	
 
class FBConstraintGenerator(ansisql.ANSIConstraintGenerator):
 
    """Firebird constraint generator implementation."""
 

	
 

	
 
class FBConstraintDropper(ansisql.ANSIConstraintDropper):
 
    """Firebird constaint dropper implementation."""
 
    """Firebird constraint dropper implementation."""
 

	
 
    def cascade_constraint(self, constraint):
 
        """Cascading constraints is not supported"""
 
        raise exceptions.NotSupportedError(
 
            "Firebird does not support cascading constraints")
 

	
 

	
 
class FBDialect(ansisql.ANSIDialect):
 
    columngenerator = FBColumnGenerator
 
    columndropper = FBColumnDropper
 
    schemachanger = FBSchemaChanger
 
    constraintgenerator = FBConstraintGenerator
kallithea/lib/dbmigrate/migrate/changeset/databases/postgres.py
Show inline comments
 
@@ -22,22 +22,22 @@ class PGColumnDropper(ansisql.ANSIColumn
 

	
 
class PGSchemaChanger(ansisql.ANSISchemaChanger):
 
    """PostgreSQL schema changer implementation."""
 
    pass
 

	
 

	
 
class PGConstraintGenerator(ansisql.ANSIConstraintGenerator):
 
    """PostgreSQL constraint generator implementation."""
 
    pass
 

	
 

	
 
class PGConstraintDropper(ansisql.ANSIConstraintDropper):
 
    """PostgreSQL constaint dropper implementation."""
 
    """PostgreSQL constraint dropper implementation."""
 
    pass
 

	
 

	
 
class PGDialect(ansisql.ANSIDialect):
 
    columngenerator = PGColumnGenerator
 
    columndropper = PGColumnDropper
 
    schemachanger = PGSchemaChanger
 
    constraintgenerator = PGConstraintGenerator
 
    constraintdropper = PGConstraintDropper
kallithea/lib/dbmigrate/migrate/changeset/schema.py
Show inline comments
 
@@ -421,44 +421,44 @@ class ChangesetTable(object):
 
        :type column: Column instance or string
 
        """
 
        if not isinstance(column, sqlalchemy.Column):
 
            # It's a column name
 
            column = getattr(self.c, str(column))
 
        column.create(table=self, *p, **kw)
 

	
 
    def drop_column(self, column, *p, **kw):
 
        """Drop a column, given its name or definition.
 

	
 
        API to :meth:`ChangesetColumn.drop`
 

	
 
        :param column: Column to be droped
 
        :param column: Column to be dropped
 
        :type column: Column instance or string
 
        """
 
        if not isinstance(column, sqlalchemy.Column):
 
            # It's a column name
 
            try:
 
                column = getattr(self.c, str(column))
 
            except AttributeError:
 
                # That column isn't part of the table. We don't need
 
                # its entire definition to drop the column, just its
 
                # name, so create a dummy column with the same name.
 
                column = sqlalchemy.Column(str(column), sqlalchemy.Integer())
 
        column.drop(table=self, *p, **kw)
 

	
 
    def rename(self, name, connection=None, **kwargs):
 
        """Rename this table.
 

	
 
        :param name: New name of the table.
 
        :type name: string
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 
        """
 
        engine = self.bind
 
        self.new_name = name
 
        visitorcallable = get_engine_visitor(engine, 'schemachanger')
 
        run_single_visitor(engine, visitorcallable, self, connection, **kwargs)
 

	
 
        # Fix metadata registration
 
        self.name = name
 
        self.deregister()
 
        self._set_parent(self.metadata)
 

	
 
@@ -496,25 +496,25 @@ class ChangesetColumn(object):
 

	
 
        Assumes the given table exists. ``ALTER TABLE ADD COLUMN``,
 
        for most databases.
 

	
 
        :param table: Table instance to create on.
 
        :param index_name: Creates :class:`ChangesetIndex` on this column.
 
        :param unique_name: Creates :class:\
 
`~migrate.changeset.constraint.UniqueConstraint` on this column.
 
        :param primary_key_name: Creates :class:\
 
`~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
 
        :param populate_default: If True, created column will be \
 
populated with defaults
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type table: Table instance
 
        :type index_name: string
 
        :type unique_name: string
 
        :type primary_key_name: string
 
        :type populate_default: bool
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 

	
 
        :returns: self
 
        """
 
        self.populate_default = populate_default
 
        self.index_name = index_name
 
        self.unique_name = unique_name
 
@@ -530,25 +530,25 @@ populated with defaults
 
        # TODO: reuse existing connection
 
        if self.populate_default and self.default is not None:
 
            stmt = table.update().values({self: engine._execute_default(self.default)})
 
            engine.execute(stmt)
 

	
 
        return self
 

	
 
    def drop(self, table=None, connection=None, **kwargs):
 
        """Drop this column from the database, leaving its table intact.
 

	
 
        ``ALTER TABLE DROP COLUMN``, for most databases.
 

	
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 
        """
 
        if table is not None:
 
            self.table = table
 
        engine = self.table.bind
 
        visitorcallable = get_engine_visitor(engine, 'columndropper')
 
        engine._run_visitor(visitorcallable, self, connection, **kwargs)
 
        self.remove_from_table(self.table, unset_table=False)
 
        self.table = None
 
        return self
 

	
 
    def add_to_table(self, table):
 
@@ -624,25 +624,25 @@ populated with defaults
 

	
 

	
 
class ChangesetIndex(object):
 
    """Changeset extensions to SQLAlchemy Indexes."""
 

	
 
    __visit_name__ = 'index'
 

	
 
    def rename(self, name, connection=None, **kwargs):
 
        """Change the name of an index.
 

	
 
        :param name: New name of the Index.
 
        :type name: string
 
        :param connection: reuse connection istead of creating new one.
 
        :param connection: reuse connection instead of creating new one.
 
        :type connection: :class:`sqlalchemy.engine.base.Connection` instance
 
        """
 
        engine = self.table.bind
 
        self.new_name = name
 
        visitorcallable = get_engine_visitor(engine, 'schemachanger')
 
        engine._run_visitor(visitorcallable, self, connection, **kwargs)
 
        self.name = name
 

	
 

	
 
class ChangesetDefaultClause(object):
 
    """Implements comparison between :class:`DefaultClause` instances"""
 

	
kallithea/lib/dbmigrate/migrate/versioning/script/py.py
Show inline comments
 
@@ -111,25 +111,25 @@ class PythonScript(base.BaseScript):
 
        args['engine_arg_executor'] = lambda s, p = '': buf.write(str(s) + p)
 

	
 
        @with_engine
 
        def go(url, step, **kw):
 
            engine = kw.pop('engine')
 
            self.run(engine, step)
 
            return buf.getvalue()
 

	
 
        return go(url, step, **args)
 

	
 
    def run(self, engine, step):
 
        """Core method of Script file.
 
        Exectues :func:`update` or :func:`downgrade` functions
 
        Executes :func:`update` or :func:`downgrade` functions
 

	
 
        :param engine: SQLAlchemy Engine
 
        :param step: Operation to run
 
        :type engine: string
 
        :type step: int
 
        """
 
        if step > 0:
 
            op = 'upgrade'
 
        elif step < 0:
 
            op = 'downgrade'
 
        else:
 
            raise ScriptError("%d is not a valid step" % step)
kallithea/lib/dbmigrate/migrate/versioning/shell.py
Show inline comments
 
@@ -49,25 +49,25 @@ class PassiveOptionParser(OptionParser):
 
                    del rargs[0]
 
                else:
 
                    self._process_long_opt(rargs, values)
 
            elif arg[:1] == "-" and len(arg) > 1:
 
                self._process_short_opts(rargs, values)
 
            elif self.allow_interspersed_args:
 
                largs.append(arg)
 
                del rargs[0]
 

	
 
def main(argv=None, **kwargs):
 
    """Shell interface to :mod:`migrate.versioning.api`.
 

	
 
    kwargs are default options that can be overriden with passing
 
    kwargs are default options that can be overridden with passing
 
    --some_option as command line option
 

	
 
    :param disable_logging: Let migrate configure logging
 
    :type disable_logging: bool
 
    """
 
    if argv is not None:
 
        argv = argv
 
    else:
 
        argv = list(sys.argv[1:])
 
    commands = list(api.__all__)
 
    commands.sort()
 

	
kallithea/lib/dbmigrate/schema/db_1_1_0.py
Show inline comments
 
@@ -14,25 +14,25 @@ class BaseModel(object):
 
        return class_mapper(cls).c.keys()
 

	
 
    def get_dict(self):
 
        """return dict with keys and values corresponding
 
        to this model data """
 

	
 
        d = {}
 
        for k in self._get_keys():
 
            d[k] = getattr(self, k)
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
kallithea/lib/dbmigrate/schema/db_1_2_0.py
Show inline comments
 
@@ -79,44 +79,44 @@ class ModelSerializer(json.JSONEncoder):
 
                            value=self.value)
 

	
 
    """
 

	
 
    def default(self, obj):
 

	
 
        if hasattr(obj, '__json__'):
 
            return obj.__json__()
 
        else:
 
            return json.JSONEncoder.default(self, obj)
 

	
 
class BaseModel(object):
 
    """Base Model for all classess
 
    """Base Model for all classes
 

	
 
    """
 

	
 
    @classmethod
 
    def _get_keys(cls):
 
        """return column names for this model """
 
        return class_mapper(cls).c.keys()
 

	
 
    def get_dict(self):
 
        """return dict with keys and values corresponding
 
        to this model data """
 

	
 
        d = {}
 
        for k in self._get_keys():
 
            d[k] = getattr(self, k)
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -775,25 +775,25 @@ class Group(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return Group.query().filter(Group.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_3_0.py
Show inline comments
 
@@ -109,25 +109,25 @@ class BaseModel(object):
 
        to this model data """
 

	
 
        d = {}
 
        for k in self._get_keys():
 
            d[k] = getattr(self, k)
 

	
 
        # also use __json__() if present to get additional fields
 
        for k, val in getattr(self, '__json__', lambda: {})().iteritems():
 
            d[k] = val
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -803,25 +803,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_4_0.py
Show inline comments
 
@@ -86,25 +86,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1071,25 +1071,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_5_0.py
Show inline comments
 
@@ -85,25 +85,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1090,25 +1090,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_5_2.py
Show inline comments
 
@@ -87,25 +87,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1211,25 +1211,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_6_0.py
Show inline comments
 
@@ -87,25 +87,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1286,25 +1286,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_7_0.py
Show inline comments
 
@@ -87,25 +87,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1304,25 +1304,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_1_8_0.py
Show inline comments
 
@@ -87,25 +87,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1334,25 +1334,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_0_0.py
Show inline comments
 
@@ -88,25 +88,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1391,25 +1391,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_0_1.py
Show inline comments
 
@@ -88,25 +88,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1392,25 +1392,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_0_2.py
Show inline comments
 
@@ -88,25 +88,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1413,25 +1413,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_1_0.py
Show inline comments
 
@@ -88,25 +88,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1452,25 +1452,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_2_0.py
Show inline comments
 
@@ -89,25 +89,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1502,25 +1502,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/dbmigrate/schema/db_2_2_3.py
Show inline comments
 
@@ -89,25 +89,25 @@ class BaseModel(object):
 

	
 
        # also use __json__() if present to get additional fields
 
        _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
 
        return d
 

	
 
    def get_appstruct(self):
 
        """return list with keys and values tupples corresponding
 
        """return list with keys and values tuples corresponding
 
        to this model data """
 

	
 
        l = []
 
        for k in self._get_keys():
 
            l.append((k, getattr(self, k),))
 
        return l
 

	
 
    def populate_obj(self, populate_dict):
 
        """populate model with data from given populate_dict"""
 

	
 
        for k in self._get_keys():
 
            if k in populate_dict:
 
@@ -1529,25 +1529,25 @@ class RepoGroup(Base, BaseModel):
 
        if self.parent_group is None:
 
            return groups
 
        cur_gr = self.parent_group
 
        groups.insert(0, cur_gr)
 
        cnt = 0
 
        while 1:
 
            cnt += 1
 
            gr = getattr(cur_gr, 'parent_group', None)
 
            cur_gr = cur_gr.parent_group
 
            if gr is None:
 
                break
 
            if cnt == parents_recursion_limit:
 
                # this will prevent accidental infinit loops
 
                # this will prevent accidental infinite loops
 
                log.error('group nested more than %s' %
 
                          parents_recursion_limit)
 
                break
 

	
 
            groups.insert(0, gr)
 
        return groups
 

	
 
    @property
 
    def children(self):
 
        return RepoGroup.query().filter(RepoGroup.parent_group == self)
 

	
 
    @property
kallithea/lib/diffs.py
Show inline comments
 
@@ -193,25 +193,25 @@ class DiffProcessor(object):
 
        (?:^\+\+\+[ ](b/(?P<b_file>.+?)|/dev/null)\t?(?:\n|$))?
 
    """, re.VERBOSE | re.MULTILINE)
 

	
 
    #used for inline highlighter word split
 
    _token_re = re.compile(r'()(&gt;|&lt;|&amp;|<u>\t</u>| <i></i>|\W+?)')
 

	
 
    _escape_re = re.compile(r'(&)|(<)|(>)|(\t)|(\r)|(?<=.)( \n| $)')
 

	
 

	
 
    def __init__(self, diff, vcs='hg', format='gitdiff', diff_limit=None):
 
        """
 
        :param diff:   a text in diff format
 
        :param vcs: type of version controll hg or git
 
        :param vcs: type of version control hg or git
 
        :param format: format of diff passed, `udiff` or `gitdiff`
 
        :param diff_limit: define the size of diff that is considered "big"
 
            based on that parameter cut off will be triggered, set to None
 
            to show full diff
 
        """
 
        if not isinstance(diff, basestring):
 
            raise Exception('Diff must be a basestring got %s instead' % type(diff))
 

	
 
        self._diff = diff
 
        self._format = format
 
        self.adds = 0
 
        self.removes = 0
kallithea/lib/graphmod.py
Show inline comments
 
@@ -109,25 +109,25 @@ def _colored(repo, dag):
 

	
 
        # Compute row and nextrow
 
        if rev not in row:
 
            row.append(rev)  # new head
 
            colors[rev] = newcolor
 
            newcolor += 1
 

	
 
        col = row.index(rev)
 
        addparents = [p for p in dagparents if p not in row]
 

	
 
        # Add unknown parents to nextrow
 
        tmprow = row[:]
 
        tmprow[col:col + 1] = reversed(addparents) # higest revs first (to the right), dead ends last (to the left)
 
        tmprow[col:col + 1] = reversed(addparents) # highest revs first (to the right), dead ends last (to the left)
 
        # Stop looking for non-existing ancestors
 
        nextrow = []
 
        for r in tmprow:
 
            if r > nullrev or r in dagparents:
 
                nextrow.append(r)
 
            else:
 
                colors.pop(r)
 

	
 
        # Set colors for the parents
 
        color = colors.pop(rev)
 
        if addparents:
 
            b = branch(rev)
kallithea/lib/helpers.py
Show inline comments
 
@@ -115,25 +115,25 @@ def _reset(name, value=None, id=NotGiven
 
    """
 
    _set_input_attrs(attrs, type, name, value)
 
    _set_id_attr(attrs, id, name)
 
    convert_boolean_attrs(attrs, ["disabled"])
 
    return HTML.input(**attrs)
 

	
 
reset = _reset
 
safeid = _make_safe_id_component
 

	
 

	
 
def FID(raw_id, path):
 
    """
 
    Creates a uniqe ID for filenode based on it's hash of path and revision
 
    Creates a unique ID for filenode based on it's hash of path and revision
 
    it's safe to use in urls
 

	
 
    :param raw_id:
 
    :param path:
 
    """
 

	
 
    return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
 

	
 

	
 
def get_token():
 
    """Return the current authentication token, creating one if one doesn't
 
    already exist.
 
@@ -954,25 +954,25 @@ class Page(_Page):
 
            nav_items.append(self._pagerlink(self.first_page, self.first_page))
 

	
 
        # Insert dots if there are pages between the first page
 
        # and the currently displayed page range
 
        if leftmost_page - self.first_page > 1:
 
            # Wrap in a SPAN tag if nolink_attr is set
 
            text = '..'
 
            if self.dotdot_attr:
 
                text = HTML.span(c=text, **self.dotdot_attr)
 
            nav_items.append(text)
 

	
 
        for thispage in xrange(leftmost_page, rightmost_page + 1):
 
            # Hilight the current page number and do not use a link
 
            # Highlight the current page number and do not use a link
 
            if thispage == self.page:
 
                text = '%s' % (thispage,)
 
                # Wrap in a SPAN tag if nolink_attr is set
 
                if self.curpage_attr:
 
                    text = HTML.span(c=text, **self.curpage_attr)
 
                nav_items.append(text)
 
            # Otherwise create just a link to that page
 
            else:
 
                text = '%s' % (thispage,)
 
                nav_items.append(self._pagerlink(thispage, text))
 

	
 
        # Insert dots if there are pages between the displayed
 
@@ -1253,25 +1253,25 @@ def fancy_file_stats(stats):
 

	
 
    d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
 
        cgen('a', a_v, d_v), a_p, a_v
 
    )
 
    d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
 
        cgen('d', a_v, d_v), d_p, d_v
 
    )
 
    return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
 

	
 

	
 
def urlify_text(text_, safe=True):
 
    """
 
    Extrac urls from text and make html links out of them
 
    Extract urls from text and make html links out of them
 

	
 
    :param text_:
 
    """
 

	
 
    def url_func(match_obj):
 
        url_full = match_obj.groups()[0]
 
        return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
 
    _newtext = url_re.sub(url_func, text_)
 
    if safe:
 
        return literal(_newtext)
 
    return _newtext
 

	
kallithea/lib/hooks.py
Show inline comments
 
@@ -6,25 +6,25 @@
 
#
 
# 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.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.lib.hooks
 
~~~~~~~~~~~~~~~~~~~
 

	
 
Hooks runned by kallithea
 
Hooks run by Kallithea
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Aug 6, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import os
 
import sys
 
import time
 
@@ -368,27 +368,27 @@ def log_delete_user(user_dict, deleted_b
 

	
 
    return 0
 

	
 

	
 
handle_git_pre_receive = (lambda repo_path, revs, env:
 
    handle_git_receive(repo_path, revs, env, hook_type='pre'))
 
handle_git_post_receive = (lambda repo_path, revs, env:
 
    handle_git_receive(repo_path, revs, env, hook_type='post'))
 

	
 

	
 
def handle_git_receive(repo_path, revs, env, hook_type='post'):
 
    """
 
    A really hacky method that is runned by git post-receive hook and logs
 
    A really hacky method that is run by git post-receive hook and logs
 
    an push action together with pushed revisions. It's executed by subprocess
 
    thus needs all info to be able to create a on the fly pylons enviroment,
 
    thus needs all info to be able to create a on the fly pylons environment,
 
    connect to database and run the logging code. Hacky as sh*t but works.
 

	
 
    :param repo_path:
 
    :param revs:
 
    :param env:
 
    """
 
    from paste.deploy import appconfig
 
    from sqlalchemy import engine_from_config
 
    from kallithea.config.environment import load_environment
 
    from kallithea.model import init_model
 
    from kallithea.model.db import Ui
 
    from kallithea.lib.utils import make_ui
kallithea/lib/ipaddr.py
Show inline comments
 
@@ -724,25 +724,25 @@ class _BaseNet(_IPAddrBase):
 
                IPNetwork('::8/125'),
 
                ...
 
                IPNetwork('0:0:8000::/33')]
 

	
 
        Args:
 
            other: An IPvXNetwork object of the same type.
 

	
 
        Returns:
 
            A sorted list of IPvXNetwork objects addresses which is self
 
            minus other.
 

	
 
        Raises:
 
            TypeError: If self and other are of difffering address
 
            TypeError: If self and other are of differing address
 
              versions, or if other is not a network object.
 
            ValueError: If other is not completely contained by self.
 

	
 
        """
 
        if not self._version == other._version:
 
            raise TypeError("%s and %s are not of the same version" % (
 
                str(self), str(other)))
 

	
 
        if not isinstance(other, _BaseNet):
 
            raise TypeError("%s is not a network object" % str(other))
 

	
 
        if other not in self:
kallithea/lib/markup_renderer.py
Show inline comments
 
@@ -142,25 +142,25 @@ class MarkupRenderer(object):
 
        source = safe_unicode(source)
 
        try:
 
            import markdown as __markdown
 
            if flavored:
 
                source = cls._flavored_markdown(source)
 
            return __markdown.markdown(source, ['codehilite', 'extra'])
 
        except ImportError:
 
            log.warning('Install markdown to use this function')
 
            return cls.plain(source)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            if safe:
 
                log.debug('Fallbacking to render in plain mode')
 
                log.debug('Falling back to render in plain mode')
 
                return cls.plain(source)
 
            else:
 
                raise
 

	
 
    @classmethod
 
    def rst(cls, source, safe=True):
 
        source = safe_unicode(source)
 
        try:
 
            from docutils.core import publish_parts
 
            from docutils.parsers.rst import directives
 
            docutils_settings = dict([(alias, None) for alias in
 
                                cls.RESTRUCTUREDTEXT_DISALLOWED_DIRECTIVES])
 
@@ -173,25 +173,25 @@ class MarkupRenderer(object):
 

	
 
            parts = publish_parts(source=source,
 
                                  writer_name="html4css1",
 
                                  settings_overrides=docutils_settings)
 

	
 
            return parts['html_title'] + parts["fragment"]
 
        except ImportError:
 
            log.warning('Install docutils to use this function')
 
            return cls.plain(source)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            if safe:
 
                log.debug('Fallbacking to render in plain mode')
 
                log.debug('Falling back to render in plain mode')
 
                return cls.plain(source)
 
            else:
 
                raise
 

	
 
    @classmethod
 
    def rst_with_mentions(cls, source):
 
        mention_pat = re.compile(MENTIONS_REGEX)
 

	
 
        def wrapp(match_obj):
 
            uname = match_obj.groups()[0]
 
            return ' **@%(uname)s** ' % {'uname': uname}
 
        mention_hl = mention_pat.sub(wrapp, source).strip()
kallithea/lib/middleware/wrapper.py
Show inline comments
 
@@ -6,25 +6,25 @@
 
#
 
# 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.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.lib.middleware.wrapper
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
request time mesuring app
 
request time measuring app
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: May 23, 2013
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import time
 
import logging
 
from kallithea.lib.base import _get_ip_addr, _get_access_path
kallithea/lib/pidlock.py
Show inline comments
 
@@ -45,25 +45,25 @@ class DaemonLock(object):
 
        self.desc = desc
 
        self.debug = debug
 
        self.held = False
 
        #run the lock automatically !
 
        self.lock()
 
        self._finalize = Finalize(self, DaemonLock._on_finalize,
 
                                  args=(self, debug), exitpriority=10)
 

	
 
    @staticmethod
 
    def _on_finalize(lock, debug):
 
        if lock.held:
 
            if debug:
 
                print 'leck held finilazing and running lock.release()'
 
                print 'lock held finalizing and running lock.release()'
 
            lock.release()
 

	
 
    def lock(self):
 
        """
 
        locking function, if lock is present it
 
        will raise LockHeld exception
 
        """
 
        lockname = '%s' % (os.getpid())
 
        if self.debug:
 
            print 'running lock'
 
        self.trylock()
 
        self.makelock(lockname, self.pidfile)
 
@@ -121,24 +121,24 @@ class DaemonLock(object):
 
                print 'removing pidfile %s' % self.pidfile
 
            os.remove(self.pidfile)
 
            self.held = False
 
        except OSError, e:
 
            if self.debug:
 
                print 'removing pidfile failed %s' % e
 
            pass
 

	
 
    def makelock(self, lockname, pidfile):
 
        """
 
        this function will make an actual lock
 

	
 
        :param lockname: acctual pid of file
 
        :param lockname: actual pid of file
 
        :param pidfile: the file to write the pid in
 
        """
 
        if self.debug:
 
            print 'creating a file %s and pid: %s' % (pidfile, lockname)
 

	
 
        dir_, file_ = os.path.split(pidfile)
 
        if not os.path.isdir(dir_):
 
            os.makedirs(dir_)
 
        with open(self.pidfile, 'wb') as f:
 
            f.write(lockname)
 
        self.held = True
kallithea/lib/profiler.py
Show inline comments
 
@@ -18,25 +18,25 @@ class ProfilingMiddleware(object):
 
    def __call__(self, environ, start_response):
 
        with self.lock:
 
            profiler = cProfile.Profile()
 

	
 
            def run_app(*a, **kw):
 
                self.response = self.app(environ, start_response)
 

	
 
            profiler.runcall(run_app, environ, start_response)
 

	
 
            profiler.snapshot_stats()
 

	
 
            stats = pstats.Stats(profiler)
 
            stats.sort_stats('calls') #cummulative
 
            stats.sort_stats('calls') #cumulative
 

	
 
            # Redirect output
 
            out = StringIO()
 
            stats.stream = out
 

	
 
            stats.print_stats()
 

	
 
            resp = ''.join(self.response)
 

	
 
            # Lets at least only put this on html-like responses.
 
            if resp.strip().startswith('<'):
 
                ## The profiling info is just appended to the response.
kallithea/lib/utils2.py
Show inline comments
 
@@ -107,25 +107,25 @@ def aslist(obj, sep=None, strip=True):
 
            lst = [v.strip() for v in lst]
 
        return lst
 
    elif isinstance(obj, (list, tuple)):
 
        return obj
 
    elif obj is None:
 
        return []
 
    else:
 
        return [obj]
 

	
 

	
 
def convert_line_endings(line, mode):
 
    """
 
    Converts a given line  "line end" accordingly to given mode
 
    Converts a given line  "line end" according to given mode
 

	
 
    Available modes are::
 
        0 - Unix
 
        1 - Mac
 
        2 - DOS
 

	
 
    :param line: given line to convert
 
    :param mode: mode to convert to
 
    :rtype: str
 
    :return: converted line according to mode
 
    """
 
    from string import replace
kallithea/lib/vcs/backends/base.py
Show inline comments
 
@@ -56,25 +56,25 @@ class BaseRepository(object):
 
    """
 
    scm = None
 
    DEFAULT_BRANCH_NAME = None
 
    EMPTY_CHANGESET = '0' * 40
 

	
 
    def __init__(self, repo_path, create=False, **kwargs):
 
        """
 
        Initializes repository. Raises RepositoryError if repository could
 
        not be find at the given ``repo_path`` or directory at ``repo_path``
 
        exists and ``create`` is set to True.
 

	
 
        :param repo_path: local path of the repository
 
        :param create=False: if set to True, would try to craete repository.
 
        :param create=False: if set to True, would try to create repository.
 
        :param src_url=None: if set, should be proper url from which repository
 
          would be cloned; requires ``create`` parameter to be set to True -
 
          raises RepositoryError if src_url is set and create evaluates to
 
          False
 
        """
 
        raise NotImplementedError
 

	
 
    def __str__(self):
 
        return '<%s at %s>' % (self.__class__.__name__, self.path)
 

	
 
    def __repr__(self):
 
        return self.__str__()
 
@@ -624,25 +624,25 @@ class BaseChangeset(object):
 
        """
 
        raise NotImplementedError
 

	
 
    @LazyProperty
 
    def size(self):
 
        """
 
        Returns total number of bytes from contents of all filenodes.
 
        """
 
        return sum((node.size for node in self.get_filenodes_generator()))
 

	
 
    def walk(self, topurl=''):
 
        """
 
        Similar to os.walk method. Insted of filesystem it walks through
 
        Similar to os.walk method. Instead of filesystem it walks through
 
        changeset starting at given ``topurl``.  Returns generator of tuples
 
        (topnode, dirnodes, filenodes).
 
        """
 
        topnode = self.get_node(topurl)
 
        yield (topnode, topnode.dirs, topnode.files)
 
        for dirnode in topnode.dirs:
 
            for tup in self.walk(dirnode.path):
 
                yield tup
 

	
 
    def get_filenodes_generator(self):
 
        """
 
        Returns generator that yields *all* file nodes.
 
@@ -952,25 +952,25 @@ class BaseInMemoryChangeset(object):
 
        """
 
        Performs in-memory commit (doesn't check workdir in any way) and
 
        returns newly created ``Changeset``. Updates repository's
 
        ``revisions``.
 

	
 
        .. note::
 
            While overriding this method each backend's should call
 
            ``self.check_integrity(parents)`` in the first place.
 

	
 
        :param message: message of the commit
 
        :param author: full username, i.e. "Joe Doe <joe.doe@example.com>"
 
        :param parents: single parent or sequence of parents from which commit
 
          would be derieved
 
          would be derived
 
        :param date: ``datetime.datetime`` instance. Defaults to
 
          ``datetime.datetime.now()``.
 
        :param branch: branch name, as string. If none given, default backend's
 
          branch would be used.
 

	
 
        :raises ``CommitError``: if any error occurs while committing
 
        """
 
        raise NotImplementedError
 

	
 

	
 
class EmptyChangeset(BaseChangeset):
 
    """
kallithea/lib/vcs/backends/git/changeset.py
Show inline comments
 
@@ -314,25 +314,25 @@ class GitChangeset(BaseChangeset):
 

	
 
    def get_file_annotate(self, path):
 
        """
 
        Returns a generator of four element tuples with
 
            lineno, sha, changeset lazy loader and line
 

	
 
        TODO: This function now uses os underlying 'git' command which is
 
        generally not good. Should be replaced with algorithm iterating
 
        commits.
 
        """
 
        cmd = 'blame -l --root -r %s -- "%s"' % (self.id, path)
 
        # -l     ==> outputs long shas (and we need all 40 characters)
 
        # --root ==> doesn't put '^' character for bounderies
 
        # --root ==> doesn't put '^' character for boundaries
 
        # -r sha ==> blames for the given revision
 
        so, se = self.repository.run_git_command(cmd)
 

	
 
        for i, blame_line in enumerate(so.split('\n')[:-1]):
 
            ln_no = i + 1
 
            sha, line = re.split(r' ', blame_line, 1)
 
            yield (ln_no, sha, lambda: self.repository.get_changeset(sha), line)
 

	
 
    def fill_archive(self, stream=None, kind='tgz', prefix=None,
 
                     subrepos=False):
 
        """
 
        Fills up given stream.
kallithea/lib/vcs/backends/git/inmemory.py
Show inline comments
 
@@ -11,25 +11,25 @@ from kallithea.lib.vcs.utils import safe
 
class GitInMemoryChangeset(BaseInMemoryChangeset):
 

	
 
    def commit(self, message, author, parents=None, branch=None, date=None,
 
               **kwargs):
 
        """
 
        Performs in-memory commit (doesn't check workdir in any way) and
 
        returns newly created ``Changeset``. Updates repository's
 
        ``revisions``.
 

	
 
        :param message: message of the commit
 
        :param author: full username, i.e. "Joe Doe <joe.doe@example.com>"
 
        :param parents: single parent or sequence of parents from which commit
 
          would be derieved
 
          would be derived
 
        :param date: ``datetime.datetime`` instance. Defaults to
 
          ``datetime.datetime.now()``.
 
        :param branch: branch name, as string. If none given, default backend's
 
          branch would be used.
 

	
 
        :raises ``CommitError``: if any error occurs while committing
 
        """
 
        self.check_integrity(parents)
 

	
 
        from .repository import GitRepository
 
        if branch is None:
 
            branch = GitRepository.DEFAULT_BRANCH_NAME
kallithea/lib/vcs/backends/git/repository.py
Show inline comments
 
@@ -269,25 +269,25 @@ class GitRepository(BaseRepository):
 
            return []
 
        return so.splitlines()
 

	
 
    def _get_all_revisions2(self):
 
        #alternate implementation using dulwich
 
        includes = [x[1][0] for x in self._parsed_refs.iteritems()
 
                    if x[1][1] != 'T']
 
        return [c.commit.id for c in self._repo.get_walker(include=includes)]
 

	
 
    def _get_revision(self, revision):
 
        """
 
        For git backend we always return integer here. This way we ensure
 
        that changset's revision attribute would become integer.
 
        that changeset's revision attribute would become integer.
 
        """
 

	
 
        is_null = lambda o: len(o) == revision.count('0')
 

	
 
        if self._empty:
 
            raise EmptyRepositoryError("There are no changesets yet")
 

	
 
        if revision in (None, '', 'tip', 'HEAD', 'head', -1):
 
            return self.revisions[-1]
 

	
 
        is_bstr = isinstance(revision, (str, unicode))
 
        if ((is_bstr and revision.isdigit() and len(revision) < 12)
kallithea/lib/vcs/backends/hg/inmemory.py
Show inline comments
 
@@ -10,25 +10,25 @@ from kallithea.lib.vcs.utils.hgcompat im
 
class MercurialInMemoryChangeset(BaseInMemoryChangeset):
 

	
 
    def commit(self, message, author, parents=None, branch=None, date=None,
 
            **kwargs):
 
        """
 
        Performs in-memory commit (doesn't check workdir in any way) and
 
        returns newly created ``Changeset``. Updates repository's
 
        ``revisions``.
 

	
 
        :param message: message of the commit
 
        :param author: full username, i.e. "Joe Doe <joe.doe@example.com>"
 
        :param parents: single parent or sequence of parents from which commit
 
          would be derieved
 
          would be derived
 
        :param date: ``datetime.datetime`` instance. Defaults to
 
          ``datetime.datetime.now()``.
 
        :param branch: branch name, as string. If none given, default backend's
 
          branch would be used.
 

	
 
        :raises ``CommitError``: if any error occurs while committing
 
        """
 
        self.check_integrity(parents)
 

	
 
        from .repository import MercurialRepository
 
        if not isinstance(message, unicode) or not isinstance(author, unicode):
 
            raise RepositoryError('Given message and author needs to be '
kallithea/lib/vcs/conf/settings.py
Show inline comments
 
@@ -10,25 +10,25 @@ VCSRC_PATH = os.environ.get('VCSRC_PATH'
 
if not VCSRC_PATH:
 
    HOME_ = get_user_home()
 
    if not HOME_:
 
        HOME_ = tempfile.gettempdir()
 

	
 
VCSRC_PATH = VCSRC_PATH or abspath(HOME_, '.vcsrc')
 
if os.path.isdir(VCSRC_PATH):
 
    VCSRC_PATH = os.path.join(VCSRC_PATH, '__init__.py')
 

	
 
# list of default encoding used in safe_unicode/safe_str methods
 
DEFAULT_ENCODINGS = aslist('utf8')
 

	
 
# path to git executable runned by run_git_command function
 
# path to git executable run by run_git_command function
 
GIT_EXECUTABLE_PATH = 'git'
 
# can be also --branches --tags
 
GIT_REV_FILTER = '--all'
 

	
 
BACKENDS = {
 
    'hg': 'kallithea.lib.vcs.backends.hg.MercurialRepository',
 
    'git': 'kallithea.lib.vcs.backends.git.GitRepository',
 
}
 

	
 
ARCHIVE_SPECS = {
 
    'tar': ('application/x-tar', '.tar'),
 
    'tbz2': ('application/x-bzip2', '.tar.bz2'),
kallithea/lib/vcs/nodes.py
Show inline comments
 
@@ -228,25 +228,25 @@ class Node(object):
 
    def not_changed(self):
 
        return self.state is NodeState.NOT_CHANGED
 

	
 
    @LazyProperty
 
    def removed(self):
 
        return self.state is NodeState.REMOVED
 

	
 

	
 
class FileNode(Node):
 
    """
 
    Class representing file nodes.
 

	
 
    :attribute: path: path to the node, relative to repostiory's root
 
    :attribute: path: path to the node, relative to repository's root
 
    :attribute: content: if given arbitrary sets content of the file
 
    :attribute: changeset: if given, first time content is accessed, callback
 
    :attribute: mode: octal stat mode for a node. Default is 0100644.
 
    """
 

	
 
    def __init__(self, path, content=None, changeset=None, mode=None):
 
        """
 
        Only one of ``content`` and ``changeset`` may be given. Passing both
 
        would raise ``NodeError`` exception.
 

	
 
        :param path: relative path to the node
 
        :param content: content may be passed to constructor
 
@@ -470,25 +470,25 @@ class RemovedFileNode(FileNode):
 
        raise RemovedFileNodeError("Cannot access attribute %s on "
 
            "RemovedFileNode" % attr)
 

	
 
    @LazyProperty
 
    def state(self):
 
        return NodeState.REMOVED
 

	
 

	
 
class DirNode(Node):
 
    """
 
    DirNode stores list of files and directories within this node.
 
    Nodes may be used standalone but within repository context they
 
    lazily fetch data within same repositorty's changeset.
 
    lazily fetch data within same repository's changeset.
 
    """
 

	
 
    def __init__(self, path, nodes=(), changeset=None):
 
        """
 
        Only one of ``nodes`` and ``changeset`` may be given. Passing both
 
        would raise ``NodeError`` exception.
 

	
 
        :param path: relative path to the node
 
        :param nodes: content may be passed to constructor
 
        :param changeset: if given, will use it to lazily fetch content
 
        :param size: always 0 for ``DirNode``
 
        """
kallithea/lib/vcs/subprocessio.py
Show inline comments
 
@@ -220,57 +220,57 @@ class BufferedGenerator(object):
 

	
 
    @property
 
    def data_added(self):
 
        return self.worker.data_added.is_set()
 

	
 
    @property
 
    def reading_paused(self):
 
        return not self.worker.keep_reading.is_set()
 

	
 
    @property
 
    def done_reading_event(self):
 
        """
 
        Done_reding does not mean that the iterator's buffer is empty.
 
        Done_reading does not mean that the iterator's buffer is empty.
 
        Iterator might have done reading from underlying source, but the read
 
        chunks might still be available for serving through .next() method.
 

	
 
        :returns: An Event class instance.
 
        """
 
        return self.worker.EOF
 

	
 
    @property
 
    def done_reading(self):
 
        """
 
        Done_reding does not mean that the iterator's buffer is empty.
 
        Done_reading does not mean that the iterator's buffer is empty.
 
        Iterator might have done reading from underlying source, but the read
 
        chunks might still be available for serving through .next() method.
 

	
 
        :returns: An Bool value.
 
        """
 
        return self.worker.EOF.is_set()
 

	
 
    @property
 
    def length(self):
 
        """
 
        returns int.
 

	
 
        This is the lenght of the que of chunks, not the length of
 
        This is the length of the queue of chunks, not the length of
 
        the combined contents in those chunks.
 

	
 
        __len__() cannot be meaningfully implemented because this
 
        reader is just flying throuh a bottomless pit content and
 
        can only know the lenght of what it already saw.
 
        reader is just flying through a bottomless pit content and
 
        can only know the length of what it already saw.
 

	
 
        If __len__() on WSGI server per PEP 3333 returns a value,
 
        the responce's length will be set to that. In order not to
 
        the response's length will be set to that. In order not to
 
        confuse WSGI PEP3333 servers, we will not implement __len__
 
        at all.
 
        """
 
        return len(self.data)
 

	
 
    def prepend(self, x):
 
        self.data.appendleft(x)
 

	
 
    def append(self, x):
 
        self.data.append(x)
 

	
 
    def extend(self, o):
 
@@ -288,29 +288,29 @@ class SubprocessIOChunker(object):
 

	
 
    - We are multithreaded. Writing in and reading out, err are all sep threads.
 
    - We support concurrent (in and out) stream processing.
 
    - The output is not a stream. It's a queue of read string (bytes, not unicode)
 
      chunks. The object behaves as an iterable. You can "for chunk in obj:" us.
 
    - We are non-blocking in more respects than communicate()
 
      (reading from subprocess out pauses when internal buffer is full, but
 
       does not block the parent calling code. On the flip side, reading from
 
       slow-yielding subprocess may block the iteration until data shows up. This
 
       does not block the parallel inpipe reading occurring parallel thread.)
 

	
 
    The purpose of the object is to allow us to wrap subprocess interactions into
 
    and interable that can be passed to a WSGI server as the application's return
 
    an iterable that can be passed to a WSGI server as the application's return
 
    value. Because of stream-processing-ability, WSGI does not have to read ALL
 
    of the subprocess's output and buffer it, before handing it to WSGI server for
 
    HTTP response. Instead, the class initializer reads just a bit of the stream
 
    to figure out if error ocurred or likely to occur and if not, just hands the
 
    to figure out if error occurred or likely to occur and if not, just hands the
 
    further iteration over subprocess output to the server for completion of HTTP
 
    response.
 

	
 
    The real or perceived subprocess error is trapped and raised as one of
 
    EnvironmentError family of exceptions
 

	
 
    Example usage:
 
    #    try:
 
    #        answer = SubprocessIOChunker(
 
    #            cmd,
 
    #            input,
 
    #            buffer_size = 65536,
kallithea/lib/vcs/utils/__init__.py
Show inline comments
 
@@ -41,25 +41,25 @@ def date_fromtimestamp(unixts, tzoffset=
 
    """
 
    Makes a local datetime object out of unix timestamp
 

	
 
    :param unixts:
 
    :param tzoffset:
 
    """
 

	
 
    return datetime.datetime.fromtimestamp(float(unixts))
 

	
 

	
 
def safe_int(val, default=None):
 
    """
 
    Returns int() of val if val is not convertable to int use default
 
    Returns int() of val if val is not convertible to int use default
 
    instead
 

	
 
    :param val:
 
    :param default:
 
    """
 

	
 
    try:
 
        val = int(val)
 
    except (ValueError, TypeError):
 
        val = default
 

	
 
    return val
kallithea/lib/vcs/utils/baseui_config.py
Show inline comments
 
from kallithea.lib.vcs.utils.hgcompat import ui, config
 

	
 

	
 
def make_ui(self, path='hgwebdir.config'):
 
    """
 
    A funcion that will read python rc files and make an ui from read options
 
    A function that will read python rc files and make an ui from read options
 

	
 
    :param path: path to mercurial config file
 
    """
 
    #propagated from mercurial documentation
 
    sections = [
 
                'alias',
 
                'auth',
 
                'decode/encode',
 
                'defaults',
 
                'diff',
 
                'email',
 
                'extensions',
kallithea/lib/vcs/utils/compat.py
Show inline comments
 
@@ -7,25 +7,25 @@ versions.
 
import sys
 
import array
 

	
 
if sys.version_info >= (2, 7):
 
    unittest = __import__('unittest')
 
else:
 
    unittest = __import__('unittest2')
 

	
 

	
 
if sys.version_info >= (2, 6):
 
    _bytes = bytes
 
else:
 
    # in py2.6 bytes is a synonim for str
 
    # in py2.6 bytes is a synonym for str
 
    _bytes = str
 

	
 
if sys.version_info >= (2, 6):
 
    _bytearray = bytearray
 
else:
 
    # no idea if this is correct but all integration tests are passing
 
    # i think we never use bytearray anyway
 
    _bytearray = array
 

	
 
if sys.version_info >= (2, 6):
 
    from collections import deque
 
else:
kallithea/lib/vcs/utils/helpers.py
Show inline comments
 
"""
 
Utitlites aimed to help achieve mostly basic tasks.
 
Utilities aimed to help achieve mostly basic tasks.
 
"""
 
from __future__ import division
 

	
 
import re
 
import os
 
import time
 
import datetime
 
from subprocess import Popen, PIPE
 

	
 
from kallithea.lib.vcs.exceptions import VCSError
 
from kallithea.lib.vcs.exceptions import RepositoryError
 
from kallithea.lib.vcs.utils.paths import abspath
kallithea/lib/vcs/utils/hgcompat.py
Show inline comments
 
@@ -21,26 +21,26 @@ from mercurial.localrepo import localrep
 
from mercurial.match import match
 
from mercurial.mdiff import diffopts
 
from mercurial.node import hex
 
from mercurial.encoding import tolocal
 
from mercurial.discovery import findcommonoutgoing
 
from mercurial.hg import peer
 
from mercurial.httppeer import httppeer
 
from mercurial.sshpeer import sshpeer
 
from mercurial.util import url as hg_url
 
from mercurial.scmutil import revrange
 
from mercurial.node import nullrev
 

	
 
# those authnadlers are patched for python 2.6.5 bug an
 
# infinit looping when given invalid resources
 
# those authhandlers are patched for python 2.6.5 bug an
 
# infinite looping when given invalid resources
 
from mercurial.url import httpbasicauthhandler, httpdigestauthhandler
 

	
 
import inspect
 
# Mercurial 3.1 503bb3af70fe
 
if inspect.getargspec(memfilectx.__init__).args[1] != 'repo':
 
    _org__init__=memfilectx.__init__
 
    def _memfilectx__init__(self, repo, *a, **b):
 
        return _org__init__(self, *a, **b)
 
    memfilectx.__init__ = _memfilectx__init__
 

	
 
# workaround for 3.3 94ac64bcf6fe and not calling largefiles reposetup correctly
 
localrepository._lfstatuswriters = [lambda *msg, **opts: None]
kallithea/lib/vcs/utils/imports.py
Show inline comments
 
@@ -2,25 +2,25 @@ from kallithea.lib.vcs.exceptions import
 

	
 

	
 
def import_class(class_path):
 
    """
 
    Returns class from the given path.
 

	
 
    For example, in order to get class located at
 
    ``vcs.backends.hg.MercurialRepository``:
 

	
 
        try:
 
            hgrepo = import_class('vcs.backends.hg.MercurialRepository')
 
        except VCSError:
 
            # hadle error
 
            # handle error
 
    """
 
    splitted = class_path.split('.')
 
    mod_path = '.'.join(splitted[:-1])
 
    class_name = splitted[-1]
 
    try:
 
        class_mod = __import__(mod_path, {}, {}, [class_name])
 
    except ImportError, err:
 
        msg = "There was problem while trying to import backend class. "\
 
            "Original error was:\n%s" % err
 
        raise VCSError(msg)
 
    cls = getattr(class_mod, class_name)
 

	
kallithea/lib/vcs/utils/lockfiles.py
Show inline comments
 
@@ -48,25 +48,25 @@ class LockFile(object):
 
        self._owns_lock = True
 

	
 
    def _obtain_lock(self):
 
        """The default implementation will raise if a lock cannot be obtained.
 
        Subclasses may override this method to provide a different implementation"""
 
        return self._obtain_lock_or_raise()
 

	
 
    def _release_lock(self):
 
        """Release our lock if we have one"""
 
        if not self._has_lock():
 
            return
 

	
 
        # if someone removed our file beforhand, lets just flag this issue
 
        # if someone removed our file beforehand, lets just flag this issue
 
        # instead of failing, to make it more usable.
 
        lfp = self._lock_file_path()
 
        try:
 
            # on bloody windows, the file needs write permissions to be removable.
 
            # Why ...
 
            if os.name == 'nt':
 
                os.chmod(lfp, 0777)
 
            # END handle win32
 
            os.remove(lfp)
 
        except OSError:
 
            pass
 
        self._owns_lock = False
0 comments (0 inline, 0 general)