Changeset - 6484963056cd
[Not reviewed]
default
0 5 0
Marcin Kuzminski - 15 years ago 2010-07-14 12:31:11
marcin@python-works.com
implemented cache for repeated queries in simplehg mercurial requests
5 files changed with 39 insertions and 20 deletions:
0 comments (0 inline, 0 general)
development.ini
Show inline comments
 
@@ -41,17 +41,19 @@ cache_dir = %(here)s/data
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/%(here)s/data/cache/data
 
beaker.cache.lock_dir=/%(here)s/data/cache/lock
 
beaker.cache.regions=short_term,long_term
 
beaker.cache.regions=super_short_term,short_term,long_term
 
beaker.cache.long_term.type=memory
 
beaker.cache.long_term.expire=36000
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=60
 
beaker.cache.super_short_term.type=memory
 
beaker.cache.super_short_term.expire=10
 

	
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
production.ini
Show inline comments
 
@@ -36,23 +36,24 @@ port = 8001
 
use = egg:pylons_app
 
full_stack = true
 
static_files = false
 
lang=en
 
cache_dir = %(here)s/data
 

	
 

	
 
####################################
 
###         BEAKER CACHE        ####
 
####################################
 
beaker.cache.data_dir=/%(here)s/data/cache/data
 
beaker.cache.lock_dir=/%(here)s/data/cache/lock
 
beaker.cache.regions=short_term,long_term
 
beaker.cache.regions=super_short_term,short_term,long_term
 
beaker.cache.long_term.type=memory
 
beaker.cache.long_term.expire=36000
 
beaker.cache.short_term.type=memory
 
beaker.cache.short_term.expire=60
 
beaker.cache.super_short_term.type=memory
 
beaker.cache.super_short_term.expire=10
 
    
 
################################################################################
 
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*  ##
 
## Debug mode will enable the interactive debugging tool, allowing ANYONE to  ##
 
## execute malicious code after an exception is raised.                       ##
 
################################################################################
pylons_app/lib/auth.py
Show inline comments
 
@@ -19,38 +19,44 @@
 
# MA  02110-1301, USA.
 
"""
 
Created on April 4, 2010
 

	
 
@author: marcink
 
"""
 

	
 
from beaker.cache import cache_region
 
from functools import wraps
 
from pylons import session, url, request
 
from pylons import config, session, url, request
 
from pylons.controllers.util import abort, redirect
 
from pylons_app.lib.utils import get_repo_slug
 
from pylons_app.model import meta
 
from pylons_app.model.db import User, Repo2Perm, Repository, Permission
 
from pylons_app.lib.utils import get_repo_slug
 
from sqlalchemy.exc import OperationalError
 
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
 
import crypt
 
import logging
 
from pylons import config
 

	
 
log = logging.getLogger(__name__) 
 

	
 
def get_crypt_password(password):
 
    """
 
    Cryptographic function used for password hashing
 
    @param password: password to hash
 
    """
 
    return crypt.crypt(password, '6a')
 

	
 

	
 
@cache_region('super_short_term', 'cached_user')
 
def get_user_cached(username):
 
    sa = meta.Session
 
    user = sa.query(User).filter(User.username == username).one()
 
    return user
 

	
 
def authfunc(environ, username, password):
 
    sa = meta.Session
 
    password_crypt = get_crypt_password(password)
 
    try:
 
        user = sa.query(User).filter(User.username == username).one()
 
        user = get_user_cached(username)
 
    except (NoResultFound, MultipleResultsFound, OperationalError) as e:
 
        log.error(e)
 
        user = None
 
        
 
    if user:
 
        if user.active:
pylons_app/lib/middleware/simplehg.py
Show inline comments
 
@@ -24,27 +24,29 @@ Created on 2010-04-28
 
@author: marcink
 
SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
 
It's implemented with basic auth function
 
