def load_components(env): loaded_components = [] plugins_dirs = [os.path.normcase(os.path.realpath(os.path.join(env.path, 'plugins'))), default_dir('plugins')] # First look for Python source files in the plugins directories, which # simply get imported, thereby registering them with the component manager # if they define any components. for plugins_dir in plugins_dirs: auto_enable = plugins_dir != default_dir('plugins') plugin_files = glob(os.path.join(plugins_dir, '*.py')) for plugin_file in plugin_files: try: plugin_name = os.path.basename(plugin_file[:-3]) if plugin_name not in loaded_components: env.log.debug('Loading file plugin %s from %s' % \ (plugin_name, plugin_file)) module = imp.load_source(plugin_name, plugin_file) loaded_components.append(plugin_name) if auto_enable and plugin_name + '.*' \ not in env.config['components']: env.config['components'].set(plugin_name + '.*', 'enabled') except Exception, e: env.log.error('Failed to load plugin from %s', plugin_file, exc_info=True)
def load_components(env): loaded_components = [] plugins_dirs = [ os.path.normcase(os.path.realpath(os.path.join(env.path, 'plugins'))), default_dir('plugins') ] # First look for Python source files in the plugins directories, which # simply get imported, thereby registering them with the component manager # if they define any components. for plugins_dir in plugins_dirs: auto_enable = plugins_dir != default_dir('plugins') plugin_files = glob(os.path.join(plugins_dir, '*.py')) for plugin_file in plugin_files: try: plugin_name = os.path.basename(plugin_file[:-3]) if plugin_name not in loaded_components: env.log.debug('Loading file plugin %s from %s' % \ (plugin_name, plugin_file)) module = imp.load_source(plugin_name, plugin_file) loaded_components.append(plugin_name) if auto_enable and plugin_name + '.*' \ not in env.config['components']: env.config['components'].set(plugin_name + '.*', 'enabled') except Exception, e: env.log.error('Failed to load plugin from %s', plugin_file, exc_info=True)
def send_project_index(req, options, env_paths=None): from trac.web.clearsilver import HDFWrapper if 'TRAC_ENV_INDEX_TEMPLATE' in options: tmpl_path, template = os.path.split(options['TRAC_ENV_INDEX_TEMPLATE']) from trac.config import default_dir req.hdf = HDFWrapper(loadpaths=[default_dir('templates'), tmpl_path]) tmpl_vars = {} if 'TRAC_TEMPLATE_VARS' in options: for pair in options['TRAC_TEMPLATE_VARS'].split(','): key, val = pair.split('=') req.hdf[key] = val else: req.hdf = HDFWrapper() template = req.hdf.parse('''<html> <head><title>Available Projects</title></head> <body><h1>Available Projects</h1><ul><?cs each:project = projects ?><li><?cs if:project.href ?> <a href="<?cs var:project.href ?>" title="<?cs var:project.description ?>"> <?cs var:project.name ?></a><?cs else ?> <small><?cs var:project.name ?>: <em>Error</em> <br /> (<?cs var:project.description ?>)</small><?cs /if ?> </li><?cs /each ?></ul></body> </html>''') if not env_paths and 'TRAC_ENV_PARENT_DIR' in options: dir = options['TRAC_ENV_PARENT_DIR'] env_paths = [os.path.join(dir, f) for f in os.listdir(dir)] href = Href(req.idx_location) try: projects = [] for env_path in env_paths: if not os.path.isdir(env_path): continue env_dir, project = os.path.split(env_path) try: env = _open_environment(env_path) proj = { 'name': env.config.get('project', 'name'), 'description': env.config.get('project', 'descr'), 'href': href(project) } except Exception, e: proj = {'name': project, 'description': str(e)} projects.append(proj) projects.sort(lambda x, y: cmp(x['name'], y['name'])) req.hdf['projects'] = projects # TODO maybe this should be 404 if index wasn't specifically requested req.display(template, response=200)
def _new_macros(self): from trac.config import default_dir macros_dir = default_dir('macros') for f in os.listdir(macros_dir): if not f.endswith('.py'): continue src = os.path.join(macros_dir, f) dst = os.path.join(self.env.path, 'wiki-macros', f) if not os.path.isfile(dst): yield src, dst
def execute_setup_action(self, req, proj, action, args): repo_type = hasattr(proj, 'repo_type') and proj.repo_type or 'svn' repo_path = hasattr(proj, 'repo_path') and proj.repo_path or '' from trac.config import default_dir from trac.scripts.admin import run return run([proj.env_path, 'initenv', req.args.get('fullname','').strip(), 'sqlite:db/trac.db', repo_type.strip(), repo_path.strip(), default_dir('templates'), ]) == 0
def execute_setup_action(self, req, proj, action, args): repo_type = hasattr(proj, 'repo_type') and proj.repo_type or 'svn' repo_path = hasattr(proj, 'repo_path') and proj.repo_path or '' from trac.config import default_dir from trac.scripts.admin import run return run([ proj.env_path, 'initenv', req.args.get('fullname', '').strip(), 'sqlite:db/trac.db', repo_type.strip(), repo_path.strip(), default_dir('templates'), ]) == 0
def send_project_index(environ, start_response, parent_dir=None, env_paths=None): from trac.config import default_dir req = Request(environ, start_response) loadpaths = [default_dir('templates')] if req.environ.get('trac.env_index_template'): tmpl_path, template = os.path.split( req.environ['trac.env_index_template']) loadpaths.insert(0, tmpl_path) else: template = 'index.cs' req.hdf = HDFWrapper(loadpaths) tmpl_vars = {} if req.environ.get('trac.template_vars'): for pair in req.environ['trac.template_vars'].split(','): key, val = pair.split('=') req.hdf[key] = val if parent_dir and not env_paths: env_paths = dict([(filename, os.path.join(parent_dir, filename)) for filename in os.listdir(parent_dir)]) try: href = Href(req.base_path) projects = [] for env_name, env_path in get_environments(environ).items(): try: env = _open_environment(env_path, run_once=environ['wsgi.run_once']) proj = { 'name': env.project_name, 'description': env.project_description, 'href': href(env_name) } except Exception, e: proj = {'name': env_name, 'description': to_unicode(e)} projects.append(proj) projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower())) req.hdf['projects'] = projects req.display(template)
def send_project_index(environ, start_response, parent_dir=None, env_paths=None): from trac.config import default_dir req = Request(environ, start_response) loadpaths = [default_dir('templates')] if req.environ.get('trac.env_index_template'): tmpl_path, template = os.path.split(req.environ['trac.env_index_template']) loadpaths.insert(0, tmpl_path) else: template = 'index.cs' req.hdf = HDFWrapper(loadpaths) tmpl_vars = {} if req.environ.get('trac.template_vars'): for pair in req.environ['trac.template_vars'].split(','): key, val = pair.split('=') req.hdf[key] = val if parent_dir and not env_paths: env_paths = dict([(filename, os.path.join(parent_dir, filename)) for filename in os.listdir(parent_dir)]) try: href = Href(req.base_path) projects = [] for env_name, env_path in get_environments(environ).items(): try: env = _open_environment(env_path, run_once=environ['wsgi.run_once']) proj = { 'name': env.project_name, 'description': env.project_description, 'href': href(env_name) } except Exception, e: proj = {'name': env_name, 'description': to_unicode(e)} projects.append(proj) projects.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower())) req.hdf['projects'] = projects req.display(template)
def _list_wiki_default_pages(): """List wiki page files in 'wiki-default' directory. This is aimed to know page names to be categorized as 'system'. """ # get wiki-default directory try: # try for 0.10.x from trac.config import default_dir dir = default_dir('wiki') except: # try for 0.11.x (with setup tools) import pkg_resources dir = pkg_resources.resource_filename('trac.wiki', 'default-pages') if not os.path.isdir(dir): return [] pages = [] # list wiki default pages. No need to include lang variations here. re_wiki_page = re.compile(r'[A-Z][a-zA-Z0-9]+') for f in os.listdir(dir): if re_wiki_page.match(f): pages.append(f) return pages
def get_htdocs_dirs(self): from trac.config import default_dir return [('common', default_dir('htdocs')), ('site', self.env.get_htdocs_dir())]
def __init__(self): self.env_macros = os.path.join(self.env.path, 'wiki-macros') self.site_macros = default_dir('macros')
class Chrome(Component): """Responsible for assembling the web site chrome, i.e. everything that is not actual page content. """ implements(IEnvironmentSetupParticipant, IRequestHandler, ITemplateProvider, IWikiSyntaxProvider) navigation_contributors = ExtensionPoint(INavigationContributor) template_providers = ExtensionPoint(ITemplateProvider) templates_dir = Option('trac', 'templates_dir', default_dir('templates'), """Path to the !ClearSilver templates.""") htdocs_location = Option('trac', 'htdocs_location', '', """Base URL of the core static resources.""") metanav_order = ListOption( 'trac', 'metanav', 'login,logout,settings,help,about', doc="""List of items IDs to display in the navigation bar `metanav`.""" ) mainnav_order = ListOption( 'trac', 'mainnav', 'wiki,timeline,roadmap,browser,tickets,' 'newticket,search', doc="""List of item IDs to display in the navigation bar `mainnav`.""") logo_link = Option('header_logo', 'link', 'http://example.org/', """URL to link to from header logo.""") logo_src = Option('header_logo', 'src', 'common/trac_banner.png', """URL of the image to use as header logo.""") logo_alt = Option('header_logo', 'alt', '', """Alternative text for the header logo.""") logo_width = IntOption('header_logo', 'width', -1, """Width of the header logo image in pixels.""") logo_height = IntOption('header_logo', 'height', -1, """Height of the header logo image in pixels.""") # IEnvironmentSetupParticipant methods def environment_created(self): """Create the templates directory and some templates for customization. """ def _create_file(filename, data=None): fd = open(filename, 'w') if data: fd.write(data) fd.close() if self.env.path: templates_dir = os.path.join(self.env.path, 'templates') if not os.path.exists(templates_dir): os.mkdir(templates_dir) _create_file( os.path.join(templates_dir, 'README'), 'This directory contains project-specific custom ' 'templates and style sheet.\n') _create_file( os.path.join(templates_dir, 'site_header.cs'), """<?cs #################################################################### # Site header - Contents are automatically inserted above Trac HTML ?> """) _create_file( os.path.join(templates_dir, 'site_footer.cs'), """<?cs ######################################################################### # Site footer - Contents are automatically inserted after main Trac HTML ?> """) _create_file( os.path.join(templates_dir, 'site_css.cs'), """<?cs ################################################################## # Site CSS - Place custom CSS, including overriding styles here. ?> """) def environment_needs_upgrade(self, db): return False def upgrade_environment(self, db): pass # IRequestHandler methods anonymous_request = True use_template = False def match_request(self, req): match = re.match(r'/chrome/(?P<prefix>[^/]+)/(?P<filename>[/\w\-\.]+)', req.path_info) if match: req.args['prefix'] = match.group('prefix') req.args['filename'] = match.group('filename') return True def process_request(self, req): prefix = req.args['prefix'] filename = req.args['filename'] dirs = [] for provider in self.template_providers: for dir in [ os.path.normpath(dir[1]) for dir in provider.get_htdocs_dirs() if dir[0] == prefix ]: dirs.append(dir) path = os.path.normpath(os.path.join(dir, filename)) assert os.path.commonprefix([dir, path]) == dir if os.path.isfile(path): req.send_file(path, mimeview.get_mimetype(path)) self.log.warning('File %s not found in any of %s', filename, dirs) raise HTTPNotFound('File %s not found', filename) # ITemplateProvider methods def get_htdocs_dirs(self): from trac.config import default_dir return [('common', default_dir('htdocs')), ('site', self.env.get_htdocs_dir())] def get_templates_dirs(self): return [self.env.get_templates_dir(), self.templates_dir] # IWikiSyntaxProvider methods def get_wiki_syntax(self): return [] def get_link_resolvers(self): yield ('htdocs', self._format_link) def _format_link(self, formatter, ns, file, label): return html.A(label, href=formatter.href.chrome('site', file)) # Public API methods def get_all_templates_dirs(self): """Return a list of the names of all known templates directories.""" dirs = [] for provider in self.template_providers: dirs += provider.get_templates_dirs() return dirs def populate_hdf(self, req, handler): """Add chrome-related data to the HDF.""" # Provided for template customization req.hdf['HTTP.PathInfo'] = req.path_info href = Href(req.base_path) req.hdf['chrome.href'] = href.chrome() htdocs_location = self.htdocs_location or href.chrome('common') req.hdf['htdocs_location'] = htdocs_location.rstrip('/') + '/' # HTML <head> links add_link(req, 'start', req.href.wiki()) add_link(req, 'search', req.href.search()) add_link(req, 'help', req.href.wiki('TracGuide')) add_stylesheet(req, 'common/css/trac.css') add_script(req, 'common/js/trac.js') icon = self.env.project_icon if icon: if not icon.startswith('/') and icon.find('://') == -1: if '/' in icon: icon = href.chrome(icon) else: icon = href.chrome('common', icon) mimetype = mimeview.get_mimetype(icon) add_link(req, 'icon', icon, mimetype=mimetype) add_link(req, 'shortcut icon', icon, mimetype=mimetype) # Logo image logo_src = self.logo_src if logo_src: logo_src_abs = logo_src.startswith('http://') or \ logo_src.startswith('https://') if not logo_src.startswith('/') and not logo_src_abs: if '/' in logo_src: logo_src = href.chrome(logo_src) else: logo_src = href.chrome('common', logo_src) width = self.logo_width > -1 and self.logo_width height = self.logo_height > -1 and self.logo_height req.hdf['chrome.logo'] = { 'link': self.logo_link, 'src': logo_src, 'src_abs': logo_src_abs, 'alt': self.logo_alt, 'width': width, 'height': height } else: req.hdf['chrome.logo.link'] = self.logo_link # Navigation links navigation = {} active = None for contributor in self.navigation_contributors: for category, name, text in contributor.get_navigation_items(req): navigation.setdefault(category, {})[name] = text if contributor is handler: active = contributor.get_active_navigation_item(req) for category, items in [(k, v.items()) for k, v in navigation.items()]: category_order = category + '_order' if hasattr(self, category_order): order = getattr(self, category_order) def navcmp(x, y): if x[0] not in order: return int(y[0] in order) if y[0] not in order: return -int(x[0] in order) return cmp(order.index(x[0]), order.index(y[0])) items.sort(navcmp) for name, text in items: req.hdf['chrome.nav.%s.%s' % (category, name)] = text if name == active: req.hdf['chrome.nav.%s.%s.active' % (category, name)] = 1
'to locate the Trac environment(s).') run_once = environ['wsgi.run_once'] env = env_error = None try: env = _open_environment(env_path, run_once=run_once) if env.base_url: environ['trac.base_url'] = env.base_url except TracError, e: env_error = e req = Request(environ, start_response) try: if not env and env_error: from trac.config import default_dir req.hdf = HDFWrapper([default_dir('templates')]) raise HTTPInternalError(env_error.message) try: try: dispatcher = RequestDispatcher(env) dispatcher.dispatch(req) except RequestDone: pass return req._response or [] finally: if not run_once: env.shutdown(threading._get_ident()) except HTTPException, e: if env: env.log.warn(e)
'WIKI_VIEW'), ('anonymous', 'WIKI_CREATE'), ('anonymous', 'WIKI_MODIFY'), ('anonymous', 'SEARCH_VIEW'), ('anonymous', 'REPORT_VIEW'), ('anonymous', 'REPORT_SQL_VIEW'), ('anonymous', 'TICKET_VIEW'), ('anonymous', 'TICKET_CREATE'), ('anonymous', 'TICKET_MODIFY'), ('anonymous', 'BROWSER_VIEW'), ('anonymous', 'TIMELINE_VIEW'), ('anonymous', 'CHANGESET_VIEW'), ('anonymous', 'ROADMAP_VIEW'), ('anonymous', 'MILESTONE_VIEW'))), ('system', ('name', 'value'), (('database_version', str(db_version)), )), ('report', ('author', 'title', 'sql', 'description'), __mkreports(reports))) default_config = \ (('trac', 'repository_dir', ''), ('trac', 'templates_dir', default_dir('templates')), ('trac', 'database', 'sqlite:db/trac.db'), ('trac', 'default_charset', 'iso-8859-15'), ('trac', 'default_handler', 'WikiModule'), ('trac', 'check_auth_ip', 'true'), ('trac', 'ignore_auth_case', 'false'), ('trac', 'metanav', 'login,logout,settings,help,about'), ('trac', 'mainnav', 'wiki,timeline,roadmap,browser,tickets,newticket,search'), ('trac', 'permission_store', 'DefaultPermissionStore'), ('logging', 'log_type', 'none'), ('logging', 'log_file', 'trac.log'), ('logging', 'log_level', 'DEBUG'), ('project', 'name', 'My Project'), ('project', 'descr', 'My example project'), ('project', 'url', 'http://example.com/'), ('project', 'icon', 'common/trac.ico'),
def __init__(self): self.env_macros = os.path.join(self.env.path, "wiki-macros") self.site_macros = default_dir("macros")