viewvc-4intranet/lib/cvsdb.py

834 lines
25 KiB
Python
Raw Normal View History

# -*-python-*-
#
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
Work on issue 168, s/ViewCVS/ViewVC. This patch changes references to ViewCVS in comments, strings, and documentation. References to ViewCVS in filenames and urls still need to be fixed. Also, logo.png (the blimp) needs to be updated or replaced. This patch is by Gerard Gerritsen (sigcafe), the only change I've made is to restore a reference to ViewCVS in a comment about backwards compatibility. * windows/README * viewcvs-install * README * templates/include/footer.ezt * templates/include/header.ezt * templates/error.ezt * templates/query.ezt * templates/docroot/help.css * templates/docroot/help_query.html * templates/docroot/help_dirview.html * templates/docroot/help_rootview.html * templates/docroot/styles.css * templates/docroot/help_log.html * templates/diff.ezt * tools/make-release * lib/sapi.py * lib/dbi.py * lib/accept.py * lib/cvsdb.py * lib/config.py * lib/query.py * lib/vclib/bincvs/__init__.py * lib/vclib/svn/__init__.py * lib/vclib/__init__.py * lib/vclib/svn_ra/__init__.py * lib/vclib/ccvs/rcsparse/common.py * lib/vclib/ccvs/rcsparse/__init__.py * lib/vclib/ccvs/rcsparse/default.py * lib/vclib/ccvs/rcsparse/texttools.py * lib/vclib/ccvs/rcsparse/debug.py * lib/vclib/ccvs/__init__.py * lib/vclib/ccvs/blame.py * lib/blame.py * lib/popen.py * lib/compat.py * lib/viewcvs.py * lib/debug.py * INSTALL * bin/standalone.py * bin/make-database * bin/mod_python/query.py * bin/mod_python/viewcvs.py * bin/cgi/query.cgi * bin/cgi/viewcvs.cgi * bin/asp/query.asp * bin/asp/viewcvs.asp * bin/svndbadmin * bin/loginfo-handler * bin/cvsdbadmin * viewcvs.conf.dist git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1200 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-12-17 20:19:28 +03:00
# 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 os
import sys
import string
import time
import fnmatch
import re
import dbi
## error
error = "cvsdb error"
## CheckinDatabase provides all interfaces needed to the SQL database
## back-end; it needs to be subclassed, and have its "Connect" method
## defined to actually be complete; it should run well off of any DBI 2.0
## complient database interface
class CheckinDatabase:
def __init__(self, host, port, user, passwd, database, row_limit):
self._host = host
self._port = port
self._user = user
self._passwd = passwd
self._database = database
Tweak logic used to find installed paths ("lib" directory, configuration file, templates, etc). Specifically, make the following changes: - Get rid of hardcoded paths in module files ("lib" directory) and configuration files (viewcvs.conf and mod_python's .htaccess) - Allow stub scripts (for asp, cgi, and mod_python) to specify configuration files so it's possible to have multiple configurations of viewcvs running off a single installation. - Be more consistent about resolving paths when they aren't hardcoded (when ViewCVS is running from a source directory). In particular, try not to depend on the working directory. That way it's legal to run ./standalone.py instead of bin/standalone.py without getting an ImportError. - Get rid of global cfg variables in viewcvs.py and cvsdb.py. They led to all sorts of hacks in other files to pilfer and reset them. They were also possible sources of races in multithreaded environments like mod_python and asp. - Rewrite mod_python handler so library paths can be specified inside the stub files. * lib/apache.py removed, contained old mod_python handler * lib/config.py (Config.load_config): remove sys.argv voodoo, just load the configuration path specified in the pathname argument (Config.set_defaults): use relative path for cvsgraph_conf setting instead of hardcoded <VIEWCVS_INSTALL_DIRECTORY> literal * lib/cvsdb.py (CONF_PATHNAME, config, cfg): removed, configuration stuff (CheckinDatabase.__init__, CheckinDatabase.CreateSQLQueryString): add "_row_limit" member instead of using cfg object (CreateCheckinDatabase): removed, a do-nothing function (ConnectDatabaseReadOnly, ConnectDatabase): add cfg arguments (GetUnrecordedCommitList): add db argument * lib/query.py (CONF_PATHAME): removed (build_commit, run_query, main): add cfg arguments, use new viewcvs.get_template function * lib/viewcvs.py (CONF_PATHNAME, cfg, g_install_dir): removed (Request.__init__): add cfg member (Request.run_viewcvs, Request.get_link, check_freshness, get_view_template, generate_page, default_view, get_file_view_info, format_log, common_template_data, MarkupEnscript.__init__, markup_stream_python, markup_stream_php, make_time_string, view_markup, sort_file_data, view_directory, paging, view_log, view_annotate, view_cvsgraph_image, view_cvsgraph, view_doc, rcsdiff_date_reformat, spaced_html_text, DiffSource.__init__, DiffSource._get_row, view_patch, view_diff, generate_tarball, download_tarball, view_revision, is_query_supported, english_query, build_commit, view_query, view_error, main): stop using global config, use cfg arguments or request member instead (_install_path): new, use __file__ to locate template and configuation paths (get_view_template): use _install_path and return compiled template instead of path (is_viewable, default_view): rename is_viewable to default_view and return view instead of boolean (handle_config, load_config): rename handle_config to load_config and return config object instead of setting cfg global * bin/cgi/viewcvs.cgi * bin/cgi/query.cgi * bin/cvsdbadmin * bin/loginfo-handler * bin/standalone.py * bin/svndbadmin look for library relative to sys.argv[0] when no hardcoded library path is available. Also add configuration loading code. * bin/asp/viewcvs.asp * bin/asp/query.asp add configuration loading code * bin/mod_python/.htaccess specify new mod_python handler, remove reference to <VIEWCVS_APACHE_LIBRARY_DIRECTORY> * bin/mod_python/handler.py added, holds new mod_python handler * bin/mod_python/viewcvs.py * bin/mod_python/query.py rewrite for new handler, add hardcoded library and configuration paths * viewcvs.conf.dist remove references to <VIEWCVS_INSTALL_DIRECTORY> * viewcvs-install (FILE_INFO_LIST): stop hardcoding paths in config files (SetPythonPaths,): get rid of <VIEWCVS_INSTALL_DIRECTORY> and <VIEWCVS_APACHE_LIBRARY_DIRECTORY> substitutions (ApacheEscape, _re_apache): removed (InstallTree): stop hardcoding paths in lib directory git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1173 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-12-06 07:04:14 +03:00
self._row_limit = row_limit
## database lookup caches
self._get_cache = {}
self._get_id_cache = {}
self._desc_id_cache = {}
def Connect(self):
self.db = dbi.connect(
self._host, self._port, self._user, self._passwd, self._database)
cursor = self.db.cursor()
cursor.execute("SET AUTOCOMMIT=1")
def sql_get_id(self, table, column, value, auto_set):
sql = "SELECT id FROM %s WHERE %s=%%s" % (table, column)
sql_args = (value, )
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
try:
(id, ) = cursor.fetchone()
except TypeError:
if not auto_set:
return None
else:
return str(int(id))
## insert the new identifier
sql = "INSERT INTO %s(%s) VALUES(%%s)" % (table, column)
sql_args = (value, )
cursor.execute(sql, sql_args)
return self.sql_get_id(table, column, value, 0)
def get_id(self, table, column, value, auto_set):
## attempt to retrieve from cache
try:
return self._get_id_cache[table][column][value]
except KeyError:
pass
id = self.sql_get_id(table, column, value, auto_set)
if id == None:
return None
## add to cache
try:
temp = self._get_id_cache[table]
except KeyError:
temp = self._get_id_cache[table] = {}
try:
temp2 = temp[column]
except KeyError:
temp2 = temp[column] = {}
temp2[value] = id
return id
def sql_get(self, table, column, id):
sql = "SELECT %s FROM %s WHERE id=%%s" % (column, table)
sql_args = (id, )
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
try:
(value, ) = cursor.fetchone()
except TypeError:
return None
return value
def get(self, table, column, id):
## attempt to retrieve from cache
try:
return self._get_cache[table][column][id]
except KeyError:
pass
value = self.sql_get(table, column, id)
if value == None:
return None
## add to cache
try:
temp = self._get_cache[table]
except KeyError:
temp = self._get_cache[table] = {}
try:
temp2 = temp[column]
except KeyError:
temp2 = temp[column] = {}
temp2[id] = value
return value
def get_list(self, table, field_index):
sql = "SELECT * FROM %s" % (table)
cursor = self.db.cursor()
cursor.execute(sql)
list = []
while 1:
row = cursor.fetchone()
if row == None:
break
list.append(row[field_index])
return list
def GetBranchID(self, branch, auto_set = 1):
return self.get_id("branches", "branch", branch, auto_set)
def GetBranch(self, id):
return self.get("branches", "branch", id)
def GetDirectoryID(self, dir, auto_set = 1):
return self.get_id("dirs", "dir", dir, auto_set)
def GetDirectory(self, id):
return self.get("dirs", "dir", id)
def GetFileID(self, file, auto_set = 1):
return self.get_id("files", "file", file, auto_set)
def GetFile(self, id):
return self.get("files", "file", id)
def GetAuthorID(self, author, auto_set = 1):
return self.get_id("people", "who", author, auto_set)
def GetAuthor(self, id):
return self.get("people", "who", id)
def GetRepositoryID(self, repository, auto_set = 1):
return self.get_id("repositories", "repository", repository, auto_set)
def GetRepository(self, id):
return self.get("repositories", "repository", id)
def SQLGetDescriptionID(self, description, auto_set = 1):
## lame string hash, blame Netscape -JMP
hash = len(description)
sql = "SELECT id FROM descs WHERE hash=%s AND description=%s"
sql_args = (hash, description)
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
try:
(id, ) = cursor.fetchone()
except TypeError:
if not auto_set:
return None
else:
return str(int(id))
sql = "INSERT INTO descs (hash,description) values (%s,%s)"
sql_args = (hash, description)
cursor.execute(sql, sql_args)
return self.GetDescriptionID(description, 0)
def GetDescriptionID(self, description, auto_set = 1):
## attempt to retrieve from cache
hash = len(description)
try:
return self._desc_id_cache[hash][description]
except KeyError:
pass
id = self.SQLGetDescriptionID(description, auto_set)
if id == None:
return None
## add to cache
try:
temp = self._desc_id_cache[hash]
except KeyError:
temp = self._desc_id_cache[hash] = {}
temp[description] = id
return id
def GetDescription(self, id):
return self.get("descs", "description", id)
def GetRepositoryList(self):
return self.get_list("repositories", 1)
def GetBranchList(self):
return self.get_list("branches", 1)
def GetAuthorList(self):
return self.get_list("people", 1)
def AddCommitList(self, commit_list):
for commit in commit_list:
self.AddCommit(commit)
def AddCommit(self, commit):
ci_when = dbi.DateTimeFromTicks(commit.GetTime() or 0.0)
ci_type = commit.GetTypeString()
who_id = self.GetAuthorID(commit.GetAuthor())
repository_id = self.GetRepositoryID(commit.GetRepository())
directory_id = self.GetDirectoryID(commit.GetDirectory())
file_id = self.GetFileID(commit.GetFile())
revision = commit.GetRevision()
sticky_tag = "NULL"
branch_id = self.GetBranchID(commit.GetBranch())
plus_count = commit.GetPlusCount() or '0'
minus_count = commit.GetMinusCount() or '0'
description_id = self.GetDescriptionID(commit.GetDescription())
sql = "REPLACE INTO checkins"\
" (type,ci_when,whoid,repositoryid,dirid,fileid,revision,"\
" stickytag,branchid,addedlines,removedlines,descid)"\
"VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
sql_args = (ci_type, ci_when, who_id, repository_id,
directory_id, file_id, revision, sticky_tag, branch_id,
plus_count, minus_count, description_id)
cursor = self.db.cursor()
try:
cursor.execute(sql, sql_args)
except Exception, e:
raise Exception("Error adding commit: '%s'\n"
"Values were:\n"
"\ttype = %s\n"
"\tci_when = %s\n"
"\twhoid = %s\n"
"\trepositoryid = %s\n"
"\tdirid = %s\n"
"\tfileid = %s\n"
"\trevision = %s\n"
"\tstickytag = %s\n"
"\tbranchid = %s\n"
"\taddedlines = %s\n"
"\tremovedlines = %s\n"
"\tdescid = %s\n"
% ((str(e), ) + sql_args))
def SQLQueryListString(self, field, query_entry_list):
sqlList = []
for query_entry in query_entry_list:
data = query_entry.data
## figure out the correct match type
if query_entry.match == "exact":
match = "="
elif query_entry.match == "like":
match = " LIKE "
elif query_entry.match == "glob":
match = " REGEXP "
# use fnmatch to translate the glob into a regexp
data = fnmatch.translate(data)
if data[0] != '^': data = '^' + data
elif query_entry.match == "regex":
match = " REGEXP "
elif query_entry.match == "notregex":
match = " NOT REGEXP "
sqlList.append("%s%s%s" % (field, match, self.db.literal(data)))
return "(%s)" % (string.join(sqlList, " OR "))
def CreateSQLQueryString(self, query):
tableList = [("checkins", None)]
condList = []
if len(query.repository_list):
tableList.append(("repositories",
"(checkins.repositoryid=repositories.id)"))
temp = self.SQLQueryListString("repositories.repository",
query.repository_list)
condList.append(temp)
if len(query.branch_list):
tableList.append(("branches", "(checkins.branchid=branches.id)"))
temp = self.SQLQueryListString("branches.branch",
query.branch_list)
condList.append(temp)
if len(query.directory_list):
tableList.append(("dirs", "(checkins.dirid=dirs.id)"))
temp = self.SQLQueryListString("dirs.dir", query.directory_list)
condList.append(temp)
if len(query.file_list):
tableList.append(("files", "(checkins.fileid=files.id)"))
temp = self.SQLQueryListString("files.file", query.file_list)
condList.append(temp)
if len(query.author_list):
tableList.append(("people", "(checkins.whoid=people.id)"))
temp = self.SQLQueryListString("people.who", query.author_list)
condList.append(temp)
if len(query.comment_list):
tableList.append(("descs", "(checkins.descid=descs.id)"))
temp = self.SQLQueryListString("descs.description",
query.comment_list)
condList.append(temp)
if query.from_date:
temp = "(checkins.ci_when>=\"%s\")" % (str(query.from_date))
condList.append(temp)
if query.to_date:
temp = "(checkins.ci_when<=\"%s\")" % (str(query.to_date))
condList.append(temp)
if query.sort == "date":
order_by = "ORDER BY checkins.ci_when DESC,descid"
elif query.sort == "author":
tableList.append(("people", "(checkins.whoid=people.id)"))
order_by = "ORDER BY people.who,descid"
elif query.sort == "file":
tableList.append(("files", "(checkins.fileid=files.id)"))
order_by = "ORDER BY files.file,descid"
## exclude duplicates from the table list, and split out join
## conditions from table names. In future, the join conditions
## might be handled by INNER JOIN statements instead of WHERE
## clauses, but MySQL 3.22 apparently doesn't support them well.
tables = []
joinConds = []
for (table, cond) in tableList:
if table not in tables:
tables.append(table)
if cond is not None: joinConds.append(cond)
tables = string.join(tables, ",")
conditions = string.join(joinConds + condList, " AND ")
conditions = conditions and "WHERE %s" % conditions
## limit the number of rows requested or we could really slam
## a server with a large database
limit = ""
if query.limit:
limit = "LIMIT %s" % (str(query.limit))
elif self._row_limit:
Tweak logic used to find installed paths ("lib" directory, configuration file, templates, etc). Specifically, make the following changes: - Get rid of hardcoded paths in module files ("lib" directory) and configuration files (viewcvs.conf and mod_python's .htaccess) - Allow stub scripts (for asp, cgi, and mod_python) to specify configuration files so it's possible to have multiple configurations of viewcvs running off a single installation. - Be more consistent about resolving paths when they aren't hardcoded (when ViewCVS is running from a source directory). In particular, try not to depend on the working directory. That way it's legal to run ./standalone.py instead of bin/standalone.py without getting an ImportError. - Get rid of global cfg variables in viewcvs.py and cvsdb.py. They led to all sorts of hacks in other files to pilfer and reset them. They were also possible sources of races in multithreaded environments like mod_python and asp. - Rewrite mod_python handler so library paths can be specified inside the stub files. * lib/apache.py removed, contained old mod_python handler * lib/config.py (Config.load_config): remove sys.argv voodoo, just load the configuration path specified in the pathname argument (Config.set_defaults): use relative path for cvsgraph_conf setting instead of hardcoded <VIEWCVS_INSTALL_DIRECTORY> literal * lib/cvsdb.py (CONF_PATHNAME, config, cfg): removed, configuration stuff (CheckinDatabase.__init__, CheckinDatabase.CreateSQLQueryString): add "_row_limit" member instead of using cfg object (CreateCheckinDatabase): removed, a do-nothing function (ConnectDatabaseReadOnly, ConnectDatabase): add cfg arguments (GetUnrecordedCommitList): add db argument * lib/query.py (CONF_PATHAME): removed (build_commit, run_query, main): add cfg arguments, use new viewcvs.get_template function * lib/viewcvs.py (CONF_PATHNAME, cfg, g_install_dir): removed (Request.__init__): add cfg member (Request.run_viewcvs, Request.get_link, check_freshness, get_view_template, generate_page, default_view, get_file_view_info, format_log, common_template_data, MarkupEnscript.__init__, markup_stream_python, markup_stream_php, make_time_string, view_markup, sort_file_data, view_directory, paging, view_log, view_annotate, view_cvsgraph_image, view_cvsgraph, view_doc, rcsdiff_date_reformat, spaced_html_text, DiffSource.__init__, DiffSource._get_row, view_patch, view_diff, generate_tarball, download_tarball, view_revision, is_query_supported, english_query, build_commit, view_query, view_error, main): stop using global config, use cfg arguments or request member instead (_install_path): new, use __file__ to locate template and configuation paths (get_view_template): use _install_path and return compiled template instead of path (is_viewable, default_view): rename is_viewable to default_view and return view instead of boolean (handle_config, load_config): rename handle_config to load_config and return config object instead of setting cfg global * bin/cgi/viewcvs.cgi * bin/cgi/query.cgi * bin/cvsdbadmin * bin/loginfo-handler * bin/standalone.py * bin/svndbadmin look for library relative to sys.argv[0] when no hardcoded library path is available. Also add configuration loading code. * bin/asp/viewcvs.asp * bin/asp/query.asp add configuration loading code * bin/mod_python/.htaccess specify new mod_python handler, remove reference to <VIEWCVS_APACHE_LIBRARY_DIRECTORY> * bin/mod_python/handler.py added, holds new mod_python handler * bin/mod_python/viewcvs.py * bin/mod_python/query.py rewrite for new handler, add hardcoded library and configuration paths * viewcvs.conf.dist remove references to <VIEWCVS_INSTALL_DIRECTORY> * viewcvs-install (FILE_INFO_LIST): stop hardcoding paths in config files (SetPythonPaths,): get rid of <VIEWCVS_INSTALL_DIRECTORY> and <VIEWCVS_APACHE_LIBRARY_DIRECTORY> substitutions (ApacheEscape, _re_apache): removed (InstallTree): stop hardcoding paths in lib directory git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1173 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-12-06 07:04:14 +03:00
limit = "LIMIT %s" % (str(self._row_limit))
sql = "SELECT checkins.* FROM %s %s %s %s" % (
tables, conditions, order_by, limit)
return sql
def RunQuery(self, query):
sql = self.CreateSQLQueryString(query)
cursor = self.db.cursor()
cursor.execute(sql)
while 1:
row = cursor.fetchone()
if not row:
break
(dbType, dbCI_When, dbAuthorID, dbRepositoryID, dbDirID,
dbFileID, dbRevision, dbStickyTag, dbBranchID, dbAddedLines,
dbRemovedLines, dbDescID) = row
commit = LazyCommit(self)
if dbType == 'Add':
commit.SetTypeAdd()
elif dbType == 'Remove':
commit.SetTypeRemove()
else:
commit.SetTypeChange()
commit.SetTime(dbi.TicksFromDateTime(dbCI_When))
commit.SetFileID(dbFileID)
commit.SetDirectoryID(dbDirID)
commit.SetRevision(dbRevision)
commit.SetRepositoryID(dbRepositoryID)
commit.SetAuthorID(dbAuthorID)
commit.SetBranchID(dbBranchID)
commit.SetPlusCount(dbAddedLines)
commit.SetMinusCount(dbRemovedLines)
commit.SetDescriptionID(dbDescID)
query.AddCommit(commit)
def CheckCommit(self, commit):
repository_id = self.GetRepositoryID(commit.GetRepository(), 0)
if repository_id == None:
return None
dir_id = self.GetDirectoryID(commit.GetDirectory(), 0)
if dir_id == None:
return None
file_id = self.GetFileID(commit.GetFile(), 0)
if file_id == None:
return None
sql = "SELECT * FROM checkins WHERE "\
" repositoryid=%s AND dirid=%s AND fileid=%s AND revision=%s"
sql_args = (repository_id, dir_id, file_id, commit.GetRevision())
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
try:
(ci_type, ci_when, who_id, repository_id,
dir_id, file_id, revision, sticky_tag, branch_id,
plus_count, minus_count, description_id) = cursor.fetchone()
except TypeError:
return None
return commit
def sql_delete(self, table, key, value):
sql = "DELETE FROM %s WHERE %s=%%s" % (table, key)
sql_args = (value, )
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
def PurgeRepository(self, repository):
rep_id = self.GetRepositoryID(repository)
if not rep_id:
raise Exception, "Unknown repository '%s'" % (repository)
sql = "SELECT * FROM checkins WHERE repositoryid=%s"
sql_args = (rep_id, )
cursor = self.db.cursor()
cursor.execute(sql, sql_args)
checkins = []
while 1:
try:
(ci_type, ci_when, who_id, repository_id,
dir_id, file_id, revision, sticky_tag, branch_id,
plus_count, minus_count, description_id) = cursor.fetchone()
except TypeError:
break
checkins.append([file_id, dir_id, branch_id, description_id])
#self.sql_delete('repositories', 'id', rep_id)
self.sql_delete('checkins', 'repositoryid', rep_id)
for checkin in checkins:
self.sql_delete('files', 'id', checkin[0])
self.sql_delete('dirs', 'id', checkin[1])
self.sql_delete('branches', 'id', checkin[2])
self.sql_delete('descs', 'id', checkin[3])
## the Commit class holds data on one commit, the representation is as
## close as possible to how it should be committed and retrieved to the
## database engine
class Commit:
## static constants for type of commit
CHANGE = 0
ADD = 1
REMOVE = 2
def __init__(self):
self.__directory = ''
self.__file = ''
self.__repository = ''
self.__revision = ''
self.__author = ''
self.__branch = ''
self.__pluscount = ''
self.__minuscount = ''
self.__description = ''
self.__gmt_time = 0.0
self.__type = Commit.CHANGE
def SetRepository(self, repository):
self.__repository = repository
def GetRepository(self):
return self.__repository
def SetDirectory(self, dir):
self.__directory = dir
def GetDirectory(self):
return self.__directory
def SetFile(self, file):
self.__file = file
def GetFile(self):
return self.__file
def SetRevision(self, revision):
self.__revision = revision
def GetRevision(self):
return self.__revision
def SetTime(self, gmt_time):
if gmt_time is None:
### We're just going to assume that a datestamp of The Epoch
### ain't real.
self.__gmt_time = 0.0
else:
self.__gmt_time = float(gmt_time)
def GetTime(self):
return self.__gmt_time and self.__gmt_time or None
def SetAuthor(self, author):
self.__author = author
def GetAuthor(self):
return self.__author
def SetBranch(self, branch):
self.__branch = branch or ''
def GetBranch(self):
return self.__branch
def SetPlusCount(self, pluscount):
self.__pluscount = pluscount
def GetPlusCount(self):
return self.__pluscount
def SetMinusCount(self, minuscount):
self.__minuscount = minuscount
def GetMinusCount(self):
return self.__minuscount
def SetDescription(self, description):
self.__description = description
def GetDescription(self):
return self.__description
def SetTypeChange(self):
self.__type = Commit.CHANGE
def SetTypeAdd(self):
self.__type = Commit.ADD
def SetTypeRemove(self):
self.__type = Commit.REMOVE
def GetType(self):
return self.__type
def GetTypeString(self):
if self.__type == Commit.CHANGE:
return 'Change'
elif self.__type == Commit.ADD:
return 'Add'
elif self.__type == Commit.REMOVE:
return 'Remove'
## LazyCommit overrides a few methods of Commit to only retrieve
## it's properties as they are needed
class LazyCommit(Commit):
def __init__(self, db):
Commit.__init__(self)
self.__db = db
def SetFileID(self, dbFileID):
self.__dbFileID = dbFileID
def GetFileID(self):
return self.__dbFileID
def GetFile(self):
return self.__db.GetFile(self.__dbFileID)
def SetDirectoryID(self, dbDirID):
self.__dbDirID = dbDirID
def GetDirectoryID(self):
return self.__dbDirID
def GetDirectory(self):
return self.__db.GetDirectory(self.__dbDirID)
def SetRepositoryID(self, dbRepositoryID):
self.__dbRepositoryID = dbRepositoryID
def GetRepositoryID(self):
return self.__dbRepositoryID
def GetRepository(self):
return self.__db.GetRepository(self.__dbRepositoryID)
def SetAuthorID(self, dbAuthorID):
self.__dbAuthorID = dbAuthorID
def GetAuthorID(self):
return self.__dbAuthorID
def GetAuthor(self):
return self.__db.GetAuthor(self.__dbAuthorID)
def SetBranchID(self, dbBranchID):
self.__dbBranchID = dbBranchID
def GetBranchID(self):
return self.__dbBranchID
def GetBranch(self):
return self.__db.GetBranch(self.__dbBranchID)
def SetDescriptionID(self, dbDescID):
self.__dbDescID = dbDescID
def GetDescriptionID(self):
return self.__dbDescID
def GetDescription(self):
return self.__db.GetDescription(self.__dbDescID)
## QueryEntry holds data on one match-type in the SQL database
## match is: "exact", "like", or "regex"
class QueryEntry:
def __init__(self, data, match):
self.data = data
self.match = match
## CheckinDatabaseQueryData is a object which contains the search parameters
## for a query to the CheckinDatabase
class CheckinDatabaseQuery:
def __init__(self):
## sorting
self.sort = "date"
## repository to query
self.repository_list = []
self.branch_list = []
self.directory_list = []
self.file_list = []
self.author_list = []
self.comment_list = []
## date range in DBI 2.0 timedate objects
self.from_date = None
self.to_date = None
## limit on number of rows to return
self.limit = None
## list of commits -- filled in by CVS query
self.commit_list = []
## commit_cb provides a callback for commits as they
## are added
self.commit_cb = None
def SetRepository(self, repository, match = "exact"):
Fix file path issues in CVSdb on windows. Summary of changes: - Stop converting directory and file paths to lower case with native slashes before storing them in the database. Instead store with preserved case and forward slashes. - Stop trying to clean up paths haphazardly all over the cvsdb module, instead expect paths to be normalized before they get passed to cvsdb. * lib/cvsdb.py (Commit.SetRepository, Commit.SetDirectory, Commit.SetFile, CheckinDatabaseQuery.SetRepository, CheckinDatabaseQuery.SetDirectory): remove path cleanup code (RLogDataToCommitList) don't strip repository prefix because rlog module now does it (CleanRepository): new function * lib/rlog.py (_get_co_file): change to return paths with forward slashes and without repository prefixes (GetRLogData): update call to _get_co_file * tools/cvsdbadmin (UpdateFile, CommandUpdate, RebuildFile, CommandRebuild) remove calls to normcase here (module code): use CleanRepository function to clean up repository path * tools/loginfo-handler (CleanDirectory): removed (HeuristicArgParse, CvsNtArgParse): don't call CleanDirectory or normcase here (HeuristicArgParseDirectory): remove stray print statement (module code): use cvsdb.CleanRepository function to clean up repository path * tools/svndbadmin (module code): use cvsdb.CleanRepository function to clean up repository path * lib/viewcvs.py (view_query): change to use forward slashes in directory names instead of native slashes use cvsdb.CleanRepository function to clean up repository paths * lib/query.py (build_commit): change to handle forward slashes in directory paths instead of native slashes (run_query): use cvsdb.CleanRepository function to clean up repository path git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@952 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 04:47:42 +04:00
self.repository_list.append(QueryEntry(repository, match))
def SetBranch(self, branch, match = "exact"):
self.branch_list.append(QueryEntry(branch, match))
def SetDirectory(self, directory, match = "exact"):
Fix file path issues in CVSdb on windows. Summary of changes: - Stop converting directory and file paths to lower case with native slashes before storing them in the database. Instead store with preserved case and forward slashes. - Stop trying to clean up paths haphazardly all over the cvsdb module, instead expect paths to be normalized before they get passed to cvsdb. * lib/cvsdb.py (Commit.SetRepository, Commit.SetDirectory, Commit.SetFile, CheckinDatabaseQuery.SetRepository, CheckinDatabaseQuery.SetDirectory): remove path cleanup code (RLogDataToCommitList) don't strip repository prefix because rlog module now does it (CleanRepository): new function * lib/rlog.py (_get_co_file): change to return paths with forward slashes and without repository prefixes (GetRLogData): update call to _get_co_file * tools/cvsdbadmin (UpdateFile, CommandUpdate, RebuildFile, CommandRebuild) remove calls to normcase here (module code): use CleanRepository function to clean up repository path * tools/loginfo-handler (CleanDirectory): removed (HeuristicArgParse, CvsNtArgParse): don't call CleanDirectory or normcase here (HeuristicArgParseDirectory): remove stray print statement (module code): use cvsdb.CleanRepository function to clean up repository path * tools/svndbadmin (module code): use cvsdb.CleanRepository function to clean up repository path * lib/viewcvs.py (view_query): change to use forward slashes in directory names instead of native slashes use cvsdb.CleanRepository function to clean up repository paths * lib/query.py (build_commit): change to handle forward slashes in directory paths instead of native slashes (run_query): use cvsdb.CleanRepository function to clean up repository path git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@952 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 04:47:42 +04:00
self.directory_list.append(QueryEntry(directory, match))
def SetFile(self, file, match = "exact"):
self.file_list.append(QueryEntry(file, match))
def SetAuthor(self, author, match = "exact"):
self.author_list.append(QueryEntry(author, match))
def SetComment(self, comment, match = "exact"):
self.comment_list.append(QueryEntry(comment, match))
def SetSortMethod(self, sort):
self.sort = sort
def SetFromDateObject(self, ticks):
self.from_date = dbi.DateTimeFromTicks(ticks)
def SetToDateObject(self, ticks):
self.to_date = dbi.DateTimeFromTicks(ticks)
def SetFromDateHoursAgo(self, hours_ago):
ticks = time.time() - (3600 * hours_ago)
self.from_date = dbi.DateTimeFromTicks(ticks)
def SetFromDateDaysAgo(self, days_ago):
ticks = time.time() - (86400 * days_ago)
self.from_date = dbi.DateTimeFromTicks(ticks)
def SetToDateDaysAgo(self, days_ago):
ticks = time.time() - (86400 * days_ago)
self.to_date = dbi.DateTimeFromTicks(ticks)
def SetLimit(self, limit):
self.limit = limit;
def AddCommit(self, commit):
self.commit_list.append(commit)
##
## entrypoints
##
def CreateCommit():
return Commit()
def CreateCheckinQuery():
return CheckinDatabaseQuery()
def ConnectDatabase(cfg, readonly=0):
if readonly:
user = cfg.cvsdb.readonly_user
passwd = cfg.cvsdb.readonly_passwd
else:
user = cfg.cvsdb.user
passwd = cfg.cvsdb.passwd
db = CheckinDatabase(cfg.cvsdb.host, cfg.cvsdb.port, user, passwd,
cfg.cvsdb.database_name, cfg.cvsdb.row_limit)
db.Connect()
return db
Tweak logic used to find installed paths ("lib" directory, configuration file, templates, etc). Specifically, make the following changes: - Get rid of hardcoded paths in module files ("lib" directory) and configuration files (viewcvs.conf and mod_python's .htaccess) - Allow stub scripts (for asp, cgi, and mod_python) to specify configuration files so it's possible to have multiple configurations of viewcvs running off a single installation. - Be more consistent about resolving paths when they aren't hardcoded (when ViewCVS is running from a source directory). In particular, try not to depend on the working directory. That way it's legal to run ./standalone.py instead of bin/standalone.py without getting an ImportError. - Get rid of global cfg variables in viewcvs.py and cvsdb.py. They led to all sorts of hacks in other files to pilfer and reset them. They were also possible sources of races in multithreaded environments like mod_python and asp. - Rewrite mod_python handler so library paths can be specified inside the stub files. * lib/apache.py removed, contained old mod_python handler * lib/config.py (Config.load_config): remove sys.argv voodoo, just load the configuration path specified in the pathname argument (Config.set_defaults): use relative path for cvsgraph_conf setting instead of hardcoded <VIEWCVS_INSTALL_DIRECTORY> literal * lib/cvsdb.py (CONF_PATHNAME, config, cfg): removed, configuration stuff (CheckinDatabase.__init__, CheckinDatabase.CreateSQLQueryString): add "_row_limit" member instead of using cfg object (CreateCheckinDatabase): removed, a do-nothing function (ConnectDatabaseReadOnly, ConnectDatabase): add cfg arguments (GetUnrecordedCommitList): add db argument * lib/query.py (CONF_PATHAME): removed (build_commit, run_query, main): add cfg arguments, use new viewcvs.get_template function * lib/viewcvs.py (CONF_PATHNAME, cfg, g_install_dir): removed (Request.__init__): add cfg member (Request.run_viewcvs, Request.get_link, check_freshness, get_view_template, generate_page, default_view, get_file_view_info, format_log, common_template_data, MarkupEnscript.__init__, markup_stream_python, markup_stream_php, make_time_string, view_markup, sort_file_data, view_directory, paging, view_log, view_annotate, view_cvsgraph_image, view_cvsgraph, view_doc, rcsdiff_date_reformat, spaced_html_text, DiffSource.__init__, DiffSource._get_row, view_patch, view_diff, generate_tarball, download_tarball, view_revision, is_query_supported, english_query, build_commit, view_query, view_error, main): stop using global config, use cfg arguments or request member instead (_install_path): new, use __file__ to locate template and configuation paths (get_view_template): use _install_path and return compiled template instead of path (is_viewable, default_view): rename is_viewable to default_view and return view instead of boolean (handle_config, load_config): rename handle_config to load_config and return config object instead of setting cfg global * bin/cgi/viewcvs.cgi * bin/cgi/query.cgi * bin/cvsdbadmin * bin/loginfo-handler * bin/standalone.py * bin/svndbadmin look for library relative to sys.argv[0] when no hardcoded library path is available. Also add configuration loading code. * bin/asp/viewcvs.asp * bin/asp/query.asp add configuration loading code * bin/mod_python/.htaccess specify new mod_python handler, remove reference to <VIEWCVS_APACHE_LIBRARY_DIRECTORY> * bin/mod_python/handler.py added, holds new mod_python handler * bin/mod_python/viewcvs.py * bin/mod_python/query.py rewrite for new handler, add hardcoded library and configuration paths * viewcvs.conf.dist remove references to <VIEWCVS_INSTALL_DIRECTORY> * viewcvs-install (FILE_INFO_LIST): stop hardcoding paths in config files (SetPythonPaths,): get rid of <VIEWCVS_INSTALL_DIRECTORY> and <VIEWCVS_APACHE_LIBRARY_DIRECTORY> substitutions (ApacheEscape, _re_apache): removed (InstallTree): stop hardcoding paths in lib directory git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1173 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-12-06 07:04:14 +03:00
def ConnectDatabaseReadOnly(cfg):
return ConnectDatabase(cfg, 1)
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
def GetCommitListFromRCSFile(repository, path_parts, revision=None):
commit_list = []
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
directory = string.join(path_parts[:-1], "/")
file = path_parts[-1]
revs = repository.itemlog(path_parts, revision, {"cvs_pass_rev": 1})
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
for rev in revs:
commit = CreateCommit()
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
commit.SetRepository(repository.rootpath)
commit.SetDirectory(directory)
commit.SetFile(file)
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
commit.SetRevision(rev.string)
commit.SetAuthor(rev.author)
commit.SetDescription(rev.log)
commit.SetTime(rev.date)
if rev.changed:
# extract the plus/minus and drop the sign
plus, minus = string.split(rev.changed)
commit.SetPlusCount(plus[1:])
commit.SetMinusCount(minus[1:])
if rev.dead:
commit.SetTypeRemove()
else:
commit.SetTypeChange()
else:
commit.SetTypeAdd()
commit_list.append(commit)
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
# if revision is on a branch which has at least one tag
if len(rev.number) > 2 and rev.branches:
commit.SetBranch(rev.branches[0].name)
return commit_list
Tweak logic used to find installed paths ("lib" directory, configuration file, templates, etc). Specifically, make the following changes: - Get rid of hardcoded paths in module files ("lib" directory) and configuration files (viewcvs.conf and mod_python's .htaccess) - Allow stub scripts (for asp, cgi, and mod_python) to specify configuration files so it's possible to have multiple configurations of viewcvs running off a single installation. - Be more consistent about resolving paths when they aren't hardcoded (when ViewCVS is running from a source directory). In particular, try not to depend on the working directory. That way it's legal to run ./standalone.py instead of bin/standalone.py without getting an ImportError. - Get rid of global cfg variables in viewcvs.py and cvsdb.py. They led to all sorts of hacks in other files to pilfer and reset them. They were also possible sources of races in multithreaded environments like mod_python and asp. - Rewrite mod_python handler so library paths can be specified inside the stub files. * lib/apache.py removed, contained old mod_python handler * lib/config.py (Config.load_config): remove sys.argv voodoo, just load the configuration path specified in the pathname argument (Config.set_defaults): use relative path for cvsgraph_conf setting instead of hardcoded <VIEWCVS_INSTALL_DIRECTORY> literal * lib/cvsdb.py (CONF_PATHNAME, config, cfg): removed, configuration stuff (CheckinDatabase.__init__, CheckinDatabase.CreateSQLQueryString): add "_row_limit" member instead of using cfg object (CreateCheckinDatabase): removed, a do-nothing function (ConnectDatabaseReadOnly, ConnectDatabase): add cfg arguments (GetUnrecordedCommitList): add db argument * lib/query.py (CONF_PATHAME): removed (build_commit, run_query, main): add cfg arguments, use new viewcvs.get_template function * lib/viewcvs.py (CONF_PATHNAME, cfg, g_install_dir): removed (Request.__init__): add cfg member (Request.run_viewcvs, Request.get_link, check_freshness, get_view_template, generate_page, default_view, get_file_view_info, format_log, common_template_data, MarkupEnscript.__init__, markup_stream_python, markup_stream_php, make_time_string, view_markup, sort_file_data, view_directory, paging, view_log, view_annotate, view_cvsgraph_image, view_cvsgraph, view_doc, rcsdiff_date_reformat, spaced_html_text, DiffSource.__init__, DiffSource._get_row, view_patch, view_diff, generate_tarball, download_tarball, view_revision, is_query_supported, english_query, build_commit, view_query, view_error, main): stop using global config, use cfg arguments or request member instead (_install_path): new, use __file__ to locate template and configuation paths (get_view_template): use _install_path and return compiled template instead of path (is_viewable, default_view): rename is_viewable to default_view and return view instead of boolean (handle_config, load_config): rename handle_config to load_config and return config object instead of setting cfg global * bin/cgi/viewcvs.cgi * bin/cgi/query.cgi * bin/cvsdbadmin * bin/loginfo-handler * bin/standalone.py * bin/svndbadmin look for library relative to sys.argv[0] when no hardcoded library path is available. Also add configuration loading code. * bin/asp/viewcvs.asp * bin/asp/query.asp add configuration loading code * bin/mod_python/.htaccess specify new mod_python handler, remove reference to <VIEWCVS_APACHE_LIBRARY_DIRECTORY> * bin/mod_python/handler.py added, holds new mod_python handler * bin/mod_python/viewcvs.py * bin/mod_python/query.py rewrite for new handler, add hardcoded library and configuration paths * viewcvs.conf.dist remove references to <VIEWCVS_INSTALL_DIRECTORY> * viewcvs-install (FILE_INFO_LIST): stop hardcoding paths in config files (SetPythonPaths,): get rid of <VIEWCVS_INSTALL_DIRECTORY> and <VIEWCVS_APACHE_LIBRARY_DIRECTORY> substitutions (ApacheEscape, _re_apache): removed (InstallTree): stop hardcoding paths in lib directory git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@1173 8cb11bc2-c004-0410-86c3-e597b4017df7
2005-12-06 07:04:14 +03:00
def GetUnrecordedCommitList(repository, path_parts, db):
Get rid of rlog module, make CVSdb use bincvs instead. * lib/rlog.py deleted * lib/cvsdb.py (RLogDataToCommitList): removed (GetCommitListFromRCSFile): change to use vclib instead of rlog module (GetCommitListFromRCSFile, GetUnrecordedCommitList): update to accept vclib-style path_parts arguments * lib/vclib/bincvs/__init__.py (BinCVSRepository.filelog): accept "cvs_pass_rev" option for passing -r arguments to rlog (_match_revs_tags): make this function work with an incomplete list of revisions instead of crashing. This is neccessary when an -r argument is passed to rlog. (_add_tag): make this function work when we need to create a tag with no revision object. We need this to create a HEAD tag when an -r argument is passed to rlog and we don't know what the HEAD revision is. (fetch_log): removed * tools/cvsdbadmin (RebuildFile): removed, merged into UpdateFile (UpdateFile) accept new argument to reinsert all commits (RecurseRebuild): removed, merged into RecurseUpdate (RecurseUpdate): update to use vclib's listdir instead of os.listdir (CommandRebuild, CommandUpdate): removed, code moved into __main__ section * tools/loginfo-handler (FileData, CommitFromFileData, GetUnrecordedCommitList): removed, these were just wrappers over the cvsdb interface (HeuristicArgParse, CvsNtArgParse) return tuples describing file data instead of file data objects (ProcessLoginfo): update to use cvsdb interface git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@953 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 06:23:23 +04:00
commit_list = GetCommitListFromRCSFile(repository, path_parts)
unrecorded_commit_list = []
for commit in commit_list:
result = db.CheckCommit(commit)
if not result:
unrecorded_commit_list.append(commit)
return unrecorded_commit_list
_re_likechars = re.compile(r"([_%\\])")
def EscapeLike(literal):
"""Escape literal string for use in a MySQL LIKE pattern"""
return re.sub(_re_likechars, r"\\\1", literal)
Fix file path issues in CVSdb on windows. Summary of changes: - Stop converting directory and file paths to lower case with native slashes before storing them in the database. Instead store with preserved case and forward slashes. - Stop trying to clean up paths haphazardly all over the cvsdb module, instead expect paths to be normalized before they get passed to cvsdb. * lib/cvsdb.py (Commit.SetRepository, Commit.SetDirectory, Commit.SetFile, CheckinDatabaseQuery.SetRepository, CheckinDatabaseQuery.SetDirectory): remove path cleanup code (RLogDataToCommitList) don't strip repository prefix because rlog module now does it (CleanRepository): new function * lib/rlog.py (_get_co_file): change to return paths with forward slashes and without repository prefixes (GetRLogData): update call to _get_co_file * tools/cvsdbadmin (UpdateFile, CommandUpdate, RebuildFile, CommandRebuild) remove calls to normcase here (module code): use CleanRepository function to clean up repository path * tools/loginfo-handler (CleanDirectory): removed (HeuristicArgParse, CvsNtArgParse): don't call CleanDirectory or normcase here (HeuristicArgParseDirectory): remove stray print statement (module code): use cvsdb.CleanRepository function to clean up repository path * tools/svndbadmin (module code): use cvsdb.CleanRepository function to clean up repository path * lib/viewcvs.py (view_query): change to use forward slashes in directory names instead of native slashes use cvsdb.CleanRepository function to clean up repository paths * lib/query.py (build_commit): change to handle forward slashes in directory paths instead of native slashes (run_query): use cvsdb.CleanRepository function to clean up repository path git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@952 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 04:47:42 +04:00
def FindRepository(db, path):
"""Find repository path in database given path to subdirectory
Returns normalized repository path and relative directory path"""
path = os.path.normpath(path)
dirs = []
while path:
rep = os.path.normcase(path)
if db.GetRepositoryID(rep, 0) is None:
path, pdir = os.path.split(path)
if not pdir:
return None, None
dirs.append(pdir)
else:
break
dirs.reverse()
return rep, dirs
Fix file path issues in CVSdb on windows. Summary of changes: - Stop converting directory and file paths to lower case with native slashes before storing them in the database. Instead store with preserved case and forward slashes. - Stop trying to clean up paths haphazardly all over the cvsdb module, instead expect paths to be normalized before they get passed to cvsdb. * lib/cvsdb.py (Commit.SetRepository, Commit.SetDirectory, Commit.SetFile, CheckinDatabaseQuery.SetRepository, CheckinDatabaseQuery.SetDirectory): remove path cleanup code (RLogDataToCommitList) don't strip repository prefix because rlog module now does it (CleanRepository): new function * lib/rlog.py (_get_co_file): change to return paths with forward slashes and without repository prefixes (GetRLogData): update call to _get_co_file * tools/cvsdbadmin (UpdateFile, CommandUpdate, RebuildFile, CommandRebuild) remove calls to normcase here (module code): use CleanRepository function to clean up repository path * tools/loginfo-handler (CleanDirectory): removed (HeuristicArgParse, CvsNtArgParse): don't call CleanDirectory or normcase here (HeuristicArgParseDirectory): remove stray print statement (module code): use cvsdb.CleanRepository function to clean up repository path * tools/svndbadmin (module code): use cvsdb.CleanRepository function to clean up repository path * lib/viewcvs.py (view_query): change to use forward slashes in directory names instead of native slashes use cvsdb.CleanRepository function to clean up repository paths * lib/query.py (build_commit): change to handle forward slashes in directory paths instead of native slashes (run_query): use cvsdb.CleanRepository function to clean up repository path git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@952 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 04:47:42 +04:00
def CleanRepository(path):
"""Return normalized top-level repository path"""
Fix file path issues in CVSdb on windows. Summary of changes: - Stop converting directory and file paths to lower case with native slashes before storing them in the database. Instead store with preserved case and forward slashes. - Stop trying to clean up paths haphazardly all over the cvsdb module, instead expect paths to be normalized before they get passed to cvsdb. * lib/cvsdb.py (Commit.SetRepository, Commit.SetDirectory, Commit.SetFile, CheckinDatabaseQuery.SetRepository, CheckinDatabaseQuery.SetDirectory): remove path cleanup code (RLogDataToCommitList) don't strip repository prefix because rlog module now does it (CleanRepository): new function * lib/rlog.py (_get_co_file): change to return paths with forward slashes and without repository prefixes (GetRLogData): update call to _get_co_file * tools/cvsdbadmin (UpdateFile, CommandUpdate, RebuildFile, CommandRebuild) remove calls to normcase here (module code): use CleanRepository function to clean up repository path * tools/loginfo-handler (CleanDirectory): removed (HeuristicArgParse, CvsNtArgParse): don't call CleanDirectory or normcase here (HeuristicArgParseDirectory): remove stray print statement (module code): use cvsdb.CleanRepository function to clean up repository path * tools/svndbadmin (module code): use cvsdb.CleanRepository function to clean up repository path * lib/viewcvs.py (view_query): change to use forward slashes in directory names instead of native slashes use cvsdb.CleanRepository function to clean up repository paths * lib/query.py (build_commit): change to handle forward slashes in directory paths instead of native slashes (run_query): use cvsdb.CleanRepository function to clean up repository path git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@952 8cb11bc2-c004-0410-86c3-e597b4017df7
2004-10-16 04:47:42 +04:00
return os.path.normcase(os.path.normpath(path))