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

Compare commits

..

32 Commits

Author SHA1 Message Date
cmpilato
c780600519 Tag the 1.1.20 final release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/tags/1.1.20@2898 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-24 13:27:13 +00:00
cmpilato
58633b700f * CHANGES
Plan to release 1.1.20 today.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2897 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-24 13:26:07 +00:00
cmpilato
420a1820dd Record the no-op merge of r2895 from ^/trunk.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2896 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-23 20:18:19 +00:00
cmpilato
ab355e92a2 Merge from trunk r2891, r2892, and r2893, which addressed the
embarrassing regression tracked in issue #526 ("Subversion roots not
longer accessible").

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2894 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-23 18:57:55 +00:00
cmpilato
37765cfb3e * CHANGES
Note the fix from r2889.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2890 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-23 18:07:52 +00:00
cmpilato
b09addcefb * lib/viewvc.py
(markup_stream): Fix typo/syntax error.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2889 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-23 18:04:32 +00:00
cmpilato
5329de2411 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2887 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-22 19:26:36 +00:00
cmpilato
40e938f123 Merge from trunk r2880:
Finish issue #46 ("ISO 8601 date/time format").
   
   * lib/viewvc.py
     (make_time_string): If cfg.options.iso8601_timestamps is set,
       generate ISO-8601-compliant timestamp strings.
   
   * lib/config.py
     (Config.set_defaults): Initialize 'iso8601_timestamps' option value.
   
   * conf/viewvc.conf.dist
     (iso8601_timestamps): New option.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2883 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-19 20:41:18 +00:00
cmpilato
57ab699677 * CHANGES
Group some related changes.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2882 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-19 20:35:23 +00:00
cmpilato
c4ec79be78 Merge from trunk r2876:
Fix some latent bugs whitespace handling.
   
   * lib/viewvc.py
     (markup_stream): Only expand tabs if the tabsize > 0.
     (DiffSource._format_text): Only strip EOL stuffs from the ends of
       lines -- preserve other whitespace forms.  Also, only expand tabs if
       the tabsize > 0.
   
   * conf/viewvc.conf.dist
     (tabsize): Use the term "horizontal tab character" rather than
       "tabstop".  The latter is the destination; the former is the
       character that tells the text flow to resume there.

Also:

* CHANGES
  Note these changes.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2879 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-18 14:06:58 +00:00
cmpilato
6f8c5a64b4 Followup to r2877, fixing a syntax error introduce there.
* lib/viewvc.py
  (detect_encoding): Fix syntax error.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2878 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-18 14:03:49 +00:00
cmpilato
f3335bd10c Merge from trunk r2872 and r2873:
Make some additional dents on issue #11 ("Universal UTF-8 output from
   ViewVC").

   Use the 'chardet' module where available and enabled by configuration
   to detect source file content encoding, and transcode the output to
   UTF-8.  We supported this already via Pygments when
   'enable_syntax_coloration' was set; now we can also support this when
   it isn't.

   * lib/viewvc.py
     (detect_encoding, transcode_text): New helper functions.
     (markup_stream): Use the new helper functions to attempt to
       transcode text into UTF-8 even when syntax coloration is *not* in
       use.

   * conf/viewvc.conf.dist
     (detect_encoding): Remove notation about this only being used when
       'enable_syntax_coloration' is also enabled.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2877 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-18 13:57:11 +00:00
