1
0
mirror of https://github.com/vitalif/viewvc-4intranet synced 2019-04-16 04:14:59 +03:00

Compare commits

..

1 Commits

Author SHA1 Message Date
cmpilato
382ac29ed0 Tag the 1.1.15 final release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/tags/1.1.15@2776 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-06-22 18:43:12 +00:00
56 changed files with 185 additions and 639 deletions

38
CHANGES
View File

@@ -1,39 +1,3 @@
Version 1.1.19 (released 22-Apr-2013)
* improve root lookup performance (issue #523)
* new 'max_filesize_kbytes' config option and handling (issue #524)
* tarball generation improvements:
- preserve Subversion symlinks in generated tarballs (issue #487)
- reduce memory usage of tarball generation logic
- fix double compression of generated tarballs (issue #525)
* file content handling improvements:
- expanded support for encoding detection and transcoding (issue #11)
- fix tab-to-space conversion bugs in markup, annotate, and diff views
- fix handling of trailing whitespace in diff view
* add support for timestamp display in ISO8601 format (issue #46)
Version 1.1.18 (released 28-Feb-2013)
* fix exception raised by BDB-backed SVN repositories (issue #519)
* hide revision-less files when rcsparse is in use
* include branchpoints in branch views using rcsparse (issue #347)
* miscellaneous cvsdb improvements:
- add --port option to make-database (issue #521)
- explicitly name columns in queries (issue #522)
- update MySQL syntax to avoid discontinued "TYPE=" terms
Version 1.1.17 (released 25-Oct-2012)
* fix exception caused by uninitialized variable usage (issue #516)
Version 1.1.16 (released 24-Oct-2012)
* security fix: escape "extra" diff info to avoid XSS attack (issue #515)
* add 'binary_mime_types' configuration option and handling (issue #510)
* fix 'select for diffs' persistence across log pages (issue #512)
* remove lock status and filesize check on directories in remote SVN views
* fix bogus 'Annotation of' page title for non-annotated view (issue #514)
Version 1.1.15 (released 22-Jun-2012)
* security fix: complete authz support for remote SVN views (issue #353)
@@ -48,7 +12,7 @@ Version 1.1.14 (released 12-Jun-2012)
* handle file:/// Subversion rootpaths as local roots (issue #446)
* fix bug caused by trying to case-normalize anon usernames (issue #505)
* speed up log handling by reusing tokenization results (issue #506)
* add support for custom revision log markup rules (issue #246)
* add support for custom review log markup rules (issue #429)
Version 1.1.13 (released 23-Jan-2012)

View File

@@ -15,7 +15,7 @@
<blockquote>
<p><strong>Copyright &copy; 1999-2013 The ViewCVS Group. All rights
<p><strong>Copyright &copy; 1999-2012 The ViewCVS Group. All rights
reserved.</strong></p>
<p>By using ViewVC, you agree to the terms and conditions set forth
@@ -63,7 +63,6 @@
<li>March 29, 2010 &mdash; copyright years updated</li>
<li>February 18, 2011 &mdash; copyright years updated</li>
<li>January 23, 2012 &mdash; copyright years updated</li>
<li>January 04, 2013 &mdash; copyright years updated</li>
</ul>
</body>

View File

@@ -3,7 +3,7 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -3,7 +3,7 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -40,7 +40,7 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE branch (branch)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS checkins;
CREATE TABLE checkins (
@@ -63,7 +63,7 @@ CREATE TABLE checkins (
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS descs;
CREATE TABLE descs (
@@ -72,7 +72,7 @@ CREATE TABLE descs (
hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY hash (hash)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs (
@@ -80,7 +80,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE dir (dir)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS files;
CREATE TABLE files (
@@ -88,7 +88,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE file (file)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS people;
CREATE TABLE people (
@@ -96,7 +96,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE who (who)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories (
@@ -104,7 +104,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE repository (repository)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS tags;
CREATE TABLE tags (
@@ -118,7 +118,7 @@ CREATE TABLE tags (
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
) TYPE=MyISAM;
"""
## ------------------------------------------------------------------------
@@ -132,7 +132,7 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE branch (branch)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS commits;
CREATE TABLE commits (
@@ -156,7 +156,7 @@ CREATE TABLE commits (
KEY fileid (fileid),
KEY branchid (branchid),
KEY descid (descid)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS descs;
CREATE TABLE descs (
@@ -165,7 +165,7 @@ CREATE TABLE descs (
hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY hash (hash)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs (
@@ -173,7 +173,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE dir (dir)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS files;
CREATE TABLE files (
@@ -181,7 +181,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE file (file)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS people;
CREATE TABLE people (
@@ -189,7 +189,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE who (who)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories (
@@ -197,7 +197,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE repository (repository)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS tags;
CREATE TABLE tags (
@@ -211,7 +211,7 @@ CREATE TABLE tags (
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
) TYPE=MyISAM;
DROP TABLE IF EXISTS metadata;
CREATE TABLE metadata (
@@ -219,7 +219,7 @@ CREATE TABLE metadata (
value text,
PRIMARY KEY (name),
UNIQUE name (name)
) ENGINE=MyISAM;
) TYPE=MyISAM;
INSERT INTO metadata (name, value) VALUES ('version', '1');
"""
@@ -245,10 +245,6 @@ options.) This script will use the 'mysql' program to create the
database for you. You will then need to set the appropriate
parameters in the [cvsdb] section of your viewvc.conf file.
NOTE: If a hostname or port is supplied at the command line or during
interactive prompting, this script will pass '--protocol=TCP' to
'mysql'.
Options:
--dbname=ARG Use ARG as the ViewVC database name to create.
@@ -257,8 +253,7 @@ Options:
--help Show this usage message.
--hostname=ARG Use ARG as the hostname for the MySQL connection.
--port=ARG Use ARG as the port for the MySQL connection.
[Default: localhost]
--password=ARG Use ARG as the password for the MySQL connection.
@@ -278,11 +273,10 @@ Options:
if __name__ == "__main__":
try:
# Parse the command-line options, if any.
dbname = version = hostname = port = username = password = None
dbname = version = hostname = username = password = None
opts, args = getopt.getopt(sys.argv[1:], '', [ 'dbname=',
'help',
'hostname=',
'port=',
'password=',
'username=',
'version=',
@@ -296,8 +290,6 @@ if __name__ == "__main__":
dbname = value
elif name == '--hostname':
hostname = value
elif name == '--port':
port = value
elif name == '--username':
username = value
elif name == '--password':
@@ -310,9 +302,7 @@ if __name__ == "__main__":
# Prompt for information not provided via command-line options.
if hostname is None:
hostname = raw_input("MySQL Hostname (leave blank for default): ")
if port is None:
port = raw_input("MySQL Port (leave blank for default): ")
hostname = raw_input("MySQL Hostname [default: localhost]: ") or ""
if username is None:
username = raw_input("MySQL User: ")
if password is None:
@@ -320,7 +310,7 @@ if __name__ == "__main__":
if dbname is None:
dbname = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC"
# Create the database.
# Create the database
dscript = string.replace(DATABASE_SCRIPT_COMMON, "<dbname>", dbname)
if version == "1.0":
print BONSAI_COMPAT
@@ -328,22 +318,16 @@ if __name__ == "__main__":
else:
dscript = dscript + DATABASE_SCRIPT_VERSION_1
# Calculate command arguments.
cmd_args = "--user=%s --password=%s" % (username, password)
if hostname or port:
cmd_args = cmd_args + " --protocol=TCP"
if hostname:
cmd_args = cmd_args + " --host=%s" % (hostname)
if port:
cmd_args = cmd_args + " --port=%s" % (port)
host_option = hostname and "--host=%s" % (hostname) or ""
if sys.platform == "win32":
cmd = "mysql %s" % (cmd_args)
cmd = "mysql --user=%s --password=%s %s "\
% (username, password, host_option)
mysql = os.popen(cmd, "w") # popen2.Popen3 is not provided on windows
mysql.write(dscript)
status = mysql.close()
else:
cmd = "{ mysql %s ; } 2>&1" % (cmd_args)
cmd = "{ mysql --user=%s --password=%s %s ; } 2>&1" \
% (username, password, host_option)
pipes = popen2.Popen3(cmd)
pipes.tochild.write(dscript)
pipes.tochild.close()

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 2004-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004-2007 James Henstridge
#
# By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -391,24 +391,6 @@
##
#allowed_views = annotate, diff, markup, roots
## Comma-delimited list of MIME content types (with support for fnmatch-
## style glob characters) which are considered not-human-readable and for
## which ViewVC will neither generate links to, nor support the direct
## display of, non-checkout views which carry the file's content (the
## 'markup', 'annotate', 'diff', and 'patch' views).
##
## NOTE: Handling of this option is given priority over ViewVC's
## longstanding support for showing web-friendly file formats -- even
## binary ones such as "image/jpeg" and "image/gif" -- in the 'markup'
## view. Thus, if you add "image/*" to this list, 'markup'-view
## display of JPEG, GIF, and PNG images will be disabled.
##
## Example:
## binary_mime_types = application/octet-stream, image/*, application/pdf,
## application/vnd*, application/msword, audio/*
#
#binary_mime_types =
## authorizer: The name of the ViewVC authorizer plugin to use when
## authorizing access to repository contents. This value must be the
## name of a Python module addressable as vcauth.MODULENAME (most
@@ -510,15 +492,6 @@
##
#svn_ignore_mimetype = 0
## max_filesize_kbytes: Limit ViewVC's processing of file contents in
## "markup" and "annotate" views to only those files which are smaller
## than this setting, expressed in kilobytes. Set to 0 to disable
## this safeguard.
##
## NOTE: The "co" and "tar" views are unaffected by this setting.
##
#max_filesize_kbytes = 512
## svn_config_dir: Path of the Subversion runtime configuration
## directory ViewVC should consult for various things, including cached
## remote authentication credentials. If unset, Subversion will use
@@ -588,7 +561,7 @@
## (Only works well for C source files, otherwise diff's heuristic falls short.)
## ('-p' option to diff)
##
#hr_funout = 1
#hr_funout = 0
## hr_ignore_white: Ignore whitespace (indendation and stuff) for human
## readable diffs.
@@ -686,10 +659,6 @@
##
#use_localtime = 0
## iso8601_dates: Display timestamps using a standard ISO-8601 format.
##
#iso8601_timestamps = 0
## short_log_len: The length (in characters) to which the most recent
## log entry should be truncated when shown in the directory view.
##
@@ -706,15 +675,15 @@
##
#enable_syntax_coloration = 1
## tabsize: The number of spaces into which horizontal tab characters
## are converted when viewing file contents. Set to 0 to preserve
## tab characters.
## tabsize: The number of spaces into which tabstops are converted
## when viewing file contents.
##
#tabsize = 8
## detect_encoding: Should we attempt to detect versioned file
## character encodings? [Requires 'chardet' module, and is currently
## used only for the 'markup' and 'annotate' views.]
## used only by the syntax coloration logic -- if enabled -- for the
## 'markup' and 'annotate' views; see 'enable_syntax_coloration'.]
##
#detect_encoding = 0

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
#
# By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -112,7 +112,6 @@ class Config:
_force_multi_value = (
# Configuration values with multiple, comma-separated values.
'allowed_views',
'binary_mime_types',
'custom_log_formatting',
'cvs_roots',
'kv_files',
@@ -402,12 +401,10 @@ class Config:
self.options.mangle_email_addresses = 0
self.options.custom_log_formatting = []
self.options.default_file_view = "log"
self.options.binary_mime_types = []
self.options.http_expiration_time = 600
self.options.generate_etags = 1
self.options.svn_ignore_mimetype = 0
self.options.svn_config_dir = None
self.options.max_filesize_kbytes = 512
self.options.use_rcsparse = 0
self.options.sort_by = 'file'
self.options.sort_group_dirs = 1
@@ -430,7 +427,6 @@ class Config:
self.options.show_log_in_markup = 1
self.options.cross_copies = 1
self.options.use_localtime = 0
self.options.iso8601_timestamps = 0
self.options.short_log_len = 80
self.options.enable_syntax_coloration = 1
self.options.tabsize = 8

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -520,10 +520,7 @@ class CheckinDatabase:
if file_id == None:
return None
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, fileid, " \
"revision, stickytag, branchid, addedlines, removedlines, " \
"descid "\
" FROM %s WHERE "\
sql = "SELECT * FROM %s WHERE "\
" repositoryid=%%s "\
" AND dirid=%%s"\
" AND fileid=%%s"\
@@ -573,10 +570,7 @@ class CheckinDatabase:
self.sql_purge('descs', 'id', 'descid', 'commits')
self.sql_purge('people', 'id', 'whoid', 'commits')
else:
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, " \
"fileid, revision, stickytag, branchid, addedlines, " \
"removedlines, descid "\
" FROM checkins WHERE repositoryid=%s"
sql = "SELECT * FROM checkins WHERE repositoryid=%s"
sql_args = (rep_id, )
cursor = self.db.cursor()
cursor.execute(sql, sql_args)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2008-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2008-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -207,21 +207,7 @@ class Repository:
rev is the revision of the item to return information about
"""
def filesize(self, path_parts, rev):
"""Return the size of a versioned file's contents if it can be
obtained without a brute force measurement; -1 otherwise.
NOTE: Callers that require a filesize answer when this function
returns -1 may obtain it by measuring the data returned via
openfile().
The path is specified as a list of components, relative to the root
of the repository. e.g. ["subdir1", "subdir2", "filename"]
rev is the revision of the item to return information about
"""
# ======================================================================
class DirEntry:

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -35,23 +35,6 @@ def expand_root_parent(parent_path):
return roots
def find_root_in_parent(parent_path, rootname):
"""Search PARENT_PATH for a root named ROOTNAME, returning the
canonicalized ROOTPATH of the root if found; return None if no such
root is found."""
assert os.path.isabs(parent_path)
# Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME
# to be any subdir within it. Otherwise, we expect
# PARENT_PATH/ROOTNAME to be a CVS repository.
rootpath = os.path.join(parent_path, rootname)
if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")):
return canonicalize_rootpath(rootpath)
if os.path.exists(os.path.join(rootpath, "CVSROOT", "config")):
return canonicalize_rootpath(rootpath)
return None
def CVSRepository(name, rootpath, authorizer, utilities, use_rcsparse):
rootpath = canonicalize_rootpath(rootpath)
if use_rcsparse:

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -149,11 +149,6 @@ class BaseCVSRepository(vclib.Repository):
% (string.join(path_parts, "/")))
rcsfile = self.rcsfile(path_parts, 1)
return os.access(rcsfile, os.X_OK)
def filesize(self, path_parts, rev):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
return -1
class BinCVSRepository(BaseCVSRepository):

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
#
# By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -200,7 +200,6 @@ class InfoSink(MatchingSink):
self.matching_rev = None
self.perfect_match = 0
self.lockinfo = { }
self.saw_revision = False
def define_tag(self, name, revision):
MatchingSink.define_tag(self, name, revision)
@@ -214,17 +213,10 @@ class InfoSink(MatchingSink):
self.entry.absent = 1
raise rcsparse.RCSStopParser
def parse_completed(self):
if not self.saw_revision:
#self.entry.errors.append("No revisions exist on %s" % (view_tag or "MAIN"))
self.entry.absent = 1
def set_locker(self, rev, locker):
self.lockinfo[rev] = locker
def define_revision(self, revision, date, author, state, branches, next):
self.saw_revision = True
if self.perfect_match:
return
@@ -232,18 +224,14 @@ class InfoSink(MatchingSink):
rev = Revision(revision, date, author, state == "dead")
rev.lockinfo = self.lockinfo.get(revision)
# perfect match if revision number matches tag number or if
# revision is on trunk and tag points to trunk. imperfect match
# if tag refers to a branch and either a) this revision is the
# highest revision so far found on that branch, or b) this
# revision is the branchpoint.
# perfect match if revision number matches tag number or if revision is on
# trunk and tag points to trunk. imperfect match if tag refers to a branch
# and this revision is the highest revision so far found on that branch
perfect = ((rev.number == tag.number) or
(not tag.number and len(rev.number) == 2))
if perfect or (tag.is_branch and \
((tag.number == rev.number[:-1] and
(not self.matching_rev or
rev.number > self.matching_rev.number)) or
(rev.number == tag.number[:-1]))):
if perfect or (tag.is_branch and tag.number == rev.number[:-1] and
(not self.matching_rev or
rev.number > self.matching_rev.number)):
self.matching_rev = rev
self.perfect_match = perfect

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -77,20 +77,6 @@ def expand_root_parent(parent_path):
return roots
def find_root_in_parent(parent_path, rootname):
"""Search PARENT_PATH for a root named ROOTNAME, returning the
canonicalized ROOTPATH of the root if found; return None if no such
root is found."""
if not re.search(_re_url, parent_path):
assert os.path.isabs(parent_path)
rootpath = os.path.join(parent_path, rootname)
format_path = os.path.join(rootpath, "format")
if os.path.exists(format_path):
return canonicalize_rootpath(rootpath)
return None
def SubversionRepository(name, rootpath, authorizer, utilities, config_dir):
rootpath = canonicalize_rootpath(rootpath)
if re.search(_re_url, rootpath):

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -79,40 +79,6 @@ def client_log(url, start_rev, end_rev, log_limit, include_changes,
client.svn_client_log2([url], start_rev, end_rev, log_limit,
include_changes, not cross_copies, cb_convert, ctx)
def setup_client_ctx(config_dir):
# Ensure that the configuration directory exists.
core.svn_config_ensure(config_dir)
# Fetch the configuration (and 'config' bit thereof).
cfg = core.svn_config_get_config(config_dir)
config = cfg.get(core.SVN_CONFIG_CATEGORY_CONFIG)
# Here's the compat-sensitive part: try to use
# svn_cmdline_create_auth_baton(), and fall back to making our own
# if that fails.
try:
auth_baton = core.svn_cmdline_create_auth_baton(1, None, None, config_dir,
1, 1, config, None)
except AttributeError:
auth_baton = core.svn_auth_open([
client.svn_client_get_simple_provider(),
client.svn_client_get_username_provider(),
client.svn_client_get_ssl_server_trust_file_provider(),
client.svn_client_get_ssl_client_cert_file_provider(),
client.svn_client_get_ssl_client_cert_pw_file_provider(),
])
if config_dir is not None:
core.svn_auth_set_parameter(auth_baton,
core.SVN_AUTH_PARAM_CONFIG_DIR,
config_dir)
# Create, setup, and return the client context baton.
ctx = client.svn_client_create_context()
ctx.config = cfg
ctx.auth_baton = auth_baton
return ctx
### END COMPATABILITY CODE ###
@@ -166,7 +132,7 @@ class LogCollector:
if this_path:
self.path = this_path
def cat_to_tempfile(svnrepos, path, rev):
def temp_checkout(svnrepos, path, rev):
"""Check out file revision to temporary file"""
temp = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(temp)
@@ -227,8 +193,21 @@ class RemoteSubversionRepository(vclib.Repository):
def open(self):
# Setup the client context baton, complete with non-prompting authstuffs.
self.ctx = setup_client_ctx(self.config_dir)
# TODO: svn_cmdline_setup_auth_baton() is mo' better (when available)
core.svn_config_ensure(self.config_dir)
self.ctx = client.svn_client_create_context()
self.ctx.auth_baton = core.svn_auth_open([
client.svn_client_get_simple_provider(),
client.svn_client_get_username_provider(),
client.svn_client_get_ssl_server_trust_file_provider(),
client.svn_client_get_ssl_client_cert_file_provider(),
client.svn_client_get_ssl_client_cert_pw_file_provider(),
])
self.ctx.config = core.svn_config_get_config(self.config_dir)
if self.config_dir is not None:
core.svn_auth_set_parameter(self.ctx.auth_baton,
core.SVN_AUTH_PARAM_CONFIG_DIR,
self.config_dir)
ra_callbacks = ra.svn_ra_callbacks_t()
ra_callbacks.auth_baton = self.ctx.auth_baton
self.ra_session = ra.svn_ra_open(self.rootpath, ra_callbacks, None,
@@ -280,10 +259,13 @@ class RemoteSubversionRepository(vclib.Repository):
raise vclib.Error("Path '%s' is not a file." % path)
rev = self._getrev(rev)
url = self._geturl(path)
tmp_file = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(tmp_file)
### rev here should be the last history revision of the URL
fp = SelfCleanFP(cat_to_tempfile(self, path, rev))
client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev), self.ctx)
core.svn_stream_close(stream)
lh_rev, c_rev = self._get_last_history_rev(path_parts, rev)
return fp, lh_rev
return SelfCleanFP(tmp_file), lh_rev
def listdir(self, path_parts, rev, options):
path = self._getpath(path_parts)
@@ -331,18 +313,14 @@ class RemoteSubversionRepository(vclib.Repository):
rev = self._getrev(rev)
url = self._geturl(path)
# If this is a file, fetch the lock status and size (as of REV)
# for this item.
lockinfo = size_in_rev = None
if path_type == vclib.FILE:
basename = path_parts[-1]
list_url = self._geturl(self._getpath(path_parts[:-1]))
dirents, locks = list_directory(list_url, _rev2optrev(rev),
_rev2optrev(rev), 0, self.ctx)
if locks.has_key(basename):
lockinfo = locks[basename].owner
if dirents.has_key(basename):
size_in_rev = dirents[basename].size
# Use ls3 to fetch the lock status and size (as of REV) for this item.
lockinfo = None
basename = path_parts and path_parts[-1] or ""
dirents, locks = list_directory(url, _rev2optrev(rev),
_rev2optrev(rev), 0, self.ctx)
if locks.has_key(basename):
lockinfo = locks[basename].owner
size_in_rev = dirents[basename].size
# Special handling for the 'svn_latest_log' scenario.
### FIXME: Don't like this hack. We should just introduce
@@ -460,8 +438,8 @@ class RemoteSubversionRepository(vclib.Repository):
return date
try:
temp1 = cat_to_tempfile(self, p1, r1)
temp2 = cat_to_tempfile(self, p2, r2)
temp1 = temp_checkout(self, p1, r1)
temp2 = temp_checkout(self, p2, r2)
info1 = p1, _date_from_rev(r1), r1
info2 = p2, _date_from_rev(r2), r2
return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args)
@@ -475,15 +453,6 @@ class RemoteSubversionRepository(vclib.Repository):
props = self.itemprops(path_parts, rev) # does authz-check
return props.has_key(core.SVN_PROP_EXECUTABLE)
def filesize(self, path_parts, rev):
path = self._getpath(path_parts)
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % path)
rev = self._getrev(rev)
dirents, locks = self._get_dirents(self._getpath(path_parts[:-1]), rev)
dirent = dirents.get(path_parts[-1], None)
return dirent.size
def _getpath(self, path_parts):
return string.join(path_parts, '/')
@@ -766,33 +735,3 @@ class RemoteSubversionRepository(vclib.Repository):
else:
peg_revision = mid
return peg_revision, path
def get_symlink_target(self, path_parts, rev):
"""Return the target of the symbolic link versioned at PATH_PARTS
in REV, or None if that object is not a symlink."""
path = self._getpath(path_parts)
path_type = self.itemtype(path_parts, rev) # does auth-check
rev = self._getrev(rev)
url = self._geturl(path)
# Symlinks must be files with the svn:special property set on them
# and with file contents which read "link SOME_PATH".
if path_type != vclib.FILE:
return None
pairs = client.svn_client_proplist2(url, _rev2optrev(rev),
_rev2optrev(rev), 0, self.ctx)
props = pairs and pairs[0][1] or {}
if not props.has_key(core.SVN_PROP_SPECIAL):
return None
pathspec = ''
### FIXME: We're being a touch sloppy here, first by grabbing the
### whole file and then by checking only the first line
### of it.
fp = SelfCleanFP(cat_to_tempfile(self, path, rev))
pathspec = fp.readline()
fp.close()
if pathspec[:5] != 'link ':
return None
return pathspec[5:]

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -587,13 +587,6 @@ class LocalSubversionRepository(vclib.Repository):
props = self.itemprops(path_parts, rev) # does authz-check
return props.has_key(core.SVN_PROP_EXECUTABLE)
def filesize(self, path_parts, rev):
path = self._getpath(path_parts)
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % path)
fsroot = self._getroot(self._getrev(rev))
return fs.file_length(fsroot, path)
##--- helpers ---##
def _revinfo(self, rev, include_changed_paths=0):
@@ -670,19 +663,11 @@ class LocalSubversionRepository(vclib.Repository):
return found_readable, found_unreadable, changedpaths.values()
def _get_change_copyinfo(fsroot, path, change):
# If we know the copyfrom info, return it...
if hasattr(change, 'copyfrom_known') and change.copyfrom_known:
copyfrom_path = change.copyfrom_path
copyfrom_rev = change.copyfrom_rev
# ...otherwise, if this change could be a copy (that is, it
# contains an add action), query the copyfrom info ...
elif (change.change_kind == fs.path_change_add or
change.change_kind == fs.path_change_replace):
copyfrom_rev, copyfrom_path = fs.copied_from(fsroot, path)
# ...else, there's no copyfrom info.
else:
copyfrom_rev = core.SVN_INVALID_REVNUM
copyfrom_path = None
copyfrom_rev, copyfrom_path = fs.copied_from(fsroot, path)
return copyfrom_path, copyfrom_rev
def _simple_auth_check(fsroot):
@@ -949,32 +934,3 @@ class LocalSubversionRepository(vclib.Repository):
return peg_revision, path
finally:
pass
def get_symlink_target(self, path_parts, rev):
"""Return the target of the symbolic link versioned at PATH_PARTS
in REV, or None if that object is not a symlink."""
path = self._getpath(path_parts)
rev = self._getrev(rev)
path_type = self.itemtype(path_parts, rev) # does auth-check
fsroot = self._getroot(rev)
# Symlinks must be files with the svn:special property set on them
# and with file contents which read "link SOME_PATH".
if path_type != vclib.FILE:
return None
props = fs.node_proplist(fsroot, path)
if not props.has_key(core.SVN_PROP_SPECIAL):
return None
pathspec = ''
### FIXME: We're being a touch sloppy here, only checking the first line
### of the file.
stream = fs.file_contents(fsroot, path)
try:
pathspec, eof = core.svn_stream_readline(stream, '\n')
finally:
core.svn_stream_close(stream)
if pathspec[:5] != 'link ':
return None
return pathspec[5:]

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -14,7 +14,7 @@
#
# -----------------------------------------------------------------------
__version__ = '1.1.19'
__version__ = '1.1.15'
# this comes from our library; measure the startup time
import debug
@@ -24,7 +24,6 @@ debug.t_start('imports')
# standard modules that we know are in the path or builtin
import sys
import os
import fnmatch
import gzip
import mimetypes
import re
@@ -230,12 +229,9 @@ class Request:
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)
debug.t_end('setup-authorizer')
# Create the repository object
debug.t_start('select-repos')
try:
if roottype == 'cvs':
self.rootpath = vclib.ccvs.canonicalize_rootpath(rootpath)
@@ -258,7 +254,6 @@ class Request:
raise vclib.ReposNotFound()
except vclib.ReposNotFound:
pass
debug.t_end('select-repos')
if self.repos is None:
raise debug.ViewVCException(
'The root "%s" is unknown. If you believe the value is '
@@ -266,9 +261,7 @@ class Request:
% self.rootname, "404 Not Found")
if self.repos:
debug.t_start('select-repos')
self.repos.open()
debug.t_end('select-repos')
type = self.repos.roottype()
if type == vclib.SVN:
self.roottype = 'svn'
@@ -398,9 +391,7 @@ class Request:
if needs_redirect:
self.server.redirect(self.get_url())
else:
debug.t_start('view-func')
self.view_func(self)
debug.t_end('view-func')
def get_url(self, escape=0, partial=0, prefix=0, **args):
"""Constructs a link to another ViewVC page just like the get_link
@@ -902,7 +893,7 @@ def get_view_template(cfg, view_name, language="en"):
return template
def get_writeready_server_file(request, content_type=None, encoding=None,
content_length=None, allow_compress=True):
content_length=None):
"""Return a file handle to a response body stream, after outputting
any queued special headers (on REQUEST.server) and (optionally) a
'Content-Type' header whose value is CONTENT_TYPE and character set
@@ -911,14 +902,10 @@ def get_writeready_server_file(request, content_type=None, encoding=None,
If CONTENT_LENGTH is provided and compression is not in use, also
generate a 'Content-Length' header for this response.
Callers my use ALLOW_COMPRESS to disable compression where it would
otherwise be allowed. (Such as when transmitting an
already-compressed response.)
After this function is called, it is too late to add new headers to
the response."""
if allow_compress and request.gzip_compress_level:
if request.gzip_compress_level:
request.server.addheader('Content-Encoding', 'gzip')
elif content_length is not None:
request.server.addheader('Content-Length', content_length)
@@ -930,7 +917,7 @@ def get_writeready_server_file(request, content_type=None, encoding=None,
else:
request.server.header()
if allow_compress and request.gzip_compress_level:
if request.gzip_compress_level:
fp = gzip.GzipFile('', 'wb', request.gzip_compress_level,
request.server.file())
else:
@@ -1030,15 +1017,6 @@ def default_view(mime_type, cfg):
return view_markup
return view_checkout
def is_binary_file_mime_type(mime_type, cfg):
"""Return True iff MIME_TYPE is set and matches one of the binary
file mime type patterns in CFG."""
if mime_type:
for pattern in cfg.options.binary_mime_types:
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
@@ -1099,12 +1077,7 @@ def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1):
params={'revision': rev},
escape=1)
is_binary_file = is_binary_file_mime_type(mime_type, request.cfg)
if is_binary_file:
download_text_href = annotate_href = view_href = None
prefer_markup = False
else:
prefer_markup = default_view(mime_type, request.cfg) == view_markup
prefer_markup = default_view(mime_type, request.cfg) == view_markup
return _item(view_href=view_href,
download_href=download_href,
@@ -1660,37 +1633,6 @@ def markup_escaped_urls(s):
return re.sub(_re_rewrite_escaped_url, _url_repl, s)
def detect_encoding(text_block):
# Does the TEXT_BLOCK start with a BOM?
for bom, encoding in [('\xef\xbb\xbf', 'utf-8'),
('\xff\xfe', 'utf-16'),
('\xfe\xff', 'utf-16be'),
('\xff\xfe\0\0', 'utf-32'),
('\0\0\xfe\xff', 'utf-32be'),
]:
if text_block[:len(bom)] == bom:
return encoding
# If no recognized BOM, see if chardet can help us.
try:
import chardet
return chardet.detect(text_block).get('encoding')
except:
pass
# 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."""
if not encoding or encoding == 'utf-8':
return text
return unicode(text, encoding,
errors='replace').encode('utf-8',
errors='replace')
def markup_stream(request, cfg, blame_data, file_lines, filename,
mime_type, encoding, colorize):
"""Return the contents of a versioned file as a list of
@@ -1760,31 +1702,11 @@ def markup_stream(request, cfg, blame_data, file_lines, filename,
# If we aren't highlighting, just return an amalgamation of the
# BLAME_DATA (if any) and the FILE_LINES.
if not pygments_lexer:
# If allowed by configuration, try to detect the source encoding
# for this file. We'll assemble a block of data from the file
# contents to do so... 1024 bytes should be enough.
if not encoding and cfg.options.detect_encoding:
block_size = 0
text_block = ''
for i in range(len(file_lines)):
text_block = text_block + file_lines[i]
if len(text_block) >= 1024:
break
encoding = detect_encoding(text_block)
# Built output data comprised of marked-up and possibly-transcoded
# source text lines wrapped in (possibly dummy) vclib.Annotation
# objects.
lines = []
file_lines = transcode_text(string.join(file_lines, ''), encoding)
file_lines = string.rstrip(file_lines, '\n')
file_lines = string.split(file_lines, '\n')
for i in range(len(file_lines)):
line = file_lines[i]
if cfg.options.tabsize > 0:
line = string.expandtabs(lin, cfg.options.tabsize)
line = markup_escaped_urls(sapi.escape(line))
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
line = markup_escaped_urls(line)
if blame_data:
blame_item = blame_data[i]
blame_item.text = line
@@ -1806,7 +1728,7 @@ def markup_stream(request, cfg, blame_data, file_lines, filename,
self.line_no = 0
def write(self, buf):
### FIXME: Don't bank on write() being called once per line
buf = markup_escaped_urls(string.rstrip(buf, '\n\r'))
buf = markup_escaped_urls(buf)
if self.has_blame_data:
self.blame_data[self.line_no].text = buf
else:
@@ -1832,23 +1754,10 @@ def make_time_string(date, cfg):
if date is None:
return None
if cfg.options.use_localtime:
tm = time.localtime(date)
localtime = time.localtime(date)
return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]
else:
tm = time.gmtime(date)
if cfg.options.iso8601_timestamps:
if cfg.options.use_localtime:
if tm[8] and time.daylight:
tz = time.altzone
else:
tz = time.timezone
tz = float(tz) / 3600.0
tz = string.replace(str.format('{0:+06.2f}', tz), '.', ':')
else:
tz = 'Z'
return time.strftime('%Y-%m-%dT%H:%M:%S', tm) + tz
else:
return time.asctime(tm) + ' ' + \
(cfg.options.use_localtime and time.tzname[tm[8]] or 'UTC')
return time.asctime(time.gmtime(date)) + ' UTC'
def make_rss_time_string(date, cfg):
"""Returns formatted date string in UTC, formatted for RSS.
@@ -1914,15 +1823,6 @@ def calculate_mime_type(request, path_parts, rev):
pass
return guess_mime(path_parts[-1]), None
def assert_viewable_filesize(cfg, filesize):
if cfg.options.max_filesize_kbytes \
and filesize != -1 \
and filesize > (1024 * cfg.options.max_filesize_kbytes):
raise debug.ViewVCException('Display of files larger than %d KB '
'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')
@@ -1931,11 +1831,6 @@ def markup_or_annotate(request, is_annotate):
revision = None
mime_type, encoding = calculate_mime_type(request, path, rev)
# Is this display blocked by 'binary_mime_types' configuration?
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:
@@ -1950,16 +1845,11 @@ def markup_or_annotate(request, is_annotate):
# Not a viewable image.
else:
filesize = request.repos.filesize(path, rev)
# If configuration disallows display of large files, try to honor
# that request.
assert_viewable_filesize(cfg, filesize)
blame_data = None
# If this was an annotation request, try to annotate this file.
# If something goes wrong, that's okay -- we'll gracefully revert
# to a plain markup display.
blame_data = None
if is_annotate:
try:
blame_source, revision = request.repos.annotate(path, rev, False)
@@ -1987,22 +1877,7 @@ def markup_or_annotate(request, is_annotate):
if check_freshness(request, None, revision, weak=1):
fp.close()
return
# If we're limiting by filesize but couldn't pull off the cheap
# check above, we'll try to do so line by line here (while
# building our file_lines array).
if cfg.options.max_filesize_kbytes and filesize == -1:
file_lines = []
filesize = 0
while 1:
line = fp.readline()
if not line:
break
filesize = filesize + len(line)
assert_viewable_filesize(cfg, filesize)
file_lines.append(line)
else:
file_lines = fp.readlines()
file_lines = fp.readlines()
fp.close()
# Do we have a differing number of file content lines and
@@ -2656,7 +2531,6 @@ def view_log(request):
sortby = vclib.SORTBY_DEFAULT
first = last = 0
log_pagestart = None
if cfg.options.log_pagesize:
log_pagestart = int(request.query_dict.get('log_pagestart', 0))
total = cfg.options.log_pagesextra * cfg.options.log_pagesize
@@ -2780,8 +2654,7 @@ def view_log(request):
if selected_rev != entry.rev:
entry.sel_for_diff_href = \
request.get_url(view_func=view_log,
params={'r1': entry.rev,
'log_pagestart': log_pagestart},
params={'r1': entry.rev},
escape=1)
if entry.prev is not None:
entry.diff_to_prev_href = \
@@ -2922,9 +2795,7 @@ def view_log(request):
if cfg.options.log_pagesize:
data['log_paging_action'], data['log_paging_hidden_values'] = \
request.get_form(params={'log_pagestart': None,
'r1': selected_rev,
})
request.get_form(params={'log_pagestart': None})
data['log_pagestart'] = int(request.query_dict.get('log_pagestart',0))
data['entries'] = paging_sws(data, 'entries', data['log_pagestart'],
'rev', cfg.options.log_pagesize,
@@ -3132,9 +3003,7 @@ class DiffSource:
return item
def _format_text(self, text):
text = string.rstrip(text, '\r\n')
if self.cfg.options.tabsize > 0:
text = string.expandtabs(text, self.cfg.options.tabsize)
text = string.expandtabs(string.rstrip(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
@@ -3192,7 +3061,7 @@ class DiffSource:
return _item(type='header',
line_info_left=match.group(1),
line_info_right=match.group(2),
line_info_extra=self._format_text(match.group(3)))
line_info_extra=match.group(3))
if line[0] == '\\':
# \ No newline at end of file
@@ -3407,13 +3276,6 @@ def view_patch(request):
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 \
is_binary_file_mime_type(mime_type2, cfg):
raise debug.ViewVCException('Display of binary file content disabled '
'by configuration', '403 Forbidden')
# In the absence of a format dictation in the CGI params, we'll let
# use the configured diff format, allowing 'c' to mean 'c' and
# anything else to mean 'u'.
@@ -3454,13 +3316,6 @@ def view_diff(request):
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 \
is_binary_file_mime_type(mime_type2, cfg):
raise debug.ViewVCException('Display of binary file content disabled '
'by configuration', '403 Forbidden')
# since templates are in use and subversion allows changes to the dates,
# we can't provide a strong etag
if check_freshness(request, None, '%s-%s' % (rev1, rev2), weak=1):
@@ -3609,7 +3464,7 @@ def view_diff(request):
def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
uid=0, gid=0, typeflag=None, linkname='',
uid=0, gid=0, typefrag=None, linkname='',
uname='viewvc', gname='viewvc',
devmajor=1, devminor=0, prefix=None,
magic='ustar', version='00', chksum=None):
@@ -3619,49 +3474,40 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
else:
mode = 0644
if not typeflag:
if linkname:
typeflag = '2' # symbolic link
elif name[-1:] == '/':
typeflag = '5' # directory
if not typefrag:
if name[-1:] == '/':
typefrag = '5' # directory
else:
typeflag = '0' # regular file
typefrag = '0' # regular file
if not prefix:
prefix = ''
# generate a GNU tar extension header for a long name.
# generate a GNU tar extension header for long names.
if len(name) >= 100:
generate_tarball_header(out, '././@LongLink', len(name),
0, 0, 0, 0, 'L')
0644, 0, 0, 0, 'L')
out.write(name)
out.write('\0' * (511 - ((len(name) + 511) % 512)))
# generate a GNU tar extension header for a long symlink name.
if len(linkname) >= 100:
generate_tarball_header(out, '././@LongLink', len(linkname),
0, 0, 0, 0, 'K')
out.write(linkname)
out.write('\0' * (511 - ((len(linkname) + 511) % 512)))
block1 = struct.pack('100s 8s 8s 8s 12s 12s',
name,
'%07o' % mode,
'%07o' % uid,
'%07o' % gid,
'%011o' % size,
'%011o' % mtime)
name,
'%07o' % mode,
'%07o' % uid,
'%07o' % gid,
'%011o' % size,
'%011o' % mtime)
block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s',
typeflag,
linkname,
magic,
version,
uname,
gname,
'%07o' % devmajor,
'%07o' % devminor,
prefix)
typefrag,
linkname,
magic,
version,
uname,
gname,
'%07o' % devmajor,
'%07o' % devminor,
prefix)
if not chksum:
dummy_chksum = ' '
@@ -3739,50 +3585,17 @@ def generate_tarball(out, request, reldir, stack, dir_mtime=None):
else:
mode = 0644
# Is this thing a symlink?
#
### FIXME: A better solution would be to have vclib returning
### symlinks with a new vclib.SYMLINK path type.
symlink_target = None
if hasattr(request.repos, 'get_symlink_target'):
symlink_target = request.repos.get_symlink_target(rep_path + [file.name],
request.pathrev)
### FIXME: Read the whole file into memory? Bad... better to do
### 2 passes.
fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0]
contents = fp.read()
fp.close()
# If the object is a symlink, generate the appropriate header.
# Otherwise, we're dealing with a regular file.
if symlink_target:
generate_tarball_header(out, tar_dir + file.name, 0, mode,
file.date is not None and file.date or 0,
typeflag='2', linkname=symlink_target)
else:
filesize = request.repos.filesize(rep_path + [file.name], request.pathrev)
if filesize == -1:
# Bummer. We have to calculate the filesize manually.
fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0]
filesize = 0
while 1:
chunk = retry_read(fp)
if not chunk:
break
filesize = filesize + len(chunk)
fp.close()
# 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:
chunk = retry_read(fp)
if not chunk:
break
out.write(chunk)
fp.close()
# ... and then add the block padding.
out.write('\0' * (511 - (filesize + 511) % 512))
generate_tarball_header(out, tar_dir + file.name,
len(contents), mode,
file.date is not None and file.date or 0)
out.write(contents)
out.write('\0' * (511 - ((len(contents) + 511) % 512)))
# Recurse into subdirectories, skipping busted and unauthorized (or
# configured-to-be-hidden) ones.
@@ -3806,10 +3619,6 @@ def download_tarball(request):
raise debug.ViewVCException('Tarball generation is disabled',
'403 Forbidden')
# If debugging, we just need to open up the specified tar path for
# writing. Otherwise, we get a writeable server output stream --
# disabling any default compression thereupon -- and wrap that in
# our own gzip stream wrapper.
if debug.TARFILE_PATH:
fp = open(debug.TARFILE_PATH, 'w')
else:
@@ -3818,9 +3627,11 @@ def download_tarball(request):
tarfile = "%s-%s" % (tarfile, request.path_parts[-1])
request.server.addheader('Content-Disposition',
'attachment; filename="%s.tar.gz"' % (tarfile))
server_fp = get_writeready_server_file(request, 'application/x-gzip',
allow_compress=False)
server_fp = get_writeready_server_file(request, 'application/x-gzip')
request.server.flush()
# Try to use the Python gzip module, if available; otherwise,
# we'll use the configured 'gzip' binary.
fp = gzip.GzipFile('', 'wb', 9, server_fp)
### FIXME: For Subversion repositories, we can get the real mtime of the
@@ -4721,14 +4532,14 @@ def find_root_in_parents(cfg, rootname, roottype):
continue
pp = os.path.normpath(string.strip(pp[:pos]))
rootpath = None
if roottype == 'cvs':
rootpath = vclib.ccvs.find_root_in_parent(pp, rootname)
roots = vclib.ccvs.expand_root_parent(pp)
elif roottype == 'svn':
rootpath = vclib.svn.find_root_in_parent(pp, rootname)
if rootpath is not None:
return rootpath
roots = vclib.svn.expand_root_parent(pp)
else:
roots = {}
if roots.has_key(rootname):
return roots[rootname]
return None
def locate_root(cfg, rootname):

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -9,11 +9,7 @@
[# ------------------------------------------------------------------------- ]
[# setup page definitions]
[is annotation "annotated"]
[define page_title]Annotation of /[where][end]
[else]
[define page_title]Contents of /[where][end]
[end]
[define page_title]Contents of /[where][end]
[define help_href][docroot]/help_rootview.html[end]
[# end]

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- Mode: python -*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC