Commit 50bfdffe authored by Christophe Dumez's avatar Christophe Dumez

- rewritten tree construction. It consumes a lot less memory and is a bit faster.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@7370 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 4731ebd5
...@@ -48,7 +48,6 @@ from Products.CMFCore.utils import getToolByName ...@@ -48,7 +48,6 @@ from Products.CMFCore.utils import getToolByName
from Products.ERP5.Document.BusinessTemplate import removeAll from Products.ERP5.Document.BusinessTemplate import removeAll
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
try: try:
from base64 import b64encode, b64decode from base64 import b64encode, b64decode
except ImportError: except ImportError:
...@@ -60,6 +59,47 @@ try: ...@@ -60,6 +59,47 @@ try:
except NameError: except NameError:
from sets import Set as set from sets import Set as set
class File(object):
__slots__ = ('status','name')
# Constructor
def __init__(self, name, status) :
self.status = status
self.name = name
## End of File Class
class Dir(object):
__slots__ = ('status','name','sub_dirs','sub_files')
# Constructor
def __init__(self, name, status) :
self.status = status
self.name = name
self.sub_dirs = [] # list of sub directories
self.sub_files = [] # list of sub files
# return a list of sub directories' names
def getSubDirsNameList(self) :
return [d.name for d in self.sub_dirs]
# return directory in subdirs given its name
def getDirFromName(self, name):
for d in self.sub_dirs:
if d.name == name:
return d
def getObjectFromName(self, name):
for d in self.sub_dirs:
if d.name == name:
return d
for f in self.sub_files:
if f.name == name:
return f
def getContent(self):
content = self.sub_dirs
content.extend(self.sub_files)
return content
## End of Dir Class
class Error(exceptions.EnvironmentError): class Error(exceptions.EnvironmentError):
pass pass
...@@ -151,33 +191,6 @@ def colorize(text): ...@@ -151,33 +191,6 @@ def colorize(text):
html = html.replace(os.linesep, os.linesep+"<br>") html = html.replace(os.linesep, os.linesep+"<br>")
return html return html
class File :
# Constructor
def __init__(self, full_path, msg_status) :
self.full_path = full_path
self.msg_status = msg_status
self.name = os.path.basename(full_path)
## End of File Class
class Dir :
# Constructor
def __init__(self, full_path, msg_status) :
self.full_path = full_path
self.msg_status = msg_status
self.name = os.path.basename(full_path)
self.sub_dirs = [] # list of sub directories
# return a list of sub directories' names
def getSubDirs(self) :
return [d.name for d in self.sub_dirs]
# return directory in subdirs given its name
def getDir(self, name):
for d in self.sub_dirs:
if d.name == name:
return d
## End of Dir Class
class DiffFile: class DiffFile:
# Members : # Members :
# - path : path of the modified file # - path : path of the modified file
...@@ -936,44 +949,51 @@ class SubversionTool(BaseTool, UniqueObject, Folder): ...@@ -936,44 +949,51 @@ class SubversionTool(BaseTool, UniqueObject, Folder):
removeAll(file) removeAll(file)
def getModifiedTree(self, bt, show_unmodified=False) : def getModifiedTree(self, bt, show_unmodified=False) :
# Remove trailing slash if it's present # Get subversion path without business template name at the end
path = self._getWorkingPath(self.getSubversionPath(bt)) bt_path = self._getWorkingPath(self.getSubversionPath(bt, False))
root = Dir(path, "normal") if bt_path[-1] != '/':
bt_path += '/'
# Business template root directory is the root of the tree
root = Dir(bt.getTitle(), "normal")
somethingModified = False somethingModified = False
for statusObj in self.status(path) : # We browse the files returned by svn status
for status_obj in self.status(os.path.join(bt_path, bt.getTitle())) :
# can be (normal, added, modified, deleted, conflicted, unversioned) # can be (normal, added, modified, deleted, conflicted, unversioned)
msg_status = statusObj.getTextStatus() status = str(status_obj.getTextStatus())
if (show_unmodified or str(msg_status) != "normal") and str(msg_status) != "unversioned": if (show_unmodified or status != "normal") and status != "unversioned":
somethingModified = True somethingModified = True
full_path = statusObj.getPath() # Get object path
full_path_list = full_path.split(os.sep)[1:] full_path = status_obj.getPath()
relative_path_list = full_path[len(path)+1:].split(os.sep) relative_path = full_path.replace(bt_path, '')
# Processing entry filename = os.path.basename(relative_path)
filename = relative_path_list[-1]
# Needed or files will be both File & Dir objects # Always start from root
relative_path_list = relative_path_list[:-1]
parent = root parent = root
i = len(path.split(os.sep))
for d in relative_path_list : # First we add the directories present in the path to the tree
# if it does not already exist
for d in relative_path.split(os.sep)[1:-1] :
if d : if d :
full_pathOfd = os.sep+os.sep.join(full_path_list[:i]).strip() if d not in parent.getSubDirsNameList() :
if d not in parent.getSubDirs() : parent.sub_dirs.append(Dir(d, "normal"))
parent.sub_dirs.append(Dir(full_pathOfd, "normal")) parent = parent.getDirFromName(d)
parent = parent.getDir(d)
i += 1
# Consider the whole path which can be a folder or a file
# We add it the to the tree if it does not already exist
if os.path.isdir(full_path) : if os.path.isdir(full_path) :
if full_path == parent.full_path : if filename == parent.name :
parent.msg_status = str(msg_status) parent.status = status
elif filename not in parent.getSubDirs() : elif filename not in parent.getSubDirsNameList() :
parent.sub_dirs.append(Dir(filename, str(msg_status))) # Add new dir to the tree
parent.sub_dirs.append(Dir(filename, str(status)))
else : else :
tmp = parent.getDir(filename) # update msg status
tmp.msg_status = str(msg_status) tmp = parent.getDirFromName(filename)
tmp.status = str(status)
else : else :
parent.sub_dirs.append(File(full_path, str(msg_status))) # add new file to the tree
parent.sub_files.append(File(filename, str(status)))
return somethingModified and root return somethingModified and root
def extractBT(self, bt): def extractBT(self, bt):
...@@ -1083,51 +1103,41 @@ class SubversionTool(BaseTool, UniqueObject, Folder): ...@@ -1083,51 +1103,41 @@ class SubversionTool(BaseTool, UniqueObject, Folder):
self.add([os.path.join(old_dir, x[1]) for x in list]) self.add([os.path.join(old_dir, x[1]) for x in list])
def treeToXML(self, item, bt) : def treeToXML(self, item, bt) :
working_copy = self._getWorkingPath(self.getSubversionPath(bt, False) + os.sep)
output = "<?xml version='1.0' encoding='iso-8859-1'?>"+ os.linesep output = "<?xml version='1.0' encoding='iso-8859-1'?>"+ os.linesep
output += "<tree id='0'>" + os.linesep output += "<tree id='0'>" + os.linesep
output = self._treeToXML(item, working_copy, output, 1, True) output = self._treeToXML(item, output, bt.getTitle(), True)
output += "</tree>" + os.linesep output += "</tree>" + os.linesep
return output return output
def _treeToXML(self, item, working_copy, output, ident, first) : def _treeToXML(self, item, output, relative_path, first) :
# Choosing a color coresponding to the status # Choosing a color coresponding to the status
itemStatus = item.msg_status status = item.status
if itemStatus == 'added' : if status == 'added' :
itemColor='green' color = 'green'
elif itemStatus == 'modified' or itemStatus == 'replaced' : elif status == 'modified' or status == 'replaced' :
itemColor='orange' color = 'orange'
elif itemStatus == 'deleted' : elif status == 'deleted' :
itemColor='red' color = 'red'
elif itemStatus == 'conflicted' : elif status == 'conflicted' :
itemColor='grey' color = 'grey'
else : else :
itemColor='black' color = 'black'
if isinstance(item, Dir) : if isinstance(item, Dir) :
for i in range(ident) :
output += '\t'
if first : if first :
output += '<item open="1" text="%s" id="%s" aCol="%s" '\ output += '<item open="1" text="%s" id="%s" aCol="%s" '\
'im0="folder.png" im1="folder_open.png" '\ 'im0="folder.png" im1="folder_open.png" '\
'im2="folder.png">'%(item.name, item.full_path.replace(working_copy, ''), itemColor,) + os.linesep 'im2="folder.png">'%(item.name, relative_path, color) + os.linesep
first = False first = False
else : else :
output += '<item text="%s" id="%s" aCol="%s" im0="folder.png" ' \ output += '<item text="%s" id="%s" aCol="%s" im0="folder.png" ' \
'im1="folder_open.png" im2="folder.png">'%(item.name, 'im1="folder_open.png" im2="folder.png">'%(item.name,
item.full_path.replace(working_copy, ''), itemColor,) + os.linesep relative_path, color) + os.linesep
for it in item.sub_dirs: for it in item.getContent():
ident += 1 output = self._treeToXML(item.getObjectFromName(it.name), output, os.path.join(relative_path,it.name),first)
output = self._treeToXML(item.getDir(it.name), working_copy, output, ident,
first)
ident -= 1
for i in range(ident) :
output += '\t'
output += '</item>' + os.linesep output += '</item>' + os.linesep
else : else :
for i in range(ident) :
output += '\t'
output += '<item text="%s" id="%s" aCol="%s" im0="document.png"/>'\ output += '<item text="%s" id="%s" aCol="%s" im0="document.png"/>'\
%(item.name, item.full_path.replace(working_copy, ''), itemColor,) + os.linesep %(item.name, relative_path, color) + os.linesep
return output return output
InitializeClass(SubversionTool) InitializeClass(SubversionTool)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment