# -*- coding: iso8859-1 -*- # # Copyright (C) 2003, 2004 Edgewall Software # Copyright (C) 2003, 2004 Jonas Borgström # # Trac is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # Trac 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Author: Jonas Borgström import os import re import sys import cgi import warnings from PermissionError import PermissionError warnings.filterwarnings('ignore', 'DB-API extension cursor.next() used') modules = { # name module class need_db need_svn 'log' : ('Log', 'Log', 1), 'file' : ('File', 'File', 1), 'wiki' : ('Wiki', 'Wiki', 0), 'about' : ('About', 'About', 0), 'search' : ('Search', 'Search', 0), 'report' : ('Report', 'Report', 0), 'ticket' : ('Ticket', 'Ticket', 0), 'browser' : ('Browser', 'Browser', 1), 'timeline' : ('Timeline', 'Timeline', 1), 'changeset' : ('Changeset', 'Changeset', 1), 'newticket' : ('Ticket', 'Newticket', 0), } def parse_args(): args = {} info = os.getenv ('PATH_INFO') if not info: return args match = re.search('/about(/?.*)', info) if match: args['mode'] = 'about' if len(match.group(1)) > 0: args['page'] = match.group(1) return args if re.search('/newticket/?', info): args['mode'] = 'newticket' return args if re.search('/timeline/?', info): args['mode'] = 'timeline' return args if re.search('/search/?', info): args['mode'] = 'search' return args match = re.search('/wiki/(.*[^/])/?', info) if match: args['mode'] = 'wiki' if len(match.group(1)) > 0: args['page'] = match.group(1) return args match = re.search('/ticket/([0-9]+)/?', info) if match: args['mode'] = 'ticket' args['id'] = match.group(1) return args match = re.search('/report/([0-9]*)/?', info) if match: args['mode'] = 'report' if len(match.group(1)) > 0: args['id'] = match.group(1) return args match = re.search('/browser(/?.*)', info) if match: args['mode'] = 'browser' if len(match.group(1)) > 0: args['path'] = match.group(1) return args match = re.search('/log/(.+)', info) if match: args['mode'] = 'log' args['path'] = match.group(1) return args match = re.search('/file/(.+)/?', info) if match: args['mode'] = 'file' args['path'] = match.group(1) return args match = re.search('/changeset/([0-9]+)/?', info) if match: args['mode'] = 'changeset' args['rev'] = match.group(1) return args return args def real_main(): import Href import db from util import dict_get_with_default, redirect from auth import verify_authentication, authenticate_user from perm import cache_permissions, PermissionError, perm_to_hdf db.init() config = db.load_config() Href.initialize(config) args = parse_args() _args = cgi.FieldStorage() for x in _args.keys(): args[x] = _args[x].value mode = dict_get_with_default(args, 'mode', 'wiki') module_name, constructor_name, need_svn = modules[mode] module = __import__(module_name, globals(), locals(), []) constructor = getattr(module, constructor_name) module = constructor(config, args) module._name = mode verify_authentication(args) cache_permissions() perm_to_hdf(module.cgi.hdf) # Only open the subversion repository for the modules that really # need it. This saves us some precious time. if need_svn: from svn import util, repos, core core.apr_initialize() pool = core.svn_pool_create(None) repos_dir = config['general']['repository_dir'] rep = repos.svn_repos_open(repos_dir, pool) fs_ptr = repos.svn_repos_fs(rep) module.repos = rep module.fs_ptr = fs_ptr db.sync(rep, fs_ptr, pool) else: pool = None # Let the wiki module build a dictionary of all page names import Wiki Wiki.populate_page_dict() module.pool = pool module.run() if pool: core.svn_pool_destroy(pool) core.apr_terminate() def create_error_cgi(): import neo_cgi import os.path import db from auth import get_authname from Href import href cnx = db.get_connection() cursor = cnx.cursor() cursor.execute('SELECT value FROM config WHERE section=%s ' 'AND name=%s', 'general', 'templates_dir') row = cursor.fetchone() templates_dir = row[0] cursor.execute('SELECT value FROM config WHERE section=%s ' 'AND name=%s', 'general', 'htdocs_location') row = cursor.fetchone() htdocs_location = row[0] cgi = neo_cgi.CGI() cgi.hdf.setValue('hdf.loadpaths.0', templates_dir) cgi.hdf.setValue('htdocs_location', htdocs_location) cgi.hdf.setValue('trac.authname', get_authname()) cgi.hdf.setValue('trac.href.wiki', href.wiki()) cgi.hdf.setValue('trac.href.browser', href.browser('/')) cgi.hdf.setValue('trac.href.timeline', href.timeline()) cgi.hdf.setValue('trac.href.report', href.report()) cgi.hdf.setValue('trac.href.newticket', href.newticket()) cgi.hdf.setValue('trac.href.search', href.search()) cgi.hdf.setValue('trac.href.about', href.about()) cgi.hdf.setValue('trac.href.about_config', href.about('config/')) cgi.hdf.setValue('trac.href.login', href.login()) cgi.hdf.setValue('trac.href.logout', href.logout()) cgi.hdf.setValue('trac.href.homepage', 'http://trac.edgewall.com/') return cgi, templates_dir def main(): real_e = None real_tb = None # In case of an exception. First try to display a fancy error # message using the error.cs template. If that failes fall # back to a plain/text version. try: try: real_main() except PermissionError, e: import traceback import StringIO tb = StringIO.StringIO() traceback.print_exc(file=tb) real_e = e real_tb = tb cgi, templates_dir = create_error_cgi() cgi.hdf.setValue('title', 'Permission Denied') cgi.hdf.setValue('error.type', 'permission') cgi.hdf.setValue('error.action', e.action) cgi.hdf.setValue('error.message', str(e)) cgi.hdf.setValue('error.traceback',tb.getvalue()) name = os.path.join (templates_dir, 'error.cs') cgi.display(name) except Exception, e: import traceback import StringIO tb = StringIO.StringIO() traceback.print_exc(file=tb) real_e = e real_tb = tb cgi, templates_dir = create_error_cgi() cgi.hdf.setValue('title', 'Oups') cgi.hdf.setValue('error.type', 'internal') cgi.hdf.setValue('error.message', str(e)) cgi.hdf.setValue('error.traceback',tb.getvalue()) name = os.path.join (templates_dir, 'error.cs') cgi.display(name) except Exception: print 'Content-Type: text/plain\r\n\r\n', print 'Oups...' print print 'Trac detected an internal error:' print print real_e print print real_tb.getvalue()