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

Compare commits

...

189 Commits

Author SHA1 Message Date
3c1cfef827 fix glob pattern interpretation 2015-06-16 16:17:01 +03:00
6c18327bbf fix fulltext comment search type radiobutton 2014-12-03 16:38:21 +03:00
cd14ba3825 Fix patch view 2014-04-02 15:29:04 +04:00
8ca4b5b85a Enable branch field if roottype != svn, not if is == cvs 2013-11-20 17:07:20 +04:00
8b3d3363f2 Use non-destructive subconfigs instead of in-place per-root patching of config object 2013-11-20 17:03:33 +04:00
44c5f2bb1a Remove binary_mime_re option 2013-11-20 17:03:33 +04:00
d3d81490e3 Use REQUEST_URI instead of SCRIPT_NAME 2013-09-11 17:05:26 +04:00
5814634779 Fix auth for repository root 2013-08-16 20:18:21 +04:00
b3000cf63b More fixes for globalauth 2013-08-12 16:48:21 +04:00
0a6f6a7a66 OK, now globalauth works without apache2 fixup handler 2013-08-12 16:27:54 +04:00
3ddd0caa42 Start new globalauth implementation 2013-08-09 20:13:57 +04:00
983f9c7379 Post-merge debug.
Also return some lost files back, document 4intra.net modifications
in CHANGES and README files, remove 'union' authorizer and rewritehtml
as the similar functionality is already provided by the core.

Also fix diffs for non-bash (sh/ash/dash) shells.
2013-07-24 17:37:59 +04:00
56c2b61458 Merge with original r2905 2013-07-18 19:13:28 +04:00
vfilippov
479a5b4506 Bug 124910 - Fix indexing file deletions (f**king undocumented swig bindings!!!)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1653 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:24 +04:00
vfilippov
5d442fac7d Bug 113586 - Suppress UNSAFE STATEMENT warning
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1628 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:24 +04:00
vfilippov
57e1ca8909 Bug 113586 - Suppress UNSAFE STATEMENT warning
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1626 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:24 +04:00
vfilippov
8492aa772e Bug 82651 - Limit content length for CALL SNIPPETS
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1609 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:24 +04:00
vfilippov
e854e254f9 Bug 106871
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1603 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
4b06eeeb94 Bug 105184 - Force annotation using client.blame3()
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1593 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
ac063ff93a Bug 82651 - 500 instead of 404 on module import errors
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1591 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
b5ac9522cc Bug 82651 - Allow index entries overwrite mode for Sphinx content indexing
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1588 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
a071627c59 Bug 82651 - Pass force to handle_revision
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1587 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
24e0a24ca9 Bug 99105 - Exact match on repo using last part of name
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1585 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:12:23 +04:00
vfilippov
dfff9c0cc2 Bug 82651
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1573 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:05 +04:00
vfilippov
0bd2b940f9 Bug 82651
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1452 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:05 +04:00
vfilippov
24b979d9e2 Bug 88900 - Force cvs_ondisk_charset
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1451 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:05 +04:00
vfilippov
7d06bd21bc Bug 82651
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1447 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:05 +04:00
vfilippov
fa08478619 Bug 82651 - () -> None
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1446 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
7d15648286 Bug 82651 - Fix for inaccessible repos
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1445 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
76987f0851 Bug 82651 - Retrieve text file contents from SVN when searching (debug)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1444 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
928bf6f1a6 Bug 82651 - Retrieve text file contents from SVN when searching
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1443 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
4cd52560ac Bug 88267 - Partial rebuild ability for CVS
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1442 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
a0a40b6047 Bug 87710
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1424 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:04 +04:00
vfilippov
e8c05fc096 Bug 87133
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1423 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:03 +04:00
vfilippov
999c9de4d3 Bug 87501 - Add must-revalidate headers
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1422 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:03 +04:00
vfilippov
131171943d Bug 87501 - Guess for full diff
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1421 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:03 +04:00
vfilippov
e415cd7bb0 Bug 87501 - init charset guesser
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1417 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:03 +04:00
vfilippov
575b4d8a49 Bug 63447 - 1/20 probability for cache clean
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1411 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:03 +04:00
vfilippov
3ec2c244a8 Bug 82651 - simple buffered reader for diff pipes
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1402 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:02 +04:00
vfilippov
160233f758 Bug 82651 - Content size limit (4MB Sphinx)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1401 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:02 +04:00
vfilippov
72934bf6cd Bug 82651 - Content size limit (4MB Sphinx), enable snippets setting
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1400 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:02 +04:00
vfilippov
a564b02d18 Bug 82651 - Store contents for snippet retrieval in MySQL
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1399 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:02 +04:00
vfilippov
80ccb26b20 Bug 82651 - Store contents for snippet retrieval in MySQL
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1398 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
1b75ada880 Bug 82651 - Remove rest of UTF-8 ugly hacks
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1396 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
ecadbf9fd3 Bug 82651 - Remove rest of UTF-8 ugly hacks
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1394 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
8dc02448bc Bug 82651
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1393 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
8aca8406a3 Bug 82651 - Non-verbose mode
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1392 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
639d1c25db Bug 82651 - Tika&Sphinx&chardet content indexing (done!)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1389 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:01 +04:00
vfilippov
e363cf19b1 Bug 82651 - Tika&Sphinx&chardet content indexing (done!)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1388 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
83c7e6fe49 Bug 82651
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1371 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
361a00ff13 Bug 82651 - Fix cvsdb glob search, TODO index file contents
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1365 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
e8f25d9c7b Bug 63447 - Cache expiration using mtime; Clean cache sometimes! (with 1/1000 probability)
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1345 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
c6582d1480 Bug 79260 - Fix cvsntacl auth for Python 2.6
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1265 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
ceb4990dec Bug 79260 - Fix cvsntacl auth for Python 2.6
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1264 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:07:00 +04:00
vfilippov
12434cb5b7 Bug 57786 - Fix ViewVC pipe errors through use of inetd "cvsnt rcsfile" service
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1242 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:59 +04:00
vfilippov
f4f2e432a7 Bug 76690 - Index
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1231 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:59 +04:00
vfilippov
7eb621bcd1 Bug 76690 - Optimize "only svn" / "only cvs"
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1230 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:59 +04:00
vfilippov
5de0639a9c Bug 76690 - Check glob match for being really an exact one
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1229 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:59 +04:00
vfilippov
e25a91837e Bug 74522 - Ignore spaces in ViewVC diffstat
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1225 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:59 +04:00
vfilippov
6df7a894d1 Bug 70605
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1219 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
04d3d504e0 Bug 73748 - Use real paths for repositories
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1195 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
33fffa82e8 Bug 71273 - Fix exception in ViewVC diffs
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@1041 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
fdd255f0ff Bug 63447 - /i
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@894 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
0b5123e1b8 Bug 63447
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@884 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
56614d0f13 Bug 63447 - Support for FOF_Sudo authorization
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@883 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
94c0c90329 Bug 63447 - include fof_sudo in rss links
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@879 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:58 +04:00
vfilippov
a4c3bd1a46 Bug 63447
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@877 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
a9701721e2 Bug 63447 - Cache security
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@875 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
5c1ac512d1 Bug 57786
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@871 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
cd9c47fe46 Bug 57786Show diff href
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@870 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
bb906c1f70 Bug 63447
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@869 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
b9a894f708 Bug 63447 - Global auth with external config file
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@868 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
1fae3f7e3e Bug 63447
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@865 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:57 +04:00
vfilippov
c73ba23f6e Bug 63447 - AnyJSON instead of simply json, debug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@864 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
0f323a50a4 Bug 63447 - Single sign-on for ViewVC
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@862 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
f3ba9d5e0a Bug 63447 - Single sign-on for ViewVC
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@861 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
1cda6497e1 Debug "unsecure patch" detection for queries across multiple repos,
debug vcauth grp


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@771 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
b9f2b63c09 Bug 45675: Bug 60603 displayed an empty patch
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@661 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
b1cffd5f2d Bug 60409 - Output correct link rel=self in RSS feeds
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@644 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:56 +04:00
vfilippov
323a4d5629 Bug 59499
Show diffs for moved files in query results


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@633 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
d65737cc43 Bug 57786
Ignore SIGPIPE


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@587 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
67b205634e Bug 37020
Удалил изврат, добавив чуть меньший изврат:
Теперь в процессе установки bin-файлы не модифицируются,
а только добавляется рядом с ними файл viewvcinstallpath,
в котором прописываются пути.


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@539 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
4e9089255c Bug 57246
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@538 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
bf062cc41b Bug 57245
Hyperlink bug URLs

[rewritehtml]
name.find = REGEXP
name.replace = REPLACEMENT


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@537 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
ab7e1bdc64 Bug 37020
SP4 lexer


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@529 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
e17b0dce21 Bug 56474
Honor repository for build_commit


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@518 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
552d04e882 Bug 45200
remove temp files


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@517 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:55 +04:00
vfilippov
f0a1418fbf Bug 45200
USE SHELL!!!
The bug was probably somewhere in file descriptor cloning + Apache webserver


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@516 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
75be406156 Bug 45200
Use temp file


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@512 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
964531a7a9 Bug 37020
mystical empty diffs


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@421 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
4304976db7 Bug 37020
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@280 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
8a649198d4 Bug 37020
Bug 32155
remove date & author from table


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@272 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
e78c234550 Bug 37020
Bug 32155
Fix an EVERLASTING error for all RSS generator:
Generating dates via strftime() with non-english LC_TIME


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@271 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
8367e08370 Bug 37020
Don't verify comments


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@270 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
vfilippov
b7c8b5eb6f Bug 37020
Bug 32155
RSS with committed file lists


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@269 6955db30-a419-402b-8a0d-67ecbb4d7f56
2013-07-18 17:06:54 +04:00
06bfb6a5fe Record merge with r2243 in git 2013-07-18 17:05:41 +04:00
vfilippov
04d3b88f6a Bug 37020
Merge with r2243 from official SVN


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@268 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-08-20 12:43:52 +00:00
vfilippov
d85d6578da Bug 53107
For Wiki Template:cvs


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@256 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-08-17 14:30:37 +00:00
vfilippov
7a40e1c902 Bug 52230
A fix for potential bug when no Subversion repositories are visible



git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@206 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-07-24 17:35:25 +00:00
stas
c8dbd38e0c Bug 51239
try: except: pass
FUCKING PYDON


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@198 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-07-02 13:46:38 +00:00
stas
82ea92e4a4 Bug 44995
Unicode() string in format_log


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@196 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-07-02 11:22:55 +00:00
vfilippov
be67aab7dc Bug 32155
Fix RSS urls in multi-repository feeds


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@194 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-07-01 10:29:45 +00:00
stas
8ecc076ebc Bug 37020
Fix build_commit access check


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@186 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-06-17 12:13:05 +00:00
stas
6a0562d708 Bug 37020
debug


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@185 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-06-16 16:54:14 +00:00
vfilippov
6835e74f20 Merge with ViewVC 1.2-dev http://viewvc.tigris.org/svn/viewvc@2204
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@184 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-06-16 14:11:20 +00:00
svnuser
4b05147064 Bug 50473
A workaround for line counts when moving


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@178 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-06-15 15:53:35 +00:00
svnuser
a208ec46ab Bug 37020
Search by revision number


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@165 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-05-21 14:42:39 +00:00
stas
86c313bcf8 Bug 37020
rss_href


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@163 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-04-10 10:26:29 +00:00
vfilippov
a2e45b4468 Bug 37020
404 not found on log_href's of removed files
More request.roottype ---> my_repos['roottype']


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@157 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-03-31 13:07:48 +00:00
stas
5ed8c4967a Bug 47903
Incorrect exam_rev for SVN deleted files


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@150 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-03-25 18:14:54 +00:00
stas
dbd3e4af59 Bug 46528
Bug 46710
default format


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@134 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-16 12:57:47 +00:00
vfilippov
5349a36a18 Bug 46528
Bug 46710
OR in group formats


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@133 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-16 12:55:32 +00:00
stas
81df47c357 Bug 46528
strip's


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@132 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-16 12:44:38 +00:00
stas
c916450eac Bug 46710
Bug 46528
Debugw


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@131 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-16 11:43:17 +00:00
stas
e4ea3a9f85 Bug 46710
Bug 46528
debug cvsntacl authorizer


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@130 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-16 11:41:16 +00:00
vfilippov
e6be979387 Bug 46528
By root group check specification


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@128 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-13 10:43:39 +00:00
vfilippov
2896c70f26 Bug 46528
New authorizers: grp, union, cvsntacl


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@127 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-12 16:37:15 +00:00
vfilippov
50b67b3ddb Bug 45076
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@126 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-11 12:57:01 +00:00
vfilippov
3c7ad9405c Bug 46239
Look in CVS/SVN/All repos link on query results page


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@121 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-03 12:19:33 +00:00
vfilippov
ab286694fe Bug 46239
Search only CVS/SVN repositories option


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@119 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-02-02 17:20:11 +00:00
vfilippov
1cf0815b3d Bug 45675
Unsecure patch detection fix for SVN roots


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@108 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-01-27 11:27:05 +00:00
vfilippov
355033b015 Bug 45675 -- debug
!!previous commit also was related to bug 45675


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@100 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-01-15 10:18:33 +00:00
vfilippov
2f99f7b72c Bug 45675 -- better way of diffing added/removed files
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@99 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-01-15 10:00:38 +00:00
vfilippov
e8d7fb16ff Bug 45675
debug


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@98 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-01-15 09:11:40 +00:00
vfilippov
e1cc47c375 Bug 45675: Patches from query results
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@97 6955db30-a419-402b-8a0d-67ecbb4d7f56
2009-01-14 14:07:41 +00:00
stas
5a55d3c0cd O_o max context value = 2^25-1 ... workaround for Bug 45200
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@76 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-22 18:13:08 +00:00
vfilippov
00d1ffe3e0 fix
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@75 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-22 18:00:37 +00:00
vfilippov
0d3176a320 bug 45200
'rcsdiff' workaround for fucking cvsnt


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@73 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-19 14:47:24 +00:00
vfilippov
053cc33ffd bug 44943
blame_source ---->> utf8string


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@68 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-16 14:29:30 +00:00
vfilippov
93144b2168 bug 37020
bug 44996
more CVS charset fixes


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@62 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-12 16:19:41 +00:00
vfilippov
c102b6b2a0 utf8string cvs logs
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@61 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-12 12:36:39 +00:00
vfilippov
7cd0e372bb russian filenames in cvs fix
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@60 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-11 16:02:02 +00:00
vfilippov
4e047ae281 bug 44931
s.encode('utf-8') in ezt


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@59 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-11 10:46:42 +00:00
vfilippov
1128625ac3 bug 44887
debug Magic MIME type guessing


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@58 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-10 13:21:37 +00:00
stas
15e2d27b7d xml
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@57 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-10 13:06:59 +00:00
vfilippov
86dcf849e3 debug magic code
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@56 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-10 13:03:55 +00:00
vfilippov
5f66346633 bug 44887
do not annotate binary files


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@55 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-10 12:26:16 +00:00
vfilippov
6586c8e4d7 bug 37020
enc fix


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@54 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 18:44:05 +00:00
vfilippov
d34f8f5946 bug 37020
debug


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@53 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 16:52:16 +00:00
vfilippov
842f0e712a bug 37020
templates for multi-repos query form


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@52 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 16:46:42 +00:00
vfilippov
0ad8ee1554 debug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@51 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 16:46:28 +00:00
vfilippov
0f545ca76b del
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@50 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 16:36:37 +00:00
vfilippov
c3f2777a4e bug 37020
multi-root query form


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@49 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 16:34:49 +00:00
vfilippov
45c636fd11 bug 37020
no pagesize by default


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@48 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 15:18:31 +00:00
vfilippov
2d9276a06d KEY descid
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@47 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 14:54:40 +00:00
vfilippov
eb6edef712 cvs logs -----> utf8
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@46 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-09 11:23:21 +00:00
vfilippov
b574b8594d utf8
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@45 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-08 13:00:51 +00:00
vfilippov
3bfb004158 asynchronous SVN update script
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@44 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-08 12:32:42 +00:00
vfilippov
23eea873fa fix a bug in setup cvs hooks script
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@43 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-04 21:51:19 +00:00
vfilippov
9f0557ff85 testing ViewVC hooks
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@42 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-04 21:32:44 +00:00
vfilippov
00f38a1b55 utf8string diffs
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@41 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-04 15:47:45 +00:00
vfilippov
3b4f7698af rights
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@40 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-02 14:55:27 +00:00
vfilippov
0114b46db0 fix directory rights
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@39 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-02 14:53:23 +00:00
vfilippov
a0c895b5a6 debug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@38 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-02 14:46:25 +00:00
vfilippov
e74a8ac42d Apache config via virthost
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@37 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-02 14:15:01 +00:00
vfilippov
d94e658457 cvs_ondisk_charset
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@36 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-02 10:39:18 +00:00
vfilippov
cbcffad79a physical charset
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@35 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-12-01 18:16:46 +00:00
vfilippov
025eb36df4 multiple repos co CVSROOT
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@34 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-27 15:20:35 +00:00
vfilippov
33a8f2849c CustIS install script, it's done and tested now
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@33 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-26 14:18:40 +00:00
vfilippov
1bbf731b83 setup-svn-hooks
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@32 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-26 14:15:32 +00:00
vfilippov
cd68fb0f79 improved ACL import script
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@31 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-21 17:06:03 +00:00
vfilippov
97e5d91c18 import
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@30 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-18 17:25:26 +00:00
vfilippov
28ba6929af cvsacl
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@29 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-18 17:24:50 +00:00
vfilippov
3187e57026 None
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@28 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-18 13:49:12 +00:00
vfilippov
a30b597260 check access rights when querying commit database
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@27 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-18 13:36:33 +00:00
vfilippov
1480000938 debug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@26 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-17 17:04:16 +00:00
vfilippov
bfe175e5cd setup cvs hook script
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@25 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-17 16:19:31 +00:00
vfilippov
2cadb542a2 pygments
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@24 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-14 19:42:47 +00:00
vfilippov
13b23a5696 total plus/minus lines
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@23 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-14 17:57:57 +00:00
vfilippov
822ec29624 bug 37020
fucking encodings


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@22 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-14 14:53:48 +00:00
vfilippov
f9b1b8a50c encodings
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@21 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-13 16:51:57 +00:00
vfilippov
6978ac9e5d merged
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@20 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-13 14:56:58 +00:00
vfilippov
230e2f1700 bug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@19 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 20:17:34 +00:00
vfilippov
899204468b cron reload
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@18 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 19:04:57 +00:00
vfilippov
712761df3f fast cvsdbadmin
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@17 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:52:54 +00:00
vfilippov
73eaad686b bug 37020
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@16 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:48:25 +00:00
vfilippov
6556287ff3 bug 37020
debug


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@15 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:46:44 +00:00
vfilippov
4b51a62390 bug 37020
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@14 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:45:01 +00:00
vfilippov
5ea538f50e Pygments from tarball
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@13 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:26:03 +00:00
vfilippov
521261bb34 bug 37020
automatic hook setup


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@12 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 18:14:50 +00:00
vfilippov
9e55dba9f9 bug 37020
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@11 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 17:40:19 +00:00
vfilippov
9ac8f10967 bug 37020
http_proxy


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@10 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 17:08:12 +00:00
vfilippov
6ef2a85ae9 debug
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@9 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 16:42:44 +00:00
vfilippov
1200a15887 bug 37020
config


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@8 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 16:39:48 +00:00
vfilippov
0fddc0bb87 Bug 37020
Install script


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@7 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 16:12:45 +00:00
vfilippov
28a41fb268 fix pygments
git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@6 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-12 16:12:19 +00:00
vfilippov
585580ec57 bug 37020
Ability to connect to MySQL through UNIX socket
diff links in query.py are shown now (moved expand_root_parents to config.py)
full-text comment searches in query and query_form are supported using MySQL FULLTEXT indexes
<select> for repository selection in query


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@5 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-11 14:25:07 +00:00
vfilippov
f3aa325419 bug 37020
viewvc 1.1.0-beta1 initial commit


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@4 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-11 14:17:41 +00:00
vfilippov
9b00bc278f bug 43834
dirs


git-svn-id: svn://svn.office.custis.ru/3rdparty/viewvc.org/trunk@3 6955db30-a419-402b-8a0d-67ecbb4d7f56
2008-11-11 14:12:33 +00:00
205 changed files with 10364 additions and 898 deletions

25
CHANGES
View File