"""
 
from datetime import datetime
 
from itertools import chain
 
from mercurial.error import RepoError
 
from mercurial.hgweb import hgweb
 
from mercurial.hgweb.request import wsgiapplication
 
from mercurial.error import RepoError
 
from paste.auth.basic import AuthBasicAuthenticator
 
from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 
from pylons_app.lib.auth import authfunc, HasPermissionAnyMiddleware
 
from pylons_app.lib.auth import authfunc, HasPermissionAnyMiddleware, \
 
    get_user_cached
 
from pylons_app.lib.utils import is_mercurial, make_ui, invalidate_cache, \
 
    check_repo_fast
 
from pylons_app.model import meta
 
from pylons_app.model.db import UserLog, User
 
import pylons_app.lib.helpers as h
 
from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError
 
import logging
 
import os
 
import pylons_app.lib.helpers as h
 
import traceback
 
 
 
log = logging.getLogger(__name__)
 

	
 
class SimpleHg(object):
 

	
 
    def __init__(self, application, config):
 
        self.application = application
 
@@ -53,13 +55,13 @@ class SimpleHg(object):
 
        realm = self.config['hg_app_auth_realm']
 
        self.authenticate = AuthBasicAuthenticator(realm, authfunc)
 
        
 
    def __call__(self, environ, start_response):
 
        if not is_mercurial(environ):
 
            return self.application(environ, start_response)
 
        else:
 

	
 
            #===================================================================
 
            # AUTHENTICATE THIS MERCURIAL REQUEST
 
            #===================================================================
 
            username = REMOTE_USER(environ)
 
            if not username:
 
                result = self.authenticate(environ)
 
@@ -79,15 +81,13 @@ class SimpleHg(object):
 
            # CHECK PERMISSIONS FOR THIS REQUEST
 
            #===================================================================
 
            action = self.__get_action(environ)
 
            if action:
 
                username = self.__get_environ_user(environ)
 
                try:
 
                    sa = meta.Session
 
                    user = sa.query(User)\
 
                        .filter(User.username == username).one()
 
                user = self.__get_user(username)
 
                except:
 
                    log.error(traceback.format_exc())
 
                    return HTTPInternalServerError()(environ, start_response)
 
                #check permissions for this repository
 
                if action == 'pull':
 
                    if not HasPermissionAnyMiddleware('repository.read',
 
@@ -157,12 +157,17 @@ class SimpleHg(object):
 
        hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
 
        return  self.__load_web_settings(hgserve)
 
    
 
    def __get_environ_user(self, environ):
 
        return environ.get('REMOTE_USER')
 
    
 
    def __get_user(self, username):
 
        return get_user_cached(username)
 
        
 
        
 
                        
 
    def __get_size(self, repo_path, content_size):
 
        size = int(content_size)
 
        for path, dirs, files in os.walk(repo_path):
 
            if path.find('.hg') == -1:
 
                for f in files:
 
                    size += os.path.getsize(os.path.join(path, f))
pylons_app/lib/utils.py
Show inline comments
 
@@ -13,12 +13,13 @@
 
# 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, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
from beaker.cache import cache_region
 

	
 
"""
 
Created on April 18, 2010
 
Utilities for hg app
 
@author: marcink
 
"""
 
@@ -72,12 +73,19 @@ def check_repo(repo_name, base_path, ver
 
        return False
 
    except RepoError:
 
        #it means that there is no valid repo there...
 
        log.info('%s repo is free for creation', repo_name)
 
        return True
 

	
 

	
 
@cache_region('super_short_term', 'cached_hg_ui')
 
def get_hg_ui_cached():
 
    from pylons_app.model.meta import Session
 
    sa = Session()
 
    return sa.query(HgAppUi).all()    
 

	
 
def make_ui(read_from='file', path=None, checkpaths=True):        
 
    """
 
    A function that will read python rc files or database
 
    and make an mercurial ui object from read options
 
    
 
    @param path: path to mercurial config file
 
@@ -109,16 +117,13 @@ def make_ui(read_from='file', path=None,
 
            for k, v in cfg.items(section):
 
                baseui.setconfig(section, k, v)
 
        if checkpaths:check_repo_dir(cfg.items('paths'))                
 
              
 
        
 
    elif read_from == 'db':
 
        from pylons_app.model.meta import Session
 
        sa = Session()
 
            
 
        hg_ui = sa.query(HgAppUi).all()
 
        hg_ui = get_hg_ui_cached()
 
        for ui_ in hg_ui:
 
            baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
 
        
 
    
 
    return baseui
 

	
0 comments (0 inline, 0 general)