def find_hook_dirs(self): from submin.models import options hooks_dir = options.static_path("hooks") + "submin" event_dirs = glob.glob(str(hooks_dir + "*")) event_dirs = [os.path.basename(x) for x in event_dirs if os.path.isdir(x)] return event_dirs
def __init__(self, environ, start_response): self.environ = environ self.start_response = start_response from submin.models import storage self.storage = storage self.storage.open() # importing options is only possbile after storage.open() from submin.models import options submin_www_dir = options.static_path('www') os.chdir(submin_www_dir) # same behaviour as CGI script from submin.bootstrap import SubminInstallationCheck submin_dir = options.lib_path() check = SubminInstallationCheck(submin_dir, environ) if not check.ok: self.start_response("500 Not Ok", []) return check.error_page().encode("utf-8") os.environ['SUBMIN_ENV'] = environ['SUBMIN_ENV'] from submin.dispatch.wsgirequest import WSGIRequest from submin.dispatch.dispatcher import dispatcher self.WSGIRequest = WSGIRequest self.dispatcher = dispatcher
def export_notifications(**kwargs): """Export a mailer.py config file For each user/repository pair, a config group is created. Only if a user has read or read/write permission to one or multiple paths in that repository, _and_ if the user has notifications enabled for that repository, _and_ if the user has a non-empty email-address. Multiple paths are grouped together by a regexp group (multiple|paths)""" bindir = options.static_path("hooks") + 'svn' # get a list of all users from submin.models import user users = [user.User(name) for name in user.list(user.FakeAdminUser())] groups = [] for u in users: if not u.email: continue u_notif = u.notifications() for repos in u_notif: repos_path = str(options.env_path("svn_dir") + repos) if not u_notif[repos]["enabled"]: continue # strip leading / paths = [ x[1:] for x in permissions.list_readable_user_paths(repos, "svn", u) ] if len(paths) == 0: continue elif len(paths) == 1: for_paths = paths[0] elif len(paths) > 0: for_paths = "(" + "|".join(paths) + ")" # Only match complete path, not partial paths (ticket #257) repos_path_re = '^' + repos_path + '$' g = { "repos_name": repos, "for_repos": repos_path_re, "email": u.email, "for_paths": for_paths, "username": u.name } groups.append(g) email = options.value( 'commit_email_from', 'Please configure commit_email_from <*****@*****.**>') templatevariables = {"groups": groups, 'from_addr': email} from submin.template.shortcuts import evaluate content = evaluate("plugins/vcs/svn/mailer.conf", templatevariables) filename = str((options.env_path() + 'conf') + 'mailer.py.conf') file(filename, 'w').writelines(content.encode('utf-8'))
def find_hook_dirs(self): from submin.models import options hooks_dir = options.static_path("hooks") + "submin" event_dirs = glob.glob(str(hooks_dir + "*")) event_dirs = [ os.path.basename(x) for x in event_dirs if os.path.isdir(x) ] return event_dirs
def copy_system_hooks(self, event_dir): from submin.models import options sys_event_dir = options.static_path("hooks") + "submin" + event_dir env_event_dir = options.env_path() + "hooks" + event_dir for script in glob.glob(str(sys_event_dir + "[3-6]*")): try: shutil.copy(script, str(env_event_dir)) except IOError as e: print "updating hook %s failed, do you have permissions?" % script
def copy_system_hooks(self, event_dir): from submin.models import options sys_event_dir = options.static_path("hooks") + "submin" + event_dir env_event_dir = options.env_path() + "hooks" + event_dir for script in glob.glob(str(sys_event_dir + "[3-6]*")): try: shutil.copy(script, str(env_event_dir)) except IOError as e: print 'updating hook %s failed, do you have permissions?' % \ script
def enableTracCommitHook(self, enable): """Add or remove trac commit script to/from the post-commit hook""" import os bindir = options.static_path('hooks') + 'svn' fullpath = str(bindir + 'trac-post-commit-hook') trac_env = str(options.env_path('trac_dir') + self.name) new_hook = '/usr/bin/python %s -p %s -r "$2"\n' % \ (fullpath, trac_env) self.rewritePostCommitHook(self.trac_signature, new_hook, enable)
def enable_hook(reposdir, hookname, targetname, interpreter='/usr/bin/python', args='"$@"'): """Assumes no hook is already there, or if there is, that is a shell script. If you want to overwrite the hook with a clean submin-hook, call rewrite_hook instead.""" target_script = options.static_path("hooks") + "git" + targetname new_hook = '%s %s %s\n' % (interpreter, target_script, args) hook = reposdir + 'hooks' + hookname if shellscript.hasSignature(hook, signature): return shellscript.rewriteWithSignature(hook, signature, new_hook, True, mode=0o755)
def export_notifications(**kwargs): """Export a mailer.py config file For each user/repository pair, a config group is created. Only if a user has read or read/write permission to one or multiple paths in that repository, _and_ if the user has notifications enabled for that repository, _and_ if the user has a non-empty email-address. Multiple paths are grouped together by a regexp group (multiple|paths)""" bindir = options.static_path("hooks") + 'svn' # get a list of all users from submin.models import user users = [user.User(name) for name in user.list(user.FakeAdminUser())] groups = [] for u in users: if not u.email: continue u_notif = u.notifications() for repos in u_notif: repos_path = str(options.env_path("svn_dir") + repos) if not u_notif[repos]["enabled"]: continue # strip leading / paths = [x[1:] for x in permissions.list_readable_user_paths(repos, "svn", u)] if len(paths) == 0: continue elif len(paths) == 1: for_paths = paths[0] elif len(paths) > 0: for_paths = "(" + "|".join(paths) + ")" # Only match complete path, not partial paths (ticket #257) repos_path_re = '^' + repos_path + '$' g = {"repos_name": repos, "for_repos": repos_path_re, "email": u.email, "for_paths": for_paths, "username": u.name} groups.append(g) email = options.value('commit_email_from', 'Please configure commit_email_from <*****@*****.**>') templatevariables = {"groups": groups, 'from_addr': email} from submin.template.shortcuts import evaluate content = evaluate("plugins/vcs/svn/mailer.conf", templatevariables) filename = str((options.env_path() + 'conf') + 'mailer.py.conf') file(filename, 'w').writelines(content.encode('utf-8'))
def enableCommitEmails(self, enable): """Add or remove our script to/from the post-commit hook""" import os bindir = options.static_path('hooks') + 'svn' fullpath = str(bindir + 'mailer.py') base_env = options.env_path() mailer_conf = str((base_env + 'conf') + 'mailer.py.conf') if not os.path.exists(mailer_conf): export_notifications() # create mailer_conf new_hook = '/usr/bin/python %s commit "$1" "$2" "%s"\n' % \ (fullpath, mailer_conf) self.rewritePostCommitHook(self.svn_signature, new_hook, enable)
def handler(self, req, path): """The subdir is expected to be in self.custom""" wwwroot = options.static_path('www') fullpath = wwwroot + self.custom + '/'.join(path) canonicalpath = os.path.realpath(fullpath) if not req.remove_base_url: # Someone is trying to be funny? We can be funny too! if not canonicalpath.startswith(wwwroot): return TeapotResponse("You tried to brew coffee, but I'm a teapot!") else: # more difficult check if '/../' in fullpath: return TeapotResponse("You tried to brew coffee, but I'm a teapot!") _, ext = os.path.splitext(fullpath) return FileResponse(''.join(file(fullpath).readlines()), self.mimetype(ext))
def evaluate(templatename, localvars={}): import os template_path = options.static_path('templates') templatename = str(template_path + templatename) localvars['SUBMIN_VERSION'] = submin_version oldcwd = os.getcwd() if os.path.dirname(templatename): os.chdir(os.path.dirname(templatename)) fp = open(os.path.basename(templatename), 'r') evaluated_string = '' if fp: template = Template(fp, localvars) evaluated_string = template.evaluate() fp.close() if os.path.dirname(templatename): os.chdir(oldcwd) return evaluated_string
def handler(self, req, path): """The subdir is expected to be in self.custom""" wwwroot = options.static_path('www') fullpath = wwwroot + self.custom + '/'.join(path) canonicalpath = os.path.realpath(fullpath) if not req.remove_base_url: # Someone is trying to be funny? We can be funny too! if not canonicalpath.startswith(wwwroot): return TeapotResponse( "You tried to brew coffee, but I'm a teapot!") else: # more difficult check if '/../' in fullpath: return TeapotResponse( "You tried to brew coffee, but I'm a teapot!") _, ext = os.path.splitext(fullpath) return FileResponse(''.join(file(fullpath).readlines()), self.mimetype(ext))
def main(): from sys import argv, path import os path.append('_SUBMIN_LIB_DIR_') interpreter = "perl" scriptname = 'commit-email.pl' scriptdir = os.path.dirname(argv[0]) env = 'SUBMIN_LIB_DIR' if env in os.environ: path.append(os.environ[env]) if len(argv) < 4: print "Usage: %s <configfile> <repository path> <revision>" % argv[0] return os.environ['SUBMIN_ENV'] = argv[1] repospath = argv[2] rev = argv[3] from submin.models import storage storage.open() from submin.models import options bindir = options.static_path("hooks") + 'svn' from submin.models import user userlist = [user.User(name) for name in user.list(user.FakeAdminUser())] n = buildNotifications(userlist) repos = os.path.basename(repospath) if repos not in n: print "no such repository" return mailer = bindir + scriptname for email in n[repos]: os.system("%s %s '%s' '%s' -s '[%s]' '%s'" % (interpreter, mailer, repospath, rev, repos, email))