def dispatch_request(path_info, req, env): """Main entry point for the Trac web interface.""" # Re-parse the configuration file if it changed since the last the time it # was parsed env.config.parse_if_needed() base_url = env.config.get('trac', 'base_url') if not base_url: base_url = absolute_url(req) req.base_url = base_url req.path_info = to_utf8(path_info) env.href = Href(req.cgi_location) env.abs_href = Href(req.base_url) db = env.get_db_cnx() try: try: dispatcher = RequestDispatcher(env) dispatcher.dispatch(req) except RequestDone: pass finally: db.close()
def url( req, argument_text, env): 'can be also done as html-inline-frame or html-object - instead of direct-insert-inline' import urllib url = argument_text try: f = urllib.urlopen( url) except: raise util.TracError( _error_url % locals() ) text = f.read() m = _re_meta_charset.search( text) if m: charset = m.group(1) text = util.to_utf8( text, charset.lower() ) if 0: path,suffix = os.path.splitext( argument_text) suffix = suffix[1:] #skip . from .xxx try: Format = WikiProcessor( env, suffix) html = Format.process( req, text) return html, None except: pass return util.Markup( text), None #raw?
def preview_to_hdf(self, req, mimetype, charset, content, filename, detail=None, annotations=None): max_preview_size = self.max_preview_size() if len(content) >= max_preview_size: return { 'max_file_size_reached': True, 'max_file_size': max_preview_size } if not is_binary(content): content = to_utf8(content, charset or self.preview_charset(content)) return { 'preview': self.render(req, mimetype, content, filename, detail, annotations) }
def _render_diff(self, req, repos, chgset, diff_options): """Raw Unified Diff version""" req.send_response(200) req.send_header('Content-Type', 'text/plain;charset=utf-8') req.send_header('Content-Disposition', 'filename=Changeset%s.diff' % req.args.get('rev')) req.end_headers() for path, kind, change, base_path, base_rev in chgset.get_changes(): if change == Changeset.ADD: old_node = None else: old_node = repos.get_node(base_path or path, base_rev) if change == Changeset.DELETE: new_node = None else: new_node = repos.get_node(path, chgset.rev) # TODO: Property changes # Content changes if kind == 'dir': continue default_charset = self.config.get('trac', 'default_charset') new_content = old_content = '' new_node_info = old_node_info = ('', '') if old_node: charset = mimeview.get_charset(old_node.content_type) or \ default_charset old_content = util.to_utf8(old_node.get_content().read(), charset) old_node_info = (old_node.path, old_node.rev) if mimeview.is_binary(old_content): continue if new_node: charset = mimeview.get_charset(new_node.content_type) or \ default_charset new_content = util.to_utf8(new_node.get_content().read(), charset) new_node_info = (new_node.path, new_node.rev) if mimeview.is_binary(new_content): continue if old_content != new_content: context = 3 for option in diff_options[1]: if option.startswith('-U'): context = int(option[2:]) break req.write('Index: ' + path + util.CRLF) req.write('=' * 67 + util.CRLF) req.write('--- %s (revision %s)' % old_node_info + util.CRLF) req.write('+++ %s (revision %s)' % new_node_info + util.CRLF) for line in unified_diff(old_content.splitlines(), new_content.splitlines(), context, ignore_blank_lines='-B' in diff_options[1], ignore_case='-i' in diff_options[1], ignore_space_changes='-b' in diff_options[1]): req.write(line + util.CRLF)
def _render_html(self, req, repos, chgset, diff_options): """HTML version""" req.hdf['title'] = '[%s]' % chgset.rev req.hdf['changeset'] = { 'revision': chgset.rev, 'time': time.strftime('%c', time.localtime(chgset.date)), 'author': util.escape(chgset.author or 'anonymous'), 'message': wiki_to_html(chgset.message or '--', self.env, req, escape_newlines=True) } oldest_rev = repos.oldest_rev if chgset.rev != oldest_rev: add_link(req, 'first', self.env.href.changeset(oldest_rev), 'Changeset %s' % oldest_rev) previous_rev = repos.previous_rev(chgset.rev) add_link(req, 'prev', self.env.href.changeset(previous_rev), 'Changeset %s' % previous_rev) youngest_rev = repos.youngest_rev if str(chgset.rev) != str(youngest_rev): next_rev = repos.next_rev(chgset.rev) add_link(req, 'next', self.env.href.changeset(next_rev), 'Changeset %s' % next_rev) add_link(req, 'last', self.env.href.changeset(youngest_rev), 'Changeset %s' % youngest_rev) edits = [] idx = 0 for path, kind, change, base_path, base_rev in chgset.get_changes(): info = {'change': change} if base_path: info['path.old'] = base_path info['rev.old'] = base_rev info['browser_href.old'] = self.env.href.browser(base_path, rev=base_rev) if path: info['path.new'] = path info['rev.new'] = chgset.rev info['browser_href.new'] = self.env.href.browser( path, rev=chgset.rev) if change in (Changeset.COPY, Changeset.EDIT, Changeset.MOVE): edits.append((idx, path, kind, base_path, base_rev)) req.hdf['changeset.changes.%d' % idx] = info idx += 1 hidden_properties = [ p.strip() for p in self.config.get('browser', 'hide_properties', 'svk:merge').split(',') ] for idx, path, kind, base_path, base_rev in edits: old_node = repos.get_node(base_path or path, base_rev) new_node = repos.get_node(path, chgset.rev) # Property changes old_props = old_node.get_properties() new_props = new_node.get_properties() changed_props = {} if old_props != new_props: for k, v in old_props.items(): if not k in new_props: changed_props[k] = {'old': v} elif v != new_props[k]: changed_props[k] = {'old': v, 'new': new_props[k]} for k, v in new_props.items(): if not k in old_props: changed_props[k] = {'new': v} for k in hidden_properties: if k in changed_props: del changed_props[k] req.hdf['changeset.changes.%d.props' % idx] = changed_props if kind == Node.DIRECTORY: continue # Content changes default_charset = self.config.get('trac', 'default_charset') old_content = old_node.get_content().read() if mimeview.is_binary(old_content): continue charset = mimeview.get_charset(old_node.content_type) or \ default_charset old_content = util.to_utf8(old_content, charset) new_content = new_node.get_content().read() if mimeview.is_binary(new_content): continue charset = mimeview.get_charset(new_node.content_type) or \ default_charset new_content = util.to_utf8(new_content, charset) if old_content != new_content: context = 3 for option in diff_options[1]: if option.startswith('-U'): context = int(option[2:]) break tabwidth = int( self.config.get('diff', 'tab_width', self.config.get('mimeviewer', 'tab_width'))) changes = hdf_diff(old_content.splitlines(), new_content.splitlines(), context, tabwidth, ignore_blank_lines='-B' in diff_options[1], ignore_case='-i' in diff_options[1], ignore_space_changes='-b' in diff_options[1]) req.hdf['changeset.changes.%d.diff' % idx] = changes
def render_downloads_table(env, req): """Prepares data for table of downloads.""" categories_d = {} releases_d = {} files_d = {} categories_obj, categories_list = Categories(env).list categories = [] for category in categories_list: category_dict = { 'id': category.id, 'name': category.name, 'notes': category.notes, 'sort': category.sort, 'timestamp': category.timestamp } # Format timestamp category_dict['timestamp'] = util.format_datetime( category_dict['timestamp']) releases_obj, releases_list = category.get_releases() releases = [] for release in releases_list: release_dict = { 'id': release.id, 'name': release.name, 'notes': release.notes, 'sort': release.sort, 'timestamp': release.timestamp } # Format timestamp release_dict['timestamp'] = util.format_datetime( release_dict['timestamp']) files_obj, files_list = release.get_files() files = [] for file in files_list: file_dict = { 'id': file.id, 'file': file.file, 'name': file.name, 'name_disp': file.name_disp, 'notes': file.notes, 'sort': file.sort, 'architecture': file.architecture, 'size': '', 'timestamp': file.timestamp } # Format timestamp file_dict['timestamp'] = \ util.format_datetime(file_dict['timestamp']) # Get filesize try: size = os.path.getsize(file.file) / 1024.0 size = round(size, 2) except OSError: env.log.warning("Cannot access file \"" + file.name +\ "\".") size = 0 size = util.to_utf8(locale.format("%0.2f", size, True)) file_dict['size'] = size files.append(file_dict) files_d[file_dict['id']] = file_dict release_dict['files'] = files releases.append(release_dict) releases_d[release_dict['id']] = release_dict category_dict['releases'] = releases categories.append(category_dict) categories_d[category_dict['id']] = category_dict req.hdf['categories_list'] = categories req.hdf['categories'] = categories_d req.hdf['releases'] = releases_d req.hdf['files'] = files_d
def render_downloads_table(env, req, filter=None, f_id=None): """Prepares data for table of downloads.""" categories_d = {} releases_d = {} files_d = {} categories_obj, categories_list = Categories(env).list categories = [] for category in categories_list: releases_obj, releases_list = category.get_releases() releases = [] # Skip unwanted records if filter == 'category' and f_id != category.id: continue elif filter == 'release': display = False for r in releases_list: if r.id == f_id: display = True if not display: continue category_dict = {'id': category.id, 'name': category.name, 'notes': category.notes, 'sort': category.sort, 'timestamp': category.timestamp} # Format timestamp category_dict['timestamp'] = util.format_datetime(category_dict['timestamp']) for release in releases_list: # Skip unwanted records if filter == 'release' and f_id != release.id: continue release_dict = {'id': release.id, 'name': release.name, 'notes': release.notes, 'sort': release.sort, 'timestamp': release.timestamp} # Format timestamp release_dict['timestamp'] = util.format_datetime(release_dict['timestamp']) files_obj, files_list = release.get_files() files = [] for file in files_list: file_dict = {'id': file.id, 'file': file.file, 'name': file.name, 'name_disp': file.name_disp, 'notes': file.notes, 'sort': file.sort, 'architecture': file.architecture, 'size': '', 'timestamp': file.timestamp} # Format timestamp file_dict['timestamp'] = \ util.format_datetime(file_dict['timestamp']) # Get filesize try: size = os.path.getsize(file.file) / 1024.0 size = round(size, 2) except OSError: env.log.warning("Cannot access file \"" + file.name +\ "\".") size = 0 size = util.to_utf8(locale.format("%0.2f", size, True)) file_dict['size'] = size files.append(file_dict) files_d[file_dict['id']] = file_dict release_dict['files'] = files releases.append(release_dict) releases_d[release_dict['id']] = release_dict category_dict['releases'] = releases categories.append(category_dict) categories_d[category_dict['id']] = category_dict req.hdf['categories_list'] = categories req.hdf['categories'] = categories_d req.hdf['releases'] = releases_d req.hdf['files'] = files_d
def _render_diff(self, req, repos, chgset, diff_options): """Raw Unified Diff version""" req.send_response(200) req.send_header('Content-Type', 'text/plain;charset=utf-8') req.send_header('Content-Disposition', 'inline;' 'filename=Changeset%s.diff' % chgset.rev) req.end_headers() for path, kind, change, base_path, base_rev in chgset.get_changes(): if change == Changeset.ADD: old_node = None else: old_node = repos.get_node(base_path or path, base_rev) if change == Changeset.DELETE: new_node = None else: new_node = repos.get_node(path, chgset.rev) # TODO: Property changes # Content changes if kind == 'dir': continue default_charset = self.config.get('trac', 'default_charset') new_content = old_content = '' new_node_info = old_node_info = ('','') if old_node: charset = mimeview.get_charset(old_node.content_type) or \ default_charset old_content = util.to_utf8(old_node.get_content().read(), charset) old_node_info = (old_node.path, old_node.rev) if mimeview.is_binary(old_content): continue if new_node: charset = mimeview.get_charset(new_node.content_type) or \ default_charset new_content = util.to_utf8(new_node.get_content().read(), charset) new_node_info = (new_node.path, new_node.rev) if mimeview.is_binary(new_content): continue if old_content != new_content: context = 3 for option in diff_options[1]: if option.startswith('-U'): context = int(option[2:]) break req.write('Index: ' + path + util.CRLF) req.write('=' * 67 + util.CRLF) req.write('--- %s (revision %s)' % old_node_info + util.CRLF) req.write('+++ %s (revision %s)' % new_node_info + util.CRLF) for line in unified_diff(old_content.splitlines(), new_content.splitlines(), context, ignore_blank_lines='-B' in diff_options[1], ignore_case='-i' in diff_options[1], ignore_space_changes='-b' in diff_options[1]): req.write(line + util.CRLF)
def _render_view(self, req, attachment): perm_map = {'ticket': 'TICKET_VIEW', 'wiki': 'WIKI_VIEW'} req.perm.assert_permission(perm_map[attachment.parent_type]) fmt = req.args.get('format') mimetype = fmt == 'txt' and 'text/plain' or \ get_mimetype(attachment.filename) or 'application/octet-stream' req.check_modified(attachment.time) # Render HTML view text, link = self._get_parent_link(attachment) add_link(req, 'up', link, text) req.hdf['title'] = attachment.title req.hdf['attachment'] = attachment_to_hdf(self.env, None, req, attachment) req.hdf['attachment.parent'] = { 'type': attachment.parent_type, 'id': attachment.parent_id, 'name': text, 'href': link, } raw_href = attachment.href(format='raw') add_link(req, 'alternate', raw_href, 'Original Format', mimetype) req.hdf['attachment.raw_href'] = raw_href perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'} if req.perm.has_permission(perm_map[attachment.parent_type]): req.hdf['attachment.can_delete'] = 1 self.log.debug("Rendering preview of file %s with mime-type %s" % (attachment.filename, mimetype)) fd = attachment.open() try: max_preview_size = int( self.config.get('mimeviewer', 'max_preview_size', '262144')) data = fd.read(max_preview_size) max_size_reached = len(data) == max_preview_size charset = detect_unicode(data) or self.config.get( 'trac', 'default_charset') if fmt in ('raw', 'txt'): # Send raw file req.send_file(attachment.path, mimetype + ';charset=' + charset) return if not is_binary(data): data = util.to_utf8(data, charset) add_link(req, 'alternate', attachment.href(format='txt'), 'Plain Text', mimetype) if max_size_reached: req.hdf['attachment.max_file_size_reached'] = 1 req.hdf['attachment.max_file_size'] = max_preview_size vdata = '' else: mimeview = Mimeview(self.env) vdata = mimeview.render(req, mimetype, data, attachment.filename) req.hdf['attachment.preview'] = vdata finally: fd.close()
def _render_file(self, req, repos, node, rev=None): req.perm.assert_permission('FILE_VIEW') changeset = repos.get_changeset(node.rev) req.hdf['file'] = { 'rev': node.rev, 'changeset_href': util.escape(self.env.href.changeset(node.rev)), 'date': time.strftime('%x %X', time.localtime(changeset.date)), 'age': util.pretty_timedelta(changeset.date), 'author': changeset.author or 'anonymous', 'message': wiki_to_html(changeset.message or '--', self.env, req, escape_newlines=True) } mime_type = node.content_type if not mime_type or mime_type == 'application/octet-stream': mime_type = get_mimetype(node.name) or mime_type or 'text/plain' # We don't have to guess if the charset is specified in the # svn:mime-type property ctpos = mime_type.find('charset=') if ctpos >= 0: charset = mime_type[ctpos + 8:] else: charset = None format = req.args.get('format') if format in ['raw', 'txt']: req.send_response(200) req.send_header('Content-Type', format == 'txt' and 'text/plain' or mime_type) req.send_header('Content-Length', node.content_length) req.send_header('Last-Modified', util.http_date(node.last_modified)) req.end_headers() content = node.get_content() while 1: chunk = content.read(CHUNK_SIZE) if not chunk: raise RequestDone req.write(chunk) else: # Generate HTML preview max_preview_size = int( self.config.get('mimeviewer', 'max_preview_size', '262144')) content = node.get_content().read(max_preview_size) max_size_reached = len(content) == max_preview_size if not charset: charset = detect_unicode(content) or \ self.config.get('trac', 'default_charset') if not is_binary(content): content = util.to_utf8(content, charset) if mime_type != 'text/plain': plain_href = self.env.href.browser(node.path, rev=rev and node.rev, format='txt') add_link(req, 'alternate', plain_href, 'Plain Text', 'text/plain') if max_size_reached: req.hdf['file.max_file_size_reached'] = 1 req.hdf['file.max_file_size'] = max_preview_size preview = ' ' else: preview = Mimeview(self.env).render(req, mime_type, content, node.name, node.rev, annotations=['lineno']) req.hdf['file.preview'] = preview raw_href = self.env.href.browser(node.path, rev=rev and node.rev, format='raw') req.hdf['file.raw_href'] = util.escape(raw_href) add_link(req, 'alternate', raw_href, 'Original Format', mime_type) add_stylesheet(req, 'common/css/code.css')