@@ -1,3 +1,28 @@
4Intra.net/CUSTIS improvements
* Support for full-text search over file contents, including binary
documents like *.doc and so on using Sphinx Search and Apache Tika
server. Patched Tika with fixes for #TIKA709 and #TIKA964 is highly
recommended:
http://wiki.4intra.net/public/tika-app-1.2-fix-TIKA709-TIKA964.jar
(SHA1 efef722a5e2322f7c2616d096552a48134dc5faa)
* Access right checks in query results.
* Access right checks for repository root directories.
* New query parameters: repository, repo type, revision number.
* Authorizer for CVSnt ACLs.
* InnoDB, additional database indexes and some search query
optimisations.
* Support for specifying path to MySQL UNIX socket.
* Asynchronous hook examples for updating SVN and CVS repos.
* Slightly more correct charset guessing, especially for Russian.
* Support for diffing added/removed files.
* File lists in RSS feeds for 'classic' template.
* Path configuration via a single 'viewvcinstallpath.py' file,
not via editing multiple bin/* files.
* Link to repository list instead of viewvc.org from the logo
* "rcsfile service" support used to workaround command execution
problems (forks) from Apache mod_python.
Version 1.2.0 (released ??-???-????)
* bumped minimum support Python version to 2.4

3
README
View File

@@ -1,6 +1,9 @@
ViewVC -- Viewing the content of CVS/SVN repositories with a Webbrowser.
This is the 4Intra.net patched version with some extra features.
Please read the file INSTALL for more information.
And see windows/README for more information on running ViewVC on
Microsoft Windows.

View File

@@ -24,15 +24,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#

View File

@@ -24,15 +24,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#

View File

@@ -22,15 +22,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#

View File

@@ -22,15 +22,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#

216
bin/custis-install Executable file
View File

@@ -0,0 +1,216 @@
#!/bin/sh
# ViewVC installation script for CustIS
if [ -f custis-install-config ]; then
. custis-install-config
else
cat >custis-install-config <<EOF
CVS_ASYNC=
SVN_ASYNC=
CVS_USER=www-data
CVS_GROUP=cvs.users
CVSROOTS=
SVNROOT=
SVN_FORBIDDENRE=
DB_HOST=
DB_PORT=
DB_SOCKET=/var/run/mysqld/mysqld.sock
DB=
DB_USER=
DB_PASSWD=
VIEWVC_DIR=
VIEWVC_URI=/
VIEWVC_URI_SLASH=/
VIEWVC_STATIC_URI=/static
http_proxy=
no_proxy=
EOF
echo Empty 'custis-install-config' initialized, please edit it before installation.
exit
fi
if [ ! "$DB" -o ! "$VIEWVC_DIR" ]; then
echo Please set up 'custis-install-config' before installation.
exit
fi
################################################################################
export http_proxy
export no_proxy
DEPS="python libapache2-mod-python rcs diff cvsnt subversion subversion-tools python-setuptools python-subversion python-mysqldb cvsgraph"
echo "*** Installing dependency packages: $DEPS"
apt-get install $DEPS
echo "*** Installing Pygments for Python"
wget http://pypi.python.org/packages/source/P/Pygments/Pygments-0.11.1.tar.gz
tar -zxf Pygments-0.11.1.tar.gz
cd Pygments-0.11.1
python setup.py install
cd ..
echo "*** Installing ViewVC into $VIEWVC_DIR"
if [ ! -e $VIEWVC_DIR/viewvc.conf ]; then
../viewvc-install <<EOF
$VIEWVC_DIR
EOF
fi
echo "*** Writing ViewVC configuration into $VIEWVC_DIR/viewvc.conf"
for CVSROOT in $CVSROOTS; do
if [ "$vccvsroots" ]; then
vccvsroots="$vccvsroots, "
fi
vcrootname=`basename $CVSROOT`
vccvsroots="$vccvsroots$vcrootname: $CVSROOT"
done;
cat >"$VIEWVC_DIR/viewvc.conf" <<EOF
[general]
cvs_roots = $vccvsroots
root_parents = $SVNROOT : svn
cvsnt_exe_path = /usr/bin/cvsnt
mime_types_file = /etc/mime.types
address = Admin address: stas [gav-gav] custis [ru]
kv_files =
languages = en-us, ru-ru
[utilities]
rcs_dir = /usr/bin
cvsnt = /usr/bin/cvsnt
svn = /usr/bin/svn
diff = /usr/bin/diff
cvsgraph = /usr/bin/cvsgraph
[options]
allowed_views = markup, annotate, roots
authorizer = forbiddenre
checkout_magic = 0
cross_copies = 1
cvsgraph_conf = $VIEWVC_DIR/cvsgraph.conf
default_file_view = log
diff_format = h
docroot = $VIEWVC_STATIC_URI
enable_syntax_coloration = 1
generate_etags = 1
hide_attic = 1
hide_cvsroot = 1
hide_errorful_entries = 0
hr_breakable = 1
hr_funout = 0
hr_ignore_keyword_subst = 1
hr_ignore_white = 1
hr_intraline = 0
http_expiration_time = 600
limit_changes = 100
log_sort = date
mangle_email_addresses = 1
root_as_url_component = 1
short_log_len = 80
show_log_in_markup = 1
show_logs = 1
show_subdir_lastmod = 0
sort_by = file
sort_group_dirs = 1
svn_config_dir =
template_dir = templates
use_cvsgraph = 1
use_localtime = 1
use_pagesize = 0
use_rcsparse = 0
use_re_search = 0
[templates]
[cvsdb]
enabled = 1
host = $DB_HOST
socket = $DB_SOCKET
database_name = $DB
user = $DB_USER
passwd = $DB_PASSWD
readonly_user = $DB_USER
readonly_passwd = $DB_PASSWD
[vhosts]
[authz-forbidden]
forbidden =
[authz-forbiddenre]
forbiddenre = $SVN_FORBIDDENRE
[authz-svnauthz]
authzfile =
EOF
echo "*** Initializing database: $DB using $DB_USER@$DB_HOST"
$VIEWVC_DIR/bin/make-database <<EOF
$DB_HOST
$DB_USER
$DB_PASSWD
$DB
EOF
echo "*** Configuring Apache"
cat >/etc/apache2/sites-available/viewvc <<EOF
<VirtualHost *:80>
ServerName viewvc.office.custis.ru
ServerAlias viewvc
ServerAdmin sysadmins@custis.ru
ServerSignature Off
ErrorLog /var/log/apache2/viewvc-error.log
TransferLog /var/log/apache2/viewvc-access.log
LogLevel warn
# ViewVC at $VIEWVC_URI installed at $VIEWVC_DIR
DocumentRoot $VIEWVC_DIR/bin/mod_python
Alias $VIEWVC_STATIC_URI $VIEWVC_DIR/templates/docroot
Alias $VIEWVC_URI $VIEWVC_DIR/bin/mod_python/
<Location ~ ^${VIEWVC_URI_SLASH}*(\?.*)?$>
Options -Indexes
RewriteEngine On
RewriteRule .* ${VIEWVC_URI_SLASH}viewvc.py%{REQUEST_URI} [R,L]
</Location>
<Directory $VIEWVC_DIR/bin/mod_python>
Options +ExecCGI
AddHandler python-program .py
PythonHandler handler
PythonDebug Off
</Directory>
</VirtualHost>
EOF
a2enmod python
a2enmod mod_python
a2enmod rewrite
a2ensite viewvc
echo "*** Restarting Apache"
apache2ctl stop
sleep 1
apache2ctl start
echo "*** Building commit database for CVS"
for CVSROOT in $CVSROOTS; do
$VIEWVC_DIR/bin/cvsdbadmin rebuild $CVSROOT
done;
echo "*** Building commit database for Subversion repositories"
for i in `ls $SVNROOT`; do
if [ -d "$SVNROOT/$i" ]; then
$VIEWVC_DIR/bin/svndbadmin -v rebuild "$SVNROOT/$i"
fi
done;
# setup hooks for CVS
./setup-cvs-hooks "$CVSROOTS" "$VIEWVC_DIR" "$CVS_USER" "$CVS_GROUP" "$CVS_ASYNC"
# setup hooks for Subversion
./setup-svn-hooks "$SVNROOT" "$VIEWVC_DIR" "$SVN_ASYNC"

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
@@ -18,15 +18,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
# Adjust sys.path to include our library directory
import sys
@@ -43,17 +43,23 @@ import os
import cvsdb
import viewvc
import vclib.ccvs
from stat import *
def UpdateFile(db, repository, path, update, quiet_level):
def UpdateFile(db, repository, path, update, latest_checkin, quiet_level, encoding = None):
try:
if update:
mtime = os.stat(repository.rcsfile(path, 1))[ST_MTIME]
if mtime < latest_checkin:
return
commit_list = cvsdb.GetUnrecordedCommitList(repository, path, db)
else:
commit_list = cvsdb.GetCommitListFromRCSFile(repository, path)
except cvsdb.error, e:
print '[ERROR] %s' % (e)
return
except vclib.ItemNotFound, e:
return
file = '/'.join(path)
printing = 0
@@ -68,6 +74,8 @@ def UpdateFile(db, repository, path, update, quiet_level):
## add the commits into the database
for commit in commit_list:
if encoding:
commit.SetFile(commit.GetFile().decode(encoding).encode('utf-8'))
db.AddCommit(commit)
if printing:
sys.stdout.write('.')
@@ -76,7 +84,8 @@ def UpdateFile(db, repository, path, update, quiet_level):
print
def RecurseUpdate(db, repository, directory, update, quiet_level):
def RecurseUpdate(db, repository, directory, update, latest_checkin,
quiet_level, encoding = None):
for entry in repository.listdir(directory, None, {}):
path = directory + [entry.name]
@@ -84,11 +93,14 @@ def RecurseUpdate(db, repository, directory, update, quiet_level):
continue
if entry.kind is vclib.DIR:
RecurseUpdate(db, repository, path, update, quiet_level)
RecurseUpdate(db, repository, path, update, latest_checkin,
quiet_level, encoding)
continue
if entry.kind is vclib.FILE:
UpdateFile(db, repository, path, update, quiet_level)
UpdateFile(db, repository, path, update, latest_checkin,
quiet_level, encoding)
def RootPath(path, quiet_level):
"""Break os path into cvs root path and other parts"""
@@ -177,7 +189,7 @@ if __name__ == '__main__':
if quiet_level < 2:
print "Purging existing data for repository root `%s'" % root
try:
db.PurgeRepository(root)
db.PurgeRepository(root, len(path_parts) and '/'.join(path_parts) or '')
except cvsdb.UnknownRepositoryError, e:
if command == 'purge':
sys.stderr.write("ERROR: " + str(e) + "\n")
@@ -185,11 +197,15 @@ if __name__ == '__main__':
if command in ('rebuild', 'update'):
repository = vclib.ccvs.CVSRepository(None, rootpath, None,
cfg.utilities, 0)
cfg.utilities, 0, cfg.guesser())
latest_checkin = db.GetLatestCheckinTime(repository)
if latest_checkin is None:
command = 'rebuild'
RecurseUpdate(db, repository, path_parts,
command == 'update', quiet_level)
command == 'update', latest_checkin, quiet_level,
cfg.options.cvs_ondisk_charset)
except KeyboardInterrupt:
print
print '** break **'
sys.exit(0)

57
bin/cvsnt-import-cvsacl Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/perl
use strict;
my ($type, $path, $branch, $user, $perm);
my $R = ''; # -R for recursive
my $lvl = {
r => 1,
t => 2,
w => 3,
c => 4,
a => 4,
p => 5,
};
while(<>)
{
chomp;
next if /^\s*#/so;
($type, $path, $branch, $user, $perm) = split /:/, $_;
($user, $perm) = split /!/, $user;
next unless $perm;
$perm = [ sort { $lvl->{$b} cmp $lvl->{$a} } split //, $perm ];
$perm = $perm->[0];
if ($perm eq 't')
{
$perm = 'read,tag,nowrite,nocreate,nocontrol';
}
elsif ($perm eq 'r')
{
$perm = 'read,notag,nowrite,nocreate,nocontrol';
}
elsif ($perm eq 'w')
{
$perm = 'read,tag,write,nocreate,nocontrol';
}
elsif ($perm eq 'c' || $perm eq 'a')
{
$perm = 'read,tag,write,create,nocontrol';
}
elsif ($perm eq 'p')
{
$perm = 'read,tag,write,create,control';
}
print "cvs rchacl$R -a $perm";
print " -u '$user'" if $user ne 'ALL';
print " -r '$branch'" if $branch ne 'ALL';
if ($path ne 'ALL')
{
print " '$path'";
}
else
{
print ' `ls $CVSROOT | grep -v '."'#cvs'`";
}
print "\n";
}

21
bin/cvsnt-rcsfile-inetd.pl Executable file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/perl
# Very simple inetd/xinetd "cvsnt rcsfile" service
# Useful for ViewVC as there is an unpleasant non-stable bug, probably somewhere
# inside mod_python or Apache, which SOMETIMES causes cvsnt subprocesses forked
# from mod_python to die. This gives empty diff outputs or different errors like
# "Error: Rlog output ended early. Expected RCS file ..."
# This script removes forking from mod_python code and solves the issue.
# Additional profit of this script is that you can probably browse REMOTE cvs
# repositories, if you expose this service to ViewVC, although it is not tested.
# USAGE: (local) create an inetd service with this script as server listening
# on some port of 127.0.0.1 and put "rcsfile_socket = 127.0.0.1:port"
# into "utilities" section of viewvc.conf
$args = <STDIN>;
$args =~ s/\s+$//so;
@args = $args =~ /\'([^\']+)\'/giso;
# We don't execute shell, so this is mostly safe, not a backdoor :)
exec('/usr/bin/cvsnt', 'rcsfile', @args);

View File

@@ -17,15 +17,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
# Adjust sys.path to include our library directory
import sys

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2009 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
@@ -16,8 +16,7 @@
#
# -----------------------------------------------------------------------
import os
import sys
import os, sys, string
import popen2
import getopt
@@ -41,10 +40,11 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE branch (branch)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS checkins;
CREATE TABLE checkins (
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
type enum('Change','Add','Remove'),
ci_when datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
whoid mediumint(9) DEFAULT '0' NOT NULL,
@@ -58,13 +58,14 @@ CREATE TABLE checkins (
removedlines int(11) DEFAULT '0' NOT NULL,
descid mediumint(9),
UNIQUE repositoryid (repositoryid,dirid,fileid,revision),
KEY repositoryid_when (repositoryid,ci_when),
KEY ci_when (ci_when),
KEY whoid (whoid),
KEY repositoryid_2 (repositoryid),
KEY whoid (whoid,ci_when),
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
KEY branchid (branchid),
KEY descid (descid)
) TYPE=InnoDB;
DROP TABLE IF EXISTS descs;
CREATE TABLE descs (
@@ -72,8 +73,9 @@ CREATE TABLE descs (
description text,
hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY hash (hash)
) ENGINE=MyISAM;
KEY hash (hash),
FULLTEXT KEY description (description)
) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs (
@@ -81,7 +83,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE dir (dir)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS files;
CREATE TABLE files (
@@ -89,7 +91,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE file (file)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS people;
CREATE TABLE people (
@@ -97,7 +99,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE who (who)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories (
@@ -105,7 +107,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE repository (repository)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS tags;
CREATE TABLE tags (
@@ -119,7 +121,13 @@ CREATE TABLE tags (
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS contents;
CREATE TABLE contents (
id int NOT NULL PRIMARY KEY,
content MEDIUMTEXT NOT NULL DEFAULT ''
) TYPE=MyISAM;
"""
## ------------------------------------------------------------------------
@@ -133,10 +141,11 @@ CREATE TABLE branches (
branch varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE branch (branch)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS commits;
CREATE TABLE commits (
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
type enum('Change','Add','Remove'),
ci_when datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
whoid mediumint(9) DEFAULT '0' NOT NULL,
@@ -150,14 +159,14 @@ CREATE TABLE commits (
removedlines int(11) DEFAULT '0' NOT NULL,
descid mediumint(9),
UNIQUE repositoryid (repositoryid,dirid,fileid,revision),
KEY repositoryid_when (repositoryid,ci_when),
KEY ci_when (ci_when),
KEY whoid (whoid),
KEY repositoryid_2 (repositoryid),
KEY whoid (whoid,ci_when),
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid),
KEY descid (descid)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS descs;
CREATE TABLE descs (
@@ -165,8 +174,9 @@ CREATE TABLE descs (
description text,
hash bigint(20) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY hash (hash)
) ENGINE=MyISAM;
KEY hash (hash),
FULLTEXT KEY description (description)
) TYPE=MyISAM;
DROP TABLE IF EXISTS dirs;
CREATE TABLE dirs (
@@ -174,7 +184,7 @@ CREATE TABLE dirs (
dir varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE dir (dir)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS files;
CREATE TABLE files (
@@ -182,7 +192,7 @@ CREATE TABLE files (
file varchar(255) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE file (file)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS people;
CREATE TABLE people (
@@ -190,7 +200,7 @@ CREATE TABLE people (
who varchar(128) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE who (who)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS repositories;
CREATE TABLE repositories (
@@ -198,7 +208,7 @@ CREATE TABLE repositories (
repository varchar(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (id),
UNIQUE repository (repository)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS tags;
CREATE TABLE tags (
@@ -212,7 +222,7 @@ CREATE TABLE tags (
KEY dirid (dirid),
KEY fileid (fileid),
KEY branchid (branchid)
) ENGINE=MyISAM;
) TYPE=InnoDB;
DROP TABLE IF EXISTS metadata;
CREATE TABLE metadata (
@@ -220,8 +230,14 @@ CREATE TABLE metadata (
value text,
PRIMARY KEY (name),
UNIQUE name (name)
) ENGINE=MyISAM;
) TYPE=InnoDB;
INSERT INTO metadata (name, value) VALUES ('version', '1');
DROP TABLE IF EXISTS contents;
CREATE TABLE contents (
id int NOT NULL PRIMARY KEY,
content MEDIUMTEXT NOT NULL DEFAULT ''
) TYPE=MyISAM;
"""
BONSAI_COMPAT="""
@@ -246,20 +262,15 @@ 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.
[Default: ViewVC]
--help Show this usage message.
--hostname=ARG Use ARG as the hostname for the MySQL connection.
--port=ARG Use ARG as the port for the MySQL connection.
--hostname=ARG Use ARG as the hostname for the MySQL connection.
[Default: localhost]
--password=ARG Use ARG as the password for the MySQL connection.
@@ -268,7 +279,7 @@ Options:
--version=ARG Create the database using the schema employed by
version ARG of ViewVC. Valid values are:
[ "1.0" ]
""" % (os.path.basename(sys.argv[0])))
if errmsg is not None:
stream.write("[ERROR] %s.\n" % (errmsg))
@@ -279,11 +290,10 @@ Options:
if __name__ == "__main__":
try:
# Parse the command-line options, if any.
dbname = version = hostname = port = username = password = None
dbname = version = hostname = username = password = None
opts, args = getopt.getopt(sys.argv[1:], '', [ 'dbname=',
'help',
'hostname=',
'port=',
'password=',
'username=',
'version=',
@@ -297,8 +307,6 @@ if __name__ == "__main__":
dbname = value
elif name == '--hostname':
hostname = value
elif name == '--port':
port = value
elif name == '--username':
username = value
elif name == '--password':
@@ -311,9 +319,7 @@ if __name__ == "__main__":
# Prompt for information not provided via command-line options.
if hostname is None:
hostname = raw_input("MySQL Hostname (leave blank for default): ")
if port is None:
port = raw_input("MySQL Port (leave blank for default): ")
hostname = raw_input("MySQL Hostname [default: localhost]: ") or ""
if username is None:
username = raw_input("MySQL User: ")
if password is None:
@@ -321,30 +327,24 @@ if __name__ == "__main__":
if dbname is None:
dbname = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC"
# Create the database.
dscript = DATABASE_SCRIPT_COMMON.replace("<dbname>", dbname)
# Create the database
dscript = string.replace(DATABASE_SCRIPT_COMMON, "<dbname>", dbname)
if version == "1.0":
print BONSAI_COMPAT
dscript = dscript + DATABASE_SCRIPT_VERSION_0
else:
dscript = dscript + DATABASE_SCRIPT_VERSION_1
# Calculate command arguments.
cmd_args = "--user=%s --password=%s" % (username, password)
if hostname or port:
cmd_args = cmd_args + " --protocol=TCP"
if hostname:
cmd_args = cmd_args + " --host=%s" % (hostname)
if port:
cmd_args = cmd_args + " --port=%s" % (port)
host_option = hostname and "--host=%s" % (hostname) or ""
if sys.platform == "win32":
cmd = "mysql %s" % (cmd_args)
cmd = "mysql --user=%s --password=%s %s "\
% (username, password, host_option)
mysql = os.popen(cmd, "w") # popen2.Popen3 is not provided on windows
mysql.write(dscript)
status = mysql.close()
else:
cmd = "{ mysql %s ; } 2>&1" % (cmd_args)
cmd = "{ mysql --user=%s --password=%s %s ; } 2>&1" \
% (username, password, host_option)
pipes = popen2.Popen3(cmd)
pipes.tochild.write(dscript)
pipes.tochild.close()

View File

@@ -1,3 +1,3 @@
AddHandler python-program .py
PythonHandler handler
PythonDebug On
PythonDebug Off

6
bin/mod_python/handler.py Normal file → Executable file
View File

@@ -20,10 +20,8 @@ import os.path
def handler(req):
path, module_name = os.path.split(req.filename)
module_name, module_ext = os.path.splitext(module_name)
try:
module = apache.import_module(module_name, path=[path])
except ImportError:
raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
# Let it be 500 Internal Server Error in case of import error
module = apache.import_module(module_name, path=[path])
req.add_common_vars()
module.index(req)

9
bin/mod_python/query.py Normal file → Executable file
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
@@ -21,15 +22,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#

16
bin/mod_python/viewvc.py Normal file → Executable file
View File

@@ -1,3 +1,4 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2013 The ViewCVS Group. All Rights Reserved.
@@ -21,15 +22,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
#########################################################################
#
@@ -43,6 +44,13 @@ if LIBRARY_DIR:
import sapi
import imp
import signal
# Totally ignore SIGPIPE - needed for overcoming popen() errors
def sigpipe(signum, frame):
pass
signal.signal(signal.SIGPIPE, sigpipe)
# Import real ViewVC module
fp, pathname, description = imp.find_module('viewvc', [LIBRARY_DIR])

57
bin/setup-cvs-hooks Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/sh
CVSROOTS=$1
VIEWVC_DIR=$2
CVS_USER=$3
CVS_GROUP=$4
CVS_ASYNC=$5
if [ ! "$CVSROOTS" -o ! "$VIEWVC_DIR" -o ! "$CVS_USER" -o ! "$CVS_GROUP" ]; then
echo "USAGE: $0 <CVS_ROOTS> <VIEWVC_DIR> <CVS_USER> <CVS_GROUP> [CVS_ASYNC]"
exit
fi
echo "*** Setting up commit hooks for CVS repositories (job=$CVS_ASYNC)"
chgrp $CVS_GROUP $VIEWVC_DIR
chmod 775 $VIEWVC_DIR
chmod 1777 .
for CVSROOT in $CVSROOTS; do
vcrootname=`basename $CVSROOT`
if [ "$CVS_ASYNC" ]; then
VHOOK="touch $VIEWVC_DIR/.cvs-updated-$vcrootname"
else
VHOOK="$VIEWVC_DIR/bin/cvsdbadmin update $CVSROOT >/dev/null"
fi;
su $CVS_USER -s /bin/sh <<EOSH
CVSROOT=$CVSROOT cvs co CVSROOT
if [ $? -eq 0 ]; then
cd CVSROOT
mv loginfo loginfo.bak
grep -v '/.cvs-updated' <loginfo.bak | grep -v '/bin/cvsdbadmin update' >loginfo
cat >>loginfo <<EOF
ALL $VHOOK
EOF
cvs ci -m 'CVS commit hook for ViewVC' loginfo
cd ..
rm -Rf CVSROOT
fi
EOSH
if [ "$CVS_ASYNC" ]; then
cat >$VIEWVC_DIR/cvshook-$vcrootname <<EOF
#!/bin/sh
if [ -e "$VIEWVC_DIR/.cvs-updated-$vcrootname" ]; then
rm "$VIEWVC_DIR/.cvs-updated-$vcrootname"
$VIEWVC_DIR/bin/cvsdbadmin update $CVSROOT >/dev/null
fi
EOF
chmod 755 $VIEWVC_DIR/cvshook-$vcrootname
cat >/etc/cron.d/viewvc-cvs-$vcrootname <<EOF
*/5 * * * * root $VIEWVC_DIR/cvshook-$vcrootname
EOF
fi
done;
if [ "$CVS_ASYNC" ]; then
echo "*** Reloading cron daemon"
/etc/init.d/cron reload
fi

36
bin/setup-svn-hooks Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/sh
SVNROOT=$1
VIEWVC_DIR=$2
SVN_ASYNC=$3
if [ ! "$SVNROOT" -o ! "$VIEWVC_DIR" ]; then
echo "USAGE: $0 <SVNROOT> <VIEWVC_DIR>"
exit
fi
echo "*** Setting up commit hooks for Subversion"
for i in `ls $SVNROOT`; do
if [ -d "$SVNROOT/$i" ]; then
if [ "$SVN_ASYNC" ]; then
cat >"$SVNROOT/$i/hooks/post-commit.tmp" <<EOF
#!/bin/sh
echo "\$1 \$2" >> $VIEWVC_DIR/.svn-updated
EOF
else
cat >"$SVNROOT/$i/hooks/post-commit.tmp" <<EOF
#!/bin/sh
$VIEWVC_DIR/bin/svndbadmin update \$1 \$2
EOF
fi
chmod 755 "$SVNROOT/$i/hooks/post-commit.tmp"
mv "$SVNROOT/$i/hooks/post-commit.tmp" "$SVNROOT/$i/hooks/post-commit"
fi
done;
if [ "$SVN_ASYNC" ]; then
cat >/etc/cron.d/viewvc-svn <<EOF
*/10 * * * * root $VIEWVC_DIR/bin/svnupdate-async.sh "$VIEWVC_DIR"
EOF
/etc/init.d/cron reload
fi

View File

@@ -16,15 +16,20 @@
#
# -----------------------------------------------------------------------
"""Run "standalone.py -p <port>" to start an HTTP server on a given port
on the local machine to generate ViewVC web pages.
"""
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
import sys
import os

View File

@@ -35,15 +35,15 @@
#
#########################################################################
#
# INSTALL-TIME CONFIGURATION
#
# These values will be set during the installation process. During
# development, they will remain None.
# development, there will be no 'viewvcinstallpath.py'
#
LIBRARY_DIR = None
CONF_PATHNAME = None
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
# Adjust sys.path to include our library directory
import sys
@@ -57,7 +57,12 @@ else:
#########################################################################
import os
import string
import socket
import select
import re
import mimetypes
import time
import svn.core
import svn.repos
@@ -67,14 +72,21 @@ import svn.delta
import cvsdb
import viewvc
import vclib
from viewvcmagic import ContentMagic
class SvnRepo:
"""Class used to manage a connection to a SVN repository."""
def __init__(self, path):
def __init__(self, path, index_content = None, tika_client = None, guesser = None,
svn_ignore_mimetype = False, verbose = False):
self.path = path
self.repo = svn.repos.svn_repos_open(path)
self.fs = svn.repos.svn_repos_fs(self.repo)
self.rev_max = svn.fs.youngest_rev(self.fs)
self.index_content = index_content
self.tika_client = tika_client
self.guesser = guesser
self.verbose = verbose
self.svn_ignore_mimetype = svn_ignore_mimetype
def __getitem__(self, rev):
if rev is None:
rev = self.rev_max
@@ -84,7 +96,36 @@ class SvnRepo:
rev = SvnRev(self, rev)
return rev
_re_diff_change_command = re.compile('(\d+)(?:,(\d+))?([acd])(\d+)(?:,(\d+))?')
_re_diff_change_command = re.compile('^(\d+)(?:,(\d+))?([acd])(\d+)(?:,(\d+))?')
class StupidBufferedReader:
def __init__(self, fp, buffer = 262144):
self.fp = fp
self.bufsize = buffer
self.buffer = ''
self.eof = False
def __iter__(self):
return self
def next(self):
if self.eof:
raise StopIteration
return self.readline()
def readline(self):
if self.eof:
return ''
p = self.buffer.find('\n')
while p < 0:
b = self.fp.read(self.bufsize)
if not len(b):
r = self.buffer
self.buffer = ''
self.eof = True
return r
self.buffer = self.buffer + b
p = self.buffer.find('\n')
r = self.buffer[0:p+1]
self.buffer = self.buffer[p+1:]
return r
def _get_diff_counts(diff_fp):
"""Calculate the plus/minus counts by parsing the output of a
@@ -97,8 +138,7 @@ def _get_diff_counts(diff_fp):
GNU diff manual."""
plus, minus = 0, 0
line = diff_fp.readline()
while line:
for line in diff_fp:
match = re.match(_re_diff_change_command, line)
if match:
# size of first range
@@ -124,9 +164,79 @@ def _get_diff_counts(diff_fp):
# RdL - remove range R of file1, which would have been
# at line L of file2
minus = minus + count1
line = diff_fp.readline()
return plus, minus
class TikaClient:
# Create tika client
def __init__(self, tika_server, mime_types, verbose):
self.tika_server = tika_server
self.mime_types = mime_types
self.verbose = verbose
self.addr = tika_server.split(':')
# Split address
if len(self.addr) != 2:
raise Exception('tika_server value is incorrect: \''+tika_server+'\', please use \'host:port\' format')
self.addr = (self.addr[0], int(self.addr[1]))
# Build regexp for MIME types
m = re.split('\s+', mime_types.strip())
self.mime_regexp = re.compile('|'.join('^'+re.escape(i).replace('\\*', '.*')+'$' for i in m))
# Extract text content from file using Tika which runs in server mode
def get_text(self, filename, mime_type, log_filename):
if not self.mime_regexp.match(mime_type):
# Tika can't handle this mime type, return nothing
return ''
fd = None
s = None
text = ''
fsize = 0
try:
# Read original file
fd = open(filename, 'rb')
data = fd.read()
fsize = len(data)
if not fsize:
return ''
# Connect to Tika
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(self.addr)
s.setblocking(0)
sockfd = s.fileno()
# Tika is somewhat delicate about network IO, so:
# Read and write using poll(2) system call
p = select.poll()
p.register(sockfd)
while 1:
fds = p.poll()
if not fds:
break
(pollfd, event) = fds[0]
if event & select.POLLIN:
# Exception or empty data means EOF...
try: part = os.read(sockfd, 65536)
except: break
if not part: break
text += part
if event & select.POLLOUT:
if not len(data):
# Shutdown output and forget about POLLOUT
s.shutdown(socket.SHUT_WR)
p.modify(sockfd, select.POLLIN)
else:
# Write and consume some data
l = os.write(sockfd, data)
data = data[l:]
if len(text) == 0:
raise Exception('Empty response from Tika server')
if self.verbose:
print "Extracted %d bytes from %s (%s) of size %d" % (len(text), log_filename, mime_type, fsize)
except Exception, e:
if self.verbose:
print "Error extracting text from %s (%s) of size %d: %s" % (log_filename, mime_type, fsize, str(e))
finally:
if fd: fd.close()
if s: s.close()
return text
class SvnRev:
"""Class used to hold information about a particular revision of
@@ -150,13 +260,14 @@ class SvnRev:
# get a root for the current revisions
fsroot = self._get_root_for_rev(rev)
# find changes in the revision
editor = svn.repos.ChangeCollector(repo.fs, fsroot)
e_ptr, e_baton = svn.delta.make_editor(editor)
svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton)
self.changes = []
changes_hash = {}
for path, change in editor.changes.items():
# skip non-file changes
if change.item_kind != svn.core.svn_node_file:
@@ -185,14 +296,61 @@ class SvnRev:
action = 'change'
if action == 'remove':
diffobj = svn.fs.FileDiff(base_root, base_path, None, None)
diffobj = svn.fs.FileDiff(base_root, change.base_path, None, None, None, ['-b', '-B'])
else:
diffobj = svn.fs.FileDiff(base_root, base_path,
fsroot, change.path)
diffobj = svn.fs.FileDiff(base_root, change.base_path, fsroot, change.path, None, ['-b', '-B'])
diff_fp = diffobj.get_pipe()
diff_fp = StupidBufferedReader(diff_fp)
plus, minus = _get_diff_counts(diff_fp)
self.changes.append((path, action, plus, minus))
# CustIS Bug 50473: a workaround for svnlib behaviour in file movements (FILE1 -> FILE2 + FILE1 -> null)
if change.base_path:
if not change.path and change.base_path in changes_hash:
minus = 0
elif change.path:
changes_hash[change.base_path] = change.path
content = ''
mime = ''
# need to check if binary file's content changed when copying,
# if not, don't extract it, just get it from previous revision later
if repo.index_content and action != 'remove' and change.path and (not change.base_path
or svn.fs.contents_changed(
base_root and base_root or None,
base_root and change.base_path or None,
fsroot, change.path
)):
props = svn.fs.node_proplist(fsroot, change.path)
if not repo.svn_ignore_mimetype:
mime = props.get('svn:mime-type', None)
else:
mime = None
mime = repo.guesser.guess_mime(
mime,
os.path.basename(change.path),
diffobj.tempfile2
)
# Read and guess charset by ourselves for text files
if mime and mime.startswith('text/') or (mime.startswith('application/') and mime.endswith('xml')):
try:
fd = open(diffobj.tempfile2, 'rb')
content = fd.read()
fd.close()
except: pass
# Guess charset
if content:
content, charset = repo.guesser.guess_charset(content)
if charset:
content = content.encode('utf-8')
if repo.verbose:
print 'Guessed %s for %s' % (charset, change.path)
elif repo.verbose:
print 'Failed to guess charset for %s, not indexing' % (change.path, )
# Try to extract content using Tika from binary documents
elif repo.tika_client:
content = repo.tika_client.get_text(diffobj.tempfile2, mime, change.path)
self.changes.append((path, action, plus, minus, content, mime))
def _get_root_for_rev(self, rev):
"""Fetch a revision root from a cache of such, or a fresh root
@@ -213,7 +371,7 @@ def handle_revision(db, command, repo, rev, verbose, force=0):
if verbose: print "skipped (no changes)."
return
for (path, action, plus, minus) in revision.changes:
for (path, action, plus, minus, content, mime) in revision.changes:
directory, file = os.path.split(path)
commit = cvsdb.CreateCommit()
commit.SetRepository(repo.path)
@@ -226,6 +384,8 @@ def handle_revision(db, command, repo, rev, verbose, force=0):
commit.SetPlusCount(plus)
commit.SetMinusCount(minus)
commit.SetBranch(None)
commit.SetContent(content)
commit.SetMimeType(mime)
if action == 'add':
commit.SetTypeAdd()
@@ -253,6 +413,7 @@ def main(command, repository, revs=[], verbose=0, force=0):
cfg = viewvc.load_config(CONF_PATHNAME)
db = cvsdb.ConnectDatabase(cfg)
repository = os.path.realpath(repository)
# Purge what must be purged.
if command in ('rebuild', 'purge'):
if verbose:
@@ -264,24 +425,29 @@ def main(command, repository, revs=[], verbose=0, force=0):
sys.stderr.write("ERROR: " + str(e) + "\n")
sys.exit(1)
tika_client = None
if cfg.utilities.tika_server:
tika_client = TikaClient(cfg.utilities.tika_server, cfg.utilities.tika_mime_types, verbose)
repo = SvnRepo(
path = repository,
index_content = cfg.cvsdb.index_content,
tika_client = tika_client,
guesser = cfg.guesser(),
svn_ignore_mimetype = cfg.options.svn_ignore_mimetype,
verbose = verbose,
)
# Record what must be recorded.
if command in ('rebuild', 'update'):
if not os.path.exists(repository):
sys.stderr.write('ERROR: could not find repository %s\n'
% (repository))
sys.exit(1)
repo = SvnRepo(repository)
if command == 'rebuild' or (command == 'update' and not revs):
for rev in range(repo.rev_max+1):
handle_revision(db, command, repo, rev, verbose)
elif command == 'update':
if revs[0] is None:
revs[0] = repo.rev_max
if revs[1] is None:
revs[1] = repo.rev_max
revs.sort()
for rev in range(revs[0], revs[1]+1):
handle_revision(db, command, repo, rev, verbose, force)
if command == 'rebuild' or (command == 'update' and not revs):
for rev in range(repo.rev_max+1):
handle_revision(db, command, repo, rev, verbose, force)
elif command == 'update':
if revs[0] is None:
revs[0] = repo.rev_max
if revs[1] is None:
revs[1] = repo.rev_max
revs.sort()
for rev in range(revs[0], revs[1]+1):
handle_revision(db, command, repo, rev, verbose, force)
def _rev2int(r):
if r == 'HEAD':
@@ -314,7 +480,7 @@ Usage: 1. %s [-v] rebuild REPOS-PATH
the database. If a range is specified, the revisions will be
processed in ascending order, and you may specify "HEAD" to
indicate "the youngest revision currently in the repository".
3. Purge information specific to the repository located at REPOS-PATH
from the database.
@@ -339,7 +505,7 @@ if __name__ == '__main__':
del args[index]
except ValueError:
pass
if len(args) < 3:
usage()

