Changeset - 7f5976da192c
[Not reviewed]
beta
0 3 0
Marcin Kuzminski - 15 years ago 2010-11-05 18:26:26
marcin@python-works.com
#48 rewrite action loggers into hooks with all changesets that are inside a push
3 files changed with 84 insertions and 48 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/hooks.py
Show inline comments
 
@@ -22,12 +22,12 @@ Created on Aug 6, 2010
 

	
 
@author: marcink
 
"""
 

	
 
import sys
 
from mercurial.cmdutil import revrange
 
from mercurial.node import nullrev
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.utils import action_logger
 
import os
 
from rhodecode.lib import helpers as h
 
from rhodecode.model import meta
 
from rhodecode.model.db import UserLog, User
 
import sys
 

	
 
def repo_size(ui, repo, hooktype=None, **kwargs):
 

	
 
@@ -48,31 +48,52 @@ def repo_size(ui, repo, hooktype=None, *
 
    sys.stdout.write('Repository size .hg:%s repo:%s total:%s\n' \
 
                     % (size_hg_f, size_root_f, size_total_f))
 
    
 
    user_action_mapper(ui, repo, hooktype, **kwargs)
 
def log_pull_action(ui, repo, **kwargs):
 
    """
 
    Logs user last pull action
 
    :param ui:
 
    :param repo:
 
    """
 

	
 
def user_action_mapper(ui, repo, hooktype=None, **kwargs):
 
    extra_params = dict(repo.ui.configitems('rhodecode_extras'))
 
    username = extra_params['username']
 
    repository = extra_params['repository']
 
    action = 'pull'
 
       
 
    action_logger(username, action, repository, extra_params['ip'])
 
    
 
    return 0
 

	
 
def log_push_action(ui, repo, **kwargs):
 
    """
 
    Maps user last push action to new changeset id, from mercurial
 
    :param ui:
 
    :param repo:
 
    :param hooktype:
 
    """
 
    
 
    try:
 
        sa = meta.Session()
 
        username = kwargs['url'].split(':')[-1]
 
        user_log = sa.query(UserLog)\
 
            .filter(UserLog.user == sa.query(User)\
 
                                    .filter(User.username == username).one())\
 
            .order_by(UserLog.user_log_id.desc()).first()
 
    extra_params = dict(repo.ui.configitems('rhodecode_extras'))
 
    username = extra_params['username']
 
    repository = extra_params['repository']
 
    action = 'push:%s'
 
    node = kwargs['node']
 
    
 
    def get_revs(repo, rev_opt):
 
        if rev_opt:
 
            revs = revrange(repo, rev_opt)
 
        
 
        if user_log and not user_log.revision:
 
            user_log.revision = str(repo['tip'])
 
            sa.add(user_log)
 
            sa.commit()
 
            if len(revs) == 0:
 
                return (nullrev, nullrev)
 
            return (max(revs), min(revs))
 
        else:
 
            return (len(repo) - 1, 0)
 
    
 
    stop, start = get_revs(repo, [node + ':'])
 
        
 
    except Exception, e:
 
        sa.rollback()
 
        raise
 
    finally:
 
        meta.Session.remove()    
 
    revs = (str(repo[r]) for r in xrange(start, stop + 1))
 
    
 
    action = action % ','.join(revs)
 
        
 
    action_logger(username, action, repository, extra_params['ip'])
 
    
 
    return 0
 
  
rhodecode/lib/middleware/simplehg.py
Show inline comments
 
@@ -49,15 +49,24 @@ class SimpleHg(object):
 
        self.config = config
 
        #authenticate this mercurial request using 
 
        self.authenticate = AuthBasicAuthenticator('', authfunc)
 
        self.ipaddr = '0.0.0.0'
 
        self.repository = None
 
        self.username = None
 
        self.action = None
 

	
 
    def __call__(self, environ, start_response):
 
        if not is_mercurial(environ):
 
            return self.application(environ, start_response)
 

	
 
        proxy_key = 'HTTP_X_REAL_IP'
 
        def_key = 'REMOTE_ADDR'
 
        self.ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
 
        
 
        #===================================================================
 
        # AUTHENTICATE THIS MERCURIAL REQUEST
 
        #===================================================================
 
        username = REMOTE_USER(environ)
 
        
 
        if not username:
 
            self.authenticate.realm = self.config['rhodecode_realm']
 
            result = self.authenticate(environ)
 
@@ -67,10 +76,14 @@ class SimpleHg(object):
 
            else:
 
                return result.wsgi_application(environ, start_response)
 

	
 
        #=======================================================================
 
        # GET REPOSITORY
 
        #=======================================================================
 
        try:
 
            repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:])
 
            if repo_name.endswith('/'):
 
                repo_name = repo_name.rstrip('/')
 
            self.repository = repo_name
 
        except:
 
            log.error(traceback.format_exc())
 
            return HTTPInternalServerError()(environ, start_response)
 
@@ -78,17 +91,18 @@ class SimpleHg(object):
 
        #===================================================================
 
        # CHECK PERMISSIONS FOR THIS REQUEST
 
        #===================================================================
 
        action = self.__get_action(environ)
 
        if action:
 
        self.action = self.__get_action(environ)
 
        if self.action:
 
            username = self.__get_environ_user(environ)
 
            try:
 
                user = self.__get_user(username)
 
                self.username = user.username
 
            except:
 
                log.error(traceback.format_exc())
 
                return HTTPInternalServerError()(environ, start_response)
 

	
 
            #check permissions for this repository
 
            if action == 'push':
 
            if self.action == 'push':
 
                if not HasPermissionAnyMiddleware('repository.write',
 
                                                  'repository.admin')\
 
                                                    (user, repo_name):
 
@@ -102,13 +116,11 @@ class SimpleHg(object):
 
                                                    (user, repo_name):
 
                    return HTTPForbidden()(environ, start_response)
 

	
 
            #log action
 
            if action in ('push', 'pull', 'clone'):
 
                proxy_key = 'HTTP_X_REAL_IP'
 
                def_key = 'REMOTE_ADDR'
 
                ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0'))
 
                self.__log_user_action(user, action, repo_name, ipaddr)
 

	
 
        self.extras = {'ip':self.ipaddr,
 
                       'username':self.username,
 
                       'action':self.action,
 
                       'repository':self.repository}
 
        print self.extras
 
        #===================================================================
 
        # MERCURIAL REQUEST HANDLING
 
        #===================================================================
 
@@ -130,7 +142,7 @@ class SimpleHg(object):
 
            return HTTPInternalServerError()(environ, start_response)
 

	
 
        #invalidate cache on push
 
        if action == 'push':
 
        if self.action == 'push':
 
            self.__invalidate_cache(repo_name)
 
            messages = []
 
            messages.append('thank you for using rhodecode')
 
@@ -157,7 +169,7 @@ class SimpleHg(object):
 

	
 
    def __make_app(self):
 
        hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
 
        return  self.__load_web_settings(hgserve)
 
        return  self.__load_web_settings(hgserve, self.extras)
 

	
 
    def __get_environ_user(self, environ):
 
        return environ.get('REMOTE_USER')
 
@@ -174,7 +186,7 @@ class SimpleHg(object):
 
        mapping = {'changegroup': 'pull',
 
                   'changegroupsubset': 'pull',
 
                   'stream_out': 'pull',
 
                   #'listkeys': 'pull',
 
                   'listkeys': 'pull',
 
                   'unbundle': 'push',
 
                   'pushkey': 'push', }
 
        for qry in environ['QUERY_STRING'].split('&'):
 
@@ -185,9 +197,6 @@ class SimpleHg(object):
 
                else:
 
                    return cmd
 

	
 
    def __log_user_action(self, user, action, repo, ipaddr):
 
        action_logger(user, action, repo, ipaddr)
 

	
 
    def __invalidate_cache(self, repo_name):
 
        """we know that some change was made to repositories and we should
 
        invalidate the cache to see the changes right away but only for
 