cmpilato
f842941cd1 Merge from trunk r2874:
Fix an exception recently introduced.
   
   * lib/vclib/svn/svn_ra.py
     (RemoteSubversionRepository.filesize): Recombine path_parts before
       calling _get_dirents().


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2875 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-17 18:18:21 +00:00
cmpilato
d4eedc49b9 Merge from trunk r2870:
Fix issue #525 ("Tarball output is double-compressed when
   allow_compress=1").
   
   * lib/viewvc.py
     (get_writeready_server_file): Add 'allow_compress' parameter, and
       handling to give callers the power to disable response-level
       compression.
     (download_tarball): When calling get_writeready_server_file(),
       disable compression (if any) since we're doing our own gzipping
       herein.

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2871 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-16 18:18:26 +00:00
cmpilato
24b213e14c Merge from trunk r2867:
Fix an ancient code concern by no longer reading file content fully
   into memory when generating tarballs.
   
   * lib/viewvc.py
     (generate_tarball): Avoid reading file contents fully into memory.
       Rather, query the filesize from the vclib provider and chunk the
       output.  If the filesize must be calculated, use two chunked
       passes over those contents (one to measure, one to write to the
       tarball).

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2869 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-16 13:07:02 +00:00
cmpilato
82c0b25d80 Merge from trunk r2866:
Fix issue #524 ("Give administrators a way to limit the size of files
   processed by markup and annotate views").  This introduces a new
   'max_filesize_kbytes' configuration option for limiting markup and
   annotate operations on really big files (whose contents unfortunately
   must be read fully into memory sometimes).  By default, a 512-kilobyte
   limit will be in place.
   
   * lib/vclib/__init__.py
     (Repository.filesize): New.
   
   * lib/vclib/svn/svn_repos.py
     (LocalSubversionRepository.filesize): New function.
   
   * lib/vclib/svn/svn_ra.py
     (RemoteSubversionRepository.filesize): New function.
   
   * lib/vclib/ccvs/bincvs.py
     (BaseCVSRepository.filesize): New function (returns -1 aka "not
       implemented")
   
   * conf/viewvc.conf.dist
     (max_filesize_kbytes): New configuration option.
   
   * lib/config.py
     (Config.set_defaults): Set default value for new
       'max_filesize_kbytes' configuration option.
   
   * lib/viewvc.py
     (assert_viewable_filesize): New helper function.
     (markup_or_annotate): Use assert_viewable_filesize() and the new
       repos.filesize() API to honor the new 'max_filesize_kbytes'
       configuration option.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2868 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-15 19:54:57 +00:00
cmpilato
8fdb3c6a98 Merge from trunk r2864:
Over in Subversion-land, I finally got around to exposing the
   svn_cmdline_create_auth_baton() function via the SWIG Python
   bindings.  So now use it if it's available!
   
   * lib/vclib/svn/svn_ra.py
     (setup_client_ctx): New compatability-sensitive function.
     (RemoteSubversionRepository.open): Use setup_client_ctx() now.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2865 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-04-12 15:06:12 +00:00
cmpilato
ea15def7ad Merge from trunk r2862:
Optimize the mapping of a single root name to a root path by avoiding
   a potentially costly directory listing within the root parent paths.
   This has been shown to reduce the initial ViewVC startup overhead by
   400% in some situations where disk I/O is especially sluggish.
   
   * lib/vclib/ccvs/__init__.py
     (find_root_in_parent): New function.
   
   * lib/vclib/svn/__init__.py
     (find_root_in_parent): New function.
   
   * lib/viewvc.py
     (find_root_in_parents): Use the new find_root_in_parent() functions
       offered by the vclib implementations rather than the more expensive
       full root expansion stuffs.

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2863 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-03-20 13:22:14 +00:00
cmpilato
d15ff63726 Merged from trunk r2860 (dropping in some more debugging timestamp
points).

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2861 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-03-18 18:40:04 +00:00
cmpilato
ac2566c7ab Merge from trunk r2856-r2858, whose combined log messages might read:
Finish issue #487 ("Preserve Subversion symlinks in generated
   tarballs") for remote Subversion repositories, too.
   
   * lib/vclib/svn/svn_ra.py
     (cat_to_tempfile): Renamed from temp_checkout().  Callers updated.
     (RemoteSubversionRepository.openfile): Use cat_to_tempfile() now,
       and try to head off a race condition that could leave tempfiles
       lying about.
     (RemoteSubversionRepository.get_symlink_target): New function.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2859 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-03-04 20:56:05 +00:00
cmpilato
41fdf2b86d Merge from trunk r2853-r2855:
Finish issue #487 ("Preserve Subversion symlinks in generated tarballs")
   
   * lib/vclib/svn/svn_repos.py
     (LocalSubversionRepository.get_symlink_target): New function.
   
   * lib/viewvc.py
     (generate_tarball_header): Add the ability to generate private
       headers for long symlink names, too.
     (generate_tarball): Use the Repository object's get_symlink_target()
       function (if available) to determine whether a versioned object is a
       symlink, and use that information to preserve symlinks in
       generated tarballs.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2856 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-03-04 19:41:45 +00:00
cmpilato
a878d93992 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2850 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-28 19:27:40 +00:00
cmpilato
dae4abebaf * CHANGES: Minor wording tweaks.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2847 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-28 19:12:17 +00:00
cmpilato
dba173ca38 Signal intent to release 1.1.18 today.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2846 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-28 19:11:20 +00:00
cmpilato
5e18bf0aa4 Merge from trunk r2841-r2844, all of which were commits-db related changes.
* bin/make-database
     Add a --port option and handling thereof, passing the value off to
     'mysql'.
   
     Be less sloppy about what this script reports as default behavior
     around hostnames and ports.  If a hostname isn't supplied,
     "localhost" isn't strictly passed to 'mysql'; same for the port.
     And on UNIX, the lack of an explicit hostname (or an explicit
     "localhost" one) will cause 'mysql' to use a UNIX socket rather than
     a TCP/IP one, regardless of what the provided port is.  So it's not
     strictly accurate to imply that by not providing a hostname and
     port, 'make-database' will use "localhost/3306" for that
     information.
   
     Use "ENGINE=MyISAM" rather than "TYPE=MyISAM" throughout.  The
     latter syntax was deprecated in MySQL 5.0 and dropped in 5.5.
   
   * lib/cvsdb.py
     (CheckinDatabase.CheckCommit, CheckinDatabase.PurgeRepository):
       Name columns in SELECT statement rather than using '*'.

Also:

* CHANGES:
  Note these changes.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2845 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-26 17:04:10 +00:00
cmpilato
41809c22bf Merge from trunk r2839:
Fix issue #347 ("ccvs module handling of "dead" files doesn't jive
   with that of bincvs logic").
   
   * lib/vclib/ccvs/ccvs.py
     (InfoSink.define_revision): Tweak the revision matching logic a bit
       to include branch points as valid revisions when examining branch
       tags.

Also:

* CHANGES:
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2840 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-25 20:38:09 +00:00
cmpilato
850f4dd0eb Merge from trunk r2837:
Mark busted ,v files with no revisions as "absent" in the rcsparse-
   driven CVS backend, fixing an inconsistency between rcsparse-based and
   binary-based parsing.
   
   * lib/vclib/ccvs/ccvs.py
     (InfoSink.__init__): Init new 'saw_revision' flag.
     (InfoSink.define_revision): Set 'saw_revision'.
     (InfoSink.parse_completed): If 'saw_revision' is not set, set the
       'absent' flag.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2838 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-25 20:04:19 +00:00
cmpilato
7eace69bfb Merge from trunk r2832, whose log message said a little sum'thin' like
this:

   * lib/viewvc.py
     (markup_stream): Strip EOL characters from the ends of marked-up
       lines.  Templates can re-add line breaks, but they can't easily
       strip them.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2833 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-02-22 16:36:21 +00:00
cmpilato
907d9eddd2 Correct a royally botched CHANGES entry.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2829 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-01-31 19:49:41 +00:00
cmpilato
02eefc07a5 Merge from trunk r2827, described as follows:
Fix issue #519 ("Stack trace while accessing a BDB repository if last
   commit deleted a file or directory").
   
   * lib/vclib/svn/svn_repos.py
     (_get_change_copyinfo): Only call svn_fs_copied_from() on "add" and
       "replace" change items (which might actually be copies).  This
       avoids raising an exception caused by running svn_fs_copied_from()
       on a missing (via deletion) root/path pair.

Also:

* CHANGES:
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2828 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-01-29 16:00:02 +00:00
cmpilato
ddd96672b0 Bump copyright years. (Merged r2820 from ^/trunk.)
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2821 8cb11bc2-c004-0410-86c3-e597b4017df7
2013-01-04 19:04:36 +00:00
cmpilato
0fc67216d5 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2813 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-10-25 14:07:05 +00:00
55 changed files with 555 additions and 174 deletions

31
CHANGES
View File

@@ -1,3 +1,32 @@
Version 1.1.20 (released 24-Apr-2013)
* fix tab-to-space handling regression in markup view
* fix regression in root lookup handling (issue #526)
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)
@@ -24,7 +53,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 review log markup rules (issue #429)
* add support for custom revision log markup rules (issue #246)
Version 1.1.13 (released 23-Jan-2012)

View File

@@ -15,7 +15,7 @@
<blockquote>
<p><strong>Copyright &copy; 1999-2012 The ViewCVS Group. All rights
<p><strong>Copyright &copy; 1999-2013 The ViewCVS Group. All rights
reserved.</strong></p>
<p>By using ViewVC, you agree to the terms and conditions set forth
@@ -63,6 +63,7 @@
<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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=MyISAM;
"""
## ------------------------------------------------------------------------
@@ -132,7 +132,7 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE branch (branch)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=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)
) TYPE=MyISAM;
) ENGINE=MyISAM;
DROP TABLE IF EXISTS metadata;
CREATE TABLE metadata (
@@ -219,7 +219,7 @@ CREATE TABLE metadata (
value text,
PRIMARY KEY (name),
UNIQUE name (name)
) TYPE=MyISAM;
) ENGINE=MyISAM;
INSERT INTO metadata (name, value) VALUES ('version', '1');
"""
@@ -245,6 +245,10 @@ 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.
@@ -253,7 +257,8 @@ Options:
--help Show this usage message.
--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.
@@ -273,10 +278,11 @@ Options:
if __name__ == "__main__":
try:
# Parse the command-line options, if any.
dbname = version = hostname = username = password = None
dbname = version = hostname = port = username = password = None
opts, args = getopt.getopt(sys.argv[1:], '', [ 'dbname=',
'help',
'hostname=',
'port=',
'password=',
'username=',
'version=',
@@ -290,6 +296,8 @@ if __name__ == "__main__":
dbname = value
elif name == '--hostname':
hostname = value
elif name == '--port':
port = value
elif name == '--username':
username = value
elif name == '--password':
@@ -302,7 +310,9 @@ if __name__ == "__main__":
# Prompt for information not provided via command-line options.
if hostname is None:
hostname = raw_input("MySQL Hostname [default: localhost]: ") or ""
hostname = raw_input("MySQL Hostname (leave blank for default): ")
if port is None:
port = raw_input("MySQL Port (leave blank for default): ")
if username is None:
username = raw_input("MySQL User: ")
if password is None:
@@ -310,7 +320,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
@@ -318,16 +328,22 @@ if __name__ == "__main__":
else:
dscript = dscript + DATABASE_SCRIPT_VERSION_1
host_option = hostname and "--host=%s" % (hostname) or ""
# 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)
if sys.platform == "win32":
cmd = "mysql --user=%s --password=%s %s "\
% (username, password, host_option)
cmd = "mysql %s" % (cmd_args)
mysql = os.popen(cmd, "w") # popen2.Popen3 is not provided on windows
mysql.write(dscript)
status = mysql.close()
else:
cmd = "{ mysql --user=%s --password=%s %s ; } 2>&1" \
% (username, password, host_option)
cmd = "{ mysql %s ; } 2>&1" % (cmd_args)
pipes = popen2.Popen3(cmd)
pipes.tochild.write(dscript)
pipes.tochild.close()

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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

@@ -510,6 +510,15 @@
##
#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
@@ -677,6 +686,10 @@
##
#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.
##
@@ -693,15 +706,15 @@
##
#enable_syntax_coloration = 1
## tabsize: The number of spaces into which tabstops are converted
## when viewing file contents.
## tabsize: The number of spaces into which horizontal tab characters
## are converted when viewing file contents. Set to 0 to preserve
## tab characters.
##
#tabsize = 8
## detect_encoding: Should we attempt to detect versioned file
## character encodings? [Requires 'chardet' module, and is currently
## used only by the syntax coloration logic -- if enabled -- for the
## 'markup' and 'annotate' views; see 'enable_syntax_coloration'.]
## used only for the 'markup' and 'annotate' views.]
##
#detect_encoding = 0

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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
@@ -407,6 +407,7 @@ class Config:
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
@@ -429,6 +430,7 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,7 +520,10 @@ class CheckinDatabase:
if file_id == None:
return None
sql = "SELECT * FROM %s WHERE "\
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, fileid, " \
"revision, stickytag, branchid, addedlines, removedlines, " \
"descid "\
" FROM %s WHERE "\
" repositoryid=%%s "\
" AND dirid=%%s"\
" AND fileid=%%s"\
@@ -570,7 +573,10 @@ class CheckinDatabase:
self.sql_purge('descs', 'id', 'descid', 'commits')
self.sql_purge('people', 'id', 'whoid', 'commits')
else:
sql = "SELECT * FROM checkins WHERE repositoryid=%s"
sql = "SELECT type, ci_when, whoid, repositoryid, dirid, " \
"fileid, revision, stickytag, branchid, addedlines, " \
"removedlines, descid "\
" 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2008-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,7 +207,21 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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
@@ -18,6 +18,10 @@ def canonicalize_rootpath(rootpath):
return os.path.normpath(rootpath)
def _is_cvsroot(path):
return os.path.exists(os.path.join(path, "CVSROOT", "config"))
def expand_root_parent(parent_path):
# Each subdirectory of PARENT_PATH that contains a child
# "CVSROOT/config" is added the set of returned roots. Or, if the
@@ -26,15 +30,28 @@ def expand_root_parent(parent_path):
assert os.path.isabs(parent_path)
roots = {}
subpaths = os.listdir(parent_path)
cvsroot = os.path.exists(os.path.join(parent_path, "CVSROOT", "config"))
for rootname in subpaths:
rootpath = os.path.join(parent_path, rootname)
if cvsroot \
or (os.path.exists(os.path.join(rootpath, "CVSROOT", "config"))):
if _is_cvsroot(parent_path) or _is_cvsroot(rootpath):
roots[rootname] = canonicalize_rootpath(rootpath)
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."""
# 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.
assert os.path.isabs(parent_path)
rootpath = os.path.join(parent_path, rootname)
if (_is_cvsroot(parent_path) and os.path.exists(rootpath)) \
or _is_cvsroot(rootpath):
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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,6 +149,11 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,6 +200,7 @@ 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)
@@ -213,10 +214,17 @@ 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
@@ -224,14 +232,18 @@ 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 this revision is the highest revision so far found on that branch
# 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 = ((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)):
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]))):
self.matching_rev = rev
self.perfect_match = perfect

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,6 +77,20 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,6 +79,40 @@ 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 ###
@@ -132,7 +166,7 @@ class LogCollector:
if this_path:
self.path = this_path
def temp_checkout(svnrepos, path, rev):
def cat_to_tempfile(svnrepos, path, rev):
"""Check out file revision to temporary file"""
temp = tempfile.mktemp()
stream = core.svn_stream_from_aprfile(temp)
@@ -193,21 +227,8 @@ class RemoteSubversionRepository(vclib.Repository):
def open(self):
# Setup the client context baton, complete with non-prompting authstuffs.
# 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)
self.ctx = setup_client_ctx(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,
@@ -259,13 +280,10 @@ 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
client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev), self.ctx)
core.svn_stream_close(stream)
fp = SelfCleanFP(cat_to_tempfile(self, path, rev))
lh_rev, c_rev = self._get_last_history_rev(path_parts, rev)
return SelfCleanFP(tmp_file), lh_rev
return fp, lh_rev
def listdir(self, path_parts, rev, options):
path = self._getpath(path_parts)
@@ -442,8 +460,8 @@ class RemoteSubversionRepository(vclib.Repository):
return date
try:
temp1 = temp_checkout(self, p1, r1)
temp2 = temp_checkout(self, p2, r2)
temp1 = cat_to_tempfile(self, p1, r1)
temp2 = cat_to_tempfile(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)
@@ -457,6 +475,15 @@ 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, '/')
@@ -739,3 +766,33 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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,6 +587,13 @@ 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):
@@ -663,11 +670,19 @@ 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
else:
# ...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
return copyfrom_path, copyfrom_rev
def _simple_auth_check(fsroot):
@@ -934,3 +949,32 @@ 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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.17'
__version__ = '1.1.20'
# this comes from our library; measure the startup time
import debug
@@ -230,9 +230,12 @@ 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)
@@ -255,6 +258,7 @@ 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 '
@@ -262,7 +266,9 @@ 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'
@@ -392,7 +398,9 @@ 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
@@ -894,7 +902,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):
content_length=None, allow_compress=True):
"""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
@@ -903,10 +911,14 @@ 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 request.gzip_compress_level:
if allow_compress and request.gzip_compress_level:
request.server.addheader('Content-Encoding', 'gzip')
elif content_length is not None:
request.server.addheader('Content-Length', content_length)
@@ -918,7 +930,7 @@ def get_writeready_server_file(request, content_type=None, encoding=None,
else:
request.server.header()
if request.gzip_compress_level:
if allow_compress and request.gzip_compress_level:
fp = gzip.GzipFile('', 'wb', request.gzip_compress_level,
request.server.file())
else:
@@ -1648,6 +1660,37 @@ 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
@@ -1717,11 +1760,31 @@ 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]
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
line = markup_escaped_urls(line)
if cfg.options.tabsize > 0:
line = string.expandtabs(line, cfg.options.tabsize)
line = markup_escaped_urls(sapi.escape(line))
if blame_data:
blame_item = blame_data[i]
blame_item.text = line
@@ -1743,7 +1806,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(buf)
buf = markup_escaped_urls(string.rstrip(buf, '\n\r'))
if self.has_blame_data:
self.blame_data[self.line_no].text = buf
else:
@@ -1769,10 +1832,23 @@ def make_time_string(date, cfg):
if date is None:
return None
if cfg.options.use_localtime:
localtime = time.localtime(date)
return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]
tm = time.localtime(date)
else:
return time.asctime(time.gmtime(date)) + ' UTC'
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')
def make_rss_time_string(date, cfg):
"""Returns formatted date string in UTC, formatted for RSS.
@@ -1838,6 +1914,15 @@ 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')
@@ -1865,11 +1950,16 @@ def markup_or_annotate(request, is_annotate):
# Not a viewable image.
else:
blame_data = None
filesize = request.repos.filesize(path, rev)
# 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 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)
@@ -1897,7 +1987,22 @@ def markup_or_annotate(request, is_annotate):
if check_freshness(request, None, revision, weak=1):
fp.close()
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()
# Do we have a differing number of file content lines and
@@ -3027,7 +3132,9 @@ class DiffSource:
return item
def _format_text(self, text):
text = string.expandtabs(string.rstrip(text), self.cfg.options.tabsize)
text = string.rstrip(text, '\r\n')
if self.cfg.options.tabsize > 0:
text = string.expandtabs(text, self.cfg.options.tabsize)
hr_breakable = self.cfg.options.hr_breakable
# in the code below, "\x01" will be our stand-in for "&". We don't want
@@ -3502,7 +3609,7 @@ def view_diff(request):
def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
uid=0, gid=0, typefrag=None, linkname='',
uid=0, gid=0, typeflag=None, linkname='',
uname='viewvc', gname='viewvc',
devmajor=1, devminor=0, prefix=None,
magic='ustar', version='00', chksum=None):
@@ -3512,40 +3619,49 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
else:
mode = 0644
if not typefrag:
if name[-1:] == '/':
typefrag = '5' # directory
if not typeflag:
if linkname:
typeflag = '2' # symbolic link
elif name[-1:] == '/':
typeflag = '5' # directory
else:
typefrag = '0' # regular file
typeflag = '0' # regular file
if not prefix:
prefix = ''
# generate a GNU tar extension header for long names.
# generate a GNU tar extension header for a long name.
if len(name) >= 100:
generate_tarball_header(out, '././@LongLink', len(name),
0644, 0, 0, 0, 'L')
0, 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',
typefrag,
linkname,
magic,
version,
uname,
gname,
'%07o' % devmajor,
'%07o' % devminor,
prefix)
typeflag,
linkname,
magic,
version,
uname,
gname,
'%07o' % devmajor,
'%07o' % devminor,
prefix)
if not chksum:
dummy_chksum = ' '
@@ -3623,17 +3739,50 @@ def generate_tarball(out, request, reldir, stack, dir_mtime=None):
else:
mode = 0644
### 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()
# 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)
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)))
# 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))
# Recurse into subdirectories, skipping busted and unauthorized (or
# configured-to-be-hidden) ones.
@@ -3657,6 +3806,10 @@ 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:
@@ -3665,11 +3818,9 @@ 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')
server_fp = get_writeready_server_file(request, 'application/x-gzip',
allow_compress=False)
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
@@ -4570,14 +4721,14 @@ def find_root_in_parents(cfg, rootname, roottype):
continue
pp = os.path.normpath(string.strip(pp[:pos]))
rootpath = None
if roottype == 'cvs':
roots = vclib.ccvs.expand_root_parent(pp)
rootpath = vclib.ccvs.find_root_in_parent(pp, rootname)
elif roottype == 'svn':
roots = vclib.svn.expand_root_parent(pp)
else:
roots = {}
if roots.has_key(rootname):
return roots[rootname]
rootpath = vclib.svn.find_root_in_parent(pp, rootname)
if rootpath is not None:
return rootpath
return None
def locate_root(cfg, rootname):

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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 @@
#!/bin/sh
#
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2013 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