50
bin/svnupdate-async Executable file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/perl
# Скрипт для обновления SVN репозиториев svndbadmin-ом
# Берёт номера ревизий и имена репозиториев из перечисленных файлов или STDIN,
# группирует их по номерам и выводит список команд, необходимых для обновления
use strict;
# первый аргумент - путь к svndbadmin
my $svndbadmin = shift @ARGV
|| die "USAGE: $0 <path_to_svndbadmin> FILES...";
# считываем названия репозиториев и номера ревизий из файла
my $tou = {};
my ($repos, $rev);
while (<>)
{
s/^\s+//so;
s/\s+$//so;
($repos, $rev) = split /\s+/, $_;
$tou->{$repos}->{$rev} = 1;
}
# превращаем номера ревизий в диапазоны ревизий
my ($i, $j, $r, $nr);
foreach $repos (keys %$tou)
{
$rev = [ sort keys %{$tou->{$repos}} ];
$nr = [];
$j = 0;
for $i (1..@$rev)
{
if ($i > $#$rev || $rev->[$i]-$rev->[$j] > $i-$j)
{
$r = $rev->[$j];
$r .= ":".$rev->[$i-1] if $i-$j > 1;
push @$nr, $r;
$j = $i;
}
}
$tou->{$repos} = $nr;
}
# выводим список команд для выполнения
foreach $repos (keys %$tou)
{
foreach (@{$tou->{$repos}})
{
print "$svndbadmin update $repos $_\n";
}
}

8
bin/svnupdate-async.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
VIEWVC_DIR=$1
test -f "$VIEWVC_DIR/.svn-updating" -o ! -f "$VIEWVC_DIR/.svn-updated" && exit 0
mv "$VIEWVC_DIR/.svn-updated" "$VIEWVC_DIR/.svn-updating"
"$VIEWVC_DIR/bin/svnupdate-async" "$VIEWVC_DIR/bin/svndbadmin" "$VIEWVC_DIR/.svn-updating" | sh &> /tmp/svnupdate-async.log
rm "$VIEWVC_DIR/.svn-updating"

41
bin/wsgi/viewvcwsgi.py Normal file
View File

@@ -0,0 +1,41 @@
# -*-python-*-
#
# 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
# distribution or at http://viewvc.org/license-1.html.
#
# For more information, visit http://viewvc.org/
#
# -----------------------------------------------------------------------
#
# viewvc: View CVS/SVN repositories via a web browser
#
# -----------------------------------------------------------------------
#
# This is a wsgi entry point for the main ViewVC app. It's appropriate
# for use with mod_wsgi. It defines a single application function that
# is a valid wsgi entry point.
#
# -----------------------------------------------------------------------
import sys, os
import viewvcinstallpath
LIBRARY_DIR = viewvcinstallpath.LIBRARY_DIR
CONF_PATHNAME = viewvcinstallpath.CONF_PATHNAME
if LIBRARY_DIR:
sys.path.insert(0, LIBRARY_DIR)
else:
sys.path.insert(0, os.path.abspath(os.path.join(
os.path.dirname(__file__), "../../lib")))
import sapi
import viewvc
def application(environ, start_response):
server = sapi.WsgiServer(environ, start_response)
cfg = viewvc.load_config(CONF_PATHNAME, server)
viewvc.main(server, cfg)
return []

View File

@@ -1,6 +1,6 @@
##---------------------------------------------------------------------------
##
## Configuration file for ViewVC
## Configuration file for ViewVC (4IntraNet patched version)
##
## Information on ViewVC is located at the following web site:
## http://viewvc.org/
@@ -301,6 +301,21 @@
##
#cvsnt =
# ViewVC can use an inetd service instead of local "cvsnt rcsfile"
# This is recommended for all UNIX installations which use cvsnt,
# as there is an unpleasant non-stable bug, probably somewhere
# inside mod_python or Apache, which SOMETIMES causes cvsnt subprocesses forked
# from mod_python to die. This gives empty diff outputs or different errors like
# "Error: Rlog output ended early. Expected RCS file ..."
# This script removes forking from mod_python code and solves the issue.
# Additional profit of this script is that you can probably browse REMOTE cvs
# repositories, if you expose this service to ViewVC, although it is not tested.
# See also bin/cvsnt-rcsfile-inetd.pl
#rcsfile_socket = host:port
# Example: rcsfile_socket = 127.0.0.1:8071
## diff: Location of the GNU diff program, used for showing file
## version differences.
##
@@ -317,6 +332,32 @@
##
#cvsgraph =
# Apache Tika TCP server host and port, used to extract text from binary documents
# Note that as of 2011-09-12, Tika 0.9 has a bug which leads to hangups on processing
# M$Word documents in server mode. So you must use the fixed version, downloaded from:
# http://wiki.4intra.net/public/tika-app-0.9-fix-TIKA709.jar
# (mirror) http://code.google.com/p/mediawiki4intranet/downloads/detail?name=tika-app-0.9-fix-TIKA709.jar
# Or apply the patch by yourself and rebuild Tika from source, see patch here:
# https://issues.apache.org/jira/browse/TIKA-709
# Tika server should be started with command 'java -jar tika-app-0.9.jar -p PORT -t -eutf-8'
#tika_server = host:port
# Example: tika_server = 127.0.0.1:8072
# This lists MIME types that can be processed by Tika
# You may change it if your Tika is newer than 0.9 and supports more formats
# (note) *+xml examples: xhtml+xml, rss+xml, atom+xml, docbook+xml, rdf+xml
tika_mime_types =
text/*
application/*+xml
application/xml
application/vnd.oasis.opendocument.*
application/vnd.openxmlformats
application/vnd.ms-*
application/msaccess
application/msword
application/pdf
application/rtf
##---------------------------------------------------------------------------
[options]
@@ -713,7 +754,7 @@
## character encodings? [Requires 'chardet' module, and is currently
## used only for the 'markup' and 'annotate' views.]
##
#detect_encoding = 0
detect_encoding = 1
## use_cvsgraph: Use CvsGraph to offer visual graphs of CVS revision history.
##
@@ -805,6 +846,17 @@
##
#limit_changes = 100
# You can also use primitive charset guessing instead of chardet (options.detect_encoding)
# Just set this to the list of possible charsets in your repository.
# ViewVC will simply try to decode content using each of them, and pick
# the first which succeeds. UTF-8 is always tried automatically.
#encodings = cp1251:iso-8859-1
# Sadly this is also required - for back-links from query results to files
# in CVS, because it doesn't recode file names to UTF-8 as Subversion does.
# Just set to cp1251 if you work with your CVS from Windowz.
#cvs_ondisk_charset = cp1251
##---------------------------------------------------------------------------
[templates]
@@ -888,6 +940,10 @@
##
#port = 3306
## socket: Database listening socket.
## On Debian Linux, enable this:
#socket = /var/run/mysqld/mysqld.sock
## database_name: ViewVC database name.
##
#database_name = ViewVC
@@ -912,6 +968,51 @@
##
#readonly_passwd =
# ViewVC can use Sphinx (http://sphinxsearch.com) full-text search engine
# to index file contents with full history and then search over them.
# Also, Apache Tika console application can be used in TCP server mode to
# add support for indexing binary documents (M$Word, PDF and etc).
# See tika_server in [utilities].
# Requires Sphinx >= 0.9.9 with a real-time updatable SphinxQL index.
# Index must be created in sphinx.conf by hand and have the following fields:
# rt_field = content
# rt_attr_string = mimetype
# rt_attr_timestamp = ci_when
# rt_attr_uint = whoid
# rt_attr_uint = repositoryid
# rt_attr_uint = dirid
# rt_attr_uint = fileid
# rt_attr_uint = revision
# rt_attr_uint = branchid
# Set to 1 to enable indexing of file contents using Sphinx and Tika
index_content = 0
# Set to limit stored text file content size (max. 4MB - Sphinx limit)
#content_max_size = 4194304
# Sphinx connection parameters:
#sphinx_host =
#sphinx_port =
#sphinx_socket = /var/run/sphinxql.sock
#sphinx_index = viewvc
## Parameters for snippet (excerpt) display
# Enable snippets? ViewVC indexes binary file contents in MySQL when enabled.
enable_snippets = 1
# Regexp for MIME types in which \n means "newline"
sphinx_preformatted_mime = text/(?!html|xml).*
# Sphinx snippet options - see http://sphinxsearch.com/docs/current.html#api-func-buildexcerpts
sphinx_snippet_options =
around: 15
limit: 200
before_match: <span style="color:red">
after_match: </span>
chunk_separator: ... \n
## row_limit: Maximum number of rows returned by a given normal query
## to the database.
##

View File

@@ -146,8 +146,9 @@ td {
configuration's "general" section.</li>
<li>Finally, ensure that that the new <code>authorizer</code>
option is set to either "forbidden" or "forbiddenre", depending
on which of those you were using in ViewVC 1.0.x.</li>
option is set to either "forbidden" (which is the default) or
"forbiddenre", depending on which of those you were using in
ViewVC 1.0.x.</li>
</ol>
@@ -223,9 +224,10 @@ td {
<li>options/py2html_path</li>
<li>options/use_enscript</li>
<li>options/use_highlight</li>
<li>options/use_pagesize</li>
<li>options/use_php</li>
<li>options/use_py2html</li>
<li>options/use_pygments</li>
<li>options/use_source_highlight</li>
</ul>
</div>
@@ -233,23 +235,16 @@ td {
<div class="h3">
<h3>Checkin Database</h3>
<p>ViewVC 1.1 introduces to the <code>cvsdbadmin</code>
and <code>svndbadmin</code> tools a new "purge" operation, which
allows you to remove all the information related to a given root
from your checkins database (without disturbing the information
associated with other roots). Likewise, the "rebuild" command in
those tools now implies a "purge" followed by an update.</p>
<p>As a related change, the <code>svndbadmin</code> program's
"rebuild" subcommand has had its purpose become more defined. It
no longer accepts a revision argument, and therefore can now only
be used to completely rebuild the entirety of the checkin database
information for a Subversion repository (instead of being able to
only update the information related to single Subversion revision).
For per-revision updating, use <code>svndbadmin update</code> and
<p>In ViewVC 1.1, the <code>svndbadmin</code> program's "rebuild"
subcommand has had its purpose become more defined. It no longer
accepts a revision argument, and therefore can now only be used to
completely rebuild the entirety of the checkin database information
for a Subversion repository (instead of being able to only update
the information related to single Subversion revision). For
per-revision updating, use <code>svndbadmin update</code> and
provide a revision (or revision range). And to get the previous
rebuild-a-revision effect, pass the new <code>--force</code> option
to <code>svndbadmin update</code>.</p>
rebuild-a-revision effect, pass the new <code>--force</code>
option to <code>svndbadmin update</code>.</p>
<p>In other words, where you once did this:</p>
@@ -263,19 +258,6 @@ td {
</pre>
</blockquote>
<p>To enhance the performance of the new "purge" operation, ViewVC 1.1
introduces some slight changes to the checkin database schema. If
you use the <code>make-database</code> tool to (re)create your
checkins database, it will by default employ the new database
schema. This should cause the database to be virtually unusable by
previous versions of ViewVC, and that's by design. If, however,
you need to (re)create your checkins database and you require
compatibility with previous versions of ViewVC or ViewCVS, simply
pass the "--version=1.0" option to the <code>make-database</code>
script. Note that your "purge" and "rebuild" operations could be
abysmally slow, though, as that version of the database schema is
not optimized for those operations.</p>
</div>
<div class="h3">
@@ -323,22 +305,6 @@ td {
<li>options/allow_tar</li>
</ul>
<p>ViewVC now honors the "svn:mime-type" property stored on
Subversion-versioned files as the primary source of MIME type
determination (before falling back to name-based MIME mappings and
such). However, this can negatively affect the viewability of
certain files &mdash; especially images &mdash; whose
"svn:mime-type" properties are set incorrectly, such as will happen
if Subversion itself merely determines that the file isn't
human-readable and uses the "application/octet-stream" MIME type to
record this determination. To make ViewVC <em>not</em> honor the
"svn:mime-type" property value, set the <code>svn_ignore_mimetype</code>
configuration option.</p>
<p>Speaking of MIME types, the option <code>mime_types_file</code> is
now <code>mime_types_files</code>, as it now carries multiple paths
to MIME mappings files, ordered by preference.</p>
<p>The <code>use_rcsparse</code> option was moved from the "general"
section to the "options" section.</p>
@@ -674,11 +640,6 @@ allowed_views = annotate, diff, markup, tar
<td>revision.ezt</td>
<td>now is an iterable list of objects with .name and .value attributes</td>
</tr>
<tr class="added">
<td class="varname">num_changes</td>
<td>revision.ezt</td>
<td>added</td>
</tr>
</tbody>
</table>
@@ -707,7 +668,7 @@ allowed_views = annotate, diff, markup, tar
<h3>Checkin Database</h3>
<p>ViewVC 1.0 reads and writes commit times in the MySQL database in
UTC time rather than local time. This can cause times displayed on
UTC time rather than local time. This can cause times displayed on
the query page to be a few hours off if an old database is being
used with a new version of ViewVC. The best way to fix this is to
rebuild the database with the new version of cvsdbadmin, but it
@@ -750,8 +711,7 @@ allowed_views = annotate, diff, markup, tar
<li>options/root_as_url_component</li>
<li>options/default_file_view</li>
<li>options/sort_group_dirs</li>
<li>options/dir_pagesize</li>
<li>options/log_pagesize</li>
<li>options/use_pagesize</li>
<li>options/limit_changes</li>
<li>options/use_localtime</li>
<li>options/cross_copies</li>

View File

@@ -18,7 +18,13 @@ import sys
import os
import ConfigParser
import fnmatch
import vclib
import vclib.ccvs
import vclib.svn
import cvsdb
import viewvc
import copy
from viewvcmagic import ContentMagic
#########################################################################
#
@@ -137,6 +143,9 @@ class Config:
}
def __init__(self):
self.__guesser = None
self.__root_configs = {}
self.__parent = None
self.root_options_overlayed = 0
for section in self._base_sections:
if section[-1] == '*':
@@ -277,6 +286,34 @@ class Config:
return None
def get_root_config(self, rootname):
"""Get configuration object with per-root overrides for 'rootname'"""
if self.__parent:
return self.__parent.get_root_config(rootname)
elif rootname in self.__root_configs:
return self.__root_configs[rootname]
__guesser = self.__guesser
__root_configs = self.__root_configs
parser = self.parser
self.parser = None
self.__guesser = None
self.__root_configs = None
sub = copy.deepcopy(self)
sub.parser = parser
self.parser = parser
self.__guesser = __guesser
self.__root_configs = __root_configs
self.__root_configs[rootname] = sub
sub.__parent = self
sub.overlay_root_options(rootname)
return sub
def get_parent_config(self):
"""Get the parent non-overridden config."""
if self.__parent:
return self.__parent
return self
def overlay_root_options(self, rootname):
"""Overlay per-root options for ROOTNAME atop the existing option
set. This is a destructive change to the configuration."""
@@ -311,54 +348,6 @@ class Config:
d[option] = parser.get(section, option)
return d.items()
def get_authorizer_and_params_hack(self, rootname):
"""Return a 2-tuple containing the name and parameters of the
authorizer configured for use with ROOTNAME.
### FIXME: This whole thing is a hack caused by our not being able
### to non-destructively overlay root options when trying to do
### something like a root listing (which might need to get
### different authorizer bits for each and every root in the list).
### Until we have a good way to do that, we expose this function,
### which assumes that base and per-vhost configuration has been
### absorbed into this object and that per-root options have *not*
### been overlayed. See issue #371."""
# We assume that per-root options have *not* been overlayed.
assert(self.root_options_overlayed == 0)
if not self.conf_path:
return None, {}
# Figure out the authorizer by searching first for a per-root
# override, then falling back to the base/vhost configuration.
authorizer = None
root_options_section = 'root-%s/options' % (rootname)
if self.parser.has_section(root_options_section) \
and self.parser.has_option(root_options_section, 'authorizer'):
authorizer = self.parser.get(root_options_section, 'authorizer')
if not authorizer:
authorizer = self.options.authorizer
# No authorizer? Get outta here.
if not authorizer:
return None, {}
# Dig up the parameters for the authorizer, starting with the
# base/vhost items, then overlaying any root-specific ones we find.
params = {}
authz_section = 'authz-%s' % (authorizer)
if hasattr(self, authz_section):
sub_config = getattr(self, authz_section)
for attr in dir(sub_config):
params[attr] = getattr(sub_config, attr)
root_authz_section = 'root-%s/authz-%s' % (rootname, authorizer)
for section in self.parser.sections():
if section == root_authz_section:
for key, value in self._get_parser_items(self.parser, section):
params[key] = value
return authorizer, params
def get_authorizer_params(self, authorizer=None):
"""Return a dictionary of parameter names and values which belong
to the configured authorizer (or AUTHORIZER, if provided)."""
@@ -371,8 +360,14 @@ class Config:
sub_config = getattr(self, authz_section)
for attr in dir(sub_config):
params[attr] = getattr(sub_config, attr)
params['__config'] = self
return params
def guesser(self):
if not self.__guesser:
self.__guesser = ContentMagic(self.options.encodings)
return self.__guesser
def set_defaults(self):
"Set some default values in the configuration."
@@ -390,8 +385,12 @@ class Config:
self.utilities.cvsnt = 'cvs'
else:
self.utilities.cvsnt = None
self.utilities.rcsfile_socket = ''
self.utilities.svn = ''
self.utilities.diff = ''
self.utilities.cvsgraph = ''
self.utilities.tika_server = ''
self.utilities.tika_mime_types = ''
self.options.root_as_url_component = 1
self.options.checkout_magic = 0
@@ -441,6 +440,8 @@ class Config:
self.options.log_pagesize = 0
self.options.log_pagesextra = 3
self.options.limit_changes = 100
self.options.cvs_ondisk_charset = 'cp1251'
self.options.encodings = 'cp1251:iso-8859-1'
self.templates.diff = None
self.templates.directory = None
@@ -454,16 +455,33 @@ class Config:
self.templates.roots = None
self.cvsdb.enabled = 0
self.cvsdb.index_content = 0
self.cvsdb.enable_snippets = 1
self.cvsdb.content_max_size = 0
self.cvsdb.host = ''
self.cvsdb.port = 3306
self.cvsdb.socket = ''
self.cvsdb.database_name = ''
self.cvsdb.user = ''
self.cvsdb.passwd = ''
self.cvsdb.readonly_user = ''
self.cvsdb.readonly_passwd = ''
self.cvsdb.readonly_passwd = ''
self.cvsdb.row_limit = 1000
self.cvsdb.rss_row_limit = 100
self.cvsdb.check_database_for_root = 0
self.cvsdb.fulltext_min_relevance = 0.2
self.cvsdb.sphinx_host = ''
self.cvsdb.sphinx_port = 3307
self.cvsdb.sphinx_socket = ''
self.cvsdb.sphinx_index = ''
self.cvsdb.sphinx_preformatted_mime = 'text/(?!html|xml).*'
self.cvsdb.sphinx_snippet_options = \
'around: 15\n'\
'limit: 200\n'\
'before_match: <span style="color:red">\n'\
'after_match: </span>\n'\
'chunk_separator: ... \n\n'
self.query.viewvc_base_url = None
@@ -490,7 +508,7 @@ class IllegalOverrideSection(ViewVCConfigurationError):
def __str__(self):
return "malformed configuration: illegal %s override section: %s" \
% (self.override_type, self.section_name)
class MalformedRoot(ViewVCConfigurationError):
def __init__(self, config_name, value_given):
Exception.__init__(self, config_name, value_given)

File diff suppressed because it is too large Load Diff

View File

@@ -59,5 +59,13 @@ def TicksFromDateTime(datetime):
else:
return time.mktime(t[:8] + (-1,))
def connect(host, port, user, passwd, db):
return MySQLdb.connect(host=host, port=port, user=user, passwd=passwd, db=db)
def connect(host, port, socket, user, passwd, db, charset = 'utf8'):
return MySQLdb.connect(
host = host,
port = port,
unix_socket = socket,
user = user,
passwd = passwd,
db = db,
charset = charset,
use_unicode = charset == 'utf8')

View File

@@ -805,18 +805,26 @@ class UnknownFormatConstantError(EZTException):
"""The format specifier is an unknown value."""
def _raw_formatter(s):
try: s = s.encode('utf-8')
except: pass
return s
def _html_formatter(s):
try: s = s.encode('utf-8')
except: pass
return cgi.escape(s)
def _xml_formatter(s):
try: s = s.encode('utf-8')
except: pass
s = s.replace('&', '&#x26;')
s = s.replace('<', '&#x3C;')
s = s.replace('>', '&#x3E;')
return s
def _uri_formatter(s):
try: s = s.encode('utf-8')
except: pass
return urllib.quote(s)
_formatters = {
@@ -841,7 +849,7 @@ def test_parse():
['', '["a \\"b[foo]" c.d f]', None, '']
def _test(argv):
import doctest, ezt
import doctest, ezt
verbose = "-v" in argv
return doctest.testmod(ezt, verbose=verbose)

283
lib/globalauth.py Normal file
View File

@@ -0,0 +1,283 @@
# -*-python-*-
# -----------------------------------------------------------------------
# Simple Global Authentication client for ViewVC
# License: GPLv2+
# Author: Vitaliy Filippov
# -----------------------------------------------------------------------
#
# USAGE:
#
# import globalauth
# c = globalauth.GlobalAuthClient()
# c.auth(server)
# user_name = c.user_name
# user_url = c.user_url
#
# auth() will call sys.exit() when it needs to stop request processing
#
# -----------------------------------------------------------------------
import os
import re
import sys
import struct
import cgi
import binascii
import time
import datetime
import urllib
import urllib2
import anyjson
import random
import Cookie
import ga_config
class FileCache:
def __init__(self, dir):
self.dir = dir
if not os.path.isdir(dir):
os.mkdir(dir)
def fn(self, key):
key = re.sub('([^a-zA-Z0-9_\-]+)', lambda x: binascii.hexlify(x.group(1)), key)
return self.dir+'/'+key
def clean(self):
t = time.time()
for fn in os.listdir(self.dir):
if t > os.stat(self.dir+'/'+fn).st_mtime:
os.unlink(self.dir+'/'+fn)
def set(self, key, value, expire = 86400):
fn = self.fn(key)
try:
f = open(fn,'w')
if not expire:
expire = 86400
expire = time.time()+expire
f.write(value)
f.close()
os.chmod(fn, 0600)
os.utime(fn, (expire, expire))
except:
raise
return 1
def get(self, key):
fn = self.fn(key)
try:
f = open(fn,'r')
value = f.read()
f.close()
if time.time() > os.stat(fn).st_mtime:
os.unlink(fn)
return ''
return value
except:
pass
return ''
def delete(self, key):
fn = self.fn(key)
try:
os.unlink(fn)
except:
pass
class GlobalAuthClient:
wd = { 0 : 'Mon', 1 : 'Tue', 2 : 'Wed', 3 : 'Thu', 4 : 'Fri', 5 : 'Sat', 6 : 'Sun' }
ms = { 1 : 'Jan', 2 : 'Feb', 3 : 'Mar', 4 : 'Apr', 5 : 'May', 6 : 'Jun', 7 : 'Jul', 8 : 'Aug', 9 : 'Sep', 10 : 'Oct', 11 : 'Nov', 12 : 'Dec' }
def __init__(self, server):
self.server = server
self.v = {}
for name, values in server.params().items():
self.v[name] = values[0]
fs = server.FieldStorage()
for name in fs:
self.v[name] = fs[name].value
self.cookies = Cookie.SimpleCookie()
# '' default value is needed here - else we die here under WSGI without any exception O_o
self.cookies.load(self.server.getenv('HTTP_COOKIE', ''))
self.user_name = ''
self.user_url = ''
if not ga_config.gac.get('globalauth_server', '') and not ga_config.gac.get('fof_sudo_server', ''):
raise Exception('ga_config.gac must contain at least globalauth_server="URL" or fof_sudo_server="URL"')
self.gac = {
'cookie_name' : 'simple_global_auth',
'cookie_expire' : 86400*7,
'cookie_path' : '/',
'cookie_domain' : '',
'globalauth_server' : '',
'cache_dir' : os.path.abspath(os.path.dirname(__file__))+'/cache',
'cut_email_at' : 0,
'ga_always_require' : 0,
'fof_sudo_server' : '',
'fof_sudo_cookie' : 'fof_sudo_id',
'gc_probability' : 20,
}
for i in self.gac:
if ga_config.gac.get(i, None) is not None:
self.gac[i] = ga_config.gac[i]
self.cache = FileCache(self.gac['cache_dir'])
def auth(self):
if self.gac['fof_sudo_server']:
self.auth_fof_sudo()
if not self.user_name and self.gac['globalauth_server']:
self.auth_ga()
def auth_ga(self):
i = random.randint(1, self.gac['gc_probability'])
if i == 1:
self.cache.clean()
r_id = self.cookies.get(self.gac['cookie_name'], '')
if r_id:
r_id = r_id.value
ga_id = self.v.get('ga_id', '')
if self.v.get('ga_client', ''):
self.ga_client(r_id, ga_id)
return
r_data = ''
if r_id == 'nologin':
r_data = 'nologin'
elif r_id != '':
r_data = self.cache.get('D'+r_id)
if r_data != 'nologin':
try: r_data = anyjson.deserialize(r_data)
except: r_data = ''
is_browser = re.match('opera|firefox|chrome|safari', self.server.getenv('HTTP_USER_AGENT'), re.I)
if not r_data and (is_browser or self.gac['ga_always_require']) or self.v.get('ga_require', None):
self.ga_begin()
elif r_data and r_data != 'nologin':
self.set_user(r_data)
def ga_client(self, r_id, ga_id):
ga_key = self.v.get('ga_key', '')
if ga_key and ga_key == self.cache.get('K'+ga_id):
# Server-to-server request
self.cache.delete('K'+ga_id)
data = ''
if self.v.get('ga_nologin','') != '':
data = 'nologin'
else:
try: data = anyjson.deserialize(self.v.get('ga_data',''))
except: raise
if data != '':
if data != 'nologin':
data = anyjson.serialize(data)
self.cache.set('D'+ga_id, data)
self.server.header('text/plain')
self.server.write('1')
sys.exit()
elif ga_key == '' and r_id != ga_id:
# User redirect with different key
d = self.cache.get('D'+ga_id)
if d != 'nologin' and d != '':
try: d = anyjson.deserialize(d)
except: d = ''
if d != '':
self.setcookie(ga_id)
self.redirect(self.clean_uri())
self.server.header('text/plain', status=404)
self.server.write('GlobalAuth key doesn\'t match')
sys.exit()
def ga_begin(self):
ga_id = binascii.hexlify(os.urandom(16))
ga_key = binascii.hexlify(os.urandom(16))
url = self.add_param(self.gac['globalauth_server'], '')
try:
resp = urllib2.urlopen(url+'ga_id='+urllib2.quote(ga_id)+'&ga_key='+urllib2.quote(ga_key))
resp.read()
if resp.code != 200:
raise Exception(resp)
except:
self.setcookie('nologin')
self.redirect(self.clean_uri())
return_uri = 'http://'+self.server.getenv('HTTP_HOST')+self.server.getenv('REQUEST_URI')
return_uri = self.add_param(return_uri, 'ga_client=1')
self.cache.set('K'+ga_id, ga_key)
url = url+'ga_id='+urllib2.quote(ga_id)+'&ga_url='+urllib2.quote(return_uri)
if self.v.get('ga_require', '') == '' and not self.gac['ga_always_require']:
url = url+'&ga_check=1'
self.redirect(url)
def add_param(self, url, param):
if url.find('?') != -1:
url = url+'&'
else:
url = url+'?'
return url+param
def auth_fof_sudo(self):
sudo_id = self.cookies.get(self.gac['fof_sudo_cookie'], '')
if sudo_id:
sudo_id = sudo_id.value
if sudo_id != '':
url = self.gac['fof_sudo_server']
if url.find('?') != -1:
url = url+'&'
else:
url = url+'?'
try:
resp = urllib2.urlopen(url+'id='+urllib2.quote(sudo_id))
d = resp.read()
if resp.code != 200:
raise Exception(resp)
d = anyjson.deserialize(d)
self.set_user(d)
except:
pass
def log(self, s):
sys.stderr.write(s+"\n")
sys.stderr.flush()
def redirect(self, url):
self.server.addheader('Location', url)
self.server.header(status='302 Moved Temporarily')
self.server.write('This document is located <a href="%s">here</a>.' % url)
sys.exit()
def setcookie(self, value):
dom = self.gac['cookie_domain']
if not dom:
dom = self.server.getenv('HTTP_HOST')
exp = ''
if self.gac['cookie_expire'] > 0:
tm = int(time.time()+self.gac['cookie_expire'])
tm = datetime.datetime.utcfromtimestamp(tm)
tm = "%s, %02d-%s-%04d %02d:%02d:%02d GMT" % (self.wd[tm.weekday()], tm.day, self.ms[tm.month], tm.year, tm.hour, tm.minute, tm.second)
exp = '; expires='+tm
self.server.addheader('Set-Cookie', "%s=%s; path=%s; domain=%s%s" % (self.gac['cookie_name'], value, self.gac['cookie_path'], dom, exp))
def clean_uri(self):
uriargs = self.v.copy()
for i in [ 'ga_id', 'ga_res', 'ga_key', 'ga_client', 'ga_nologin', 'ga_require' ]:
uriargs.pop(i, None)
uri = self.server.getenv('REQUEST_URI')
p = uri.find('?')
if p != -1:
uri = uri[0:p]
uri = 'http://'+self.server.getenv('HTTP_HOST')+uri+'?'+urllib.urlencode(uriargs)
return uri
def set_user(self, r_data):
r_email = r_data.get('user_email', '').encode('utf-8')
r_url = r_data.get('user_url', '').encode('utf-8')
if self.gac['cut_email_at']:
p = r_email.find('@')
if p != -1:
r_email = r_email[0:p]
self.user_name = r_email
self.user_url = r_url

154
lib/pygments/lexers/sp4.py Executable file
View File

@@ -0,0 +1,154 @@
# -*- coding: utf-8 -*-
"""
pygments.lexers.sp4
~~~~~~~~~~~~~~~~~~~~~
Lexer for CustIS m4-preprocessed PL/SQL.
:copyright: 2009+ by Vitaliy Filippov <vitalif@mail.ru>.
:license: BSD, see LICENSE for more details.
,
'Sp4Lexer': ('pygments.lexers.sp4', 'SP4', ('sp4',), ('*.sp4'), ('text/x-sp4',))
"""
import re
from pygments.lexer import Lexer, RegexLexer, include, bygroups, using, this, \
do_insertions
from pygments.token import Error, Punctuation, \
Text, Comment, Operator, Keyword, Name, String, Number, Generic
from pygments.util import shebang_matches
__all__ = ['Sp4Lexer']
line_re = re.compile('.*?\n')
class Sp4Lexer(RegexLexer):
name = 'SP4'
aliases = ['sp4']
filenames = ['*.sp4']
mimetypes = ['text/x-sp4']
flags = re.IGNORECASE
tokens = {
'root': [
(r'\s+', Text),
(r'--.*?\n', Comment.Single),
(r'/\*', Comment.Multiline, 'multiline-comments'),
(r'(ABORT|ABS|ABSOLUTE|ACCESS|ADA|ADD|ADMIN|AFTER|AGGREGATE|'
r'ALIAS|ALL|ALLOCATE|ALTER|ANALYSE|ANALYZE|AND|ANY|ARE|AS|'
r'ASC|ASENSITIVE|ASSERTION|ASSIGNMENT|ASYMMETRIC|AT|ATOMIC|'
r'AUTHORIZATION|AVG|BACKWARD|BEFORE|BEGIN|BETWEEN|BITVAR|'
r'BIT_LENGTH|BOTH|BREADTH|BY|C|CACHE|CALL|CALLED|CARDINALITY|'
r'CASCADE|CASCADED|CASE|CAST|CATALOG|CATALOG_NAME|CHAIN|'
r'CHARACTERISTICS|CHARACTER_LENGTH|CHARACTER_SET_CATALOG|'
r'CHARACTER_SET_NAME|CHARACTER_SET_SCHEMA|CHAR_LENGTH|CHECK|'
r'CHECKED|CHECKPOINT|CLASS|CLASS_ORIGIN|CLOB|CLOSE|CLUSTER|'
r'COALSECE|COBOL|COLLATE|COLLATION|COLLATION_CATALOG|'
r'COLLATION_NAME|COLLATION_SCHEMA|COLUMN|COLUMN_NAME|'
r'COMMAND_FUNCTION|COMMAND_FUNCTION_CODE|COMMENT|COMMIT|'
r'COMMITTED|COMPLETION|CONDITION_NUMBER|CONNECT|CONNECTION|'
r'CONNECTION_NAME|CONSTRAINT|CONSTRAINTS|CONSTRAINT_CATALOG|'
r'CONSTRAINT_NAME|CONSTRAINT_SCHEMA|CONSTRUCTOR|CONTAINS|'
r'CONTINUE|CONVERSION|CONVERT|COPY|CORRESPONTING|COUNT|'
r'CREATE|CREATEDB|CREATEUSER|CROSS|CUBE|CURRENT|CURRENT_DATE|'
r'CURRENT_PATH|CURRENT_ROLE|CURRENT_TIME|CURRENT_TIMESTAMP|'
r'CURRENT_USER|CURSOR|CURSOR_NAME|CYCLE|DATA|DATABASE|'
r'DATETIME_INTERVAL_CODE|DATETIME_INTERVAL_PRECISION|DAY|'
r'DEALLOCATE|DECLARE|DEFAULT|DEFAULTS|DEFERRABLE|DEFERRED|'
r'DEFINED|DEFINER|DELETE|DELIMITER|DELIMITERS|DEREF|DESC|'
r'DESCRIBE|DESCRIPTOR|DESTROY|DESTRUCTOR|DETERMINISTIC|'
r'DIAGNOSTICS|DICTIONARY|DISCONNECT|DISPATCH|DISTINCT|DO|'
r'DOMAIN|DROP|DYNAMIC|DYNAMIC_FUNCTION|DYNAMIC_FUNCTION_CODE|'
r'EACH|ELSE|ENCODING|ENCRYPTED|END|END-EXEC|EQUALS|ESCAPE|EVERY|'
r'EXCEPT|ESCEPTION|EXCLUDING|EXCLUSIVE|EXEC|EXECUTE|EXISTING|'
r'EXISTS|EXPLAIN|EXTERNAL|EXTRACT|FALSE|FETCH|FINAL|FIRST|FOR|'
r'FORCE|FOREIGN|FORTRAN|FORWARD|FOUND|FREE|FREEZE|FROM|FULL|'
r'FUNCTION|G|GENERAL|GENERATED|GET|GLOBAL|GO|GOTO|GRANT|GRANTED|'
r'GROUP|GROUPING|HANDLER|HAVING|HIERARCHY|HOLD|HOST|IDENTITY|'
r'IGNORE|ILIKE|IMMEDIATE|IMMUTABLE|IMPLEMENTATION|IMPLICIT|IN|'
r'INCLUDING|INCREMENT|INDEX|INDITCATOR|INFIX|INHERITS|INITIALIZE|'
r'INITIALLY|INNER|INOUT|INPUT|INSENSITIVE|INSERT|INSTANTIABLE|'
r'INSTEAD|INTERSECT|INTO|INVOKER|IS|ISNULL|ISOLATION|ITERATE|JOIN|'
r'K|KEY|KEY_MEMBER|KEY_TYPE|LANCOMPILER|LANGUAGE|LARGE|LAST|'
r'LATERAL|LEADING|LEFT|LENGTH|LESS|LEVEL|LIKE|LILMIT|LISTEN|LOAD|'
r'LOCAL|LOCALTIME|LOCALTIMESTAMP|LOCATION|LOCATOR|LOCK|LOWER|M|'
r'MAP|MATCH|MAX|MAXVALUE|MESSAGE_LENGTH|MESSAGE_OCTET_LENGTH|'
r'MESSAGE_TEXT|METHOD|MIN|MINUTE|MINVALUE|MOD|MODE|MODIFIES|'
r'MODIFY|MONTH|MORE|MOVE|MUMPS|NAMES|NATIONAL|NATURAL|NCHAR|'
r'NCLOB|NEW|NEXT|NO|NOCREATEDB|NOCREATEUSER|NONE|NOT|NOTHING|'
r'NOTIFY|NOTNULL|NULL|NULLABLE|NULLIF|OBJECT|OCTET_LENGTH|OF|OFF|'
r'OFFSET|OIDS|OLD|ON|ONLY|OPEN|OPERATION|OPERATOR|OPTION|OPTIONS|'
r'OR|ORDER|ORDINALITY|OUT|OUTER|OUTPUT|OVERLAPS|OVERLAY|OVERRIDING|'
r'OWNER|PAD|PARAMETER|PARAMETERS|PARAMETER_MODE|PARAMATER_NAME|'
r'PARAMATER_ORDINAL_POSITION|PARAMETER_SPECIFIC_CATALOG|'
r'PARAMETER_SPECIFIC_NAME|PARAMATER_SPECIFIC_SCHEMA|PARTIAL|'
r'PASCAL|PENDANT|PLACING|PLI|POSITION|POSTFIX|PRECISION|PREFIX|'
r'PREORDER|PREPARE|PRESERVE|PRIMARY|PRIOR|PRIVILEGES|PROCEDURAL|'
r'PROCEDURE|PUBLIC|READ|READS|RECHECK|RECURSIVE|REF|REFERENCES|'
r'REFERENCING|REINDEX|RELATIVE|RENAME|REPEATABLE|REPLACE|RESET|'
r'RESTART|RESTRICT|RESULT|RETURN|RETURNED_LENGTH|'
r'RETURNED_OCTET_LENGTH|RETURNED_SQLSTATE|RETURNS|REVOKE|RIGHT|'
r'ROLE|ROLLBACK|ROLLUP|ROUTINE|ROUTINE_CATALOG|ROUTINE_NAME|'
r'ROUTINE_SCHEMA|ROW|ROWS|ROW_COUNT|RULE|SAVE_POINT|SCALE|SCHEMA|'
r'SCHEMA_NAME|SCOPE|SCROLL|SEARCH|SECOND|SECURITY|SELECT|SELF|'
r'SENSITIVE|SERIALIZABLE|SERVER_NAME|SESSION|SESSION_USER|SET|'
r'SETOF|SETS|SHARE|SHOW|SIMILAR|SIMPLE|SIZE|SOME|SOURCE|SPACE|'
r'SPECIFIC|SPECIFICTYPE|SPECIFIC_NAME|SQL|SQLCODE|SQLERROR|'
r'SQLEXCEPTION|SQLSTATE|SQLWARNINIG|STABLE|START|STATE|STATEMENT|'
r'STATIC|STATISTICS|STDIN|STDOUT|STORAGE|STRICT|STRUCTURE|STYPE|'
r'SUBCLASS_ORIGIN|SUBLIST|SUBSTRING|SUM|SYMMETRIC|SYSID|SYSTEM|'
r'SYSTEM_USER|TABLE|TABLE_NAME| TEMP|TEMPLATE|TEMPORARY|TERMINATE|'
r'THAN|THEN|TIMESTAMP|TIMEZONE_HOUR|TIMEZONE_MINUTE|TO|TOAST|'
r'TRAILING|TRANSATION|TRANSACTIONS_COMMITTED|'
r'TRANSACTIONS_ROLLED_BACK|TRANSATION_ACTIVE|TRANSFORM|'
r'TRANSFORMS|TRANSLATE|TRANSLATION|TREAT|TRIGGER|TRIGGER_CATALOG|'
r'TRIGGER_NAME|TRIGGER_SCHEMA|TRIM|TRUE|TRUNCATE|TRUSTED|TYPE|'
r'UNCOMMITTED|UNDER|UNENCRYPTED|UNION|UNIQUE|UNKNOWN|UNLISTEN|'
r'UNNAMED|UNNEST|UNTIL|UPDATE|UPPER|USAGE|USER|'
r'USER_DEFINED_TYPE_CATALOG|USER_DEFINED_TYPE_NAME|'
r'USER_DEFINED_TYPE_SCHEMA|USING|VACUUM|VALID|VALIDATOR|VALUES|'
r'VARIABLE|VERBOSE|VERSION|VIEW|VOLATILE|WHEN|WHENEVER|WHERE|'
r'WITH|WITHOUT|WORK|WRITE|YEAR|ZONE|BINARY_INTEGER|BODY|BREAK|'
r'CONSTANT|DEFINITION|DELETING|DLOB|DUMMY|ELSIF|ERRLVL|ERROR|'
r'EXCEPTION|EXIT|IF|INSERTING|ISOPEN|LOOP|NO_DATA_FOUND|NOTFOUND|'
r'OTHERS|PACKAGE|PRAGMA|RAISE|RECORD|RESTRICT_REFERENCES|RETURNING|'
r'RNDS|RNPS|ROWCOUNT|ROWNUM|ROWTYPE|SAVEPOINT|SQLERRM|TOO_MANY_ROWS|'
r'UPDATING|WHILE|WNDS|WNPS|BULK|CHR|COLLECT|GREATEST|INSTR|LEAST|'
r'LENGTHB|NOCOPY|NOWAIT|NVL|RPAD|SUBST|SUBSTB|SUBSTR|SYSDATE|'
r'TABLESPACE|TO_CHAR|TO_DATE|TO_NUMBER|TRUNC)\b', Keyword),
(r'(ARRAY|BIGINT|BINARY|BIT|BLOB|BOOLEAN|CHAR|CHARACTER|DATE|'
r'DEC|DECIMAL|FLOAT|INT|INTEGER|INTERVAL|NUMBER|NUMERIC|REAL|'
r'SERIAL|SMALLINT|VARCHAR|VARCHAR2|VARYING|INT8|SERIAL8|TEXT)\b',
Name.Builtin),
(r'(_5date_args|_actual_area|_ASSERT|_doc_code|_doc_var|_doc_var_list|'
r'_enforce|_ent|_enum|_enums_define|_enums_member_define|_field|'
r'_fields|_first|_FMT|_in_list|_index|_index_unique|_indexes'
r'_MAX_STRLEN|_MID_STRLEN|_param|_package|_pk|_plsql_param|_plsql_return|'
r'_private_function|_private_procedure|_private_type|_private_var|'
r'_protected_function|_protected_procedure|_protected_type|_protected_var|'
r'_public_function|_public_procedure|_public_type|_public_var|_quote|_RAISE|'
r'_RAISEW|_reference|_references|_request_arg|_request_define|'
r'_request_res|_STR_CONST|_substr|_table|_tail|builtin|cdr|changecom|'
r'changequote|changeword|debugfile|decr|define|divert|dummy_list|dumpdef|'
r'errprint|eval|foreach|forloop|GetNth|ifelse|include|incr|index|indir|'
r'len|lowcase|maketemp|Nth|patsubst|popdef|pushdef|regexp|'
r'remove_prefix|shift|sinclude|Size|syscmd|TRACE|traceoff|traceon|'
r'translit|undefine|undivert|upcase)\b',
Name.Function),
(r'[+*/<>=~!@#%^&|`?^-]', Operator),
(r'[0-9]+', Number.Integer),
(r"'(''|[^'\\]|\\\'|\\\\)*'", String.Single),
(r'"(""|[^"\\]|\\\"|\\\\)*"', String.Symbol),
(r'[a-zA-Z_][a-zA-Z0-9_]*', Name),
(r'[;:()\[\],\.]', Punctuation)
],
'multiline-comments': [
(r'/\*', Comment.Multiline, 'multiline-comments'),
(r'\*/', Comment.Multiline, '#pop'),
(r'[^/\*]+', Comment.Multiline),
(r'[/*]', Comment.Multiline)
]
}

