Subversion Repositories Scribus

Compare Revisions

Ignore whitespace Rev 12489 → Rev 12490

/tools/mrscribe/Svnwatch/svnxmlparser.py
0,0 → 1,209
#!/usr/bin/python
# Copyright (c) 2007, Oleksandr Moskalenko, Craig Ringer
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
###
"""Subversion XML parser
"""
__version__ = "0.1"
__license__ = "GPLv2"
__copyright__ = "Copyright 2007, Oleksandr Moskalenko"
__author__ = "Oleksandr Moskalenko <malex@tagancha.org>"
__contributors__ = ["Craig Ringer <craig@postnewspapers.com.au>"]
_debug = 1
 
# HTTP "User-Agent" header to send to servers when downloading Svn XML.
USER_AGENT = "SubversionXMLParser/%s +http://linux.tagancha.org/svnxmlparser" % __version__
# HTTP "Accept" header to send to servers when downloading Svn XML. If you don't
# want to send an Accept header, set this to None.
ACCEPT_HEADER = "text/xml"
 
# Default URI:
URI = "https://www.postnewspapers.com.au/cgi-bin/xmllog"
 
def fetchXml(uri, rev):
"""Fetches a document from the given URI (with gzip encoding). Returns the
document as a string, or an empty string in case of a transmission problem."""
import urllib2, gzip, StringIO
try:
revuri = "%s?%s" % (uri,rev)
request = urllib2.Request(revuri)
request.add_header('Accept-encoding', 'gzip')
opener = urllib2.build_opener()
handle = opener.open(request)
compressedData = handle.read()
# print 'Fetched ', len(compressedData), ' bytes.'
compressedStream = StringIO.StringIO(compressedData)
gzipper = gzip.GzipFile(fileobj=compressedStream,mode='r')
xml = gzipper.read()
if len(xml) <= 28:
print "No commit for this revision\n"
return None
return xml
except:
return None
 
def longest_common_prefix_for_paths(paths):
'''
Find the longest common prefix of `paths' and return it.
`paths' must be a list of strings, using / as a path component
separator.
'''
if len(paths) == 1:
# use just this path
return paths[0]
else:
# find common prefix
p = [ x.split('/') for x in paths ]
maxi = reduce( min, map( len, p ) )
for i in range(0, maxi):
if not reduce( lambda a,b: a and (b[i] == paths[0][i]),\
paths[1:], True):
break
return '/'.join(p[0][0:i])
 
def getText(nodelist):
rc = ""
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
 
def getCommit (xml):
"""Parses Svn XML and returns a dictionary containing commit data."""
if xml == None:
return xml
from xml.dom import minidom, Node
xmltree = minidom.parseString(xml)
logentries = xmltree.getElementsByTagName('logentry')
logdata = {}
for logentry in logentries:
if logentry.hasAttributes():
revision = logentry.getAttribute('revision')
logdata[revision]= {}
logdata[revision]['author'] = logentry.getElementsByTagName('author')[0].childNodes[0].data
logdata[revision]['date'] = logentry.getElementsByTagName('date')[0].childNodes[0].data
try:
logdata[revision]['msg'] = logentry.getElementsByTagName('msg')[0].childNodes[0].data
except IndexError:
logdata[revision]['msg'] = ""
paths = []
for path in logentry.getElementsByTagName("paths")[0].childNodes:
if path.nodeType == Node.ELEMENT_NODE:
paths.append(path.childNodes[0].data)
logdata[revision]['paths'] = paths
common_path = longest_common_prefix_for_paths(paths)
logdata[revision]['common_path'] = common_path
short_paths = []
for path in paths:
try:
short_paths.append(path.split(common_path)[1][1:])
except IndexError:
pass
logdata[revision]['short_paths'] = short_paths
return logdata
 
def printoutput(commitdata):
datakeys = commitdata.keys()
datakeys.sort()
for i in datakeys:
logentry = commitdata[i]
logentry.keys().sort()
print "Revision: " + str(i)
for j in logentry.keys():
if type(logentry[j]) != list:
print "%s: \t %s" % (j,logentry[j].strip())
else:
print j+":"
for k in logentry[j]:
print "\t "+k
 
def getbranch(logentry):
import sys
fullpath = logentry['common_path']
pathelements = fullpath.split("/")
if pathelements[1] == 'trunk':
return 'trunk'
else:
return "%s" % pathelements[2]
 
def shortoutput(commitdata):
outlist = []
datakeys = commitdata.keys()
datakeys.sort()
for i in datakeys:
logentry = commitdata[i]
logentry.keys().sort()
from datetime import datetime
from time import strptime
indatetime = logentry["date"].split('.')[0]
rawdatetime = datetime(*strptime(indatetime, "%Y-%m-%dT%H:%M:%S")[0:6])
outdate,outtime = rawdatetime.strftime("%Y-%m-%d %H:%M:%S").split(" ")
branch = getbranch(logentry)
outstr = "revision %s by %s in %s on %s at %s - %s" % (i, logentry["author"], branch, outdate, outtime, logentry["msg"])
finalstr = outstr.replace("\n", " ")
outlist.append(finalstr)
return outlist
# for j in logentry.keys():
# #FIXME
# if type(logentry[j]) != list:
# print "%s: \t %s" % (j,logentry[j].strip())
# else:
# print j+":"
# for k in logentry[j]:
# print "\t "+k
 
def processUri(xmluri,rev):
print xmluri
rawxml = fetchXml(xmluri,rev)
commitdata = getCommit(rawxml)
if commitdata == None:
return None
else:
outdata = shortoutput(commitdata)
return outdata
 
def getHead(xmluri):
"""Fetches the head revision number for internal processing. Returns 'HEAD'
in case of error or misconfiguration."""
rev = "HEAD"
rawxml = fetchXml(xmluri,rev)
commitdata = getCommit(rawxml)
if commitdata == None:
return None
else:
return commitdata.keys()[0]
 
def Main ():
import sys
"""Called when the program is used interactively."""
if len(sys.argv)>1:
args = sys.argv[1:]
# print args
else:
args = ['HEAD']
for i in args:
print "Fetching commit information for '%s':" % i
xml = fetchXml(URI,i)
commitdata = getCommit(xml)
if commitdata == None:
sys.exit()
out = shortoutput(commitdata)
for i in out:
print i
sys.exit()
 
if __name__ == '__main__':
Main()