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) Version 1.1.15 (released 22-Jun-2012)
* security fix: complete authz support for remote SVN views (issue #353) * 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) * handle file:/// Subversion rootpaths as local roots (issue #446)
* fix bug caused by trying to case-normalize anon usernames (issue #505) * fix bug caused by trying to case-normalize anon usernames (issue #505)
* speed up log handling by reusing tokenization results (issue #506) * 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) Version 1.1.13 (released 23-Jan-2012)

View File

@@ -15,7 +15,7 @@
<blockquote> <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> reserved.</strong></p>
<p>By using ViewVC, you agree to the terms and conditions set forth <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>March 29, 2010 &mdash; copyright years updated</li>
<li>February 18, 2011 &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 23, 2012 &mdash; copyright years updated</li>
<li>January 04, 2013 &mdash; copyright years updated</li>
</ul> </ul>
</body> </body>

View File

@@ -3,7 +3,7 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -3,7 +3,7 @@
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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, branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE branch (branch) UNIQUE branch (branch)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS checkins; DROP TABLE IF EXISTS checkins;
CREATE TABLE checkins ( CREATE TABLE checkins (
@@ -63,7 +63,7 @@ CREATE TABLE checkins (
KEY dirid (dirid), KEY dirid (dirid),
KEY fileid (fileid), KEY fileid (fileid),
KEY branchid (branchid) KEY branchid (branchid)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS descs; DROP TABLE IF EXISTS descs;
CREATE TABLE descs ( CREATE TABLE descs (
@@ -72,7 +72,7 @@ CREATE TABLE descs (
hash bigint(20) DEFAULT '0' NOT NULL, hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
KEY hash (hash) KEY hash (hash)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs; DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs ( CREATE TABLE dirs (
@@ -80,7 +80,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL, dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE dir (dir) UNIQUE dir (dir)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS files; DROP TABLE IF EXISTS files;
CREATE TABLE files ( CREATE TABLE files (
@@ -88,7 +88,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL, file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE file (file) UNIQUE file (file)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS people; DROP TABLE IF EXISTS people;
CREATE TABLE people ( CREATE TABLE people (
@@ -96,7 +96,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL, who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE who (who) UNIQUE who (who)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS repositories; DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories ( CREATE TABLE repositories (
@@ -104,7 +104,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL, repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE repository (repository) UNIQUE repository (repository)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS tags; DROP TABLE IF EXISTS tags;
CREATE TABLE tags ( CREATE TABLE tags (
@@ -118,7 +118,7 @@ CREATE TABLE tags (
KEY dirid (dirid), KEY dirid (dirid),
KEY fileid (fileid), KEY fileid (fileid),
KEY branchid (branchid) KEY branchid (branchid)
) ENGINE=MyISAM; ) TYPE=MyISAM;
""" """
## ------------------------------------------------------------------------ ## ------------------------------------------------------------------------
@@ -132,7 +132,7 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL, branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE branch (branch) UNIQUE branch (branch)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS commits; DROP TABLE IF EXISTS commits;
CREATE TABLE commits ( CREATE TABLE commits (
@@ -156,7 +156,7 @@ CREATE TABLE commits (
KEY fileid (fileid), KEY fileid (fileid),
KEY branchid (branchid), KEY branchid (branchid),
KEY descid (descid) KEY descid (descid)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS descs; DROP TABLE IF EXISTS descs;
CREATE TABLE descs ( CREATE TABLE descs (
@@ -165,7 +165,7 @@ CREATE TABLE descs (
hash bigint(20) DEFAULT '0' NOT NULL, hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
KEY hash (hash) KEY hash (hash)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs; DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs ( CREATE TABLE dirs (
@@ -173,7 +173,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL, dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE dir (dir) UNIQUE dir (dir)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS files; DROP TABLE IF EXISTS files;
CREATE TABLE files ( CREATE TABLE files (
@@ -181,7 +181,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL, file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE file (file) UNIQUE file (file)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS people; DROP TABLE IF EXISTS people;
CREATE TABLE people ( CREATE TABLE people (
@@ -189,7 +189,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL, who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE who (who) UNIQUE who (who)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS repositories; DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories ( CREATE TABLE repositories (
@@ -197,7 +197,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL, repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE repository (repository) UNIQUE repository (repository)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS tags; DROP TABLE IF EXISTS tags;
CREATE TABLE tags ( CREATE TABLE tags (
@@ -211,7 +211,7 @@ CREATE TABLE tags (
KEY dirid (dirid), KEY dirid (dirid),
KEY fileid (fileid), KEY fileid (fileid),
KEY branchid (branchid) KEY branchid (branchid)
) ENGINE=MyISAM; ) TYPE=MyISAM;
DROP TABLE IF EXISTS metadata; DROP TABLE IF EXISTS metadata;
CREATE TABLE metadata ( CREATE TABLE metadata (
@@ -219,7 +219,7 @@ CREATE TABLE metadata (
value text, value text,
PRIMARY KEY (name), PRIMARY KEY (name),
UNIQUE name (name) UNIQUE name (name)
) ENGINE=MyISAM; ) TYPE=MyISAM;
INSERT INTO metadata (name, value) VALUES ('version', '1'); 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 database for you. You will then need to set the appropriate
parameters in the [cvsdb] section of your viewvc.conf file. 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: Options:
--dbname=ARG Use ARG as the ViewVC database name to create. --dbname=ARG Use ARG as the ViewVC database name to create.
@@ -257,8 +253,7 @@ Options:
--help Show this usage message. --help Show this usage message.
--hostname=ARG Use ARG as the hostname for the MySQL connection. --hostname=ARG Use ARG as the hostname for the MySQL connection.
[Default: localhost]
--port=ARG Use ARG as the port for the MySQL connection.
--password=ARG Use ARG as the password for the MySQL connection. --password=ARG Use ARG as the password for the MySQL connection.
@@ -278,11 +273,10 @@ Options:
if __name__ == "__main__": if __name__ == "__main__":
try: try:
# Parse the command-line options, if any. # 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=', opts, args = getopt.getopt(sys.argv[1:], '', [ 'dbname=',
'help', 'help',
'hostname=', 'hostname=',
'port=',
'password=', 'password=',
'username=', 'username=',
'version=', 'version=',
@@ -296,8 +290,6 @@ if __name__ == "__main__":
dbname = value dbname = value
elif name == '--hostname': elif name == '--hostname':
hostname = value hostname = value
elif name == '--port':
port = value
elif name == '--username': elif name == '--username':
username = value username = value
elif name == '--password': elif name == '--password':
@@ -310,9 +302,7 @@ if __name__ == "__main__":
# Prompt for information not provided via command-line options. # Prompt for information not provided via command-line options.
if hostname is None: if hostname is None:
hostname = raw_input("MySQL Hostname (leave blank for default): ") hostname = raw_input("MySQL Hostname [default: localhost]: ") or ""
if port is None:
port = raw_input("MySQL Port (leave blank for default): ")
if username is None: if username is None:
username = raw_input("MySQL User: ") username = raw_input("MySQL User: ")
if password is None: if password is None:
@@ -320,7 +310,7 @@ if __name__ == "__main__":
if dbname is None: if dbname is None:
dbname = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC" dbname = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC"
# Create the database. # Create the database
dscript = string.replace(DATABASE_SCRIPT_COMMON, "<dbname>", dbname) dscript = string.replace(DATABASE_SCRIPT_COMMON, "<dbname>", dbname)
if version == "1.0": if version == "1.0":
print BONSAI_COMPAT print BONSAI_COMPAT
@@ -328,22 +318,16 @@ if __name__ == "__main__":
else: else:
dscript = dscript + DATABASE_SCRIPT_VERSION_1 dscript = dscript + DATABASE_SCRIPT_VERSION_1
# Calculate command arguments. host_option = hostname and "--host=%s" % (hostname) or ""
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)
if sys.platform == "win32": 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 = os.popen(cmd, "w") # popen2.Popen3 is not provided on windows
mysql.write(dscript) mysql.write(dscript)
status = mysql.close() status = mysql.close()
else: 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 = popen2.Popen3(cmd)
pipes.tochild.write(dscript) pipes.tochild.write(dscript)
pipes.tochild.close() pipes.tochild.close()

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # Copyright (C) 2004-2007 James Henstridge
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 #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 ## authorizer: The name of the ViewVC authorizer plugin to use when
## authorizing access to repository contents. This value must be the ## authorizing access to repository contents. This value must be the
## name of a Python module addressable as vcauth.MODULENAME (most ## name of a Python module addressable as vcauth.MODULENAME (most
@@ -510,15 +492,6 @@
## ##
#svn_ignore_mimetype = 0 #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 ## svn_config_dir: Path of the Subversion runtime configuration
## directory ViewVC should consult for various things, including cached ## directory ViewVC should consult for various things, including cached
## remote authentication credentials. If unset, Subversion will use ## 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.) ## (Only works well for C source files, otherwise diff's heuristic falls short.)
## ('-p' option to diff) ## ('-p' option to diff)
## ##
#hr_funout = 1 #hr_funout = 0
## hr_ignore_white: Ignore whitespace (indendation and stuff) for human ## hr_ignore_white: Ignore whitespace (indendation and stuff) for human
## readable diffs. ## readable diffs.
@@ -686,10 +659,6 @@
## ##
#use_localtime = 0 #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 ## short_log_len: The length (in characters) to which the most recent
## log entry should be truncated when shown in the directory view. ## log entry should be truncated when shown in the directory view.
## ##
@@ -706,15 +675,15 @@
## ##
#enable_syntax_coloration = 1 #enable_syntax_coloration = 1
## tabsize: The number of spaces into which horizontal tab characters ## tabsize: The number of spaces into which tabstops are converted
## are converted when viewing file contents. Set to 0 to preserve ## when viewing file contents.
## tab characters.
## ##
#tabsize = 8 #tabsize = 8
## detect_encoding: Should we attempt to detect versioned file ## detect_encoding: Should we attempt to detect versioned file
## character encodings? [Requires 'chardet' module, and is currently ## 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 #detect_encoding = 0

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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> # Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -112,7 +112,6 @@ class Config:
_force_multi_value = ( _force_multi_value = (
# Configuration values with multiple, comma-separated values. # Configuration values with multiple, comma-separated values.
'allowed_views', 'allowed_views',
'binary_mime_types',
'custom_log_formatting', 'custom_log_formatting',
'cvs_roots', 'cvs_roots',
'kv_files', 'kv_files',
@@ -402,12 +401,10 @@ class Config:
self.options.mangle_email_addresses = 0 self.options.mangle_email_addresses = 0
self.options.custom_log_formatting = [] self.options.custom_log_formatting = []
self.options.default_file_view = "log" self.options.default_file_view = "log"
self.options.binary_mime_types = []
self.options.http_expiration_time = 600 self.options.http_expiration_time = 600
self.options.generate_etags = 1 self.options.generate_etags = 1
self.options.svn_ignore_mimetype = 0 self.options.svn_ignore_mimetype = 0
self.options.svn_config_dir = None self.options.svn_config_dir = None
self.options.max_filesize_kbytes = 512
self.options.use_rcsparse = 0 self.options.use_rcsparse = 0
self.options.sort_by = 'file' self.options.sort_by = 'file'
self.options.sort_group_dirs = 1 self.options.sort_group_dirs = 1
@@ -430,7 +427,6 @@ class Config:
self.options.show_log_in_markup = 1 self.options.show_log_in_markup = 1
self.options.cross_copies = 1 self.options.cross_copies = 1
self.options.use_localtime = 0 self.options.use_localtime = 0
self.options.iso8601_timestamps = 0
self.options.short_log_len = 80 self.options.short_log_len = 80
self.options.enable_syntax_coloration = 1 self.options.enable_syntax_coloration = 1
self.options.tabsize = 8 self.options.tabsize = 8

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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: if file_id == None:
return None return None
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, fileid, " \ sql = "SELECT * FROM %s WHERE "\
"revision, stickytag, branchid, addedlines, removedlines, " \
"descid "\
" FROM %s WHERE "\
" repositoryid=%%s "\ " repositoryid=%%s "\
" AND dirid=%%s"\ " AND dirid=%%s"\
" AND fileid=%%s"\ " AND fileid=%%s"\
@@ -573,10 +570,7 @@ class CheckinDatabase:
self.sql_purge('descs', 'id', 'descid', 'commits') self.sql_purge('descs', 'id', 'descid', 'commits')
self.sql_purge('people', 'id', 'whoid', 'commits') self.sql_purge('people', 'id', 'whoid', 'commits')
else: else:
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, " \ sql = "SELECT * FROM checkins WHERE repositoryid=%s"
"fileid, revision, stickytag, branchid, addedlines, " \
"removedlines, descid "\
" FROM checkins WHERE repositoryid=%s"
sql_args = (rep_id, ) sql_args = (rep_id, )
cursor = self.db.cursor() cursor = self.db.cursor()
cursor.execute(sql, sql_args) cursor.execute(sql, sql_args)

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 #!/usr/bin/env python
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*- # -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -208,20 +208,6 @@ class Repository:
rev is the revision of the item to return information about 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: class DirEntry:

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 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): def CVSRepository(name, rootpath, authorizer, utilities, use_rcsparse):
rootpath = canonicalize_rootpath(rootpath) rootpath = canonicalize_rootpath(rootpath)
if use_rcsparse: if use_rcsparse:

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC
@@ -150,11 +150,6 @@ class BaseCVSRepository(vclib.Repository):
rcsfile = self.rcsfile(path_parts, 1) rcsfile = self.rcsfile(path_parts, 1)
return os.access(rcsfile, os.X_OK) 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): class BinCVSRepository(BaseCVSRepository):
def _get_tip_revision(self, rcs_file, rev=None): def _get_tip_revision(self, rcs_file, rev=None):

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*-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> # Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
# #
# By using this file, you agree to the terms and conditions set forth in # By using this file, you agree to the terms and conditions set forth in

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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.matching_rev = None
self.perfect_match = 0 self.perfect_match = 0
self.lockinfo = { } self.lockinfo = { }
self.saw_revision = False
def define_tag(self, name, revision): def define_tag(self, name, revision):
MatchingSink.define_tag(self, name, revision) MatchingSink.define_tag(self, name, revision)
@@ -214,17 +213,10 @@ class InfoSink(MatchingSink):
self.entry.absent = 1 self.entry.absent = 1
raise rcsparse.RCSStopParser 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): def set_locker(self, rev, locker):
self.lockinfo[rev] = locker self.lockinfo[rev] = locker
def define_revision(self, revision, date, author, state, branches, next): def define_revision(self, revision, date, author, state, branches, next):
self.saw_revision = True
if self.perfect_match: if self.perfect_match:
return return
@@ -232,18 +224,14 @@ class InfoSink(MatchingSink):
rev = Revision(revision, date, author, state == "dead") rev = Revision(revision, date, author, state == "dead")
rev.lockinfo = self.lockinfo.get(revision) rev.lockinfo = self.lockinfo.get(revision)
# perfect match if revision number matches tag number or if # perfect match if revision number matches tag number or if revision is on
# revision is on trunk and tag points to trunk. imperfect match # trunk and tag points to trunk. imperfect match if tag refers to a branch
# if tag refers to a branch and either a) this revision is the # and this revision is the highest revision so far found on that branch
# highest revision so far found on that branch, or b) this
# revision is the branchpoint.
perfect = ((rev.number == tag.number) or perfect = ((rev.number == tag.number) or
(not tag.number and len(rev.number) == 2)) (not tag.number and len(rev.number) == 2))
if perfect or (tag.is_branch and \ if perfect or (tag.is_branch and tag.number == rev.number[:-1] and
((tag.number == rev.number[:-1] and (not self.matching_rev or
(not self.matching_rev or rev.number > self.matching_rev.number)):
rev.number > self.matching_rev.number)) or
(rev.number == tag.number[:-1]))):
self.matching_rev = rev self.matching_rev = rev
self.perfect_match = perfect self.perfect_match = perfect

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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 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): def SubversionRepository(name, rootpath, authorizer, utilities, config_dir):
rootpath = canonicalize_rootpath(rootpath) rootpath = canonicalize_rootpath(rootpath)
if re.search(_re_url, rootpath): if re.search(_re_url, rootpath):

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # 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, client.svn_client_log2([url], start_rev, end_rev, log_limit,
include_changes, not cross_copies, cb_convert, ctx) 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 ### ### END COMPATABILITY CODE ###
@@ -166,7 +132,7 @@ class LogCollector:
if this_path: if this_path:
self.path = 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""" """Check out file revision to temporary file"""
temp = tempfile.mktemp() temp = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(temp) stream = core.svn_stream_from_aprfile(temp)
@@ -227,8 +193,21 @@ class RemoteSubversionRepository(vclib.Repository):
def open(self): def open(self):
# Setup the client context baton, complete with non-prompting authstuffs. # 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 = ra.svn_ra_callbacks_t()
ra_callbacks.auth_baton = self.ctx.auth_baton ra_callbacks.auth_baton = self.ctx.auth_baton
self.ra_session = ra.svn_ra_open(self.rootpath, ra_callbacks, None, 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) raise vclib.Error("Path '%s' is not a file." % path)
rev = self._getrev(rev) rev = self._getrev(rev)
url = self._geturl(path) 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 ### 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) 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): def listdir(self, path_parts, rev, options):
path = self._getpath(path_parts) path = self._getpath(path_parts)
@@ -331,18 +313,14 @@ class RemoteSubversionRepository(vclib.Repository):
rev = self._getrev(rev) rev = self._getrev(rev)
url = self._geturl(path) url = self._geturl(path)
# If this is a file, fetch the lock status and size (as of REV) # Use ls3 to fetch the lock status and size (as of REV) for this item.
# for this item. lockinfo = None
lockinfo = size_in_rev = None basename = path_parts and path_parts[-1] or ""
if path_type == vclib.FILE: dirents, locks = list_directory(url, _rev2optrev(rev),
basename = path_parts[-1] _rev2optrev(rev), 0, self.ctx)
list_url = self._geturl(self._getpath(path_parts[:-1])) if locks.has_key(basename):
dirents, locks = list_directory(list_url, _rev2optrev(rev), lockinfo = locks[basename].owner
_rev2optrev(rev), 0, self.ctx) size_in_rev = dirents[basename].size
if locks.has_key(basename):
lockinfo = locks[basename].owner
if dirents.has_key(basename):
size_in_rev = dirents[basename].size
# Special handling for the 'svn_latest_log' scenario. # Special handling for the 'svn_latest_log' scenario.
### FIXME: Don't like this hack. We should just introduce ### FIXME: Don't like this hack. We should just introduce
@@ -460,8 +438,8 @@ class RemoteSubversionRepository(vclib.Repository):
return date return date
try: try:
temp1 = cat_to_tempfile(self, p1, r1) temp1 = temp_checkout(self, p1, r1)
temp2 = cat_to_tempfile(self, p2, r2) temp2 = temp_checkout(self, p2, r2)
info1 = p1, _date_from_rev(r1), r1 info1 = p1, _date_from_rev(r1), r1
info2 = p2, _date_from_rev(r2), r2 info2 = p2, _date_from_rev(r2), r2
return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args) 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 props = self.itemprops(path_parts, rev) # does authz-check
return props.has_key(core.SVN_PROP_EXECUTABLE) 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): def _getpath(self, path_parts):
return string.join(path_parts, '/') return string.join(path_parts, '/')
@@ -766,33 +735,3 @@ class RemoteSubversionRepository(vclib.Repository):
else: else:
peg_revision = mid peg_revision = mid
return peg_revision, path 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-*- # -*-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 # 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 # 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 props = self.itemprops(path_parts, rev) # does authz-check
return props.has_key(core.SVN_PROP_EXECUTABLE) 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 ---## ##--- helpers ---##
def _revinfo(self, rev, include_changed_paths=0): def _revinfo(self, rev, include_changed_paths=0):
@@ -670,19 +663,11 @@ class LocalSubversionRepository(vclib.Repository):
return found_readable, found_unreadable, changedpaths.values() return found_readable, found_unreadable, changedpaths.values()
def _get_change_copyinfo(fsroot, path, change): def _get_change_copyinfo(fsroot, path, change):
# If we know the copyfrom info, return it...
if hasattr(change, 'copyfrom_known') and change.copyfrom_known: if hasattr(change, 'copyfrom_known') and change.copyfrom_known:
copyfrom_path = change.copyfrom_path copyfrom_path = change.copyfrom_path
copyfrom_rev = change.copyfrom_rev 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: else:
copyfrom_rev = core.SVN_INVALID_REVNUM copyfrom_rev, copyfrom_path = fs.copied_from(fsroot, path)
copyfrom_path = None
return copyfrom_path, copyfrom_rev return copyfrom_path, copyfrom_rev
def _simple_auth_check(fsroot): def _simple_auth_check(fsroot):
@@ -949,32 +934,3 @@ class LocalSubversionRepository(vclib.Repository):
return peg_revision, path return peg_revision, path
finally: finally:
pass 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-*- # -*-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 # 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 # 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 # this comes from our library; measure the startup time
import debug import debug
@@ -24,7 +24,6 @@ debug.t_start('imports')
# standard modules that we know are in the path or builtin # standard modules that we know are in the path or builtin
import sys import sys
import os import os
import fnmatch
import gzip import gzip
import mimetypes import mimetypes
import re import re
@@ -230,12 +229,9 @@ class Request:
cfg.overlay_root_options(self.rootname) cfg.overlay_root_options(self.rootname)
# Setup an Authorizer for this rootname and username # Setup an Authorizer for this rootname and username
debug.t_start('setup-authorizer')
self.auth = setup_authorizer(cfg, self.username) self.auth = setup_authorizer(cfg, self.username)
debug.t_end('setup-authorizer')
# Create the repository object # Create the repository object
debug.t_start('select-repos')
try: try:
if roottype == 'cvs': if roottype == 'cvs':
self.rootpath = vclib.ccvs.canonicalize_rootpath(rootpath) self.rootpath = vclib.ccvs.canonicalize_rootpath(rootpath)
@@ -258,7 +254,6 @@ class Request:
raise vclib.ReposNotFound() raise vclib.ReposNotFound()
except vclib.ReposNotFound: except vclib.ReposNotFound:
pass pass
debug.t_end('select-repos')
if self.repos is None: if self.repos is None:
raise debug.ViewVCException( raise debug.ViewVCException(
'The root "%s" is unknown. If you believe the value is ' 'The root "%s" is unknown. If you believe the value is '
@@ -266,9 +261,7 @@ class Request:
% self.rootname, "404 Not Found") % self.rootname, "404 Not Found")
if self.repos: if self.repos:
debug.t_start('select-repos')
self.repos.open() self.repos.open()
debug.t_end('select-repos')
type = self.repos.roottype() type = self.repos.roottype()
if type == vclib.SVN: if type == vclib.SVN:
self.roottype = 'svn' self.roottype = 'svn'
@@ -398,9 +391,7 @@ class Request:
if needs_redirect: if needs_redirect:
self.server.redirect(self.get_url()) self.server.redirect(self.get_url())
else: else:
debug.t_start('view-func')
self.view_func(self) self.view_func(self)
debug.t_end('view-func')
def get_url(self, escape=0, partial=0, prefix=0, **args): def get_url(self, escape=0, partial=0, prefix=0, **args):
"""Constructs a link to another ViewVC page just like the get_link """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 return template
def get_writeready_server_file(request, content_type=None, encoding=None, 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 """Return a file handle to a response body stream, after outputting
any queued special headers (on REQUEST.server) and (optionally) a any queued special headers (on REQUEST.server) and (optionally) a
'Content-Type' header whose value is CONTENT_TYPE and character set '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 If CONTENT_LENGTH is provided and compression is not in use, also
generate a 'Content-Length' header for this response. 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 After this function is called, it is too late to add new headers to
the response.""" the response."""
if allow_compress and request.gzip_compress_level: if request.gzip_compress_level:
request.server.addheader('Content-Encoding', 'gzip') request.server.addheader('Content-Encoding', 'gzip')
elif content_length is not None: elif content_length is not None:
request.server.addheader('Content-Length', content_length) request.server.addheader('Content-Length', content_length)
@@ -930,7 +917,7 @@ def get_writeready_server_file(request, content_type=None, encoding=None,
else: else:
request.server.header() request.server.header()
if allow_compress and request.gzip_compress_level: if request.gzip_compress_level:
fp = gzip.GzipFile('', 'wb', request.gzip_compress_level, fp = gzip.GzipFile('', 'wb', request.gzip_compress_level,
request.server.file()) request.server.file())
else: else:
@@ -1030,15 +1017,6 @@ def default_view(mime_type, cfg):
return view_markup return view_markup
return view_checkout 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): 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 """Return an object holding common hrefs and a viewability flag used
for various views of FILENAME at revision REV whose MIME type is 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}, params={'revision': rev},
escape=1) escape=1)
is_binary_file = is_binary_file_mime_type(mime_type, request.cfg) prefer_markup = default_view(mime_type, request.cfg) == view_markup
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
return _item(view_href=view_href, return _item(view_href=view_href,
download_href=download_href, download_href=download_href,
@@ -1660,37 +1633,6 @@ def markup_escaped_urls(s):
return re.sub(_re_rewrite_escaped_url, _url_repl, 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, def markup_stream(request, cfg, blame_data, file_lines, filename,
mime_type, encoding, colorize): mime_type, encoding, colorize):
"""Return the contents of a versioned file as a list of """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 # If we aren't highlighting, just return an amalgamation of the
# BLAME_DATA (if any) and the FILE_LINES. # BLAME_DATA (if any) and the FILE_LINES.
if not pygments_lexer: 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 = [] 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)): for i in range(len(file_lines)):
line = file_lines[i] line = file_lines[i]
if cfg.options.tabsize > 0: line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
line = string.expandtabs(lin, cfg.options.tabsize) line = markup_escaped_urls(line)
line = markup_escaped_urls(sapi.escape(line))
if blame_data: if blame_data:
blame_item = blame_data[i] blame_item = blame_data[i]
blame_item.text = line blame_item.text = line
@@ -1806,7 +1728,7 @@ def markup_stream(request, cfg, blame_data, file_lines, filename,
self.line_no = 0 self.line_no = 0
def write(self, buf): def write(self, buf):
### FIXME: Don't bank on write() being called once per line ### 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: if self.has_blame_data:
self.blame_data[self.line_no].text = buf self.blame_data[self.line_no].text = buf
else: else:
@@ -1832,23 +1754,10 @@ def make_time_string(date, cfg):
if date is None: if date is None:
return None return None
if cfg.options.use_localtime: if cfg.options.use_localtime:
tm = time.localtime(date) localtime = time.localtime(date)
return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]
else: else:
tm = time.gmtime(date) return time.asctime(time.gmtime(date)) + ' UTC'
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')
def make_rss_time_string(date, cfg): def make_rss_time_string(date, cfg):
"""Returns formatted date string in UTC, formatted for RSS. """Returns formatted date string in UTC, formatted for RSS.
@@ -1914,15 +1823,6 @@ def calculate_mime_type(request, path_parts, rev):
pass pass
return guess_mime(path_parts[-1]), None 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): def markup_or_annotate(request, is_annotate):
cfg = request.cfg cfg = request.cfg
path, rev = _orig_path(request, is_annotate and 'annotate' or 'revision') path, rev = _orig_path(request, is_annotate and 'annotate' or 'revision')
@@ -1931,11 +1831,6 @@ def markup_or_annotate(request, is_annotate):
revision = None revision = None
mime_type, encoding = calculate_mime_type(request, path, rev) 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? # Is this a viewable image type?
if is_viewable_image(mime_type) \ if is_viewable_image(mime_type) \
and 'co' in cfg.options.allowed_views: and 'co' in cfg.options.allowed_views:
@@ -1950,16 +1845,11 @@ def markup_or_annotate(request, is_annotate):
# Not a viewable image. # Not a viewable image.
else: else:
filesize = request.repos.filesize(path, rev) blame_data = None
# If configuration disallows display of large files, try to honor
# that request.
assert_viewable_filesize(cfg, filesize)
# If this was an annotation request, try to annotate this file. # If this was an annotation request, try to annotate this file.
# If something goes wrong, that's okay -- we'll gracefully revert # If something goes wrong, that's okay -- we'll gracefully revert
# to a plain markup display. # to a plain markup display.
blame_data = None
if is_annotate: if is_annotate:
try: try:
blame_source, revision = request.repos.annotate(path, rev, False) 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): if check_freshness(request, None, revision, weak=1):
fp.close() fp.close()
return return
file_lines = fp.readlines()
# 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()
fp.close() fp.close()
# Do we have a differing number of file content lines and # Do we have a differing number of file content lines and
@@ -2656,7 +2531,6 @@ def view_log(request):
sortby = vclib.SORTBY_DEFAULT sortby = vclib.SORTBY_DEFAULT
first = last = 0 first = last = 0
log_pagestart = None
if cfg.options.log_pagesize: if cfg.options.log_pagesize:
log_pagestart = int(request.query_dict.get('log_pagestart', 0)) log_pagestart = int(request.query_dict.get('log_pagestart', 0))
total = cfg.options.log_pagesextra * cfg.options.log_pagesize total = cfg.options.log_pagesextra * cfg.options.log_pagesize
@@ -2780,8 +2654,7 @@ def view_log(request):
if selected_rev != entry.rev: if selected_rev != entry.rev:
entry.sel_for_diff_href = \ entry.sel_for_diff_href = \
request.get_url(view_func=view_log, request.get_url(view_func=view_log,
params={'r1': entry.rev, params={'r1': entry.rev},
'log_pagestart': log_pagestart},
escape=1) escape=1)
if entry.prev is not None: if entry.prev is not None:
entry.diff_to_prev_href = \ entry.diff_to_prev_href = \
@@ -2922,9 +2795,7 @@ def view_log(request):
if cfg.options.log_pagesize: if cfg.options.log_pagesize:
data['log_paging_action'], data['log_paging_hidden_values'] = \ data['log_paging_action'], data['log_paging_hidden_values'] = \
request.get_form(params={'log_pagestart': None, request.get_form(params={'log_pagestart': None})
'r1': selected_rev,
})
data['log_pagestart'] = int(request.query_dict.get('log_pagestart',0)) data['log_pagestart'] = int(request.query_dict.get('log_pagestart',0))
data['entries'] = paging_sws(data, 'entries', data['log_pagestart'], data['entries'] = paging_sws(data, 'entries', data['log_pagestart'],
'rev', cfg.options.log_pagesize, 'rev', cfg.options.log_pagesize,
@@ -3132,9 +3003,7 @@ class DiffSource:
return item return item
def _format_text(self, text): def _format_text(self, text):
text = string.rstrip(text, '\r\n') text = string.expandtabs(string.rstrip(text), self.cfg.options.tabsize)
if self.cfg.options.tabsize > 0:
text = string.expandtabs(text, self.cfg.options.tabsize)
hr_breakable = self.cfg.options.hr_breakable hr_breakable = self.cfg.options.hr_breakable
# in the code below, "\x01" will be our stand-in for "&". We don't want # 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', return _item(type='header',
line_info_left=match.group(1), line_info_left=match.group(1),
line_info_right=match.group(2), line_info_right=match.group(2),
line_info_extra=self._format_text(match.group(3))) line_info_extra=match.group(3))
if line[0] == '\\': if line[0] == '\\':
# \ No newline at end of file # \ No newline at end of file
@@ -3407,13 +3276,6 @@ def view_patch(request):
query_dict = request.query_dict query_dict = request.query_dict
p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) 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 # 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 # use the configured diff format, allowing 'c' to mean 'c' and
# anything else to mean 'u'. # anything else to mean 'u'.
@@ -3454,13 +3316,6 @@ def view_diff(request):
query_dict = request.query_dict query_dict = request.query_dict
p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) 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, # since templates are in use and subversion allows changes to the dates,
# we can't provide a strong etag # we can't provide a strong etag
if check_freshness(request, None, '%s-%s' % (rev1, rev2), weak=1): 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, 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', uname='viewvc', gname='viewvc',
devmajor=1, devminor=0, prefix=None, devmajor=1, devminor=0, prefix=None,
magic='ustar', version='00', chksum=None): magic='ustar', version='00', chksum=None):
@@ -3619,49 +3474,40 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
else: else:
mode = 0644 mode = 0644
if not typeflag: if not typefrag:
if linkname: if name[-1:] == '/':
typeflag = '2' # symbolic link typefrag = '5' # directory
elif name[-1:] == '/':
typeflag = '5' # directory
else: else:
typeflag = '0' # regular file typefrag = '0' # regular file
if not prefix: if not prefix:
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: if len(name) >= 100:
generate_tarball_header(out, '././@LongLink', len(name), generate_tarball_header(out, '././@LongLink', len(name),
0, 0, 0, 0, 'L') 0644, 0, 0, 0, 'L')
out.write(name) out.write(name)
out.write('\0' * (511 - ((len(name) + 511) % 512))) 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', block1 = struct.pack('100s 8s 8s 8s 12s 12s',
name, name,
'%07o' % mode, '%07o' % mode,
'%07o' % uid, '%07o' % uid,
'%07o' % gid, '%07o' % gid,
'%011o' % size, '%011o' % size,
'%011o' % mtime) '%011o' % mtime)
block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s', block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s',
typeflag, typefrag,
linkname, linkname,
magic, magic,
version, version,
uname, uname,
gname, gname,
'%07o' % devmajor, '%07o' % devmajor,
'%07o' % devminor, '%07o' % devminor,
prefix) prefix)
if not chksum: if not chksum:
dummy_chksum = ' ' dummy_chksum = ' '
@@ -3739,50 +3585,17 @@ def generate_tarball(out, request, reldir, stack, dir_mtime=None):
else: else:
mode = 0644 mode = 0644
# Is this thing a symlink? ### FIXME: Read the whole file into memory? Bad... better to do
# ### 2 passes.
### FIXME: A better solution would be to have vclib returning fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0]
### symlinks with a new vclib.SYMLINK path type. contents = fp.read()
symlink_target = None fp.close()
if hasattr(request.repos, 'get_symlink_target'):
symlink_target = request.repos.get_symlink_target(rep_path + [file.name],
request.pathrev)
# If the object is a symlink, generate the appropriate header. generate_tarball_header(out, tar_dir + file.name,
# Otherwise, we're dealing with a regular file. len(contents), mode,
if symlink_target: file.date is not None and file.date or 0)
generate_tarball_header(out, tar_dir + file.name, 0, mode, out.write(contents)
file.date is not None and file.date or 0, out.write('\0' * (511 - ((len(contents) + 511) % 512)))
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))
# Recurse into subdirectories, skipping busted and unauthorized (or # Recurse into subdirectories, skipping busted and unauthorized (or
# configured-to-be-hidden) ones. # configured-to-be-hidden) ones.
@@ -3806,10 +3619,6 @@ def download_tarball(request):
raise debug.ViewVCException('Tarball generation is disabled', raise debug.ViewVCException('Tarball generation is disabled',
'403 Forbidden') '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: if debug.TARFILE_PATH:
fp = open(debug.TARFILE_PATH, 'w') fp = open(debug.TARFILE_PATH, 'w')
else: else:
@@ -3818,9 +3627,11 @@ def download_tarball(request):
tarfile = "%s-%s" % (tarfile, request.path_parts[-1]) tarfile = "%s-%s" % (tarfile, request.path_parts[-1])
request.server.addheader('Content-Disposition', request.server.addheader('Content-Disposition',
'attachment; filename="%s.tar.gz"' % (tarfile)) 'attachment; filename="%s.tar.gz"' % (tarfile))
server_fp = get_writeready_server_file(request, 'application/x-gzip', server_fp = get_writeready_server_file(request, 'application/x-gzip')
allow_compress=False)
request.server.flush() 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) fp = gzip.GzipFile('', 'wb', 9, server_fp)
### FIXME: For Subversion repositories, we can get the real mtime of the ### 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 continue
pp = os.path.normpath(string.strip(pp[:pos])) pp = os.path.normpath(string.strip(pp[:pos]))
rootpath = None
if roottype == 'cvs': if roottype == 'cvs':
rootpath = vclib.ccvs.find_root_in_parent(pp, rootname) roots = vclib.ccvs.expand_root_parent(pp)
elif roottype == 'svn': elif roottype == 'svn':
rootpath = vclib.svn.find_root_in_parent(pp, rootname) roots = vclib.svn.expand_root_parent(pp)
else:
if rootpath is not None: roots = {}
return rootpath if roots.has_key(rootname):
return roots[rootname]
return None return None
def locate_root(cfg, rootname): def locate_root(cfg, rootname):

View File

@@ -1,6 +1,6 @@
# -*-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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC

View File

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

View File

@@ -1,6 +1,6 @@
#!/bin/sh #!/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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 # 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 #!/usr/bin/env python
# -*- Mode: 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 # 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 # the LICENSE.html file which can be found at the top level of the ViewVC