View File

@@ -41,12 +41,22 @@ class FormData:
self.file = ""
self.who = ""
self.sortby = ""
self.textquery = ""
self.date = ""
self.hours = 0
self.decode_thyself(form)
def decode_thyself(self, form):
try:
self.textquery = string.strip(form["textquery"].value)
except KeyError:
pass
except TypeError:
pass
else:
self.valid = 1
try:
self.repository = form["repository"].value.strip()
except KeyError:
@@ -247,10 +257,15 @@ def form_to_cvsdb_query(cfg, form_data):
cmd = decode_command(cmd)
query.SetAuthor(str, cmd)
if form_data.textquery:
query.SetTextQuery(form_data.textquery)
if form_data.sortby == "author":
query.SetSortMethod("author")
elif form_data.sortby == "file":
query.SetSortMethod("file")
elif form_data.sortby == "relevance" and form_data.textquery:
query.SetSortMethod("relevance")
else:
query.SetSortMethod("date")
@@ -285,11 +300,10 @@ def is_forbidden(cfg, cvsroot_name, module):
# the base and per-vhost configuration for authorizer and
# authorizer parameters.
if cvsroot_name:
authorizer, params = cfg.get_authorizer_and_params_hack(cvsroot_name)
else:
authorizer = cfg.options.authorizer
params = cfg.get_authorizer_params()
cfg = cfg.get_root_config(cvsroot_name)
authorizer = cfg.options.authorizer
params = cfg.get_authorizer_params()
# If CVSROOT_NAME isn't configured to use an authorizer, nothing
# is forbidden. If it's configured to use something other than
# the 'forbidden' authorizer, complain. Otherwise, check for
@@ -314,7 +328,7 @@ def is_forbidden(cfg, cvsroot_name, module):
def build_commit(server, cfg, desc, files, cvsroots, viewvc_link):
ob = _item(num_files=len(files), files=[])
ob.log = desc and server.escape(desc).replace('\n', '<br />') or ''
ob.log = desc and server.escape(desc).replace('\n', '<br />') or '&nbsp;'
for commit in files:
repository = commit.GetRepository()
@@ -365,6 +379,9 @@ def build_commit(server, cfg, desc, files, cvsroots, viewvc_link):
flink = '[%s] %s' % (repository, file)
dlink = None
ob.relevance = commit.GetRelevance()
ob.plus += int(commit.GetPlusCount())
ob.minus += int(commit.GetMinusCount())
ob.files.append(_item(date=ctime,
author=commit.GetAuthor(),
link=flink,
@@ -378,9 +395,8 @@ def build_commit(server, cfg, desc, files, cvsroots, viewvc_link):
return ob
def run_query(server, cfg, form_data, viewvc_link):
def run_query(server, cfg, db, form_data, viewvc_link):
query = form_to_cvsdb_query(cfg, form_data)
db = cvsdb.ConnectDatabaseReadOnly(cfg)
db.RunQuery(query)
commit_list = query.GetCommitList()
@@ -430,9 +446,9 @@ def main(server, cfg, viewvc_link):
form = server.FieldStorage()
form_data = FormData(form)
db = cvsdb.ConnectDatabaseReadOnly(cfg, None)
if form_data.valid:
commits, row_limit_reached = run_query(server, cfg,
form_data, viewvc_link)
commits, row_limit_reached = run_query(server, cfg, db, form_data, viewvc_link)
query = None
else:
commits = [ ]
@@ -447,6 +463,7 @@ def main(server, cfg, viewvc_link):
'cfg' : cfg,
'address' : cfg.general.address,
'vsn' : viewvc.__version__,
'textquery' : server.escape(form_data.textquery),
'repository' : server.escape(form_data.repository),
'branch' : server.escape(form_data.branch),
'directory' : server.escape(form_data.directory),
@@ -460,6 +477,7 @@ def main(server, cfg, viewvc_link):
'commits' : commits,
'num_commits' : len(commits),
'rss_href' : None,
'repositories' : db.GetRepositoryList(),
'hours' : form_data.hours and form_data.hours or 2,
})

View File

@@ -32,6 +32,8 @@ server = None
# that character as-is, and sometimes needs to embed escaped values
# into HTML attributes.
def escape(s):
try: s = s.encode('utf8')
except: pass
s = str(s)
s = s.replace('&', '&amp;')
s = s.replace('>', '&gt;')

View File

@@ -41,7 +41,7 @@ class GenericViewVCAuthorizer:
pass
##############################################################################
class ViewVCAuthorizer(GenericViewVCAuthorizer):

View File

@@ -0,0 +1,92 @@
# -*-python-*-
#
# Copyright (C) 2009 Vitaliy Filippov.
#
# 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
# distribution or at http://viewvc.org/license-1.html.
#
# For more information, visit http://viewvc.org/
#
# -----------------------------------------------------------------------
import vcauth
import vclib
import string
from xml.dom.minidom import parse
class ViewVCAuthorizer(vcauth.GenericViewVCAuthorizer):
"""An authorizer which uses CVSnt access control lists (which are in form
of XML files in CVS/ subdirectories in the repository)."""
def __init__(self, username, params={}):
self.username = username
self.params = params
self.cfg = params['__config']
self.default = params.get('default', 0)
self.cached = {}
self.xmlcache = {}
def dom_rights(self, doc, rightname, filename, username):
result = None
if filename:
for node in doc.getElementsByTagName('file'):
if node.getAttribute('name') == filename:
for acl in node.getElementsByTagName('acl'):
if not acl.getAttribute('branch'):
u = acl.getAttribute('user')
if result is None and (not u or u == 'anonymous') or u == username:
for r in acl.getElementsByTag(rightname):
result = not r.getAttribute('deny')
break
if result is None:
for node in doc.getElementsByTagName('directory'):
for acl in node.getElementsByTagName('acl'):
if not acl.getAttribute('branch'):
u = acl.getAttribute('user')
if result is None and (not u or u == 'anonymous') or u == username:
for r in acl.getElementsByTag(rightname):
result = not r.getAttribute('deny')
return result
def check(self, rootname, path_parts, filename):
d = self.cfg.general.cvs_roots.get(rootname,None)
if not d:
return self.default
i = len(path_parts)
r = None
while i >= 0:
try:
xml = d
if len(path_parts):
xml = xml + '/' + string.join(path_parts, '/')
xml = xml + '/CVS/fileattr.xml'
if self.cached.get(xml, None) is not None:
return self.cached.get(xml, None)
doc = self.xmlcache.get(xml, None)
if doc is None:
doc = parse(xml)
self.xmlcache[xml] = doc
r = self.dom_rights(doc, 'read', filename, self.username)
if r is not None:
self.cached[xml] = r
return r
raise Exception(None)
except:
if len(path_parts) > 0:
path_parts = path_parts[:-1]
filename = ''
i = i-1
return self.default
def check_root_access(self, rootname):
return self.check(rootname, [], '')
def check_path_access(self, rootname, path_parts, pathtype, rev=None):
if not path_parts:
return self.check(rootname, [], '')
if pathtype == vclib.DIR:
return self.check(rootname, path_parts, '')
f = path_parts[-1]
path_parts = path_parts[:-1]
return self.check(rootname, path_parts, f)

View File

@@ -0,0 +1,62 @@
# -*-python-*-
#
# Copyright (C) 2009 Vitaliy Filippov.
#
# 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
# distribution or at http://viewvc.org/license-1.html.
#
# For more information, visit http://viewvc.org/
#
# -----------------------------------------------------------------------
import vcauth
import vclib
import string
import grp
import re
class ViewVCAuthorizer(vcauth.GenericViewVCAuthorizer):
"""A simple authorizer checking system group membership for every
repository and every user."""
def __init__(self, username, params={}):
self.username = username
self.params = params
self.cfg = params['__config']
self.cached = {}
self.grp = {}
self.byroot = {}
self.fmt = map(lambda l: l.strip(), params.get('group_name_format', 'svn.%s|svn.%s.ro').split('|'))
byr = params.get('by_root', '')
for i in byr.split(','):
if i.find(':') < 0:
continue
(root, auth) = i.split(':', 2)
self.byroot[root.strip()] = map(lambda l: l.strip(), auth.split('|'))
def check_root_access(self, rootname):
r = self.cached.get(rootname, None)
if r is not None:
return r
grent = self.grp.get(rootname, None)
if grent is None:
grent = map(lambda grn: self.getgrnam(grn, rootname), self.byroot.get(rootname, self.fmt))
self.grp[rootname] = grent
r = 0
for i in grent:
if i and i.gr_mem and len(i.gr_mem) and self.username in i.gr_mem:
r = 1
break
self.cached[rootname] = r
return r
def getgrnam(self, grn, rootname):
try:
r = grp.getgrnam(grn.replace('%s', re.sub('[^\w\.\-]+', '', rootname)))
except KeyError:
r = None
return r
def check_path_access(self, rootname, path_parts, pathtype, rev=None):
return self.check_root_access(rootname)

View File

