comparison pylons_app/lib/simplehg.py @ 197:da59b7e07e3c

Changed import to base. Removed action logging from auth to simplehg. Splited loggin and invalidation action to private methods inside simplehg.
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 22 May 2010 19:29:50 +0200
parents 3d1dd13887f9
children be6d8aaddbd1
comparison
equal deleted inserted replaced
196:568f95056716 197:da59b7e07e3c
8 8
9 @author: marcink 9 @author: marcink
10 SimpleHG middleware for handling mercurial protocol request (push/clone etc.) 10 SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
11 It's implemented with basic auth function 11 It's implemented with basic auth function
12 """ 12 """
13 13 from datetime import datetime
14 from mercurial.hgweb import hgweb 14 from mercurial.hgweb import hgweb
15 from mercurial.hgweb.request import wsgiapplication 15 from mercurial.hgweb.request import wsgiapplication
16 from paste.auth.basic import AuthBasicAuthenticator 16 from paste.auth.basic import AuthBasicAuthenticator
17 from paste.httpheaders import REMOTE_USER, AUTH_TYPE 17 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
18 from pylons_app.lib.utils import is_mercurial
19 from pylons_app.lib.auth import authfunc 18 from pylons_app.lib.auth import authfunc
20 from pylons_app.lib.utils import make_ui, invalidate_cache 19 from pylons_app.lib.utils import is_mercurial, make_ui, invalidate_cache
20 from pylons_app.model import meta
21 from pylons_app.model.db import UserLogs, Users
21 from webob.exc import HTTPNotFound 22 from webob.exc import HTTPNotFound
23 import logging
22 import os 24 import os
25 log = logging.getLogger(__name__)
23 26
24 class SimpleHg(object): 27 class SimpleHg(object):
25 28
26 def __init__(self, application, config): 29 def __init__(self, application, config):
27 self.application = application 30 self.application = application
56 self.baseui = make_ui() 59 self.baseui = make_ui()
57 self.basepath = self.baseui.configitems('paths')[0][1]\ 60 self.basepath = self.baseui.configitems('paths')[0][1]\
58 .replace('*', '') 61 .replace('*', '')
59 self.repo_path = os.path.join(self.basepath, repo_name) 62 self.repo_path = os.path.join(self.basepath, repo_name)
60 try: 63 try:
61 app = wsgiapplication(self._make_app) 64 app = wsgiapplication(self.__make_app)
62 except Exception as e: 65 except Exception as e:
63 return HTTPNotFound()(environ, start_response) 66 return HTTPNotFound()(environ, start_response)
64 67
65 """we know that some change was made to repositories and we should 68 action = self.__get_action(environ)
66 invalidate the cache to see the changes right away""" 69 #invalidate cache on push
67 invalidate_cache('full_changelog', repo_name) 70 if action == 'push':
68 invalidate_cache('cached_repo_list') 71 self.__invalidate_cache(repo_name)
72
73 if action:
74 username = self.__get_environ_user(environ)
75 self.__log_user_action(username, action, repo_name)
69 return app(environ, start_response) 76 return app(environ, start_response)
70 77
71 def _make_app(self): 78 def __make_app(self):
72 hgserve = hgweb(self.repo_path) 79 hgserve = hgweb(self.repo_path)
73 return self.load_web_settings(hgserve) 80 return self.load_web_settings(hgserve)
81
82 def __get_environ_user(self, environ):
83 return environ.get('REMOTE_USER')
74 84
75 85 def __get_action(self, environ):
86 """
87 Maps mercurial request commands into a pull or push command.
88 @param environ:
89 """
90 mapping = {
91 'changegroup': 'pull',
92 'changegroupsubset': 'pull',
93 'unbundle': 'push',
94 'stream_out': 'pull',
95 }
96 for qry in environ['QUERY_STRING'].split('&'):
97 if qry.startswith('cmd'):
98 cmd = qry.split('=')[-1]
99 if mapping.has_key(cmd):
100 return mapping[cmd]
101
102 def __log_user_action(self, username, action, repo):
103 sa = meta.Session
104 try:
105 user = sa.query(Users)\
106 .filter(Users.username == username).one()
107 user_log = UserLogs()
108 user_log.user_id = user.user_id
109 user_log.action = action
110 user_log.repository = repo.replace('/', '')
111 user_log.action_date = datetime.now()
112 sa.add(user_log)
113 sa.commit()
114 log.info('Adding user %s, action %s on %s',
115 username, action, repo)
116 except Exception as e:
117 sa.rollback()
118 log.error('could not log user action:%s', str(e))
119
120 def __invalidate_cache(self, repo_name):
121 """we know that some change was made to repositories and we should
122 invalidate the cache to see the changes right away but only for
123 push requests"""
124 invalidate_cache('cached_repo_list')
125 invalidate_cache('full_changelog', repo_name)
126
127
76 def load_web_settings(self, hgserve): 128 def load_web_settings(self, hgserve):
77 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False) 129 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
78 #set the global ui for hgserve 130 #set the global ui for hgserve
79 hgserve.repo.ui = self.baseui 131 hgserve.repo.ui = self.baseui
80 132