@@ -196,14 +205,19 @@ class SimpleHg(object):
 
        invalidate_cache('full_changelog', repo_name)
 

	
 

	
 
    def __load_web_settings(self, hgserve):
 
    def __load_web_settings(self, hgserve, extras={}):
 
        #set the global ui for hgserve instance passed
 
        hgserve.repo.ui = self.baseui
 

	
 
        hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
 
    
 
        #inject some additional parameters that will be available in ui
 
        #for hooks
 
        for k, v in extras.items():
 
            hgserve.repo.ui.setconfig('rhodecode_extras', k, v)
 
        
 
        repoui = make_ui('file', hgrc, False)
 

	
 

	
 
        if repoui:
 
            #overwrite our ui instance with the section from hgrc file
 
            for section in ui_sections:
rhodecode/lib/utils.py
Show inline comments
 
@@ -35,6 +35,7 @@ from vcs.backends.base import BaseChange
 
from vcs.backends.git import GitRepository
 
from vcs.backends.hg import MercurialRepository
 
from vcs.utils.lazy import LazyProperty
 
import traceback
 
import datetime
 
import logging
 
import os
 
@@ -77,15 +78,15 @@ def action_logger(user, action, repo, ip
 

	
 
    try:
 
        if hasattr(user, 'user_id'):
 
            user_id = user.user_id
 
            user_obj = user
 
        elif isinstance(user, basestring):
 
            user_id = UserModel(sa).get_by_username(user, cache=False).user_id
 
            user_obj = UserModel(sa).get_by_username(user, cache=False)
 
        else:
 
            raise Exception('You have to provide user object or username')
 

	
 
        repo_name = repo.lstrip('/')
 
        user_log = UserLog()
 
        user_log.user_id = user_id
 
        user_log.user_id = user_obj.user_id
 
        user_log.action = action
 
        user_log.repository_name = repo_name
 
        user_log.repository = RepoModel(sa).get(repo_name, cache=False)
 
@@ -95,10 +96,10 @@ def action_logger(user, action, repo, ip
 
        sa.commit()
 

	
 
        log.info('Adding user %s, action %s on %s',
 
                                        user.username, action, repo)
 
    except Exception, e:
 
                                        user_obj.username, action, repo)
 
    except:
 
        log.error(traceback.format_exc())
 
        sa.rollback()
 
        log.error('could not log user action:%s', str(e))
 

	
 
def get_repos(path, recursive=False, initial=False):
 
    """
0 comments (0 inline, 0 general)