@@ -342,7 +342,7 @@ class NonTextualFileContents(Error):
# ======================================================================
# Implementation code used by multiple vclib modules
import popen
import tempfile
import os
import time
@@ -352,7 +352,7 @@ def _diff_args(type, options):
if type == CONTEXT:
if options.has_key('context'):
if options['context'] is None:
args.append('--context=-1')
args.append('--context=%i' % 0x01ffffff)
else:
args.append('--context=%i' % options['context'])
else:
@@ -360,7 +360,7 @@ def _diff_args(type, options):
elif type == UNIFIED:
if options.has_key('context'):
if options['context'] is None:
args.append('--unified=-1')
args.append('--unified=%i' % 0x01ffffff)
else:
args.append('--unified=%i' % options['context'])
else:
@@ -386,11 +386,15 @@ class _diff_fp:
def __init__(self, temp1, temp2, info1=None, info2=None, diff_cmd='diff', diff_opts=[]):
self.temp1 = temp1
self.temp2 = temp2
self.temp3 = tempfile.mktemp()
args = diff_opts[:]
if info1 and info2:
args.extend(["-L", self._label(info1), "-L", self._label(info2)])
args.extend([temp1, temp2])
self.fp = popen.popen(diff_cmd, args, "r")
args.insert(0, diff_cmd)
os.system("'"+"' '".join(args)+"' > '"+self.temp3+"' 2> '"+self.temp3+"'")
self.fp = open(self.temp3, 'rb')
self.fp.seek(0)
def read(self, bytes):
return self.fp.read(bytes)
@@ -398,6 +402,9 @@ class _diff_fp:
def readline(self):
return self.fp.readline()
def readlines(self):
return self.fp.readlines()
def close(self):
try:
if self.fp:
@@ -405,13 +412,17 @@ class _diff_fp:
self.fp = None
finally:
try:
if self.temp1:
if self.temp1 and self.temp1 != '/dev/null':
os.remove(self.temp1)
self.temp1 = None
self.temp1 = None
finally:
if self.temp2:
if self.temp2 and self.temp2 != '/dev/null':
os.remove(self.temp2)
self.temp2 = None
self.temp2 = None
try:
os.remove(self.temp3)
finally:
self.temp3 = None
def __del__(self):
self.close()
@@ -429,7 +440,7 @@ def check_root_access(repos):
if not auth:
return 1
return auth.check_root_access(repos.rootname())
def check_path_access(repos, path_parts, pathtype=None, rev=None):
"""Return 1 iff the associated username is permitted to read
revision REV of the path PATH_PARTS (of type PATHTYPE) in repository
@@ -440,5 +451,7 @@ def check_path_access(repos, path_parts, pathtype=None, rev=None):
return 1
if not pathtype:
pathtype = repos.itemtype(path_parts, rev)
if not path_parts:
return auth.check_root_access(repos.rootname())
return auth.check_path_access(repos.rootname(), path_parts, pathtype, rev)

View File

@@ -57,11 +57,11 @@ def find_root_in_parent(parent_path, rootname):
return None
def CVSRepository(name, rootpath, authorizer, utilities, use_rcsparse):
def CVSRepository(name, rootpath, authorizer, utilities, use_rcsparse, charset_guesser = None):
rootpath = canonicalize_rootpath(rootpath)
if use_rcsparse:
import ccvs
return ccvs.CCVSRepository(name, rootpath, authorizer, utilities)
return ccvs.CCVSRepository(name, rootpath, authorizer, utilities, charset_guesser)
else:
import bincvs
return bincvs.BinCVSRepository(name, rootpath, authorizer, utilities)
return bincvs.BinCVSRepository(name, rootpath, authorizer, utilities, charset_guesser)

View File

@@ -20,6 +20,8 @@ import sys
import stat
import re
import time
import cvsdb
import socket
import calendar
# ViewVC libs
@@ -30,14 +32,15 @@ def _path_join(path_parts):
return '/'.join(path_parts)
class BaseCVSRepository(vclib.Repository):
def __init__(self, name, rootpath, authorizer, utilities):
def __init__(self, name, rootpath, authorizer, utilities, charset_guesser = None):
if not os.path.isdir(rootpath):
raise vclib.ReposNotFound(name)
raise vclib.ReposNotFound(name)
self.name = name
self.rootpath = rootpath
self.auth = authorizer
self.utilities = utilities
self.guesser = charset_guesser
# See if this repository is even viewable, authz-wise.
if not vclib.check_root_access(self):
@@ -59,7 +62,7 @@ class BaseCVSRepository(vclib.Repository):
def authorizer(self):
return self.auth
def itemtype(self, path_parts, rev):
basepath = self._getpath(path_parts)
kind = None
@@ -80,7 +83,7 @@ class BaseCVSRepository(vclib.Repository):
def itemprops(self, path_parts, rev):
self.itemtype(path_parts, rev) # does auth-check
return {} # CVS doesn't support properties
def listdir(self, path_parts, rev, options):
if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check
raise vclib.Error("Path '%s' is not a directory."
@@ -121,7 +124,7 @@ class BaseCVSRepository(vclib.Repository):
data.append(CVSDirEntry(name, kind, errors, 1))
return data
def _getpath(self, path_parts):
return apply(os.path.join, (self.rootpath,) + tuple(path_parts))
@@ -166,7 +169,7 @@ class BinCVSRepository(BaseCVSRepository):
filename, default_branch, tags, lockinfo, msg, eof = _parse_log_header(fp)
revs = []
while not eof:
revision, eof = _parse_log_entry(fp)
revision, eof = _parse_log_entry(fp, self.guesser)
if revision:
revs.append(revision)
revs = _file_log(revs, tags, lockinfo, default_branch, rev)
@@ -209,14 +212,14 @@ class BinCVSRepository(BaseCVSRepository):
used_rlog = 1
if not tip_rev:
raise vclib.Error("Unable to find valid revision")
fp = self.rcs_popen('co', ('-p' + tip_rev.string, full_name), 'rb')
fp = self.rcs_popen('co', ('-p' + tip_rev.string, full_name), 'rb')
filename, revision = _parse_co_header(fp)
if filename is None:
# CVSNT's co exits without any output if a dead revision is requested.
# Bug at http://www.cvsnt.org/cgi-bin/bugzilla/show_bug.cgi?id=190
# As a workaround, we invoke rlog to find the first non-dead revision
# that precedes it and check out that revision instead. Of course,
# that precedes it and check out that revision instead. Of course,
# if we've already invoked rlog above, we just reuse its output.
if not used_rlog:
tip_rev = self._get_tip_revision(full_name + ',v', rev)
@@ -225,7 +228,7 @@ class BinCVSRepository(BaseCVSRepository):
raise vclib.Error(
'Could not find non-dead revision preceding "%s"' % rev)
fp = self.rcs_popen('co', ('-p' + tip_rev.undead.string,
full_name), 'rb')
full_name), 'rb')
filename, revision = _parse_co_header(fp)
if filename is None:
@@ -264,7 +267,7 @@ class BinCVSRepository(BaseCVSRepository):
for entry in entries:
if vclib.check_path_access(self, path_parts + [entry.name], None, rev):
entries_to_fetch.append(entry)
alltags = _get_logs(self, path_parts, entries_to_fetch, rev, subdirs)
alltags = _get_logs(self, path_parts, entries_to_fetch, rev, subdirs, self.guesser)
branches = options['cvs_branches'] = []
tags = options['cvs_tags'] = []
for name, rev in alltags.items():
@@ -309,7 +312,7 @@ class BinCVSRepository(BaseCVSRepository):
# Retrieve revision objects
revs = []
while not eof:
revision, eof = _parse_log_entry(fp)
revision, eof = _parse_log_entry(fp, self.guesser)
if revision:
revs.append(revision)
@@ -328,7 +331,17 @@ class BinCVSRepository(BaseCVSRepository):
return filtered_revs
def rcs_popen(self, rcs_cmd, rcs_args, mode, capture_err=1):
if self.utilities.cvsnt:
a = []
if self.utilities.rcsfile_socket:
a = self.utilities.rcsfile_socket.split(':')
if len(a) == 2:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((a[0], int(a[1])))
s = s.makefile()
s.write('\''+rcs_cmd+'\' \''+'\' \''.join(rcs_args)+"\'\x0d\x0a")
s.flush()
return s
elif self.utilities.cvsnt:
cmd = self.utilities.cvsnt
args = ['rcsfile', rcs_cmd]
args.extend(list(rcs_args))
@@ -342,12 +355,12 @@ class BinCVSRepository(BaseCVSRepository):
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
from vclib.ccvs import blame
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, self.guesser, include_text)
return source, source.revision
def revinfo(self, rev):
raise vclib.UnsupportedFeature
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
"""see vclib.Repository.rawdiff docstring
@@ -355,6 +368,12 @@ class BinCVSRepository(BaseCVSRepository):
ignore_keyword_subst - boolean, ignore keyword substitution
"""
if not path_parts1:
path_parts1 = path_parts2
rev1 = '1.0'
if not path_parts2:
path_parts2 = path_parts1
rev2 = '1.0'
if self.itemtype(path_parts1, rev1) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts1)))
if self.itemtype(path_parts2, rev2) != vclib.FILE: # does auth-check
@@ -367,8 +386,7 @@ class BinCVSRepository(BaseCVSRepository):
rcsfile = self.rcsfile(path_parts1, 1)
if path_parts1 != path_parts2:
raise NotImplementedError, "cannot diff across paths in cvs"
args.extend(['-r' + rev1, '-r' + rev2, rcsfile])
args.extend(['-N', '-r' + rev1, '-r' + rev2, rcsfile])
fp = self.rcs_popen('rcsdiff', args, 'rt')
# Eat up the non-GNU-diff-y headers.
@@ -377,7 +395,6 @@ class BinCVSRepository(BaseCVSRepository):
if not line or line[0:5] == 'diff ':
break
return fp
class CVSDirEntry(vclib.DirEntry):
def __init__(self, name, kind, errors, in_attic, absent=0):
@@ -439,9 +456,9 @@ def _match_revs_tags(revlist, taglist):
example: if revision is 1.2.3.4, parent is 1.2
"undead"
If the revision is dead, then this is a reference to the first
If the revision is dead, then this is a reference to the first
previous revision which isn't dead, otherwise it's a reference
to itself. If all the previous revisions are dead it's None.
to itself. If all the previous revisions are dead it's None.
"branch_number"
tuple representing branch number or empty tuple if on trunk
@@ -653,7 +670,7 @@ def _parse_co_header(fp):
pass
else:
break
raise COMalformedOutput, "Unable to find revision in co output stream"
# if your rlog doesn't use 77 '=' characters, then this must change
@@ -674,7 +691,7 @@ _EOF_ERROR = 'error message found' # rlog issued an error
# ^rlog\: (.*)(?:\:\d+)?\: (.*)$
#
# But for some reason the windows version of rlog omits the "rlog: " prefix
# for the first error message when the standard error stream has been
# for the first error message when the standard error stream has been
# redirected to a file or pipe. (the prefix is present in subsequent errors
# and when rlog is run from the console). So the expression below is more
# complicated
@@ -703,7 +720,7 @@ def _parse_log_header(fp):
Returns: filename, default branch, tag dictionary, lock dictionary,
rlog error message, and eof flag
"""
filename = head = branch = msg = ""
taginfo = { } # tag name => number
lockinfo = { } # revision => locker
@@ -732,7 +749,7 @@ def _parse_log_header(fp):
else:
# oops. this line isn't lock info. stop parsing tags.
state = 0
if state == 0:
if line[:9] == 'RCS file:':
filename = line[10:-1]
@@ -783,7 +800,7 @@ _re_log_info = re.compile(r'^date:\s+([^;]+);'
r'(\s+commitid:\s+([a-zA-Z0-9]+))?\n$')
### _re_rev should be updated to extract the "locked" flag
_re_rev = re.compile(r'^revision\s+([0-9.]+).*')
def _parse_log_entry(fp):
def _parse_log_entry(fp, guesser):
"""Parse a single log entry.
On entry, fp should point to the first line of the entry (the "revision"
@@ -849,6 +866,9 @@ def _parse_log_entry(fp):
raise ValueError, 'invalid year'
date = calendar.timegm(tm)
if guesser:
log = guesser.utf8(log)
return Revision(rev, date,
# author, state, lines changed
match.group(2), match.group(3) == "dead", match.group(5),
@@ -900,7 +920,7 @@ def _file_log(revs, taginfo, lockinfo, cur_branch, filter):
except ValueError:
view_tag = None
else:
tags.append(view_tag)
tags.append(view_tag)
# Match up tags and revisions
_match_revs_tags(revs, tags)
@@ -908,13 +928,13 @@ def _file_log(revs, taginfo, lockinfo, cur_branch, filter):
# Match up lockinfo and revision
for rev in revs:
rev.lockinfo = lockinfo.get(rev.string)
# Add artificial ViewVC tag HEAD, which acts like a non-branch tag pointing
# at the latest revision on the MAIN branch. The HEAD revision doesn't have
# anything to do with the "head" revision number specified in the RCS file
# and in rlog output. HEAD refers to the revision that the CVS and RCS co
# commands will check out by default, whereas the "head" field just refers
# to the highest revision on the trunk.
# to the highest revision on the trunk.
taginfo['HEAD'] = _add_tag('HEAD', taginfo['MAIN'].co_rev)
# Determine what revisions to return
@@ -952,10 +972,10 @@ def _file_log(revs, taginfo, lockinfo, cur_branch, filter):
_remove_tag(view_tag)
else:
filtered_revs = revs
return filtered_revs
def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs):
def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs, guesser):
alltags = { # all the tags seen in the files of this dir
'MAIN' : '',
'HEAD' : '1.1'
@@ -1002,7 +1022,7 @@ def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs):
= _parse_log_header(rlog)
if eof == _EOF_LOG:
# the rlog output ended early. this can happen on errors that rlog
# the rlog output ended early. this can happen on errors that rlog
# thinks are so serious that it stops parsing the current file and
# refuses to parse any of the files that come after it. one of the
# errors that triggers this obnoxious behavior looks like:
@@ -1050,8 +1070,8 @@ def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs):
eof = _EOF_FILE
# we don't care about the specific values -- just the keys and whether
# the values point to branches or revisions. this the fastest way to
# merge the set of keys and keep values that allow us to make the
# the values point to branches or revisions. this the fastest way to
# merge the set of keys and keep values that allow us to make the
# distinction between branch tags and normal tags
alltags.update(taginfo)
@@ -1060,7 +1080,7 @@ def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs):
while not eof:
# fetch one of the log entries
entry, eof = _parse_log_entry(rlog)
entry, eof = _parse_log_entry(rlog, guesser)
if not entry:
# parsing error
@@ -1096,7 +1116,7 @@ def _get_logs(repos, dir_path_parts, entries, view_tag, get_dirs):
file.dead = 0
#file.errors.append("No revisions exist on %s" % (view_tag or "MAIN"))
file.absent = 1
# done with this file now, skip the rest of this file's revisions
if not eof:
_skip_file(rlog)
@@ -1209,7 +1229,7 @@ def _newest_file(dirpath):
newest_time = 0
### FIXME: This sucker is leaking unauthorized paths! ###
for subfile in os.listdir(dirpath):
### filter CVS locks? stale NFS handles?
if subfile[-2:] != ',v':

View File

@@ -31,6 +31,7 @@ import time
import math
import rcsparse
import vclib
import cvsdb
class CVSParser(rcsparse.Sink):
# Precompiled regular expressions
@@ -413,7 +414,7 @@ class CVSParser(rcsparse.Sink):
class BlameSource:
def __init__(self, rcs_file, opt_rev=None, include_text=False):
def __init__(self, rcs_file, opt_rev=None, charset_guesser=None, include_text=False):
# Parse the CVS file
parser = CVSParser()
revision = parser.parse_cvs_file(rcs_file, opt_rev)
@@ -427,6 +428,7 @@ class BlameSource:
self.lines = lines
self.num_lines = count
self.parser = parser
self.guesser = charset_guesser
self.include_text = include_text
# keep track of where we are during an iteration
@@ -446,9 +448,14 @@ class BlameSource:
prev_rev = self.parser.prev_revision.get(rev)
line_number = idx + 1
author = self.parser.revision_author[rev]
thisline = self.lines[idx]
if not self.include_text:
thisline = None
elif self.guesser:
thisline = self.guesser.utf8(self.lines[idx])
else:
thisline = self.lines[idx]
### TODO: Put a real date in here.
item = vclib.Annotation(thisline, line_number, rev, prev_rev, author, None)
self.last = item

View File

@@ -18,6 +18,7 @@ import tempfile
import vclib
import rcsparse
import blame
import cvsdb
### The functionality shared with bincvs should probably be moved to a
### separate module
@@ -66,6 +67,8 @@ class CCVSRepository(BaseCVSRepository):
entry.path = path
try:
rcsparse.parse(open(path, 'rb'), InfoSink(entry, rev, alltags))
if self.guesser:
entry.log = self.guesser.utf8(entry.log)
except IOError, e:
entry.errors.append("rcsparse error: %s" % e)
except RuntimeError, e:
@@ -118,21 +121,30 @@ class CCVSRepository(BaseCVSRepository):
return filtered_revs
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
if self.itemtype(path_parts1, rev1) != vclib.FILE: # does auth-check
if path_parts1 and self.itemtype(path_parts1, rev1) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts1)))
if self.itemtype(path_parts2, rev2) != vclib.FILE: # does auth-check
if path_parts2 and self.itemtype(path_parts2, rev2) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts2)))
if not path_parts1 and not path_parts2:
raise vclib.Error("Nothing to diff.")
temp1 = tempfile.mktemp()
open(temp1, 'wb').write(self.openfile(path_parts1, rev1, {})[0].getvalue())
temp2 = tempfile.mktemp()
open(temp2, 'wb').write(self.openfile(path_parts2, rev2, {})[0].getvalue())
if path_parts1:
temp1 = tempfile.mktemp()
open(temp1, 'wb').write(self.openfile(path_parts1, rev1, {})[0].getvalue())
r1 = self.itemlog(path_parts1, rev1, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
info1 = (self.rcsfile(path_parts1, root=1, v=0), r1.date, r1.string)
else:
temp1 = '/dev/null'
info1 = ('/dev/null', '', '')
r1 = self.itemlog(path_parts1, rev1, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
r2 = self.itemlog(path_parts2, rev2, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
info1 = (self.rcsfile(path_parts1, root=1, v=0), r1.date, r1.string)
info2 = (self.rcsfile(path_parts2, root=1, v=0), r2.date, r2.string)
if path_parts2:
temp2 = tempfile.mktemp()
open(temp2, 'wb').write(self.openfile(path_parts2, rev2, {})[0].getvalue())
r2 = self.itemlog(path_parts2, rev2, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
info2 = (self.rcsfile(path_parts2, root=1, v=0), r2.date, r2.string)
else:
temp2 = '/dev/null'
info2 = ('/dev/null', '', '')
diff_args = vclib._diff_args(type, options)
@@ -142,7 +154,7 @@ class CCVSRepository(BaseCVSRepository):
def annotate(self, path_parts, rev=None, include_text=False):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, self.guesser, include_text)
return source, source.revision
def revinfo(self, rev):

View File

@@ -443,33 +443,48 @@ class RemoteSubversionRepository(vclib.Repository):
return self._revinfo(rev, 1)
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
p1 = self._getpath(path_parts1)
p2 = self._getpath(path_parts2)
r1 = self._getrev(rev1)
r2 = self._getrev(rev2)
if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1):
raise vclib.ItemNotFound(path_parts1)
if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2):
raise vclib.ItemNotFound(path_parts2)
if path_parts1 is not None:
p1 = self._getpath(path_parts1)
r1 = self._getrev(rev1)
if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1):
raise vclib.ItemNotFound(path_parts1)
else:
p1 = None
if path_parts2 is not None:
if not p1:
raise vclib.ItemNotFound(parh_parts2)
p2 = self._getpath(path_parts2)
r2 = self._getrev(rev2)
if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2):
raise vclib.ItemNotFound(path_parts2)
else:
p2 = None
args = vclib._diff_args(type, options)
def _date_from_rev(rev):
date, author, msg, revprops, changes = self._revinfo(rev)
return date
try:
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
if p1:
temp1 = cat_to_tempfile(self, p1, r1)
else:
temp1 = '/dev/null'
if p2:
temp2 = cat_to_tempfile(self, p2, r2)
else:
temp2 = '/dev/null'
return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args)
except core.SubversionException, e:
_fix_subversion_exception(e)
if e.apr_err == vclib.svn.core.SVN_ERR_FS_NOT_FOUND:
if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
raise vclib.InvalidRevision
raise
def isexecutable(self, path_parts, rev):
props = self.itemprops(path_parts, rev) # does authz-check
return props.has_key(core.SVN_PROP_EXECUTABLE)

View File

@@ -21,7 +21,7 @@ import tempfile
import popen
import re
import urllib
from svn import fs, repos, core, client, delta
from svn import fs, repos, core, client, delta, diff
### Require Subversion 1.3.1 or better.
@@ -306,8 +306,8 @@ class BlameSource:
try:
### TODO: Is this use of FIRST_REV always what we want? Should we
### pass 1 here instead and do filtering later?
client.blame2(local_url, _rev2optrev(rev), _rev2optrev(first_rev),
_rev2optrev(rev), self._blame_cb, ctx)
client.blame3(local_url, _rev2optrev(rev), _rev2optrev(first_rev),
_rev2optrev(rev), diff.svn_diff_file_options_t(), True, self._blame_cb, ctx)
except core.SubversionException, e:
_fix_subversion_exception(e)
if e.apr_err == core.SVN_ERR_CLIENT_IS_BINARY_FILE:
@@ -537,15 +537,24 @@ class LocalSubversionRepository(vclib.Repository):
return self._revinfo(rev, 1)
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
p1 = self._getpath(path_parts1)
p2 = self._getpath(path_parts2)
r1 = self._getrev(rev1)
r2 = self._getrev(rev2)
if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1):
raise vclib.ItemNotFound(path_parts1)
if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2):
raise vclib.ItemNotFound(path_parts2)
if path_parts1:
p1 = self._getpath(path_parts1)
r1 = self._getrev(rev1)
if not vclib.check_path_access(self, path_parts1, vclib.FILE, rev1):
raise vclib.ItemNotFound(path_parts1)
else:
p1 = None
if path_parts2:
p2 = self._getpath(path_parts2)
r2 = self._getrev(rev2)
if not vclib.check_path_access(self, path_parts2, vclib.FILE, rev2):
raise vclib.ItemNotFound(path_parts2)
else:
if not p1:
raise vclib.ItemNotFound(path_parts2)
p2 = None
args = vclib._diff_args(type, options)
def _date_from_rev(rev):
@@ -553,16 +562,25 @@ class LocalSubversionRepository(vclib.Repository):
return date
try:
temp1 = temp_checkout(self, p1, r1)
temp2 = temp_checkout(self, p2, r2)
info1 = p1, _date_from_rev(r1), r1
info2 = p2, _date_from_rev(r2), r2
if p1:
temp1 = temp_checkout(self, p1, r1)
info1 = p1, _date_from_rev(r1), r1
else:
temp1 = '/dev/null'
info1 = '/dev/null', _date_from_rev(rev1), rev1
if p2:
temp2 = temp_checkout(self, p2, r2)
info2 = p2, _date_from_rev(r2), r2
else:
temp2 = '/dev/null'
info2 = '/dev/null', _date_from_rev(rev2), rev2
return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args)
except core.SubversionException, e:
_fix_subversion_exception(e)
if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
raise vclib.InvalidRevision
raise
if e.apr_err != _SVN_ERR_CEASE_INVOCATION:
raise
def isexecutable(self, path_parts, rev):
props = self.itemprops(path_parts, rev) # does authz-check
@@ -902,7 +920,7 @@ class LocalSubversionRepository(vclib.Repository):
while history:
path, peg_revision = fs.history_location(history)
if peg_revision <= limit_revision:
return max(peg_revision, limit_revision), _cleanup_path(path)
return peg_revision, _cleanup_path(path)
history = fs.history_prev(history, 1)
return peg_revision, _cleanup_path(path)
else:

File diff suppressed because it is too large Load Diff

75
lib/viewvcmagic.py Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/python
import mimetypes
import magic
have_chardet = 0
try:
import chardet
have_chardet = 1
except: pass
class ContentMagic:
def __init__(self, encodings):
self.encodings = encodings.split(':')
self.mime_magic = None
self.errors = []
# Try to load magic
self.mime_magic = magic.open(magic.MAGIC_MIME_TYPE)
self.mime_magic.load()
# returns MIME type
def guess_mime(self, mime, filename, tempfile):
if mime == 'application/octet-stream':
mime = ''
if not mime and filename:
mime = mimetypes.guess_type(filename)[0]
if not mime and tempfile and self.mime_magic:
if type(tempfile) == type(''):
mime = self.mime_magic.file(tempfile)
else:
c = tempfile.read(4096)
mime = self.mime_magic.buffer(c)
return mime
# returns (utf8_content, charset)
def guess_charset(self, content):
# Try UTF-8
charset = 'utf-8'
try: content = content.decode('utf-8')
except: charset = None
if charset is None and have_chardet and len(content) > 64:
# Try to guess with chardet
try:
# Only detect on first 256KB if content is longer
if len(content) > 256*1024:
charset = chardet.detect(content[0:256*1024])
else:
charset = chardet.detect(content)
if charset and charset['encoding']:
charset = charset['encoding']
if charset == 'MacCyrillic':
# Silly MacCyr, try cp1251
try:
content = content.decode('windows-1251')
charset = 'windows-1251'
except: content = content.decode(charset)
else:
content = content.decode(charset)
except: charset = None
# Then try to guess primitively
if charset is None:
for charset in self.encodings:
try:
content = content.decode(charset)
break
except: charset = None
return (content, charset)
# guess and encode return value into UTF-8
def utf8(self, content):
(uni, charset) = self.guess_charset(content)
if charset:
return uni.encode('utf-8')
return content

5
templates-contrib/README Normal file
View File

@@ -0,0 +1,5 @@
This directory contains ViewVC template sets contributed by their
respective authors and expected to work against ViewVC 1.0.x. They
are not necessarily supported by the ViewVC development community, and
do not necessarily carry the same license or copyright as ViewVC
itself.

View File

@@ -0,0 +1,7 @@
Template Set: newvc
Author(s): C. Michael Pilato <cmpilato@red-bean.com>
Compatibility: ViewVC 1.1
The "newvc" template set uses top navigation tabs to flip between
various views of a file or directory, and aims for a clean-yet-modern
look and feel.

View File

@@ -0,0 +1,128 @@
[# Setup page definitions]
[define page_title]Diff of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "diff"]
<form method="get" action="[diff_format_action]" style="display: inline;">
<div>
[for diff_format_hidden_values]<input type="hidden" name="[diff_format_hidden_values.name]" value="[diff_format_hidden_values.value]"/>[end]
<select name="diff_format" onchange="submit()">
<option value="h" [is diff_format "h"]selected="selected"[end]>Colored Diff</option>
<option value="l" [is diff_format "l"]selected="selected"[end]>Long Colored Diff</option>
<option value="f" [is diff_format "f"]selected="selected"[end]>Full Colored Diff</option>
<option value="u" [is diff_format "u"]selected="selected"[end]>Unidiff</option>
<option value="c" [is diff_format "c"]selected="selected"[end]>Context Diff</option>
<option value="s" [is diff_format "s"]selected="selected"[end]>Side by Side</option>
</select>
<input type="submit" value="Show" />
(<a href="[patch_href]">Generate patch</a>)
</div>
</form>
<div id="vc_main_body">
<!-- ************************************************************** -->
[if-any raw_diff]
<pre>[raw_diff]</pre>
[else]
[define change_right][end]
[define last_change_type][end]
[# these should live in stylesheets]
<table cellpadding="0" cellspacing="0" style="width: 100%;">
[for changes]
[is changes.type "change"][else]
[if-any change_right][change_right][define change_right][end][end]
[end]
[is changes.type "header"]
<tr>
<th class="vc_header" style="width:6%;"><strong>#</strong></th>
<th colspan="2" class="vc_header">
<strong>Line [changes.line_info_left]</strong> |
<strong>Line [changes.line_info_right]</strong>
</th>
</tr>
[else]
[is changes.type "add"]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus"><strong style="color: green;">+</strong></td>
<td class="vc_diff_add">[changes.right]</td>
</tr>
[else]
[is changes.type "remove"]
<tr>
<td style="text-decoration: line-through">[changes.line_number]</td>
<td class="vc_diff_plusminus"><strong style="color: red;">&ndash;</strong></td>
<td class="vc_diff_remove">[changes.left]</td>
</tr>
[else]
[is changes.type "change"]
[if-any changes.have_left]
<tr>
<td style="text-decoration: line-through">[changes.line_number]</td>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&lt;</strong></td>
<td class="vc_diff_changes1">[changes.left]</td>
</tr>
[end]
[define change_right][change_right]
[if-any changes.have_right]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&gt;</strong></td>
<td class="vc_diff_changes2">[changes.right]</td>
</tr>[end]
[end]
[else]
[is changes.type "no-changes"]
<tr><td colspan="3" style="vc_diff_nochange"><strong>- No changes -</strong></td></tr>
[else]
[is changes.type "binary-diff"]
<tr><td colspan="3" class="vc_diff_binary"><strong>- Binary file revisions differ -</strong></td></tr>
[else]
[is changes.type "error"]
<tr><td colspan="3" class="vc_diff_error"><strong>- ViewVC depends on rcsdiff and GNU diff
to create this page. ViewVC cannot find GNU diff. Even if you
have GNU diff installed, the rcsdiff program must be configured
and compiled with the GNU diff location. -</strong></td></tr>
[else][# a line of context]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus">&nbsp;</td>
<td style="font-family: monospace; white-space: pre;">[changes.right]</td>
</tr>
[end][end][end][end][end][end][end]
[define last_change_type][changes.type][end]
[end]
[if-any change_right][change_right][end]
</table>
<h3>Diff Legend</h3>
<table class="auto" cellspacing="0">
<tr>
<td class="vc_diff_plusminus"><strong style="color: red;">&ndash;</strong></td>
<td class="vc_diff_remove">Removed lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: green;">+</strong></td>
<td class="vc_diff_add">Added lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&lt;</strong></td>
<td class="vc_diff_changes1">Changed lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&gt;</strong></td>
<td class="vc_diff_changes2">Changed lines</td>
</tr>
</table>
[end]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,139 @@
[# setup page definitions]
[define page_title]Index of:[end]
[define help_href][docroot]/help_[if-any where]dir[else]root[end]view.html[end]
[# end]
[include "include/header.ezt" "directory"]
[if-any where][else]
<!-- you may insert repository access instructions here -->
[end]
<table class="auto">
[is cfg.options.use_pagesize "0"][else][is picklist_len "1"][else]
<tr>
<td>Jump to page:</td>
<td><form method="get" action="[dir_paging_action]">
[for dir_paging_hidden_values]<input type="hidden" name="[dir_paging_hidden_values.name]" value="[dir_paging_hidden_values.value]"/>[end]
<select name="dir_pagestart" onchange="submit()">
[for picklist]
<option [is picklist.count dir_pagestart]selected[end] value="[picklist.count]">Page [picklist.page]: [picklist.start] to [picklist.end]</option>
[end]
</select>
<input type="submit" value="Go" />
</form>
</td>
</tr>
[end][end]
</table>
<div id="vc_main_body">
<!-- ************************************************************** -->
<div id="vc_togglables">
[is roottype "svn"]
[if-any rev]r<a href="[revision_href]">[rev]</a>[end]
[else]
[is num_dead "0"]
[else]
[if-any attic_showing]
<a href="[hide_attic_href]">Hide
[else]
<a href="[show_attic_href]">Show
[end]
dead files</a>
[end]
[end]
</div>
<table cellspacing="2" class="fixed" id="dirlist">
<thead>
<tr>
<th style="width: 200px" class="vc_header[is sortby "file"]_sort[end]">
<a href="[sortby_file_href]#dirlist">File
[is sortby "file"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end]
</a>
</th>
<th class="vc_header[is sortby "rev"]_sort[end]">
<a href="[sortby_rev_href]#dirlist">Last Change
[is sortby "rev"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end]
</a>
</th>
</tr>
</thead>
<tbody>
[if-any up_href]
<tr class="vc_row_odd">
<td colspan="2">
<a href="[up_href]">
<img src="[docroot]/images/back_small.png" alt="" class="vc_icon"
/>&nbsp;../</a>
</td>
</tr>
[end]
[for entries]
[define click_href][is entries.pathtype "dir"][entries.view_href][else][if-any entries.prefer_markup][entries.view_href][else][entries.download_href][end][end][end]
<tr class="vc_row_[if-index entries even]even[else]odd[end]">
<td style="width: 200px" onclick="jumpTo('[click_href]')">
<a name="[entries.anchor]" href="[click_href]" title="[is entries.pathtype "dir"]View Directory Contents[else][if-any entries.prefer_markup]View[else]Download[end] File Contents[end]">
<img src="[docroot]/images/[is entries.pathtype "dir"]dir[else][is entries.state "dead"]broken[else]text[end][end].png" alt="" class="vc_icon" />
[entries.name][is entries.pathtype "dir"]/[end]</a>
[is entries.state "dead"](dead)[end]
</td>
<td [if-any entries.log_href]onclick="jumpTo('[entries.log_href]')"[end]>
[if-any entries.rev]
<strong>[if-any entries.log_href]<a href="[entries.log_href]" title="Revision [entries.rev]">[entries.rev]</a>[else][entries.rev][end]</strong>
([entries.ago] ago)
by <em>[entries.author]</em>:
[entries.log]
[is entries.pathtype "dir"][is roottype "cvs"]
<em>(from [entries.log_file]/[entries.log_rev])</em>
[end][end]
[end]
</td>
</tr>
[end]
</tbody>
</table>
<div id="vc_view_summary">
[if-any search_re_form]
<form class="inline" method="get" action="[search_re_action]">
<div class="inline">
[for search_re_hidden_values]<input type="hidden" name="[search_re_hidden_values.name]" value="[search_re_hidden_values.value]"/>[end]
<input type="text" name="search" value="[search_re]" />
<input type="submit" value="Search Files" />
</div>
</form>
[if-any search_re]
<form class="inline" method="get" action="[search_re_action]">
<div class="inline">
[for search_re_hidden_values]<input type="hidden" name="[search_re_hidden_values.name]" value="[search_re_hidden_values.value]"/>[end]
<input type="submit" value="Show all files" />
</div>
</form>
[end]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
[end]
[include "include/pathrev_form.ezt"]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
[files_shown] file[is files_shown "1"][else]s[end] shown
</div>
[include "include/props.ezt"]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,8 @@
/************************************/
/*** ViewVC Help CSS Stylesheet ***/
/************************************/
body { margin: 0.5em; }
img { border: none; }
table { width: 100%; }
td { vertical-align: top; }
col.menu { width:12em; }

View File

@@ -0,0 +1,126 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Directory View</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td colspan="2">
<h1>ViewVC Help: Directory View</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<a href="help_rootview.html">General</a><br />
<strong>Directory&nbsp;View</strong><br />
<a href="help_log.html">Log&nbsp;View</a><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>The directory listing view should be a familiar sight to any
computer user. It shows the path of the current directory being viewed
at the top of the page. Below that is a table summarizing the
directory contents, and then comes actual contents, a sortable list of
all files and subdirectories inside the current directory.</p>
<p><a name="summary"></a>The summary table is made up of some or all
of the following rows:</p>
<ul>
<li><a name="summary-files-shown"><strong>Files Shown</strong></a>
- Number of files shown in the directory listing. This might be less
than the actual number of files in the directory if a
<a href="#option-search">regular expression search</a> is in place,
hiding files which don't meet the search criteria. In CVS directory
listings, this row will also have a link to toggle display of
<a href="help_rootview.html#dead-files">dead files</a>, if any are
present.</li>
<li><a name="summary-revision"><strong>Directory
Revision</strong></a> - For Subversion directories only.
Shown as "# of #" where the first number is the most recent
repository revision where the directory (or a path underneath it)
was modified. The second number is just the latest repository
revision. Both numbers are links to
<a href="help_rootview.html#view-rev">revision views</a></li>
<li><a name="summary-sticky-revision-tag"><strong>Sticky
Revision/Tag</strong></a> - shows the current
<a href="help_rootview.html#sticky-revision-tag">sticky revision or
tag</a> and contains form fields to set or clear it.</li>
<li><a name="summary-search"><strong>Current Search</strong></a> -
If a <a href="#option-search">regular expression search</a> is in place,
shows the search string.</li>
<li><a name="summary-query"><strong>Query</strong></a> - Provides
a link to a <a href="help_rootview.html#view-query">query form</a>
for the directory</li>
</ul>
<p><a name="list"></a>The actual directory list is a table with
filenames and directory names in one column and information about the
most recent revisions where each file or directory was modified in the
other columns. Column headers can be clicked to sort the directory
entries in order by a column, and clicked again to reverse the sort
order.</p>
<p>
<!-- If using directory.ezt template -->
File names are links to <a href="help_log.html">log views</a>
showing a list of revisions where a file was modified. Revision
numbers are links to either
<a href="help_rootview.html#view-markup">view</a>
or <a href="help_rootview.html#view-checkout">download</a> a file
(depending on its file type). The links are reversed for directories.
Directory revision numbers are links to <a href="help_log.html">log
views</a>, while directory names are links showing the contents of those
directories.
<!-- If using dir_alt.ezt template -->
<!--
File and directory names are links to retrieve their contents.
File links may be either
<a href="help_rootview.html#view-markup">view</a>
or <a href="help_rootview.html#view-download">download</a> links
depending on the file type. Directory links go to directory
listings. Revision numbers are links to <a href="help_log.html">log
views</a> showing lists of revisions where a file or directory was
modified.
-->
Also, in CVS repositories with the <a
href="help_rootview.html#view-graph">graph view</a> enabled, there
will be small icons next to file names which are links to revision
graphs.</p>
<p>Depending on how ViewVC is configured, there may be more options
at the bottom of directory pages:</p>
<ul>
<li><a name="option-search"><strong>Regular expression
search</strong></a> - If enabled, will show a form field accepting
a search string (a
<a href="http://doc.python.org/lib/re-syntax.html">python regular
expression</a>). Once submitted, only files that have at least
one occurance of the expression will show up in directory listings.
</li>
<li><a name="option-tarball"><strong>Tarball download</strong></a> -
If enabled, will show a link to download a gzipped tar archive of
the directory contents.</li>
</ul>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

View File

@@ -0,0 +1,71 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Log View</title>
<link rel="stylesheet" href="help.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td colspan="2">
<h1>ViewVC Help: Log View</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<a href="help_rootview.html">General</a><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<strong>Log&nbsp;View</strong><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>
The log view displays the revision history of the selected source
file or directory. For each revision the following information is
displayed:
<ul>
<li>The revision number. In Subversion repositories, this is a
link to the <a href="help_rootview.html#view-rev">revision
view</a></li>
<li>For files, links to
<a href="help_rootview.html#view-markup">view</a>,
<a href="help_rootview.html#view-checkout">download</a>, and
<a href="help_rootview.html#view-annotate">annotate</a> the
revision. For directories, a link to
<a href="help_dirview.html">list directory contents</a></li>
<li>A link to select the revision for diffs (see below)</li>
<li>The date and age of the change</li>
<li>The author of the modification</li>
<li>The CVS branch (usually <em>MAIN</em>, if not on a branch)</li>
<li>Possibly a list of CVS tags bound to the revision (if any)</li>
<li>The size of the change measured in added and removed lines of
code. (CVS only)</li>
<li>The size of the file in bytes at the time of the revision
(Subversion only)</li>
<li>Links to view diffs to the previous revision or possibly to
an arbitrary selected revision (if any, see above)</li>
<li>If the revision is the result of a copy, the path and revision
copied from</li>
<li>If the revision precedes a copy or rename, the path at the
time of the revision</li>
<li>And last but not least, the commit log message which should tell
about the reason for the change.</li>
</ul>
<p>
At the bottom of the page you will find a form which allows
to request diffs between arbitrary revisions.
</p>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Query The Commit Database</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td colspan="2">
<h1>ViewVC Help: Query The Commit Database</h1>
</td>
</tr>
<tr><td>
<h3>Other&nbsp;Help:</h3>
<a href="help_rootview.html">General</a><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<a href="help_log.html">Classic&nbsp;Log&nbsp;View</a><br />
<a href="help_logtable.html">Alternative&nbsp;Log&nbsp;View</a><br />
<strong>Query&nbsp;Database</strong>
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>
Select your parameters for querying the CVS commit database in the
form at the top of the page. You
can search for multiple matches by typing a comma-seperated list
into the text fields. Regular expressions, and wildcards are also
supported. Blank text input fields are treated as wildcards.
</p>
<p>
Any of the text entry fields can take a comma-seperated list of
search arguments. For example, to search for all commits from
authors <em>jpaint</em> and <em>gstein</em>, just type: <code>jpaint,
gstein</code> in the <em>Author</em> input box. If you are searching
for items containing spaces or quotes, you will need to quote your
request. For example, the same search above with quotes is:
<code>"jpaint", "gstein"</code>.
</p>
<p>
Wildcard and regular expression searches are entered in a similar
way to the quoted requests. You must quote any wildcard or
regular expression request, and a command character preceeds the
first quote. The command character <code>l</code>(lowercase L) is for wildcard
searches, and the wildcard character is a percent (<code>%</code>). The
command character for regular expressions is <code>r</code>, and is
passed directly to MySQL, so you'll need to refer to the MySQL
manual for the exact regex syntax. It is very similar to Perl. A
wildard search for all files with a <em>.py</em> extention is:
<code>l"%.py"</code> in the <em>File</em> input box. The same search done
with a regular expression is: <code>r".*\.py"</code>.
</p>
<p>
All search types can be mixed, as long as they are seperated by
commas.
</p>
</td></tr></table>
</body></html>

View File

@@ -0,0 +1,166 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: General</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td colspan="2">
<h1>ViewVC Help: General</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<strong>General</strong><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<a href="help_log.html">Log&nbsp;View</a><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p><em>ViewVC</em> is a WWW interface for CVS and Subversion
repositories. It allows you to browse the files and directories in a
repository while showing you metadata from the repository history: log
messages, modification dates, author names, revision numbers, copy
history, and so on. It provides several different views of repository
data to help you find the information you are looking for:</p>
<ul>
<li><a name="view-dir" href="help_dirview.html"><strong>Directory
View</strong></a> - Shows a list of files and subdirectories in a
directory of the repository, along with metadata like author names and
log entries.</li>
<li><a name="view-log" href="help_log.html"><strong>Log
View</strong></a> - Shows a revision by revision list of all the
changes that have made to a file or directory in the repository, with
metadata and links to views of each revision.</li>
<li><a name="view-markup"><strong>File Contents View (Markup
View)</strong></a> - Shows the contents of a file at a particular
revision, with revision information at the top of the page. File
revisions which are GIF, PNG, or JPEG images are displayed inline on
the page. Other file types are displayed as marked up text. The markup
may be limited to turning URLs and email addresses into links, or
configured to show colorized source code.</li>
<li><a name="view-checkout"><strong>File Download (Checkout
View)</strong></a> - Retrieves the unaltered contents of a file
revision. Browsers may try to display the file, or just save it to
disk.</li>
<li><a name="view-annotate"><strong>File Annotate View</strong></a> -
Shows the contents of a file revision and breaks it down line by line,
showing the revision number where each one was last modified, along
with links and other information. <em>This view is disabled in some
ViewVC configurations</em></li>
<li><a name="view-diff"><strong>File Diff View</strong></a> - Shows
the changes made between two revisions of a file</li>
<li><a name="view-tarball"><strong>Directory Tarball View</strong> -
Retrieves a gzipped tar archive containing the contents of a
directory.<em>This view is disabled in the default ViewVC
configuration.</em></li>
<li><a name="view-query"><strong>Directory Query View</strong></a> -
Shows information about changes made to all subdirectories and files
under a parent directory, sorted and filtered by criteria you specify.
<em>This view is disabled in the default ViewVC configuration.</em>
</li>
<li><a name="view-rev"><strong>Revision View</strong> - Shows
information about a revision including log message, author, and a list
of changed paths. <em>For Subversion repositories only.</em></li>
<li><a name="view-graph"><strong>Graph View</strong></a> - Shows a
graphical representation of a file's revisions and branches complete
with tag and author names and links to markup and diff pages.
<em>For CVS repositories only, and disabled in the default
configuration.</em></li>
</ul>
<h3><a name="multiple-repositories">Multiple Repositories</a></h3>
<p>A single installation of ViewVC is often used to provide access to
more than one repository. In these installations, ViewVC shows a
<em>Project Root</em> drop down box in the top right corner of every
generated page to allow for quick access to any repository.</p>
<h3><a name="sticky-revision-tag">Sticky Revision and Tag</a></h3>
<p>By default, ViewVC will show the files and directories and revisions
that currently exist in the repository. But it's also possible to browse
the contents of a repository at a point in its past history by choosing
a "sticky tag" (in CVS) or a "sticky revision" (in Subversion) from the
forms at the top of directory and log pages. They're called sticky
because once they're chosen, they stick around when you navigate to
other pages, until you reset them. When they're set, directory and log
pages only show revisions preceding the specified point in history. In
CVS, when a tag refers to a branch or a revision on a branch, only
revisions from the branch history are shown, including branch points and
their preceding revisions.</p>
<h3><a name="dead-files">Dead Files</a></h3>
<p>In CVS directory listings, ViewVC can optionally display dead files.
Dead files are files which used to be in a directory but are currently
deleted, or files which just don't exist in the currently selected
<a href="#sticky-revision-tag">sticky tag</a>. Dead files cannot be
shown in Subversion repositories. The only way to see a deleted file in
a Subversion directory is to navigate to a sticky revision where the
file previously existed.</p>
<h3><a name="artificial-tags">Artificial Tags</a></h3>
<p>In CVS Repositories, ViewVC adds artificial tags <em>HEAD</em> and
<em>MAIN</em> to tag listings and accepts them in place of revision
numbers and real tag names in all URLs. <em>MAIN</em> acts like a branch
tag pointing at the default branch, while <em>HEAD</em> acts like a
revision tag pointing to the latest revision on the default branch. The
default branch is usually just the trunk, but may be set to other
branches inside individual repository files. CVS will always check out
revisions from a file's default branch when no other branch is specified
on the command line.</p>
<h3><a name="more-information">More Information</a></h3>
<p>More information about <em>ViewVC</em> is available from
<a href="http://viewvc.org/">viewvc.org</a>.
See the links below for guides to CVS and Subversion</p>
<h4>Documentation about CVS</h4>
<blockquote>
<p>
<a href="http://cvsbook.red-bean.com/"><em>Open Source
Development with CVS</em></a><br />
<a href="http://www.loria.fr/~molli/cvs/doc/cvs_toc.html">CVS
User's Guide</a><br />
<a href="http://cellworks.washington.edu/pub/docs/cvs/tutorial/cvs_tutorial_1.html">Another CVS tutorial</a><br />
<a href="http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/">Yet another CVS tutorial (a little old, but nice)</a><br />
<a href="http://www.cs.utah.edu/dept/old/texinfo/cvs/FAQ.txt">An old but very useful FAQ about CVS</a>
</p>
</blockquote>
<h4>Documentation about Subversion</h3>
<blockquote>
<p>
<a href="http://svnbook.red-bean.com/"><em>Version Control with
Subversion</em></a><br />
</p>
</blockquote>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -0,0 +1,4 @@
function jumpTo(url)
{
window.location = url;
}

View File

@@ -0,0 +1,332 @@
/*******************************/
/*** ViewVC CSS Stylesheet ***/
/*******************************/
/*** Standard Tags ***/
html, body {
background-color: white;
color: black;
font-family: sans-serif;
font-size: 100%;
margin: 5px;
}
a {
text-decoration: none;
color: rgb(30%,30%,60%);
}
img { border: none; }
table {
width: 100%;
margin: 0;
border: none;
}
td, th {
vertical-align: top;
}
th { white-space: nowrap; }
table.auto {
width: auto;
}
table.fixed {
width: 100%;
table-layout: fixed;
}
table.fixed td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
form { margin: 0; }
address { font-style: normal; display: inline; }
.inline { display: inline; }
/*** Icons ***/
.vc_icon {
width: 16px;
height: 16px;
border: none;
padding: 0 1px;
}
#vc_header {
padding: 0 0 10px 0;
border-bottom: 10px solid #94bd5e;
}
#vc_footer {
text-align: right;
font-size: 85%;
padding: 10px 0 0 0;
border-top: 10px solid #94bd5e;
}
#vc_topmatter {
float: right;
text-align: right;
font-size: 85%;
}
#vc_current_path {
color: rgb(50%,50%,50%);
padding: 10px 0;
font-size: 140%;
font-weight: bold;
}
#vc_current_path a {
color: rgb(60%,60%,60%);
}
#vc_current_path a:hover {
background-color: rgb(90%,90%,90%);
}
#vc_current_path .thisitem {
color: #94bd5e;
}
#vc_current_path .pathdiv {
padding: 0 0.1em;
}
#vc_view_selection_group {
background: black;
color: white;
margin: 0 0 5px 0;
padding: 5px;
text-align: right;
}
#vc_view_selection_group a {
padding: 5px;
font-size: 100%;
color: white;
text-decoration: none;
}
#vc_view_selection_group a.vc_view_link_this, #vc_view_selection_group a.vc_view_link:hover {
color: #94bd5e;
}
#vc_view_selection_group a:hover {
background-color: black;
}
#vc_view_main {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
#vc_togglables {
text-align: right;
font-size: 85%;
}
#vc_main_body {
background: white;
padding: 5px 0 20px 0;
}
#vc_view_summary {
font-size: 85%;
text-align: right;
margin-top: 5px;
}
/*** Table Headers ***/
.vc_header, .vc_header_sort {
text-align: left;
vertical-align: top;
border-bottom: 1px solid black;
background-color: rgb(80%,80%,80%);
}
.vc_header_sort {
background-color: rgb(85%,85%,85%);
}
/*** Table Rows ***/
.vc_row_even {
background-color: rgb(95%,95%,95%);
}
.vc_row_odd {
background-color: rgb(90%,90%,90%);
}
/*** Directory View ***/
#dirlist td, #dirlist th {
padding: 0.2em;
vertical-align: middle;
}
#dirlist tr:hover {
background-color: white;
}
/*** Log messages ***/
.vc_log {
/* unfortunately, white-space: pre-wrap isn't widely supported ... */
white-space: -moz-pre-wrap; /* Mozilla based browsers */
white-space: -pre-wrap; /* Opera 4 - 6 */
white-space: -o-pre-wrap; /* Opera >= 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
}
/*** Properties Listing ***/
.vc_properties {
margin: 1em 0;
}
.vc_properties h2 {
font-size: 115%;
}
.vc_properties td, .vc_properties th {
padding: 0.2em;
}
/*** File Content Markup Styles ***/
.vc_summary {
background-color: #eeeeee;
}
#vc_file td {
border-right-style: solid;
border-right-color: #505050;
text-decoration: none;
font-weight: normal;
font-style: normal;
padding: 1px 5px;
}
.vc_file_line_number {
border-right-width: 1px;
background-color: #eeeeee;
color: #505050;
text-align: right;
}
.vc_file_line_author, .vc_file_line_rev {
border-right-width: 1px;
text-align: right;
}
.vc_file_line_text {
border-right-width: 0px;
background-color: white;
font-family: monospace;
text-align: left;
white-space: pre;
width: 100%;
}
.pygments-c { color: #408080; font-style: italic } /* Comment */
.pygments-err { border: 1px solid #FF0000 } /* Error */
.pygments-k { color: #008000; font-weight: bold } /* Keyword */
.pygments-o { color: #666666 } /* Operator */
.pygments-cm { color: #408080; font-style: italic } /* Comment.Multiline */
.pygments-cp { color: #BC7A00 } /* Comment.Preproc */
.pygments-c1 { color: #408080; font-style: italic } /* Comment.Single */
.pygments-cs { color: #408080; font-style: italic } /* Comment.Special */
.pygments-gd { color: #A00000 } /* Generic.Deleted */
.pygments-ge { font-style: italic } /* Generic.Emph */
.pygments-gr { color: #FF0000 } /* Generic.Error */
.pygments-gh { color: #000080; font-weight: bold } /* Generic.Heading */
.pygments-gi { color: #00A000 } /* Generic.Inserted */
.pygments-go { color: #808080 } /* Generic.Output */
.pygments-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.pygments-gs { font-weight: bold } /* Generic.Strong */
.pygments-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.pygments-gt { color: #0040D0 } /* Generic.Traceback */
.pygments-kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.pygments-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.pygments-kp { color: #008000 } /* Keyword.Pseudo */
.pygments-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.pygments-kt { color: #B00040 } /* Keyword.Type */
.pygments-m { color: #666666 } /* Literal.Number */
.pygments-s { color: #BA2121 } /* Literal.String */
.pygments-na { color: #7D9029 } /* Name.Attribute */
.pygments-nb { color: #008000 } /* Name.Builtin */
.pygments-nc { color: #0000FF; font-weight: bold } /* Name.Class */
.pygments-no { color: #880000 } /* Name.Constant */
.pygments-nd { color: #AA22FF } /* Name.Decorator */
.pygments-ni { color: #999999; font-weight: bold } /* Name.Entity */
.pygments-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.pygments-nf { color: #0000FF } /* Name.Function */
.pygments-nl { color: #A0A000 } /* Name.Label */
.pygments-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.pygments-nt { color: #008000; font-weight: bold } /* Name.Tag */
.pygments-nv { color: #19177C } /* Name.Variable */
.pygments-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.pygments-w { color: #bbbbbb } /* Text.Whitespace */
.pygments-mf { color: #666666 } /* Literal.Number.Float */
.pygments-mh { color: #666666 } /* Literal.Number.Hex */
.pygments-mi { color: #666666 } /* Literal.Number.Integer */
.pygments-mo { color: #666666 } /* Literal.Number.Oct */
.pygments-sb { color: #BA2121 } /* Literal.String.Backtick */
.pygments-sc { color: #BA2121 } /* Literal.String.Char */
.pygments-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.pygments-s2 { color: #BA2121 } /* Literal.String.Double */
.pygments-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.pygments-sh { color: #BA2121 } /* Literal.String.Heredoc */
.pygments-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.pygments-sx { color: #008000 } /* Literal.String.Other */
.pygments-sr { color: #BB6688 } /* Literal.String.Regex */
.pygments-s1 { color: #BA2121 } /* Literal.String.Single */
.pygments-ss { color: #19177C } /* Literal.String.Symbol */
.pygments-bp { color: #008000 } /* Name.Builtin.Pseudo */
.pygments-vc { color: #19177C } /* Name.Variable.Class */
.pygments-vg { color: #19177C } /* Name.Variable.Global */
.pygments-vi { color: #19177C } /* Name.Variable.Instance */
.pygments-il { color: #666666 } /* Literal.Number.Integer.Long */
/*** Diff Styles ***/
.vc_diff_plusminus { width: 1em; }
.vc_diff_remove, .vc_diff_add, .vc_diff_changes1, .vc_diff_changes2 {
font-family: monospace;
white-space: pre;
}
.vc_diff_remove { background: rgb(100%,60%,60%); }
.vc_diff_add { background: rgb(60%,100%,60%); }
.vc_diff_changes1 { background: rgb(100%,100%,70%); color: rgb(50%,50%,50%); text-decoration: line-through; }
.vc_diff_changes2 { background: rgb(100%,100%,0%); }
.vc_diff_nochange, .vc_diff_binary, .vc_diff_error {
font-family: sans-serif;
font-size: smaller;
}
/*** Intraline Diff Styles ***/
.vc_idiff_add {
background-color: #aaffaa;
}
.vc_idiff_change {
background-color:#ffff77;
}
.vc_idiff_remove {
background-color:#ffaaaa;
}
.vc_idiff_empty {
background-color:#e0e0e0;
}
table.vc_idiff col.content {
width: 50%;
}
table.vc_idiff tbody {
font-family: monospace;
/* unfortunately, white-space: pre-wrap isn't widely supported ... */
white-space: -moz-pre-wrap; /* Mozilla based browsers */
white-space: -pre-wrap; /* Opera 4 - 6 */
white-space: -o-pre-wrap; /* Opera >= 7 */
white-space: pre-wrap; /* CSS3 */
word-wrap: break-word; /* IE 5.5+ */
}
table.vc_idiff tbody th {
background-color:#e0e0e0;
text-align:right;
}
/*** Query Form ***/
.vc_query_form {
}

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- ViewVC :: http://www.viewvc.org/ -->
<head>
<title>ViewVC Exception</title>
</head>
<body>
<h3>An Exception Has Occurred</h3>
[if-any msg]
<p>[msg]</p>
[end]
[if-any status]
<h4>HTTP Response Status</h4>
<p><pre>[status]</pre></p>
<hr />
[end]
[if-any msg][else]
<h4>Python Traceback</h4>
<p><pre>
[stacktrace]
</pre></p>
[end]
[# Here follows a bunch of space characters, present to ensure that
our error message is larger than 512 bytes so that IE's "Friendly
Error Message" won't show. For more information, see
http://oreillynet.com/onjava/blog/2002/09/internet_explorer_subverts_err.html]
</body>
</html>

View File

@@ -0,0 +1,61 @@
[# setup page definitions]
[define page_title]Annotation of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "annotate"]
[include "include/fileview.ezt"]
<div id="vc_main_body">
<!-- ************************************************************** -->
[define last_rev]0[end]
[define rowclass]vc_row_odd[end]
[if-any lines]
<div id="vc_file">
<table cellspacing="0" cellpadding="0">
<tr>
<th class="vc_header">Line</th>
[is annotation "annotated"]
<th class="vc_header">User</th>
<th class="vc_header">Rev</th>
[end]
<th class="vc_header">File contents</th>
</tr>
[for lines]
[is lines.rev last_rev]
[else]
[is rowclass "vc_row_even"]
[define rowclass]vc_row_odd[end]
[else]
[define rowclass]vc_row_even[end]
[end]
[end]
<tr class="[rowclass]" id="l[lines.line_number]">
<td class="vc_file_line_number">[lines.line_number]</td>
[is annotation "annotated"]
<td class="vc_file_line_author">[is lines.rev last_rev]&nbsp;[else][lines.author][end]</td>
<td class="vc_file_line_rev">[is lines.rev last_rev]&nbsp;[else][if-any lines.diff_href]<a href="[lines.diff_href]">[end][lines.rev][if-any lines.diff_href]</a>[end][end]</td>
[end]
<td class="vc_file_line_text">[lines.text]</td>
</tr>
[define last_rev][lines.rev][end]
[end]
</table>
</div>
[else]
[if-any image_src_href]
<div id="vc_file_image">
<img src="[image_src_href]" alt="" />
</div>
[end]
[end]
[include "include/props.ezt"]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,15 @@
[# setup page definitions]
[define page_title]Graph of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "graph"]
<div style="text-align:center;">
[imagemap]
<img usemap="#MyMapName"
src="[imagesrc]"
alt="Revisions of [where]" />
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,70 @@
<div style="border-bottom: solid 1px black;">
<p id="diff">This form allows you to request diffs between any two
revisions of this file.
For each of the two "sides" of the diff,
[if-any tags]
select a symbolic revision name using the selection box, or choose
'Use Text Field' and enter a numeric revision.
[else]
enter a numeric revision.
[end]
</p>
<form method="get" action="[diff_select_action]" id="diff_select">
<table cellpadding="2" cellspacing="0" class="auto">
<tr>
<td>&nbsp;</td>
<td>
[for diff_select_hidden_values]<input type="hidden" name="[diff_select_hidden_values.name]" value="[diff_select_hidden_values.value]"/>[end]
Diffs between
[if-any tags]
<select name="r1">
<option value="text" selected="selected">Use Text Field</option>
[for tags]
<option value="[tags.rev]:[tags.name]">[tags.name]</option>
[end]
</select>
<input type="text" size="12" name="tr1"
value="[if-any rev_selected][rev_selected][else][first_revision][end]"
onchange="document.getElementById('diff_select').r1.selectedIndex=0" />
[else]
<input type="text" size="12" name="r1"
value="[if-any rev_selected][rev_selected][else][first_revision][end]" />
[end]
and
[if-any tags]
<select name="r2">
<option value="text" selected="selected">Use Text Field</option>
[for tags]
<option value="[tags.rev]:[tags.name]">[tags.name]</option>
[end]
</select>
<input type="text" size="12" name="tr2"
value="[last_revision]"
onchange="document.getElementById('diff_select').r2.selectedIndex=0" />
[else]
<input type="text" size="12" name="r2" value="[last_revision]" />
[end]
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
Type of Diff should be a
<select name="diff_format" onchange="submit()">
<option value="h" [is diff_format "h"]selected="selected"[end]>Colored Diff</option>
<option value="l" [is diff_format "l"]selected="selected"[end]>Long Colored Diff</option>
<option value="f" [is diff_format "f"]selected="selected"[end]>Full Colored Diff</option>
<option value="u" [is diff_format "u"]selected="selected"[end]>Unidiff</option>
<option value="c" [is diff_format "c"]selected="selected"[end]>Context Diff</option>
<option value="s" [is diff_format "s"]selected="selected"[end]>Side by Side</option>
</select>
<input type="submit" value=" Get Diffs " />
</td>
</tr>
</table>
</form>
</div>

View File

@@ -0,0 +1,74 @@
<table class="auto">
<tr>
<td>Revision:</td>
<td><strong>[if-any revision_href]<a href="[revision_href]">[rev]</a>[else][rev][end]</strong> [if-any vendor_branch] <em>(vendor branch)</em>[end]</td>
</tr>
<tr>
<tr>
<td>Committed:</td>
<td>[if-any date]<em>[date]</em> [end][if-any ago]([ago] ago) [end][if-any author]by <em>[author]</em>[end]</td>
</tr>
[if-any orig_path]
<tr>
<td>Original Path:</td>
<td><strong><a href="[orig_href]"><em>[orig_path]</em></a></strong></td>
</tr>
[end]
[if-any branches]
<tr>
<td>Branch:</td>
<td><strong>[branches]</strong></td>
</tr>
[end]
[if-any tags]
<tr>
<td>CVS Tags:</td>
<td><strong>[tags]</strong></td>
</tr>
[end]
[if-any branch_points]
<tr>
<td>Branch point for:</td>
<td><strong>[branch_points]</strong></td>
</tr>
[end]
[is roottype "cvs"][if-any changed]
<tr>
<td>Changes since <strong>[prev]</strong>:</td>
<td><strong>[changed] lines</strong></td>
</tr>
[end][end]
[is roottype "svn"][if-any size]
<td>File size:</td>
<td>[size] byte(s)</td>
</tr>
[end][end]
[if-any lockinfo]
<td>Lock status:</td>
<td>[lockinfo]</td>
[end]
[is state "dead"]
<tr>
<td>State:</td>
<td><strong><em>FILE REMOVED</em></strong></td>
</tr>
[end]
[if-any annotation]
[is annotation "binary"]
<tr>
<td colspan="2"><strong>Unable to calculate annotation data on binary file contents.</strong></td>
</tr>
[end]
[is annotation "error"]
<tr>
<td colspan="2"><strong>Error occurred while calculating annotation data.</strong></td>
</tr>
[end]
[end]
[if-any log]
<tr>
<td>Log Message:</td>
<td><pre class="vc_log">[log]</span></td>
</tr>
[end]
</table>

View File

@@ -0,0 +1,10 @@
</div> <!-- vc_view_main -->
<div id="vc_footer">
[if-any cfg.general.address]Administered by <address><a href="mailto:[cfg.general.address]">[cfg.general.address]</a></address><br/>[end]
Powered by <a href="http://viewvc.tigris.org/">ViewVC [vsn]</a>
[if-any rss_href]<br/><a href="[rss_href]" title="RSS 2.0 feed"><img src="[docroot]/images/feed-icon-16x16.jpg" class="vc_icon" alt="RSS 2.0 feed" /></a>[else]&nbsp;[end]
</div>
</body>
</html>

View File

@@ -0,0 +1,63 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- ViewVC :: http://www.viewvc.org/ -->
<head>
<title>[[]ViewVC] [page_title] [if-any rootname][rootname][if-any where]/[where][end][end]</title>
<meta name="generator" content="ViewVC [vsn]" />
<link rel="stylesheet" href="[docroot]/styles.css" type="text/css" />
<script src="[docroot]/scripts.js"></script>
[if-any rss_href]
<link rel="alternate" type="application/rss+xml" href="[rss_href]" title="ViewVC RSS: [if-any rootname][rootname][if-any where]/[where][end][end]">
[end]
</head>
<body>
<div id="vc_header">
<div id="vc_topmatter">
[if-any username]Logged in as: <strong>[username]</strong> |[end]
<a href="[help_href]">ViewVC Help</a>
</div>
<div id="vc_logo">
<a href="http://www.viewvc.org/"><img src="[docroot]/images/viewvc-logo.png" alt="ViewVC logotype" width="240" height="70" /></a>
</div>
<div id="vc_view_selection_group">
[is pathtype "dir"]
<a class="vc_view_link[is view "dir"]_this[end]" href="[view_href]">View Directory</a>
[if-any log_href]
| <a class="vc_view_link[is view "log"]_this[end]" href="[log_href]">Revision Log</a>
[end]
[if-any queryform_href]
| <a class="vc_view_link[is view "queryform"]_this[end]" href="[queryform_href]">Commit Query</a>
[end]
[if-any tarball_href]
| <a class="vc_view_link" href="[tarball_href]">Download Tarball</a>
[end]
[end]
[is pathtype "file"]
<a class="vc_view_link[is view "markup"]_this[end]" href="[view_href]">View File</a>
| <a class="vc_view_link[is view "log"]_this[end]" href="[log_href]">Revision Log</a>
| <a class="vc_view_link[is view "annotate"]_this[end]" href="[annotate_href]">Show Annotations</a>
[if-any graph_href]
| <a class="vc_view_link[is view "graph"]_this[end]" href="[graph_href]">Revision Graph</a>
[end]
| <a class="vc_view_link" href="[download_href]">Download File</a>
[end]
[if-any revision_href]
| <a class="vc_view_link[is view "revision"]_this[end]" href="[revision_href]">View Changeset</a>
[end]
| <a class="vc_view_link[is view "roots"]_this[end]" href="[roots_href]">Root Listing</a>
</div>
<div id="vc_current_path">
[if-any roots_href]<a href="[roots_href]">root</a>[end][if-any nav_path]<span class="pathdiv">/</span>[for nav_path][if-any nav_path.href]<a href="[nav_path.href]">[end][if-index nav_path last]<span class="thisitem">[end][nav_path.name][if-index nav_path last]</span>[end][if-any nav_path.href]</a>[end][if-index nav_path last][else]<span class="pathdiv">/</span>[end][end][end]
</div>
</div> <!-- vc_header -->
<div id="vc_view_main">

View File

@@ -0,0 +1,53 @@
<form method="get" action="[pathrev_action]" style="display: inline">
<div style="display: inline">
[for pathrev_hidden_values]<input type="hidden" name="[pathrev_hidden_values.name]" value="[pathrev_hidden_values.value]"/>[end]
[is roottype "cvs"]
[define pathrev_selected][pathrev][end]
<select name="pathrev" onchange="submit()">
<option value=""></option>
[if-any branch_tags]
<optgroup label="Branches">
[for branch_tags]
[is branch_tags pathrev]
<option selected>[branch_tags]</option>
[define pathrev_selected][end]
[else]
<option>[branch_tags]</option>
[end]
[end]
</optgroup>
[end]
<optgroup label="Non-branch tags">
[for plain_tags]
[is plain_tags pathrev]
<option selected>[plain_tags]</option>
[define pathrev_selected][end]
[else]
<option>[plain_tags]</option>
[end]
[end]
</optgroup>
[if-any pathrev_selected]
<option selected>[pathrev_selected]</option>
[end]
</select>
[else]
<input type="text" name="pathrev" value="[pathrev]" size="6"/>
[end]
<input type="submit" value="Set Sticky [is roottype "cvs"]Tag[else]Revision[end]" />
</div>
</form>
[if-any pathrev]
<form method="get" action="[pathrev_clear_action]" style="display: inline">
<div style="display: inline">
[for pathrev_clear_hidden_values]<input type="hidden" name="[pathrev_clear_hidden_values.name]" value="[pathrev_clear_hidden_values.value]"/>[end]
[if-any lastrev]
[is pathrev lastrev][else]<input type="submit" value="Set to [lastrev]" />[end]
(<i>Current path doesn't exist after revision <strong>[lastrev]</strong></i>)
[else]
<input type="submit" value="Clear" />
[end]
</div>
</form>
[end]

View File

@@ -0,0 +1,26 @@
[if-any properties]
<hr/>
<div class="vc_properties">
<h2>Properties</h2>
<table cellspacing="2" class="fixed">
<thead>
<tr>
<th class="vc_header_sort" style="width: 200px;">Name</th>
<th class="vc_header">Value</th>
</tr>
</thead>
<tbody>
[for properties]
<tr class="vc_row_[if-index properties even]even[else]odd[end]">
<td><strong>[properties.name]</strong></td>
[if-any properties.undisplayable]
<td><em>Property value is undisplayable.</em></td>
[else]
<td style="white-space: pre;">[properties.value]</td>
[end]
</tr>
[end]
</tbody>
</table>
</div>
[end]

View File

@@ -0,0 +1,247 @@
[# setup page definitions]
[define page_title]Log of:[end]
[define help_href][docroot]/help_log.html[end]
[# end]
[include "include/header.ezt" "log"]
<table class="auto">
[if-any default_branch]
<tr>
<td>Default branch:</td>
<td>[for default_branch]<a href="[default_branch.href]">[default_branch.name]</a>[if-index default_branch last][else], [end]
[end]</td>
</tr>
[end]
[is pathtype "file"]
[if-any view_href]
<tr>
<td>Links to HEAD:</td>
<td>
(<a href="[view_href]">view</a>)
[if-any download_href](<a href="[download_href]">download</a>)[end]
[if-any download_text_href](<a href="[download_text_href]">as text</a>)[end]
[if-any annotate_href](<a href="[annotate_href]">annotate</a>)[end]
</td>
</tr>
[end]
[if-any tag_view_href]
<tr>
<td>Links to [pathrev]:</td>
<td>
(<a href="[tag_view_href]">view</a>)
[if-any tag_download_href](<a href="[tag_download_href]">download</a>)[end]
[if-any tag_download_text_href](<a href="[tag_download_text_href]">as text</a>)[end]
[if-any tag_annotate_href](<a href="[tag_annotate_href]">annotate</a>)[end]
</td>
</tr>
[end]
[end]
<tr>
<td>Sticky [is roottype "cvs"]Tag[else]Revision[end]:</td>
<td>[include "include/pathrev_form.ezt"]</td>
</tr>
[is cfg.options.use_pagesize "0"][else][is picklist_len "1"][else]
<tr>
<td>Jump to page:</td>
<td><form method="get" action="[log_paging_action]">
[for log_paging_hidden_values]<input type="hidden" name="[log_paging_hidden_values.name]" value="[log_paging_hidden_values.value]"/>[end]
<select name="log_pagestart" onchange="submit()">
[for picklist]
[if-any picklist.more]
<option [is picklist.count log_pagestart]selected[end] value="[picklist.count]">Page [picklist.page]: [picklist.start] ...</option>
[else]
<option [is picklist.count log_pagestart]selected[end] value="[picklist.count]">Page [picklist.page]: [picklist.start] - [picklist.end]</option>
[end]
[end]
</select>
<input type="submit" value="Go" />
</form>
</td>
</tr>
[end][end]
<tr>
<td>Sort logs by:</td>
<td><form method="get" action="[logsort_action]">
<div>
<a name="logsort"></a>
[for logsort_hidden_values]<input type="hidden" name="[logsort_hidden_values.name]" value="[logsort_hidden_values.value]"/>[end]
<select name="logsort" onchange="submit()">
<option value="cvs" [is logsort "cvs"]selected="selected"[end]>Not sorted</option>
<option value="date" [is logsort "date"]selected="selected"[end]>Commit date</option>
<option value="rev" [is logsort "rev"]selected="selected"[end]>Revision</option>
</select>
<input type="submit" value=" Sort " />
</div>
</form>
</td>
</tr>
</table>
<div id="vc_main_body">
<!-- ************************************************************** -->
[define first_revision][end]
[define last_revision][end]
[for entries]
[if-index entries first][define first_revision][entries.rev][end][end]
[if-index entries last]
[define last_revision][entries.rev][end]
<div>
[else]
<div style="border-bottom: 1px dotted black">
[end]
[is entries.state "dead"]
Revision <strong>[entries.rev]</strong>
[else]
<a name="rev[entries.rev]"></a>
[for entries.tag_names]<a name="[entries.tag_names]"></a>
[end]
[for entries.branch_names]<a name="[entries.branch_names]"></a>
[end]
Revision [is roottype "svn"]<a href="[entries.revision_href]"><strong>[entries.rev]</strong></a>[else]<strong>[entries.rev]</strong>[end] -
[if-any entries.view_href]
[is pathtype "file"]
(<a href="[entries.view_href]">view</a>)
[else]
<a href="[entries.view_href]">Directory Listing</a>
[end]
[end]
[if-any entries.download_href](<a href="[entries.download_href]">download</a>)[end]
[if-any entries.download_text_href](<a href="[entries.download_text_href]">as text</a>)[end]
[if-any entries.annotate_href](<a href="[entries.annotate_href]">annotate</a>)[end]
[is pathtype "file"]
[# if you don't want to allow select for diffs then remove this section]
[is entries.rev rev_selected]
- <strong>[[]selected]</strong>
[else]
- <a href="[entries.sel_for_diff_href]">[[]select for diffs]</a>
[end]
[end]
[end]
[if-any entries.vendor_branch]
<em>(vendor branch)</em>
[end]
<br />
[is roottype "svn"]
[if-index entries last]Added[else]Modified[end]
[end]
<em>[if-any entries.date][entries.date][else](unknown date)[end]</em>
[if-any entries.ago]([entries.ago] ago)[end]
by <em>[if-any entries.author][entries.author][else](unknown author)[end]</em>
[if-any entries.orig_path]
<br />Original Path: <a href="[entries.orig_href]"><em>[entries.orig_path]</em></a>
[end]
[if-any entries.branches]
<br />Branch:
[for entries.branches]
<a href="[entries.branches.href]"><strong>[entries.branches.name]</strong></a>[if-index entries.branches last][else],[end]
[end]
[end]
[if-any entries.tags]
<br />CVS Tags:
[for entries.tags]
<a href="[entries.tags.href]"><strong>[entries.tags.name]</strong></a>[if-index entries.tags last][else],[end]
[end]
[end]
[if-any entries.branch_points]
<br />Branch point for:
[for entries.branch_points]
<a href="[entries.branch_points.href]"><strong>[entries.branch_points.name]</strong></a>[if-index entries.branch_points last][else],[end]
[end]
[end]
[if-any entries.prev]
[if-any entries.changed]
[is roottype "cvs"]
<br />Changes since <strong>[entries.prev]: [entries.changed] lines</strong>
[end]
[end]
[end]
[if-any entries.lockinfo]
<br />Lock status: [entries.lockinfo]
[end]
[is roottype "svn"]
[if-any entries.size]
<br />File length: [entries.size] byte(s)
[end]
[if-any entries.copy_path]
<br />Copied from: <a href="[entries.copy_href]"><em>[entries.copy_path]</em></a> revision [entries.copy_rev]
[end]
[end]
[is entries.state "dead"]
<br /><strong><em>FILE REMOVED</em></strong>
[else]
[is pathtype "file"]
[if-any entries.prev]
<br />Diff to <a href="[entries.diff_to_prev_href]">previous [entries.prev]</a>
[if-any human_readable]
[else]
(<a href="[entries.diff_to_prev_href]&amp;diff_format=h">colored</a>)
[end]
[end]
[is roottype "cvs"]
[if-any entries.branch_point]
, to <a href="[entries.diff_to_branch_href]">branch point [entries.branch_point]</a>
[if-any human_readable]
[else]
(<a href="[entries.diff_to_branch_href]&amp;diff_format=h">colored</a>)
[end]
[end]
[if-any entries.next_main]
, to <a href="[entries.diff_to_main_href]">next main [entries.next_main]</a>
[if-any human_readable]
[else]
(<a href="[entries.diff_to_main_href]&amp;diff_format=h">colored</a>)
[end]
[end]
[end]
[if-any entries.diff_to_sel_href]
[if-any entries.prev], [else]<br />Diff[end]
to <a href="[entries.diff_to_sel_href]">selected [rev_selected]</a>
[if-any human_readable]
[else]
(<a href="[entries.diff_to_sel_href]&amp;diff_format=h">colored</a>)
[end]
[end]
[end]
[end]
<pre class="vc_log">[entries.log]</pre>
</div>
[end]
<!-- ************************************************************** -->
</div>
[is pathtype "file"]
[include "include/diff_form.ezt"]
[end]
[include "include/footer.ezt"]

View File

@@ -0,0 +1,18 @@
[# setup page definitions]
[define page_title]View of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "markup"]
[include "include/fileview.ezt"]
<div id="vc_main_body">
<!-- ************************************************************** -->
<div id="vc_markup"><pre>[markup]</pre></div>
[include "include/props.ezt"]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,241 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- ViewVC :: http://www.viewvc.org/ -->
<head>
<title>Checkin Database Query</title>
<link rel="stylesheet" href="[docroot]/styles.css" type="text/css" />
</head>
<body>
[# setup page definitions]
[define help_href][docroot]/help_query.html[end]
[# end]
<p>
Select your parameters for querying the CVS commit database. You
can search for multiple matches by typing a comma-seperated list
into the text fields. Regular expressions, and wildcards are also
supported. Blank text input fields are treated as wildcards.
</p>
<p>
Any of the text entry fields can take a comma-seperated list of
search arguments. For example, to search for all commits from
authors <em>jpaint</em> and <em>gstein</em>, just type: <strong>jpaint,
gstein</strong> in the <em>Author</em> input box. If you are searching
for items containing spaces or quotes, you will need to quote your
request. For example, the same search above with quotes is:
<strong>"jpaint", "gstein"</strong>.
</p>
<p>
Wildcard and regular expression searches are entered in a similar
way to the quoted requests. You must quote any wildcard or
regular expression request, and a command charactor preceeds the
first quote. The command charactor <strong>l</strong> is for wildcard
searches, and the wildcard charactor is a percent (<strong>%</strong>). The
command charactor for regular expressions is <strong>r</strong>, and is
passed directly to MySQL, so you'll need to refer to the MySQL
manual for the exact regex syntax. It is very similar to Perl. A
wildard search for all files with a <em>.py</em> extention is:
<strong>l"%.py"</strong> in the <em>File</em> input box. The same search done
with a regular expression is: <strong>r".*\.py"</strong>.
</p>
<p>
All search types can be mixed, as long as they are seperated by
commas.
</p>
<form method="get" action="">
<div class="vc_query_form">
<table cellspacing="0" cellpadding="2" class="auto">
<tr>
<td>
<table>
<tr>
<td style="vertical-align:top;">
<table>
<tr>
<td align="right">CVS Repository:</td>
<td>
<input type="text" name="repository" size="40" value="[repository]" />
</td>
</tr>
<tr>
<td align="right">CVS Branch:</td>
<td>
<input type="text" name="branch" size="40" value="[branch]" />
</td>
</tr>
<tr>
<td align="right">Directory:</td>
<td>
<input type="text" name="directory" size="40" value="[directory]" />
</td>
</tr>
<tr>
<td align="right">File:</td>
<td>
<input type="text" name="file" size="40" value="[file]" />
</td>
</tr>
<tr>
<td align="right">Author:</td>
<td>
<input type="text" name="who" size="40" value="[who]" />
</td>
</tr>
</table>
</td>
<td style="vertical-align:top;">
<table>
<tr>
<td align="left">Sort By:</td>
<td>
<select name="sortby">
<option value="date" [is sortby "date"]selected="selected"[end]>Date</option>
<option value="author" [is sortby "author"]selected="selected"[end]>Author</option>
<option value="file" [is sortby "file"]selected="selected"[end]>File</option>
</select>
</td>
</tr>
<tr>
<td colspan="2">
<table cellspacing="0" cellpadding="0">
<tr>
<td>Date:</td>
</tr>
<tr>
<td><input type="radio" name="date" value="hours"
[is date "hours"]checked="checked"[end] /></td>
<td>In the last
<input type="text" name="hours" value="[hours]" size="4" />hours
</td>
</tr>
<tr>
<td><input type="radio" name="date" value="day"
[is date "day"]checked="checked"[end] /></td>
<td>In the last day</td>
</tr>
<tr>
<td><input type="radio" name="date" value="week"
[is date "week"]checked="checked"[end] /></td>
<td>In the last week</td>
</tr>
<tr>
<td><input type="radio" name="date" value="month"
[is date "month"]checked="checked"[end] /></td>
<td>In the last month</td>
</tr>
<tr>
<td><input type="radio" name="date" value="all"
[is date "all"]checked="checked"[end] /></td>
<td>Since the beginning of time</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td>
<input type="submit" value="Search" />
</td>
</tr>
</table>
</div>
</form>
[is query "skipped"]
[else]
<p><strong>[num_commits]</strong> matches found.</p>
[if-any commits]
<table cellspacing="0" cellpadding="2">
<thead>
<tr class="vc_header">
<th>Revision</th>
<th>File</th>
<th>Branch</th>
<th>+/-</th>
<th>Date</th>
<th>Author</th>
[# uncommment, if you want a separate Description column: (also see below)
<th>Description</th>
]
</tr>
</thead>
[for commits]
<tbody>
[for commits.files]
<tr class="vc_row_[if-index commits even]even[else]odd[end]">
<td style="vertical-align:top;">
[if-any commits.files.rev][commits.files.rev][else]&nbsp;[end]
</td>
<td style="vertical-align:top;">[commits.files.link]</td>
<td style="vertical-align:top;">
[if-any commits.files.branch][commits.files.branch][else]&nbsp;[end]
</td>
<td style="vertical-align:top;">
[is commits.files.type "Add"]<ins>[end]
[is commits.files.type "Change"]<a href="[commits.files.difflink]">[end]
[is commits.files.type "Remove"]<del>[end]
[commits.files.plus]/[commits.files.minus]
[is commits.files.type "Add"]</ins>[end]
[is commits.files.type "Change"]</a>[end]
[is commits.files.type "Remove"]</del>[end]
</td>
<td style="vertical-align:top;">
[if-any commits.files.date][commits.files.date][else]&nbsp;[end]
</td>
<td style="vertical-align:top;">
[if-any commits.files.author][commits.files.author][else]&nbsp;[end]
</td>
[# uncommment, if you want a separate Description column:
{if-index commits.files first{
<td style="vertical-align:top;" rowspan="{commits.num_files}">
{commits.log}
</td>
{end}
(substitute brackets for the braces)
]
</tr>
[# and also take the following out in the "Description column"-case:]
[if-index commits.files last]
<tr class="vc_row_[if-index commits even]even[else]odd[end]">
<td>&nbsp;</td>
<td colspan="5"><strong>Log:</strong><br />
<pre class="vc_log">[commits.log]</pre></td>
</tr>
[end]
[# ---]
[end]
</tbody>
[end]
<tr class="vc_header">
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
[# uncommment, if you want a separate Description column:
<th style="text-align:left;vertical-align:top;">&nbsp;</th>
]
</tr>
</table>
[end]
[end]
[include "include/footer.ezt"]

View File

@@ -0,0 +1,202 @@
[# setup page definitions]
[define page_title]Query on:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "query"]
<form action="[query_action]" method="get">
<div class="vc_query_form">
[for query_hidden_values]<input type="hidden" name="[query_hidden_values.name]" value="[query_hidden_values.value]"/>[end]
<table cellspacing="0" cellpadding="5" class="auto">
[is roottype "svn"]
[# For subversion, the branch field is not used ]
[else]
<tr>
<th style="text-align:right;vertical-align:top;">Branch:</th>
<td>
<input type="text" name="branch" value="[branch]" />
<label for="branch_match_exact">
<input type="radio" name="branch_match" id="branch_match_exact"
value="exact" [is branch_match "exact"]checked="checked"[end] />
exact
</label>
<label for="branch_match_glob">
<input type="radio" name="branch_match" id="branch_match_glob"
value="glob" [is branch_match "glob"]checked="checked"[end] />
glob pattern
</label>
<label for="branch_match_regex">
<input type="radio" name="branch_match" id="branch_match_regex"
value="regex" [is branch_match "regex"]checked="checked"[end] />
regex
</label>
<label for="branch_match_notregex">
<input type="radio" name="branch_match" id="branch_match_notregex"
value="notregex" [is branch_match "notregex"]checked="checked"[end] />
<em>not</em> regex
</label>
</td>
</tr>
[end]
<tr>
<th style="text-align:right;vertical-align:top;">Subdirectory:</th>
<td>
<input type="text" name="dir" value="[dir]" />
<em>(You can list multiple directories separated by commas.)</em>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">File:</th>
<td>
<input type="text" name="file" value="[file]" />
<label for="file_match_exact">
<input type="radio" name="file_match" id="file_match_exact"
value="exact" [is file_match "exact"]checked="checked"[end] />
exact
</label>
<label for="file_match_glob">
<input type="radio" name="file_match" id="file_match_glob"
value="glob" [is file_match "glob"]checked="checked"[end] />
glob pattern
</label>
<label for="file_match_regex">
<input type="radio" name="file_match" id="file_match_regex"
value="regex" [is file_match "regex"]checked="checked"[end] />
regex
</label>
<label for="file_match_notregex">
<input type="radio" name="file_match" id="file_match_notregex"
value="notregex" [is file_match "notregex"]checked="checked"[end] />
<em>not</em> regex
</label>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Who:</th>
<td>
<input type="text" name="who" value="[who]" />
<label for="who_match_exact">
<input type="radio" name="who_match" id="who_match_exact"
value="exact" [is who_match "exact"]checked="checked"[end] />
exact
</label>
<label for="who_match_glob">
<input type="radio" name="who_match" id="who_match_glob"
value="glob" [is who_match "glob"]checked="checked"[end] />
glob pattern
</label>
<label for="who_match_regex">
<input type="radio" name="who_match" id="who_match_regex"
value="regex" [is who_match "regex"]checked="checked"[end] />
regex
</label>
<label for="who_match_notregex">
<input type="radio" name="who_match" id="who_match_notregex"
value="notregex" [is who_match "notregex"]checked="checked"[end] />
<em>not</em> regex
</label>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Comment:</th>
<td>
<input type="text" name="comment" value="[comment]" />
<label for="comment_match_exact">
<input type="radio" name="comment_match" id="comment_match_exact"
value="exact" [is comment_match "exact"]checked=""[end] />
exact
</label>
<label for="comment_match_glob">
<input type="radio" name="comment_match" id="comment_match_glob"
value="glob" [is comment_match "glob"]checked=""[end] />
glob pattern
</label>
<label for="comment_match_regex">
<input type="radio" name="comment_match" id="comment_match_regex"
value="regex" [is comment_match "regex"]checked=""[end] />
regex
</label>
<label for="comment_match_notregex">
<input type="radio" name="comment_match" id="comment_match_notregex"
value="notregex" [is comment_match "notregex"]checked=""[end] />
<em>not</em> regex
</label>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Sort By:</th>
<td>
<select name="querysort">
<option value="date" [is querysort "date"]selected="selected"[end]>Date</option>
<option value="author" [is querysort "author"]selected="selected"[end]>Author</option>
<option value="file" [is querysort "file"]selected="selected"[end]>File</option>
</select>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Date:</th>
<td>
<table cellspacing="0" cellpadding="0">
<tr>
<td><input type="radio" name="date" id="date_hours"
value="hours" [is date "hours"]checked="checked"[end] /></td>
<td>
<label for="date_hours">In the last</label>
<input type="text" name="hours" value="[hours]" size="4" />
hours
</td>
</tr>
<tr>
<td><input type="radio" name="date" id="date_day"
value="day" [is date "day"]checked="checked"[end] /></td>
<td><label for="date_day">In the last day</label></td>
</tr>
<tr>
<td><input type="radio" name="date" id="date_week"
value="week" [is date "week"]checked="checked"[end] /></td>
<td><label for="date_week">In the last week</label></td>
</tr>
<tr>
<td><input type="radio" name="date" id="date_month"
value="month" [is date "month"]checked="checked"[end] /></td>
<td><label for="date_month">In the last month</label></td>
</tr>
<tr>
<td><input type="radio" name="date" id="date_all"
value="all" [is date "all"]checked="checked"[end] /></td>
<td><label for="date_all">Since the beginning of time</label></td>
</tr>
<tr>
<td><input type="radio" name="date" id="date_explicit"
value="explicit" [is date "explicit"]checked="checked"[end] /></td>
<td>
<label for="date_explicit">Between</label>
<input type="text" name="mindate" value="[mindate]" size="20" />
and
<input type="text" name="maxdate" value="[maxdate]" size="20" />
<br />
(use the form <strong>yyyy-mm-dd hh:mm:ss</strong>)
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th style="text-align:right;vertical-align:top;">Limit:</th>
<td>
Show at most
<input type="text" name="limit_changes" value="[limit_changes]" size="5" />
changed files per commit. <em>(Use 0 to show all files.)</em>
</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Search" /></td>
</tr>
</table>
</div>
</form>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,86 @@
[# setup page definitions]
[define page_title]Query results in:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt"]
<p><strong>[english_query]</strong></p>
[# <!-- {sql} --> ]
<p><a href="[queryform_href]">Modify query</a></p>
<p><a href="[backout_href]">Show commands which could be used to back out these changes</a></p>
<p><strong>+[plus_count]/-[minus_count]</strong> lines changed.</p>
[if-any commits]
<table cellspacing="1" cellpadding="2">
<thead>
<tr>
<th class="vc_header">Revision</th>
<th class="vc_header[is querysort "file"]_sort[end]">File</th>
[if-any show_branch]
<th class="vc_header">Branch</th>
[end]
<th class="vc_header">+/-</th>
<th class="vc_header[is querysort "date"]_sort[end]">Date</th>
<th class="vc_header[is querysort "author"]_sort[end]">Author</th>
[# uncommment, if you want a separate Description column: (also see below)
<th class="vc_header">Description</th>
]
</tr>
</thead>
[for commits]
[for commits.files]
<tbody>
<tr class="vc_row_[if-index commits even]even[else]odd[end]">
<td style="vertical-align: top;">
[define rev_href][if-any commits.files.prefer_markup][commits.files.view_href][else][if-any commits.files.download_href][commits.files.download_href][end][end][end]
[if-any commits.files.rev][if-any rev_href]<a href="[rev_href]">[end][commits.files.rev][if-any rev_href]</a>[end][else]&nbsp;[end]
</td>
<td style="vertical-align: top;">
<a href="[commits.files.dir_href]">[commits.files.dir]/</a>
<a href="[commits.files.log_href]">[commits.files.file]</a>
</td>
[if-any show_branch]
<td style="vertical-align: top;">
[if-any commits.files.branch][commits.files.branch][else]&nbsp;[end]
</td>
[end]
<td style="vertical-align: top;">
[# only show a diff link for changes ]
[is commits.files.type "Add"]<ins>[end]
[is commits.files.type "Change"]<a href="[commits.files.diff_href]">[end]
[is commits.files.type "Remove"]<del>[end]
[commits.files.plus]/[commits.files.minus]
[is commits.files.type "Add"]</ins>[end]
[is commits.files.type "Change"]</a>[end]
[is commits.files.type "Remove"]</del>[end]
</td>
<td style="vertical-align: top;">
[if-any commits.files.date][commits.files.date][else]&nbsp;[end]
</td>
<td style="vertical-align: top;">
[if-any commits.files.author][commits.files.author][else]&nbsp;[end]
</td>
</tr>
[end]
[if-any commits.limited_files]
<tr class="vc_row_[if-index commits even]even[else]odd[end]">
<td>&nbsp;</td>
<td colspan="5">
<strong><em><small>Only first [commits.num_files] files shown.
<a href="[limit_changes_href]">Show all files</a> or
<a href="[queryform_href]">adjust limit</a>.</small></em></strong>
</tr>
[end]
<tr class="vc_row_[if-index commits even]even[else]odd[end]">
<td>&nbsp;</td>
<td colspan="5"><strong>Log:</strong><br />
<pre class="vc_log">[commits.log]</pre></td>
</tr>
</tbody>
[end]
</table>
[end]
[include "include/footer.ezt"]

View File

@@ -0,0 +1,83 @@
[# setup page definitions]
[define page_title]Revision [rev] of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "revision"]
<form method="get" action="[jump_rev_action]">
<table cellspacing="1" cellpadding="2" style="width: auto;">
<tr align="left">
<th>Jump to revision:</th>
<td>
[for jump_rev_hidden_values]<input type="hidden" name="[jump_rev_hidden_values.name]" value="[jump_rev_hidden_values.value]"/>[end]
<input type="text" name="revision" value="[rev]" />
<input type="submit" value="Go" />
[if-any prev_href]
<a href="[prev_href]" title="Previous Revision"><img src="[docroot]/images/back.png" alt="Previous" width="20" height="22" /></a>[end]
[if-any next_href] <a href="[next_href]" title="Next Revision"><img src="[docroot]/images/forward.png" width="20" height="22" alt="Next" /></a>[end]
</td>
</tr>
<tr align="left">
<th>Author:</th>
<td>[if-any author][author][else]<em>(unknown author)</em>[end]</td>
</tr>
<tr align="left">
<th>Date:</th>
<td>[if-any date][date][else]<em>(unknown date)</em>[end]
[if-any ago]<em>([ago] ago)</em>[end]</td>
</tr>
<tr align="left">
<th>Log Message:</th>
<td><pre class="vc_log">[log]</pre></td>
</tr>
</table>
</form>
<div id="vc_main_body">
<!-- ************************************************************** -->
<p><strong>Changed paths:</strong></p>
[if-any more_changes]
<div>
Only [limit_changes] changes shown,
<a href="[more_changes_href]">display [more_changes] more changes...</a>
</div>
[end]
[if-any first_changes]
<div><a href="[first_changes_href]">Show only first [first_changes] changes...</div>
[end]
<table cellspacing="1" cellpadding="2">
<thead>
<tr align="left">
<th class="vc_header_sort">Path</th>
<th class="vc_header">Details</th>
</tr>
</thead>
<tbody>
[if-any changes]
[for changes]
<tr class="vc_row_[if-index changes even]even[else]odd[end]">
<td>[if-any changes.view_href]<a href="[changes.view_href]" title="View [is changes.pathtype "dir"]Directory[else]File[end] Contents">[end]<img src="[docroot]/images/[is changes.pathtype "dir"]dir[else]text[end].png" class="vc_icon" alt="Directory" />[changes.path][is changes.pathtype "dir"]/[end][if-any changes.view_href]</a>[end]
[if-any changes.is_copy]<br /><em>(Copied from [changes.copy_path], r[changes.copy_rev])</em>[end]
</td>
<td>[if-any changes.log_href]<a href="[changes.log_href]" title="View Log">[end][changes.action][if-any changes.log_href]</a>[end]
[if-any changes.text_mods], [if-any changes.diff_href]<a href="[changes.diff_href]" title="View Diff">[end]text changed[if-any changes.diff_href]</a>[end][end]
[if-any changes.prop_mods], props changed[end]
</td>
</tr>
[end]
[else]
<tr>
<td colspan="5">No changed paths.</td>
</tr>
[end]
</tbody>
</table>
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,33 @@
[# setup page definitions]
[define page_title]Repository Listing[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "directory"]
<div id="vc_main_body">
<!-- ************************************************************** -->
<table cellspacing="1" id="dirlist">
<thead>
<tr>
<th class="vc_header_sort">Name</th>
</tr>
</thead>
<tbody>
[if-any roots]
[for roots]
<tr class="vc_row_[if-index roots even]even[else]odd[end]">
<td onclick="jumpTo('[roots.href]')"><a href="[roots.href]"><img src="[docroot]/images/[roots.type]-logo.png" alt="" class="vc_icon" />[roots.name]</a></td>
</tr>
[end]
[end]
</tbody>
</table>
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<link>[rss_link_href]</link>
<title>[rootname] checkins[if-any where] (in [where])[end]</title>
<description>[is roottype "svn"]Subversion[else]CVS[end] commits to the[if-any where] [where] directory of the[end] [rootname] repository</description>
[for commits]<item>
<title>[if-any commits.rev][commits.rev]: [end][[commits.author]] [commits.short_log]</title>
[if-any commits.rss_url]<link>[commits.rss_url]</link>[end]
<author>[commits.author]</author>
<pubDate>[if-any commits.rss_date][commits.rss_date][else](unknown date)[end]</pubDate>
<description>&lt;pre&gt;[format "xml"][commits.log][end]&lt;/pre&gt;</description>
</item>[end]
</channel>
</rss>

View File

@@ -0,0 +1,8 @@
Template Set: tabbed
Author(s): C. Michael Pilato <cmpilato@red-bean.com>,
Russell Yanofsky <russ@yanofsky.org>
Compatibility: ViewVC 1.1
The "tabbed" template set uses top navigation tabs to flip between
various views of a file or directory.

View File

@@ -0,0 +1,46 @@
[# setup page definitions]
[define page_title]Annotation of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "annotate"]
[include "include/fileview.ezt"]
<div id="vc_main_body">
<!-- ************************************************************** -->
[define last_rev]0[end]
[define rowclass]vc_row_odd[end]
<table class="fixed" cellspacing="0" cellpadding="0">
<tr>
<th class="vc_header" style="text-align: center; width: 5em;">Line</th>
<th class="vc_header" style="text-align: center; width: 8em;">User</th>
<th class="vc_header" style="text-align: center; width: 5em;">Rev</th>
<th class="vc_header" style="text-align: left;">File contents</th>
</tr>
[for lines]
[is lines.rev last_rev]
[else]
[is rowclass "vc_row_even"]
[define rowclass]vc_row_odd[end]
[else]
[define rowclass]vc_row_even[end]
[end]
[end]
<tr class="[rowclass]">
<td id="l[lines.line_number]" class="vc_blame_metadata">[lines.line_number]</td>
<td class="vc_blame_metadata">[is lines.rev last_rev]&nbsp;[else][lines.author][end]</td>
<td class="vc_blame_metadata">[is lines.rev last_rev]&nbsp;[else][if-any lines.diff_url]<a href="[lines.diff_url]">[end][lines.rev][if-any lines.diff_url]</a>[end][end]</td>
<td class="vc_blame_textdata" style="background: [is rowclass "vc_row_even"]white[else]rgb(95%,95%,95%)[end];">[lines.text]</td>
</tr>
[define last_rev][lines.rev][end]
[end]
</table>
[include "include/props.ezt"]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,128 @@
[# Setup page definitions]
[define page_title]Diff of:[end]
[define help_href][docroot]/help_rootview.html[end]
[# end]
[include "include/header.ezt" "diff"]
<form method="get" action="[diff_format_action]" style="display: inline;">
<div>
[for diff_format_hidden_values]<input type="hidden" name="[diff_format_hidden_values.name]" value="[diff_format_hidden_values.value]"/>[end]
<select name="diff_format" onchange="submit()">
<option value="h" [is diff_format "h"]selected="selected"[end]>Colored Diff</option>
<option value="l" [is diff_format "l"]selected="selected"[end]>Long Colored Diff</option>
<option value="f" [is diff_format "f"]selected="selected"[end]>Full Colored Diff</option>
<option value="u" [is diff_format "u"]selected="selected"[end]>Unidiff</option>
<option value="c" [is diff_format "c"]selected="selected"[end]>Context Diff</option>
<option value="s" [is diff_format "s"]selected="selected"[end]>Side by Side</option>
</select>
<input type="submit" value="Show" />
(<a href="[patch_href]">Generate patch</a>)
</div>
</form>
<div id="vc_main_body">
<!-- ************************************************************** -->
[if-any raw_diff]
<pre>[raw_diff]</pre>
[else]
[define change_right][end]
[define last_change_type][end]
[# these should live in stylesheets]
<table cellpadding="0" cellspacing="0" style="width: 100%;">
[for changes]
[is changes.type "change"][else]
[if-any change_right][change_right][define change_right][end][end]
[end]
[is changes.type "header"]
<tr>
<th class="vc_header" style="width:6%;"><strong>#</strong></th>
<th colspan="2" class="vc_header">
<strong>Line [changes.line_info_left]</strong> |
<strong>Line [changes.line_info_right]</strong>
</th>
</tr>
[else]
[is changes.type "add"]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus"><strong style="color: green;">+</strong></td>
<td class="vc_diff_add">[changes.right]</td>
</tr>
[else]
[is changes.type "remove"]
<tr>
<td style="text-decoration: line-through">[changes.line_number]</td>
<td class="vc_diff_plusminus"><strong style="color: red;">&ndash;</strong></td>
<td class="vc_diff_remove">[changes.left]</td>
</tr>
[else]
[is changes.type "change"]
[if-any changes.have_left]
<tr>
<td style="text-decoration: line-through">[changes.line_number]</td>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&lt;</strong></td>
<td class="vc_diff_changes1">[changes.left]</td>
</tr>
[end]
[define change_right][change_right]
[if-any changes.have_right]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&gt;</strong></td>
<td class="vc_diff_changes2">[changes.right]</td>
</tr>[end]
[end]
[else]
[is changes.type "no-changes"]
<tr><td colspan="3" style="vc_diff_nochange"><strong>- No changes -</strong></td></tr>
[else]
[is changes.type "binary-diff"]
<tr><td colspan="3" class="vc_diff_binary"><strong>- Binary file revisions differ -</strong></td></tr>
[else]
[is changes.type "error"]
<tr><td colspan="3" class="vc_diff_error"><strong>- ViewVC depends on rcsdiff and GNU diff
to create this page. ViewVC cannot find GNU diff. Even if you
have GNU diff installed, the rcsdiff program must be configured
and compiled with the GNU diff location. -</strong></td></tr>
[else][# a line of context]
<tr>
<td id="l[changes.line_number]">[if-any right.annotate_href]<a href="[right.annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
<td class="vc_diff_plusminus">&nbsp;</td>
<td style="font-family: monospace; white-space: pre;">[changes.right]</td>
</tr>
[end][end][end][end][end][end][end]
[define last_change_type][changes.type][end]
[end]
[if-any change_right][change_right][end]
</table>
<h3>Diff Legend</h3>
<table class="auto" cellspacing="0">
<tr>
<td class="vc_diff_plusminus"><strong style="color: red;">&ndash;</strong></td>
<td class="vc_diff_remove">Removed lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: green;">+</strong></td>
<td class="vc_diff_add">Added lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&lt;</strong></td>
<td class="vc_diff_changes1">Changed lines</td>
</tr>
<tr>
<td class="vc_diff_plusminus"><strong style="color: yellow;">&gt;</strong></td>
<td class="vc_diff_changes2">Changed lines</td>
</tr>
</table>
[end]
<!-- ************************************************************** -->
</div>
[include "include/footer.ezt"]

View File

@@ -0,0 +1,132 @@
[include "include/dir_header.ezt"]
<table cellspacing="1" cellpadding="2" class="fixed" id="dirlist">
<thead>
<tr>
<th style="width: 200px" class="vc_header[is sortby "file"]_sort[end]">
<a href="[sortby_file_href]#dirlist">File
[is sortby "file"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end]
</a>
</th>
<th style="width: 96px" class="vc_header"></th>
<th class="vc_header[is sortby "rev"]_sort[end]">
<a href="[sortby_rev_href]#dirlist">Last Change
[is sortby "rev"]
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
width="13" height="13"
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
[end]
</a>
</th>
</tr>
</thead>
<tbody>
[if-any up_href]
<tr class="vc_row_odd">
<td style="width: 200px">
<a href="[up_href]">
<img src="[docroot]/images/back_small.png" alt="" class="vc_icon"
/>&nbsp;Parent&nbsp;Directory</a>
</td>
<td style="width: 96px; font-size: 0;"></td>
<td>&nbsp;</td>
</tr>
[end]
[for entries]
<tr class="vc_row_[if-index entries even]even[else]odd[end]">
<td style="width: 200px">
<a name="[entries.anchor]" href="[is entries.pathtype "dir"][entries.view_href][else][if-any entries.prefer_markup][entries.view_href][else][entries.download_href][end][end]" title="[is entries.pathtype "dir"]View Directory Contents[else][if-any entries.prefer_markup]View[else]Download[end] File Contents[end]">
<img src="[docroot]/images/[is entries.pathtype "dir"]dir[else][is entries.state "dead"]broken[else]text[end][end].png" alt="" class="vc_icon" />
[entries.name][is entries.pathtype "dir"]/[end]</a>
[is entries.state "dead"](dead)[end]
</td>
[if-any entries.errors]
<td colspan="2">[for entries.errors]<em>[entries.errors]</em>[end]</td>
[else]
[define view_icon_link][end]
[define graph_icon_link][end]
[define download_icon_link][end]
[define annotate_icon_link][end]
[define log_icon_link][if-any entries.log_href]<a
href="[entries.log_href]"
title="View Log"><img
src="[docroot]/images/log.png"
alt="View Log"
class="vc_icon" /></a>[end][end]
[is entries.pathtype "dir"]
[is roottype "cvs"]
[# no point in showing icon when there's only one to choose from]
[else]
[define view_icon_link]<a
href="[entries.view_href]"
title="View Directory Listing"><img
src="[docroot]/images/list.png"
alt="View Directory Listing"
class="vc_icon" /></a>[end]
[end]
[end]
[is entries.pathtype "file"]
[define view_icon_link][if-any entries.view_href]<a
href="[entries.view_href]"
title="View File"><img
src="[docroot]/images/view.png"
alt="View File"
class="vc_icon" /></a>[end][end]
[define graph_icon_link][if-any entries.graph_href]<a
href="[entries.graph_href]"
title="View Revision Graph"><img
src="[docroot]/images/cvsgraph_16x16.png"
alt="View Revision Graph"
class="vc_icon" /></a>[end][end]
[define download_icon_link][if-any entries.download_href]<a
href="[entries.download_href]"
title="Download File"><img
src="[docroot]/images/download.png"
alt="Download File"
class="vc_icon" /></a>[end][end]
[define annotate_icon_link][if-any entries.annotate_href]<a
href="[entries.annotate_href]"
title="Annotate File"><img
src="[docroot]/images/annotate.png"
alt="Annotate File"
class="vc_icon" /></a>[end][end]
[end]
<td style="width: 96px"
>[# Icon column. We might want to add more icons like a tarball
# icon for directories or a diff to previous icon for files.
# Make sure this sucker has no whitespace in it, or the fixed
# widthness of will suffer for large font sizes
][log_icon_link][view_icon_link][graph_icon_link][download_icon_link][annotate_icon_link]</td>
<td>
[if-any entries.rev]
<strong>[if-any entries.revision_href]<a href="[entries.revision_href]" title="Revision [entries.rev]">[entries.rev]</a>[else][entries.rev][end]</strong>
([entries.ago] ago)
by <em>[entries.author]</em>:
[entries.log]
[is entries.pathtype "dir"][is roottype "cvs"]
<em>(from [entries.log_file]/[entries.log_rev])</em>
[end][end]
[end]
</td>
[end]
</tr>
[end]
</tbody>
</table>
[include "include/props.ezt"]
[include "include/dir_footer.ezt"]

View File

@@ -0,0 +1,14 @@
/************************************/
/*** ViewVC Help CSS Stylesheet ***/
/************************************/
/*** Standard Tags ***/
body {
margin: 0.5em;
}
img { border: none; }
table { width: 100%; }
td { vertical-align: top; }
col.menu { width:12em; }

View File

@@ -0,0 +1,130 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Directory View</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td><a href="http://viewvc.org/index.html"><img
src="images/logo.png" alt="ViewVC logotype" /></a>
</td>
<td>
<h1>ViewVC Help: Directory View</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<a href="help_rootview.html">General</a><br />
<strong>Directory&nbsp;View</strong><br />
<a href="help_log.html">Log&nbsp;View</a><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>The directory listing view should be a familiar sight to any
computer user. It shows the path of the current directory being viewed
at the top of the page. Below that is a table summarizing the
directory contents, and then comes actual contents, a sortable list of
all files and subdirectories inside the current directory.</p>
<p><a name="summary"></a>The summary table is made up of some or all
of the following rows:</p>
<ul>
<li><a name="summary-files-shown"><strong>Files Shown</strong></a>
- Number of files shown in the directory listing. This might be less
than the actual number of files in the directory if a
<a href="#option-search">regular expression search</a> is in place,
hiding files which don't meet the search criteria. In CVS directory
listings, this row will also have a link to toggle display of
<a href="help_rootview.html#dead-files">dead files</a>, if any are
present.</li>
<li><a name="summary-revision"><strong>Directory
Revision</strong></a> - For Subversion directories only.
Shown as "# of #" where the first number is the most recent
repository revision where the directory (or a path underneath it)
was modified. The second number is just the latest repository
revision. Both numbers are links to
<a href="help_rootview.html#view-rev">revision views</a></li>
<li><a name="summary-sticky-revision-tag"><strong>Sticky
Revision/Tag</strong></a> - shows the current
<a href="help_rootview.html#sticky-revision-tag">sticky revision or
tag</a> and contains form fields to set or clear it.</li>
<li><a name="summary-search"><strong>Current Search</strong></a> -
If a <a href="#option-search">regular expression search</a> is in place,
shows the search string.</li>
<li><a name="summary-query"><strong>Query</strong></a> - Provides
a link to a <a href="help_rootview.html#view-query">query form</a>
for the directory</li>
</ul>
<p><a name="list"></a>The actual directory list is a table with
filenames and directory names in one column and information about the
most recent revisions where each file or directory was modified in the
other columns. Column headers can be clicked to sort the directory
entries in order by a column, and clicked again to reverse the sort
order.</p>
<p>
<!-- If using directory.ezt template -->
File names are links to <a href="help_log.html">log views</a>
showing a list of revisions where a file was modified. Revision
numbers are links to either
<a href="help_rootview.html#view-markup">view</a>
or <a href="help_rootview.html#view-checkout">download</a> a file
(depending on its file type). The links are reversed for directories.
Directory revision numbers are links to <a href="help_log.html">log
views</a>, while directory names are links showing the contents of those
directories.
<!-- If using dir_alt.ezt template -->
<!--
File and directory names are links to retrieve their contents.
File links may be either
<a href="help_rootview.html#view-markup">view</a>
or <a href="help_rootview.html#view-download">download</a> links
depending on the file type. Directory links go to directory
listings. Revision numbers are links to <a href="help_log.html">log
views</a> showing lists of revisions where a file or directory was
modified.
-->
Also, in CVS repositories with the
<a href="help_rootview.html#view-graph">graph view</a> enabled, there
will be small
<img src="images/cvsgraph_16x16.png" width="16" height="16" alt="graph">
icons next to file names which are links to revision graphs.</p>
<p>Depending on how ViewVC is configured, there may be more options
at the bottom of directory pages:</p>
<ul>
<li><a name="option-search"><strong>Regular expression
search</strong></a> - If enabled, will show a form field accepting
a search string (a
<a href="http://doc.python.org/lib/re-syntax.html">python regular
expression</a>). Once submitted, only files that have at least
one occurance of the expression will show up in directory listings.
</li>
<li><a name="option-tarball"><strong>Tarball download</strong></a> -
If enabled, will show a link to download a gzipped tar archive of
the directory contents.</li>
</ul>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Log View</title>
<link rel="stylesheet" href="help.css" type="text/css" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td><a href="http://viewvc.org/index.html"><img
src="images/logo.png" alt="ViewVC logotype" /></a>
</td>
<td>
<h1>ViewVC Help: Log View</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<a href="help_rootview.html">General</a><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<strong>Log&nbsp;View</strong><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>
The log view displays the revision history of the selected source
file or directory. For each revision the following information is
displayed:
<ul>
<li>The revision number. In Subversion repositories, this is a
link to the <a href="help_rootview.html#view-rev">revision
view</a></li>
<li>For files, links to
<a href="help_rootview.html#view-markup">view</a>,
<a href="help_rootview.html#view-checkout">download</a>, and
<a href="help_rootview.html#view-annotate">annotate</a> the
revision. For directories, a link to
<a href="help_dirview.html">list directory contents</a></li>
<li>A link to select the revision for diffs (see below)</li>
<li>The date and age of the change</li>
<li>The author of the modification</li>
<li>The CVS branch (usually <em>MAIN</em>, if not on a branch)</li>
<li>Possibly a list of CVS tags bound to the revision (if any)</li>
<li>The size of the change measured in added and removed lines of
code. (CVS only)</li>
<li>The size of the file in bytes at the time of the revision
(Subversion only)</li>
<li>Links to view diffs to the previous revision or possibly to
an arbitrary selected revision (if any, see above)</li>
<li>If the revision is the result of a copy, the path and revision
copied from</li>
<li>If the revision precedes a copy or rename, the path at the
time of the revision</li>
<li>And last but not least, the commit log message which should tell
about the reason for the change.</li>
</ul>
<p>
At the bottom of the page you will find a form which allows
to request diffs between arbitrary revisions.
</p>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

View File

@@ -0,0 +1,67 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: Query The Commit Database</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td><a href=".."><img
src="images/logo.png" alt="ViewVC logotype" /></a>
</td>
<td><h1>ViewVC Help: Query The Commit Database</h1></td>
</tr>
<tr><td>
<h3>Other&nbsp;Help:</h3>
<a href="help_rootview.html">General</a><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<a href="help_log.html">Classic&nbsp;Log&nbsp;View</a><br />
<a href="help_logtable.html">Alternative&nbsp;Log&nbsp;View</a><br />
<strong>Query&nbsp;Database</strong>
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p>
Select your parameters for querying the CVS commit database in the
form at the top of the page. You
can search for multiple matches by typing a comma-seperated list
into the text fields. Regular expressions, and wildcards are also
supported. Blank text input fields are treated as wildcards.
</p>
<p>
Any of the text entry fields can take a comma-seperated list of
search arguments. For example, to search for all commits from
authors <em>jpaint</em> and <em>gstein</em>, just type: <code>jpaint,
gstein</code> in the <em>Author</em> input box. If you are searching
for items containing spaces or quotes, you will need to quote your
request. For example, the same search above with quotes is:
<code>"jpaint", "gstein"</code>.
</p>
<p>
Wildcard and regular expression searches are entered in a similar
way to the quoted requests. You must quote any wildcard or
regular expression request, and a command character preceeds the
first quote. The command character <code>l</code>(lowercase L) is for wildcard
searches, and the wildcard character is a percent (<code>%</code>). The
command character for regular expressions is <code>r</code>, and is
passed directly to MySQL, so you'll need to refer to the MySQL
manual for the exact regex syntax. It is very similar to Perl. A
wildard search for all files with a <em>.py</em> extention is:
<code>l"%.py"</code> in the <em>File</em> input box. The same search done
with a regular expression is: <code>r".*\.py"</code>.
</p>
<p>
All search types can be mixed, as long as they are seperated by
commas.
</p>
</td></tr></table>
</body></html>

View File

@@ -0,0 +1,169 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>ViewVC Help: General</title>
<link rel="stylesheet" href="help.css" type="text/css" />
</head>
<body>
<table>
<col class="menu" />
<col />
<tr>
<td><a href=".."><img
src="images/logo.png" alt="ViewVC logotype" /></a>
</td>
<td>
<h1>ViewVC Help: General</h1>
</td>
</tr>
<tr><td>
<h3>Help</h3>
<strong>General</strong><br />
<a href="help_dirview.html">Directory&nbsp;View</a><br />
<a href="help_log.html">Log&nbsp;View</a><br />
<h3>Internet</h3>
<a href="http://viewvc.org/index.html">Home</a><br />
<a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
<a href="http://viewvc.org/contributing.html">Contributing</a><br />
<a href="http://viewvc.org/license-1.html">License</a><br />
</td><td colspan="2">
<p><em>ViewVC</em> is a WWW interface for CVS and Subversion
repositories. It allows you to browse the files and directories in a
repository while showing you metadata from the repository history: log
messages, modification dates, author names, revision numbers, copy
history, and so on. It provides several different views of repository
data to help you find the information you are looking for:</p>
<ul>
<li><a name="view-dir" href="help_dirview.html"><strong>Directory
View</strong></a> - Shows a list of files and subdirectories in a
directory of the repository, along with metadata like author names and
log entries.</li>
<li><a name="view-log" href="help_log.html"><strong>Log
View</strong></a> - Shows a revision by revision list of all the
changes that have made to a file or directory in the repository, with
metadata and links to views of each revision.</li>
<li><a name="view-markup"><strong>File Contents View (Markup
View)</strong></a> - Shows the contents of a file at a particular
revision, with revision information at the top of the page. File
revisions which are GIF, PNG, or JPEG images are displayed inline on
the page. Other file types are displayed as marked up text. The markup
may be limited to turning URLs and email addresses into links, or
configured to show colorized source code.</li>
<li><a name="view-checkout"><strong>File Download (Checkout
View)</strong></a> - Retrieves the unaltered contents of a file
revision. Browsers may try to display the file, or just save it to
disk.</li>
<li><a name="view-annotate"><strong>File Annotate View</strong></a> -
Shows the contents of a file revision and breaks it down line by line,
showing the revision number where each one was last modified, along
with links and other information. <em>This view is disabled in some
ViewVC configurations</em></li>
<li><a name="view-diff"><strong>File Diff View</strong></a> - Shows
the changes made between two revisions of a file</li>
<li><a name="view-tarball"><strong>Directory Tarball View</strong> -
Retrieves a gzipped tar archive containing the contents of a
directory.<em>This view is disabled in the default ViewVC
configuration.</em></li>
<li><a name="view-query"><strong>Directory Query View</strong></a> -
Shows information about changes made to all subdirectories and files
under a parent directory, sorted and filtered by criteria you specify.
<em>This view is disabled in the default ViewVC configuration.</em>
</li>
<li><a name="view-rev"><strong>Revision View</strong> - Shows
information about a revision including log message, author, and a list
of changed paths. <em>For Subversion repositories only.</em></li>
<li><a name="view-graph"><strong>Graph View</strong></a> - Shows a
graphical representation of a file's revisions and branches complete
with tag and author names and links to markup and diff pages.
<em>For CVS repositories only, and disabled in the default
configuration.</em></li>
</ul>
<h3><a name="multiple-repositories">Multiple Repositories</a></h3>
<p>A single installation of ViewVC is often used to provide access to
more than one repository. In these installations, ViewVC shows a
<em>Project Root</em> drop down box in the top right corner of every
generated page to allow for quick access to any repository.</p>
<h3><a name="sticky-revision-tag">Sticky Revision and Tag</a></h3>
<p>By default, ViewVC will show the files and directories and revisions
that currently exist in the repository. But it's also possible to browse
the contents of a repository at a point in its past history by choosing
a "sticky tag" (in CVS) or a "sticky revision" (in Subversion) from the
forms at the top of directory and log pages. They're called sticky
because once they're chosen, they stick around when you navigate to
other pages, until you reset them. When they're set, directory and log
pages only show revisions preceding the specified point in history. In
CVS, when a tag refers to a branch or a revision on a branch, only
revisions from the branch history are shown, including branch points and
their preceding revisions.</p>
<h3><a name="dead-files">Dead Files</a></h3>
<p>In CVS directory listings, ViewVC can optionally display dead files.
Dead files are files which used to be in a directory but are currently
deleted, or files which just don't exist in the currently selected
<a href="#sticky-revision-tag">sticky tag</a>. Dead files cannot be
shown in Subversion repositories. The only way to see a deleted file in
a Subversion directory is to navigate to a sticky revision where the
file previously existed.</p>
<h3><a name="artificial-tags">Artificial Tags</a></h3>
<p>In CVS Repositories, ViewVC adds artificial tags <em>HEAD</em> and
<em>MAIN</em> to tag listings and accepts them in place of revision
numbers and real tag names in all URLs. <em>MAIN</em> acts like a branch
tag pointing at the default branch, while <em>HEAD</em> acts like a
revision tag pointing to the latest revision on the default branch. The
default branch is usually just the trunk, but may be set to other
branches inside individual repository files. CVS will always check out
revisions from a file's default branch when no other branch is specified
on the command line.</p>
<h3><a name="more-information">More Information</a></h3>
<p>More information about <em>ViewVC</em> is available from
<a href="http://viewvc.org/">viewvc.org</a>.
See the links below for guides to CVS and Subversion</p>
<h4>Documentation about CVS</h4>
<blockquote>
<p>
<a href="http://cvsbook.red-bean.com/"><em>Open Source
Development with CVS</em></a><br />
<a href="http://www.loria.fr/~molli/cvs/doc/cvs_toc.html">CVS
User's Guide</a><br />
<a href="http://cellworks.washington.edu/pub/docs/cvs/tutorial/cvs_tutorial_1.html">Another CVS tutorial</a><br />
<a href="http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/">Yet another CVS tutorial (a little old, but nice)</a><br />
<a href="http://www.cs.utah.edu/dept/old/texinfo/cvs/FAQ.txt">An old but very useful FAQ about CVS</a>
</p>
</blockquote>
<h4>Documentation about Subversion</h3>
<blockquote>
<p>
<a href="http://svnbook.red-bean.com/"><em>Version Control with
Subversion</em></a><br />
</p>
</blockquote>
</td></tr></table>
<hr />
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Some files were not shown because too many files have changed in this diff Show More