Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP3:Update
viewvc
viewvc-buglink.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File viewvc-buglink.patch of Package viewvc
Index: conf/viewvc.conf.dist =================================================================== --- conf/viewvc.conf.dist.orig +++ conf/viewvc.conf.dist @@ -343,6 +343,21 @@ ##--------------------------------------------------------------------------- [options] +## The 'buglink_base' value is a string that can be used to form a URL +## by appending a bug number. If viewvc sees something that looks +## like a bug number in a log message (eg. "bug 12345" or "#12345"), it +## will be displayed as a link to the bug in your bug tracking system. +## +## For a Bugzilla installation, you probably want to set this to +## something like "http://hostname/show_bug.cgi?id=". For the Debian +## bug tracker, you might use +## "http://hostname/cgi-bin/bugreport.cgi?bug=". +## +## If 'buglink_base' is not set, then bug tracker links won't be +## generated. +## +#buglink_base = http://example.com/show_bug.cgi?id= + ## root_as_url_component: Interpret the first path component in the URL ## after the script location as the root to use. This is an ## alternative to using the "root=" query key. If ViewVC is configured Index: lib/config.py =================================================================== --- lib/config.py.orig +++ lib/config.py @@ -52,7 +52,7 @@ import fnmatch # Here's a diagram of the valid overlays/overrides: # # PER-ROOT PER-VHOST BASE -# +# # ,-----------. ,-----------. # | vhost-*/ | | | # | general | --> | general | @@ -150,13 +150,13 @@ class Config: settings there as overrides to the built-in default values. If VHOST is provided, also process the configuration overrides specific to that virtual host.""" - + self.conf_path = os.path.isfile(pathname) and pathname or None self.base = os.path.dirname(pathname) self.parser = ConfigParser.ConfigParser() self.parser.optionxform = lambda x: x # don't case-normalize option names. self.parser.read(self.conf_path or []) - + for section in self.parser.sections(): if self._is_allowed_section(section, self._base_sections): self._process_section(self.parser, section, section) @@ -168,7 +168,7 @@ class Config: """Process the key/value (kv) files specified in the configuration, merging their values into the configuration as dotted heirarchical items.""" - + kv = _sub_config() for fname in self.general.kv_files: @@ -228,7 +228,7 @@ class Config: """Return 1 iff SECTION is an allowed section, defined as being explicitly present in the ALLOWED_SECTIONS list or present in the form 'someprefix-*' in that list.""" - + for allowed_section in allowed_sections: if allowed_section[-1] == '*': if _startswith(section, allowed_section[:-1]): @@ -284,7 +284,7 @@ class Config: set. This is a destructive change to the configuration.""" did_overlay = 0 - + if not self.conf_path: return @@ -374,7 +374,7 @@ class Config: for attr in dir(sub_config): params[attr] = getattr(sub_config, attr) return params - + def set_defaults(self): "Set some default values in the configuration." @@ -445,6 +445,7 @@ class Config: self.options.log_pagesextra = 3 self.options.limit_changes = 100 self.options.stacktraces = 0 + self.options.buglink_base = None self.templates.diff = None self.templates.directory = None @@ -464,13 +465,13 @@ class Config: self.cvsdb.user = '' self.cvsdb.passwd = '' self.cvsdb.readonly_user = '' - self.cvsdb.readonly_passwd = '' + self.cvsdb.readonly_passwd = '' self.cvsdb.row_limit = 1000 self.cvsdb.rss_row_limit = 100 self.cvsdb.check_database_for_root = 0 self.query.viewvc_base_url = None - + def _startswith(somestr, substr): return somestr[:len(substr)] == substr @@ -494,7 +495,7 @@ class IllegalOverrideSection(ViewVCConfi def __str__(self): return "malformed configuration: illegal %s override section: %s" \ % (self.override_type, self.section_name) - + class MalformedRoot(ViewVCConfigurationError): def __init__(self, config_name, value_given): Exception.__init__(self, config_name, value_given) Index: lib/viewvc.py =================================================================== --- lib/viewvc.py.orig +++ lib/viewvc.py @@ -154,7 +154,7 @@ class Request: for name, values in self.server.params().items(): # we only care about the first value value = values[0] - + # patch up old queries that use 'cvsroot' to look like they used 'root' if name == 'cvsroot': name = 'root' @@ -172,12 +172,12 @@ class Request: # validate the parameter _validate_param(name, value) - + # if we're here, then the parameter is okay self.query_dict[name] = value # Resolve the view parameter into a handler function. - self.view_func = _views.get(self.query_dict.get('view', None), + self.view_func = _views.get(self.query_dict.get('view', None), self.view_func) # Process PATH_INFO component of query string @@ -239,7 +239,7 @@ class Request: if roottype: # Overlay root-specific options. cfg.overlay_root_options(self.rootname) - + # Setup an Authorizer for this rootname and username debug.t_start('setup-authorizer') self.auth = setup_authorizer(cfg, self.username) @@ -290,7 +290,7 @@ class Request: 'The root "%s" has an unknown type ("%s"). Expected "cvs" or "svn".' % (self.rootname, type), "500 Internal Server Error") - + # If this is using an old-style 'rev' parameter, redirect to new hotness. # Subversion URLs will now use 'pathrev'; CVS ones use 'revision'. if self.repos and self.query_dict.has_key('rev'): @@ -356,7 +356,7 @@ class Request: needs_redirect = 1 if self.view_func is None: - # view parameter is not set, try looking at pathtype and the + # view parameter is not set, try looking at pathtype and the # other parameters if not self.rootname: self.view_func = view_roots @@ -374,7 +374,7 @@ class Request: elif self.query_dict.has_key('graph'): if not self.query_dict.has_key('makeimage'): self.view_func = view_cvsgraph - else: + else: self.view_func = view_cvsgraph_image elif self.query_dict.has_key('revision') \ or cfg.options.default_file_view != "log": @@ -394,7 +394,7 @@ class Request: self.where = '' self.path_parts = [] self.pathtype = None - + # if we have a directory and the request didn't end in "/", then redirect # so that it does. if (self.pathtype == vclib.DIR and path_info[-1:] != '/' @@ -454,7 +454,7 @@ class Request: def get_link(self, view_func=None, where=None, pathtype=None, params=None): """Constructs a link pointing to another ViewVC page. All arguments - correspond to members of the Request object. If they are set to + correspond to members of the Request object. If they are set to None they take values from the current page. Return value is a base URL and a dictionary of parameters""" @@ -467,7 +467,7 @@ class Request: params = self.query_dict.copy() else: params = params.copy() - + # must specify both where and pathtype or neither assert (where is None) == (pathtype is None) @@ -481,7 +481,7 @@ class Request: pathtype = self.pathtype # no need to add sticky variables for views with no links - sticky_vars = not (view_func is view_checkout + sticky_vars = not (view_func is view_checkout or view_func is download_tarball) # The logic used to construct the URL is an inverse of the @@ -518,7 +518,7 @@ class Request: # no need to specify default root if rootname == cfg.general.default_root: - del params['root'] + del params['root'] # add 'pathrev' value to parameter list if (self.pathrev is not None @@ -606,7 +606,7 @@ def _normalize_path(path): because we output the script name in links and web browsers interpret //viewvc.cgi/ as http://viewvc.cgi/ """ - + i = 0 for c in path: if c != '/': @@ -687,7 +687,7 @@ _legal_params = { 'search' : _validate_regex, 'p1' : None, 'p2' : None, - + 'hideattic' : _re_validate_boolint, 'limit_changes' : _re_validate_number, 'sortby' : _re_validate_alpha, @@ -787,7 +787,7 @@ def _orig_path(request, rev_param='revis # *checkout*/circle.jpg?pathrev=3 # *checkout*/square.jpg?revision=3 # *checkout*/square.jpg?revision=3&pathrev=4 - # + # # Note that the following: # # *checkout*/circle.jpg?rev=3 @@ -799,7 +799,7 @@ def _orig_path(request, rev_param='revis # rev = request.query_dict.get(rev_param, request.pathrev) path = request.query_dict.get(path_param, request.where) - + if rev is not None and hasattr(request.repos, '_getrev'): try: pathrev = request.repos._getrev(request.pathrev) @@ -813,7 +813,7 @@ def setup_authorizer(cfg, username, root """Setup the authorizer. If ROOTNAME is provided, assume that per-root options have not been overlayed. Otherwise, assume they have (and fetch the authorizer for the configured root).""" - + if rootname is None: authorizer = cfg.options.authorizer params = cfg.get_authorizer_params() @@ -853,7 +853,7 @@ def check_freshness(request, mtime=None, # See if we are supposed to disable etags (for debugging, usually) if not cfg.options.generate_etags: return 0 - + request_etag = request_mtime = None if etag is not None: if weak: @@ -937,7 +937,7 @@ def get_writeready_server_file(request, request.server.addheader('Content-Encoding', 'gzip') elif content_length is not None: request.server.addheader('Content-Length', content_length) - + if content_type and encoding: request.server.header("%s; charset=%s" % (content_type, encoding)) elif content_type: @@ -950,9 +950,9 @@ def get_writeready_server_file(request, request.server.file()) else: fp = request.server.file() - + return fp - + def generate_page(request, view_name, data, content_type=None): server_fp = get_writeready_server_file(request, content_type) template = get_view_template(request.cfg, view_name, request.language) @@ -1040,7 +1040,7 @@ def default_view(mime_type, cfg): # very useful marked up. If the mime type is totally unknown (happens when # we encounter an unrecognized file extension) we also view it through # the markup page since that's better than sending it text/plain. - if ('markup' in cfg.options.allowed_views and + if ('markup' in cfg.options.allowed_views and (is_viewable_image(mime_type) or is_text(mime_type))): return view_markup return view_checkout @@ -1053,7 +1053,7 @@ def is_binary_file_mime_type(mime_type, if fnmatch.fnmatch(mime_type, pattern): return True return False - + def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1): """Return an object holding common hrefs and a viewability flag used for various views of FILENAME at revision REV whose MIME type is @@ -1068,9 +1068,9 @@ def get_file_view_info(request, where, r prefer_markup is_viewable_image is_binary - + """ - + rev = rev and str(rev) or None mime_type = mime_type or guess_mime(where) if pathrev == -1: # cheesy default value, since we need to preserve None @@ -1167,7 +1167,11 @@ class ViewVCHtmlFormatterTokens: return out, out_len, 1 return out, out_len, 0 - + +# Matches bug numbers +_re_rewrite_bug = re.compile(r'((?:\bbug[\s:#+]|[^&]#|^#)\s*(\d\d+))', re.I) +_re_buglink_prefix = "" + class ViewVCHtmlFormatter: """Format a string as HTML-encoded output with customizable markup rules, for example turning strings that look like URLs into anchor links. @@ -1176,10 +1180,23 @@ class ViewVCHtmlFormatter: interface, there is a good chance that there are consumers outside of ViewVC itself that make use of these things. """ - + def __init__(self): self._formatters = [] + def format_bugzilla(self, mobj, userdata, maxlen=0): + """Return a 2-tuple containing: + - the text represented by MatchObject MOBJ, formatted as + linkified URL, with no more than MAXLEN characters in the + non-HTML-tag bits. If MAXLEN is 0, there is no maximum. + - the number of non-HTML-tag characters returned. + """ + s = mobj.group(0) + trunc_s = maxlen and s[:maxlen] or s + return '<a href="%s%s">%s</a>' % (_re_buglink_prefix, urllib.quote(mobj.group(2)), + sapi.escape(trunc_s)), \ + len(trunc_s) + def format_url(self, mobj, userdata, maxlen=0): """Return a 2-tuple containing: - the text represented by MatchObject MOBJ, formatted as @@ -1212,7 +1229,7 @@ class ViewVCHtmlFormatter: entity-encoded email address, with no more than MAXLEN characters in the non-HTML-tag bits. If MAXLEN is 0, there is no maximum. - the number of non-HTML-tag characters returned. - """ + """ s = mobj.group(0) trunc_s = maxlen and s[:maxlen] or s return self._entity_encode(trunc_s), len(trunc_s) @@ -1282,10 +1299,10 @@ class ViewVCHtmlFormatter: - the text S, HTML-escaped, containing no more than MAXLEN characters. If MAXLEN is 0, there is no maximum. - the number of characters returned. - """ + """ trunc_s = maxlen and s[:maxlen] or s return sapi.escape(trunc_s), len(trunc_s) - + def add_formatter(self, regexp, conv, userdata=None): """Register a formatter which finds instances of strings matching REGEXP, and using the function CONV and USERDATA to format them. @@ -1375,11 +1392,11 @@ class LogFormatter: def get(self, maxlen=0, htmlize=1): cfg = self.request.cfg - + # Prefer the cache. if self.cache.has_key((maxlen, htmlize)): return self.cache[(maxlen, htmlize)] - + # If we are HTML-izing... if htmlize: # ...and we don't yet have ViewVCHtmlFormatter() object tokens... @@ -1399,6 +1416,11 @@ class LogFormatter: lf.add_formatter(_re_rewrite_svnrevref, lf.format_svnrevref, revision_to_url) + if cfg.options.buglink_base is not None: + global _re_buglink_prefix + _re_buglink_prefix = cfg.options.buglink_base + lf.add_formatter(_re_rewrite_bug, lf.format_bugzilla) + # Rewrite email addresses. if cfg.options.mangle_email_addresses == 2: lf.add_formatter(_re_rewrite_email, lf.format_email_truncated) @@ -1409,7 +1431,7 @@ class LogFormatter: # Add custom rewrite handling per configuration. for rule in cfg.options.custom_log_formatting: - rule = rule.replace('\\:', '\x01') + rule = rule.replace('\\:', '\x01') regexp, format = map(lambda x: x.strip(), rule.split(':', 1)) regexp = regexp.replace('\x01', ':') format = format.replace('\x01', ':') @@ -1496,7 +1518,7 @@ def html_time(request, secs, extended=0) def common_template_data(request, revision=None, mime_type=None): """Return a ezt.TemplateData instance with data dictionary items common to most ViewVC views.""" - + cfg = request.cfg # Initialize data dictionary members (sorted alphanumerically) @@ -1587,7 +1609,7 @@ def common_template_data(request, revisi data['view_href'] = request.get_url(view_func=view_directory, params={}, escape=1) if 'tar' in cfg.options.allowed_views: - data['tarball_href'] = request.get_url(view_func=download_tarball, + data['tarball_href'] = request.get_url(view_func=download_tarball, params={}, escape=1) if request.roottype == 'svn': @@ -1633,7 +1655,7 @@ def retry_read(src, reqlen=CHUNK_SIZE): time.sleep(1) continue return chunk - + def copy_stream(src, dst, htmlize=0): while 1: chunk = retry_read(src) @@ -1682,7 +1704,7 @@ def detect_encoding(text_block): Python module. (Currently, this is used only when syntax highlighting is not enabled/available; otherwise, Pygments does this work for us.)""" - + # Does the TEXT_BLOCK start with a BOM? for bom, encoding in [('\xef\xbb\xbf', 'utf-8'), ('\xff\xfe', 'utf-16'), @@ -1711,7 +1733,7 @@ def detect_encoding(text_block): # By default ... we have no idea. return None - + def transcode_text(text, encoding=None): """If ENCODING is provided and not 'utf-8', transcode TEXT from ENCODING to UTF-8.""" @@ -1735,7 +1757,7 @@ def markup_stream(request, cfg, blame_da apply syntax coloration to the file contents, and use the HTML-marked-up results as the text in the return vclib.Annotation objects.""" - + # Nothing to mark up? So be it. if not file_lines: return [] @@ -1792,7 +1814,7 @@ def markup_stream(request, cfg, blame_da stripnl=False) except ClassNotFound: pygments_lexer = None - + # If we aren't highlighting, just return an amalgamation of the # BLAME_DATA (if any) and the FILE_LINES. if not pygments_lexer: @@ -1933,7 +1955,7 @@ def parse_mime_type(mime_type): name, value = string.split(part, '=', 1) parameters[name] = value return type_subtype, parameters - + def calculate_mime_type(request, path_parts, rev): """Return a 2-tuple carrying the MIME content type and character encoding for the file represented by PATH_PARTS in REV. Use REQUEST @@ -1961,7 +1983,7 @@ def assert_viewable_filesize(cfg, filesi 'disallowed by configuration' % (cfg.options.max_filesize_kbytes), '403 Forbidden') - + def markup_or_annotate(request, is_annotate): cfg = request.cfg path, rev = _orig_path(request, is_annotate and 'annotate' or 'revision') @@ -1974,7 +1996,7 @@ def markup_or_annotate(request, is_annot if is_binary_file_mime_type(mime_type, cfg): raise debug.ViewVCException('Display of binary file content disabled ' 'by configuration', '403 Forbidden') - + # Is this a viewable image type? if is_viewable_image(mime_type) \ and 'co' in cfg.options.allowed_views: @@ -2128,9 +2150,9 @@ def markup_or_annotate(request, is_annot pathtype=vclib.FILE, params={'pathrev': revision}, escape=1) - + generate_page(request, "file", data) - + def view_markup(request): if 'markup' not in request.cfg.options.allowed_views: raise debug.ViewVCException('Markup view is disabled', @@ -2213,7 +2235,7 @@ def view_roots(request): if 'roots' not in request.cfg.options.allowed_views: raise debug.ViewVCException('Root listing view is disabled', '403 Forbidden') - + # add in the roots for the selection roots = [] expand_root_parents(request.cfg) @@ -2247,7 +2269,7 @@ def view_roots(request): data = common_template_data(request) data.merge(ezt.TemplateData({ 'roots' : roots, - 'roots_shown' : len(roots), + 'roots_shown' : len(roots), })) generate_page(request, "roots", data) @@ -2269,7 +2291,7 @@ def view_directory(request): # List current directory options = {} if request.roottype == 'cvs': - hideattic = int(request.query_dict.get('hideattic', + hideattic = int(request.query_dict.get('hideattic', cfg.options.hide_attic)) options["cvs_subdirs"] = (cfg.options.show_subdir_lastmod and cfg.options.show_logs) @@ -2321,7 +2343,7 @@ def view_directory(request): rows = [ ] dirs_displayed = files_displayed = 0 num_dead = 0 - + # set some values to be used inside loop where = request.where where_prefix = where and where + '/' @@ -2361,7 +2383,7 @@ def view_directory(request): and is_cvsroot_path(request.roottype, request.path_parts + [file.name]): continue - + dirs_displayed += 1 row.view_href = request.get_url(view_func=view_directory, @@ -2387,7 +2409,7 @@ def view_directory(request): pathtype=vclib.DIR, params={}, escape=1) - + elif file.kind == vclib.FILE: if searchstr is not None: if request.roottype == 'cvs' and (file.errors or file.dead): @@ -2399,11 +2421,11 @@ def view_directory(request): num_dead = num_dead + 1 if hideattic: continue - + files_displayed += 1 file_where = where_prefix + file.name - if request.roottype == 'svn': + if request.roottype == 'svn': row.size = file.size row.mime_type, encoding = calculate_mime_type(request, @@ -2512,7 +2534,7 @@ def view_directory(request): branch_tags.sort(icmp) branch_tags.reverse() data['branch_tags']= branch_tags - + data['attic_showing'] = ezt.boolean(not hideattic) data['show_attic_href'] = request.get_url(params={'hideattic': 0}, escape=1) @@ -2590,7 +2612,7 @@ def paging_sws(data, key, pagestart, loc try: pick.end = getattr(data[key][i+pagesize-1], local_name) except IndexError: - pick.end = getattr(data[key][-1], local_name) + pick.end = getattr(data[key][-1], local_name) picklist.append(pick) if pick.count >= last_requested: pick.more = ezt.boolean(1) @@ -2645,9 +2667,9 @@ def redirect_pathrev(request): new_pathrev = request.query_dict.get('pathrev') or None path = request.query_dict.get('orig_path', '') pathtype = request.query_dict.get('orig_pathtype') - pathrev = request.query_dict.get('orig_pathrev') + pathrev = request.query_dict.get('orig_pathrev') view = _views.get(request.query_dict.get('orig_view')) - + youngest = request.repos.get_youngest_revision() # go out of the way to allow revision numbers higher than youngest @@ -2669,7 +2691,7 @@ def redirect_pathrev(request): if new_pathrev is None and pathrev == youngest: pathrev = None - request.server.redirect(request.get_url(view_func=view, + request.server.redirect(request.get_url(view_func=view, where=path, pathtype=pathtype, params={'pathrev': pathrev})) @@ -2751,7 +2773,7 @@ def view_log(request): entry.diff_to_prev_href = None entry.diff_to_branch_href = None entry.diff_to_main_href = None - + if request.roottype == 'cvs': prev = rev.prev or rev.parent entry.prev = prev and prev.string @@ -2944,7 +2966,7 @@ def view_log(request): data['tag_annotate_href']= fvi.annotate_href data['tag_prefer_markup']= fvi.prefer_markup else: - data['head_view_href'] = request.get_url(view_func=view_directory, + data['head_view_href'] = request.get_url(view_func=view_directory, params={}, escape=1) taginfo = options.get('cvs_tags', {}) @@ -2985,7 +3007,7 @@ def view_log(request): def view_checkout(request): cfg = request.cfg - + if 'co' not in cfg.options.allowed_views: raise debug.ViewVCException('Checkout view is disabled', '403 Forbidden') @@ -3024,7 +3046,7 @@ def view_cvsgraph_image(request): ("-c", cfg.path(cfg.options.cvsgraph_conf), "-r", request.repos.rootpath, rcsfile), 'rb', 0) - + copy_stream(fp, get_writeready_server_file(request, 'image/png')) fp.close() @@ -3054,7 +3076,7 @@ def view_cvsgraph(request): "-x", "x", "-3", request.get_url(view_func=view_log, params={}, escape=1), - "-4", request.get_url(view_func=view, + "-4", request.get_url(view_func=view, params={'revision': None}, escape=1, partial=1), "-5", request.get_url(view_func=view_diff, @@ -3155,7 +3177,7 @@ class DiffSource: self.save_line = None self.line_number = None self.prev_line_number = None - + # keep track of where we are during an iteration self.idx = -1 self.last = None @@ -3186,11 +3208,11 @@ class DiffSource: if self.cfg.options.tabsize > 0: text = string.expandtabs(text, self.cfg.options.tabsize) hr_breakable = self.cfg.options.hr_breakable - + # in the code below, "\x01" will be our stand-in for "&". We don't want # to insert "&" because it would get escaped by sapi.escape(). Similarly, # we use "\x02" as a stand-in for "<br>" - + if hr_breakable > 1 and len(text) > hr_breakable: text = re.sub('(' + ('.' * hr_breakable) + ')', '\\1\x02', text) if hr_breakable: @@ -3203,7 +3225,7 @@ class DiffSource: text = string.replace(text, '\x02', '<span style="color:red">\</span><br />') return text - + def _get_row(self): if self.state[:5] == 'flush': item = self._flush_row() @@ -3243,7 +3265,7 @@ class DiffSource: line_info_left=match.group(1), line_info_right=match.group(2), line_info_extra=self._format_text(match.group(3))) - + if line[0] == '\\': # \ No newline at end of file @@ -3254,7 +3276,7 @@ class DiffSource: diff_code = line[0] output = self._format_text(line[1:]) - + if diff_code == '+': if self.state == 'dump': self.line_number = self.line_number + 1 @@ -3353,7 +3375,7 @@ def diff_parse_headers(fp, diff_type, pa elif line[:3] == 'Bin': flag = _RCSDIFF_IS_BINARY parsing = 0 - elif (string.find(line, 'not found') != -1 or + elif (string.find(line, 'not found') != -1 or string.find(line, 'illegal option') != -1): flag = _RCSDIFF_ERROR parsing = 0 @@ -3411,7 +3433,7 @@ def setup_diff(request): else: rev1 = r1[:idx] sym1 = r1[idx+1:] - + if r2 == 'text': rev2 = query_dict.get('tr2', None) if not rev2: @@ -3433,7 +3455,7 @@ def setup_diff(request): except vclib.InvalidRevision: raise debug.ViewVCException('Invalid revision(s) passed to diff', '400 Bad Request') - + p1 = _get_diff_path_parts(request, 'p1', rev1, request.pathrev) p2 = _get_diff_path_parts(request, 'p2', rev2, request.pathrev) @@ -3476,7 +3498,7 @@ def view_patch(request): else: raise debug.ViewVCException('Diff format %s not understood' % format, '400 Bad Request') - + try: fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type) except vclib.InvalidRevision: @@ -3503,7 +3525,7 @@ def view_diff(request): cfg = request.cfg query_dict = request.query_dict p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) - + mime_type1, encoding1 = calculate_mime_type(request, p1, rev1) mime_type2, encoding2 = calculate_mime_type(request, p2, rev2) if is_binary_file_mime_type(mime_type1, cfg) or \ @@ -3524,7 +3546,7 @@ def view_diff(request): and html_time(request, log_entry1.date, 1) or None ago2 = log_entry2.date is not None \ and html_time(request, log_entry2.date, 2) or None - + diff_type = None diff_options = {} human_readable = 0 @@ -3579,7 +3601,7 @@ def view_diff(request): else: unified = idiff.unified(lines_left, lines_right, diff_options.get("context", 2)) - else: + else: fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type, diff_options) except vclib.InvalidRevision: raise debug.ViewVCException('Invalid path(s) or revision(s) passed ' @@ -3622,7 +3644,7 @@ def view_diff(request): annotate_href=fvi.annotate_href, revision_href=fvi.revision_href, prefer_markup=fvi.prefer_markup) - + fvi = get_file_view_info(request, path_right, rev2) right = _item(date=make_time_string(log_entry2.date, cfg), author=log_entry2.author, @@ -3744,7 +3766,7 @@ def generate_tarball(out, request, reldi tar_dir = tar_dir + _path_join(reldir) + '/' cvs = request.roottype == 'cvs' - + # If our caller doesn't dictate a datestamp to use for the current # directory, its datestamps will be the youngest of the datestamps # of versioned items in that subdirectory. We'll be ignoring dead @@ -3822,7 +3844,7 @@ def generate_tarball(out, request, reldi # Write the tarball header... generate_tarball_header(out, tar_dir + file.name, filesize, mode, file.date is not None and file.date or 0) - + # ...the file's contents ... fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0] while 1: @@ -3852,7 +3874,7 @@ def generate_tarball(out, request, reldi def download_tarball(request): cfg = request.cfg - + if 'tar' not in request.cfg.options.allowed_views: raise debug.ViewVCException('Tarball generation is disabled', '403 Forbidden') @@ -3863,7 +3885,7 @@ def download_tarball(request): # our own gzip stream wrapper. if debug.TARFILE_PATH: fp = open(debug.TARFILE_PATH, 'w') - else: + else: tarfile = request.rootname if request.path_parts: tarfile = "%s-%s" % (tarfile, request.path_parts[-1]) @@ -3904,7 +3926,7 @@ def view_revision(request): except vclib.InvalidRevision: raise debug.ViewVCException('Invalid revision', '404 Not Found') youngest_rev = request.repos.get_youngest_revision() - + # The revision number acts as a weak validator (but we tell browsers # not to cache the youngest revision). if rev != youngest_rev and check_freshness(request, None, str(rev), weak=1): @@ -3934,7 +3956,7 @@ def view_revision(request): value = None undisplayable = ezt.boolean(1) props.append(_item(name=name, value=value, undisplayable=undisplayable)) - + # Sort the changes list by path. def changes_sort_by_path(a, b): return cmp(a.path_parts, b.path_parts) @@ -4002,14 +4024,14 @@ def view_revision(request): if change.pathtype is vclib.FILE and change.text_changed: change.diff_href = request.get_url(view_func=view_diff, - where=path, + where=path, pathtype=change.pathtype, params={'pathrev' : str(rev), 'r1' : str(rev), 'r2' : str(change.base_rev), }, escape=1) - + # use same variable names as the log template change.path = _path_join(change.path_parts) @@ -4099,7 +4121,7 @@ def is_querydb_nonempty_for_root(request def validate_query_args(request): # Do some additional input validation of query form arguments beyond # what is offered by the CGI param validation loop in Request.run_viewvc(). - + for arg_base in ['branch', 'file', 'comment', 'who']: # First, make sure the the XXX_match args have valid values: arg_match = arg_base + '_match' @@ -4122,7 +4144,7 @@ def validate_query_args(request): 'An illegal value was provided for the "%s" parameter.' % (arg_base), '400 Bad Request') - + def view_queryform(request): if not is_query_supported(request): raise debug.ViewVCException('Can not query project root "%s" at "%s".' @@ -4131,7 +4153,7 @@ def view_queryform(request): # Do some more precise input validation. validate_query_args(request) - + query_action, query_hidden_values = \ request.get_form(view_func=view_query, params={'limit_changes': None}) limit_changes = \ @@ -4140,7 +4162,7 @@ def view_queryform(request): def escaped_query_dict_get(itemname, itemdefault=''): return request.server.escape(request.query_dict.get(itemname, itemdefault)) - + data = common_template_data(request) data.merge(ezt.TemplateData({ 'branch' : escaped_query_dict_get('branch', ''), @@ -4167,7 +4189,7 @@ def view_queryform(request): def parse_date(datestr): """Parse a date string from the query form.""" - + match = re.match(r'^(\d\d\d\d)-(\d\d)-(\d\d)(?:\ +' '(\d\d):(\d\d)(?::(\d\d))?)?$', datestr) if match: @@ -4279,7 +4301,7 @@ def build_commit(request, files, max_fil plus_count = 0 minus_count = 0 found_unreadable = 0 - + for f in files: dirname = f.GetDirectory() filename = f.GetFile() @@ -4310,7 +4332,7 @@ def build_commit(request, files, max_fil and is_cvsroot_path(request.roottype, path_parts): found_unreadable = 1 continue - + # We have to do a rare authz check here because this data comes # from the CVSdb, not from the vclib providers. # @@ -4328,12 +4350,12 @@ def build_commit(request, files, max_fil if not readable: found_unreadable = 1 continue - + if request.roottype == 'svn': params = { 'pathrev': exam_rev } else: - params = { 'revision': exam_rev, 'pathrev': f.GetBranch() or None } - + params = { 'revision': exam_rev, 'pathrev': f.GetBranch() or None } + dir_href = request.get_url(view_func=view_directory, where=dirname, pathtype=vclib.DIR, params=params, escape=1) @@ -4367,7 +4389,7 @@ def build_commit(request, files, max_fil minus = int(f.GetMinusCount()) plus_count = plus_count + plus minus_count = minus_count + minus - + num_allowed = num_allowed + 1 if max_files and num_allowed > max_files: continue @@ -4560,7 +4582,7 @@ def view_query(request): db.RunQuery(query) commit_list = query.GetCommitList() row_limit_reached = query.GetLimitReached() - + # gather commits commits = [] plus_count = 0 @@ -4580,7 +4602,7 @@ def view_query(request): # base modification time on the newest commit if commit.GetTime() > mod_time: mod_time = commit.GetTime() - + # For CVS, group commits with the same commit message. # For Subversion, group them only if they have the same revision number if request.roottype == 'cvs': @@ -4605,7 +4627,7 @@ def view_query(request): limited_files = 0 current_desc = commit_desc current_rev = commit_rev - + # we need to tack on our last commit grouping, if any commit_item = build_commit(request, files, limit_changes, dir_strip, format) @@ -4614,7 +4636,7 @@ def view_query(request): plus_count = plus_count + commit_item.plus minus_count = minus_count + commit_item.minus commits.append(commit_item) - + # only show the branch column if we are querying all branches # or doing a non-exact branch match on a CVS repository. show_branch = ezt.boolean(request.roottype == 'cvs' and @@ -4689,7 +4711,7 @@ for code, view in _views.items(): def list_roots(request): cfg = request.cfg allroots = { } - + # Add the viewable Subversion roots for root in cfg.general.svn_roots.keys(): auth = setup_authorizer(cfg, request.username, root) @@ -4725,12 +4747,12 @@ def list_roots(request): except vclib.ReposNotFound: continue allroots[root] = [cfg.general.cvs_roots[root], 'cvs', None] - + return allroots def expand_root_parents(cfg): """Expand the configured root parents into individual roots.""" - + # Each item in root_parents is a "directory : repo_type" string. for pp in cfg.general.root_parents: pos = string.rfind(pp, ':') @@ -4762,7 +4784,7 @@ def find_root_in_parents(cfg, rootname, # Easy out: caller wants rootname "CVSROOT", and we're hiding those. if rootname == 'CVSROOT' and cfg.options.hide_cvsroot: return None - + for pp in cfg.general.root_parents: pos = string.rfind(pp, ':') if pos < 0: @@ -4771,7 +4793,7 @@ def find_root_in_parents(cfg, rootname, if repo_type != roottype: continue pp = os.path.normpath(string.strip(pp[:pos])) - + rootpath = None if roottype == 'cvs': rootpath = vclib.ccvs.find_root_in_parent(pp, rootname) @@ -4797,7 +4819,7 @@ def locate_root(cfg, rootname): cfg.general.svn_roots[rootname] = path_in_parent return 'svn', path_in_parent return None, None - + def load_config(pathname=None, server=None): """Load the ViewVC configuration file. SERVER is the server object that will be using this configuration. Consult the environment for @@ -4805,7 +4827,7 @@ def load_config(pathname=None, server=No legacy name) and, if set, use its value as the path of the configuration file; otherwise, use PATHNAME (if provided). Failing all else, use a hardcoded default configuration path.""" - + debug.t_start('load-config') # See if the environment contains overrides to the configuration
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor