From 60ca4c55728ee9472e4f3f9ec4110cc6141b4e2e Mon Sep 17 00:00:00 2001 From: Yoshinori Okuji <yo@nexedi.com> Date: Tue, 17 Aug 2004 14:23:50 +0000 Subject: [PATCH] Initial import. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@1379 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Extensions/CheckSkins.py | 341 ++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100755 product/ERP5/Extensions/CheckSkins.py diff --git a/product/ERP5/Extensions/CheckSkins.py b/product/ERP5/Extensions/CheckSkins.py new file mode 100755 index 0000000000..6259fe2010 --- /dev/null +++ b/product/ERP5/Extensions/CheckSkins.py @@ -0,0 +1,341 @@ +from Globals import get_request +import re +import os +import sys + +try: + from App.config import getConfiguration +except ImportError: + getConfiguration = None + +if getConfiguration is None: + data_dir = '/var/lib/zope/data' +else: + data_dir = getConfiguration().instancehome + '/data' + +fs_skin_spec = ('ERP5 Filesystem Formulator Form', + 'ERP5 Filesystem PDF Template', + 'Filesystem Formulator Form', + 'Filesystem Page Template', + 'Filesystem Script (Python)', + 'Filesystem Z SQL Method') + +zodb_skin_spec = ('ERP5 Form', 'ERP5 PDF Template', 'Page Template', 'Script', 'Script (Python)','Z SQL Method') + +def getSkinPathList(self, spec=fs_skin_spec+zodb_skin_spec): + path_list = self.portal_skins.getSkinPath(self.portal_skins.getDefaultSkin()) + path_list = path_list.split(',') + skin_list = [] + for path in path_list: + if path in ('content', 'content18', 'control', 'generic', 'mailin', 'pro', 'topic', 'zpt_content', 'zpt_control', 'zpt_generic', 'zpt_reporttool', 'zpt_topic'): + continue + for id in self.portal_skins[path].objectIds(spec): + skin_list.append(path + '/' + id) + return skin_list + +def split(name): + """ + Split the name using an underscore as a separator and + using the change from lower case to upper case as a separator. + + Example: foo_barBaz -> foo, bar, Baz + """ + part_list = [] + part = '' + pc = None + for c in name: + if c == '_': + if len(part) > 0: + part_list.append(part) + part = '' + pc = None + elif pc is not None and pc.islower() and c.isupper(): + if len(part) > 0: + part_list.append(part) + part = c + pc = None + else: + pc = c + part += c + if pc is not None: + part_list.append(part) + return part_list + +def suggestName(name, meta_type): + """ + Suggest a good name for a given name. + """ + # Determine the prefix. The default is "Base_". + i = name.find('_') + if i < 1: + prefix = 'Base' + else: + # Special treatment for view, print, create and list, because they are used very often. + # packing list is an exception, because it is confusing (i.e. sale_packing_list_list). + view_index = name.find('_view') + print_index = name.find('_print') + create_index = name.find('_create') + list_index = name.find('_list') + packing_list_index = name.find('packing_list_') + if view_index > 0: + i = view_index + elif print_index > 0: + i = print_index + elif create_index > 0: + i = create_index + elif list_index > 0: + if packing_list_index > 0: + i = packing_list_index + 12 + else: + i = list_index + part_list = split(name[:i]) + prefix = '' + for part in part_list: + prefix += part.capitalize() + name = name[i+1:] + if meta_type in ('Filesystem Z SQL Method', 'Z SQL Method'): + new_name = 'z' + if name[0] == 'z': + name = name[1:] + part_list = split(name) + for part in part_list: + new_name += part.capitalize() + else: + part_list = split(name) + new_name = part_list[0].lower() + for part in part_list[1:]: + new_name += part.capitalize() + return prefix + '_' + new_name + + +def checkSkinNames(self, REQUEST=None, csv=0, all=0): + """ + Check if the name of each skin follows the naming convention. + """ + if csv: + msg = 'Folder,Name,New Name,Meta Type\n' + else: + msg = '<html><body>' + rexp = re.compile('^[A-Z][a-zA-Z0-9]*_[a-z][a-zA-Z0-9]*$') + rexp_zsql = re.compile('^[A-Z][a-zA-Z0-9]*_z[A-Z][a-zA-Z0-9]*$') + path_list = getSkinPathList(self) + bad_list = [] + for path in path_list: + name = path.split('/')[-1] + skin = self.portal_skins.restrictedTraverse(path) + if skin.meta_type in ('Filesystem Z SQL Method', 'Z SQL Method'): + r = rexp_zsql + else: + r = rexp + if all or r.search(name) is None: + bad_list.append((path, skin.meta_type)) + if len(bad_list) == 0: + if not csv: + msg += '<p>Everything is fine.</p>\n' + else: + bad_list.sort() + if not csv: + msg += '<p>These %d skins do not follow the naming convention:</p><table width="100%%">\n' % len(bad_list) + msg += '<tr><td>Folder</td><td>Skin Name</td><td>Meta Type</td></tr>\n' + i = 0 + for path,meta_type in bad_list: + name = path.split('/')[-1] + suggested_name = suggestName(name, meta_type) + folder = path[:-len(name)-1] + if (i % 2) == 0: + c = '#88dddd' + else: + c = '#dddd88' + i += 1 + if csv: + msg += '%s,%s,%s,%s\n' % (folder, name, suggested_name, meta_type) + else: + msg += '<tr bgcolor="%s"><td>%s</td><td>%s</td><td>%s</td></tr>\n' % (c, folder, name, meta_type) + if not csv: + msg += '</table>\n' + if not csv: + msg += '</body></html>' + return msg + +def fixSkinNames(self, REQUEST=None, file=None, dry_run=1): + """ + Fix bad skin names. + + This method does: + + - Check all the contents of all skins. + + - Check immediate_view, constructor_path and actions in all portal types. + + - Check skins of all business templates. + + - Check actbox_url in transitions and worklists and scripts of all workflows. + + - Rename skins. + """ + if REQUEST is None: + REQUEST = get_request() + + if file is None: + msg = 'You must put a CSV file inside the data directory, and specify %s/ERP5Site_fixSkinNames?file=NAME \n\n' % self.absolute_url() + msg += 'The template of a CSV file is available via %s/ERP5Site_checkSkinNames?csv=1 \n\n' % self.absolute_url() + msg += 'This does not modify anything by default. If you really want to fix skin names, specify %s/ERP5Site_fixSkinNames?file=NAME&dry_run=0 \n\n' % self.absolute_url() + return msg + + file = os.path.join(data_dir, file) + file = open(file, 'r') + class NamingInformation: pass + info_list = [] + try: + for line in file: + folder, name, new_name, meta_type = line.strip().split(',') + if meta_type == 'Meta Type': continue + if name == new_name: continue + # Check the existence of the skin and the meta type. Paranoid? + #if self.portal_skins[folder][name].meta_type != meta_type: + # raise RuntimeError, '%s/%s has a different meta type' % (folder, name) + info = NamingInformation() + info.folder = folder + info.name = name + info.new_name = new_name + info.regexp = re.compile('\\b' + re.escape(name) + '\\b') # This is used to search the name + info_list.append(info) + finally: + file.close() + + # Now we have information enough. Check the skins. + msg = '' + path_list = getSkinPathList(self) + for path in path_list: + skin = self.portal_skins.restrictedTraverse(path) + try: + text = skin.manage_FTPget() + except: + type, value, traceback = sys.exc_info() + msg += 'WARNING: the skin %s could not be retrieved because of the exception %s: %s\n' % (path, str(type), str(value)) + else: + name_list = [] + for info in info_list: + if info.regexp.search(text) is not None: + text = info.regexp.sub(info.new_name, text) + name_list.append(info.name) + if len(name_list) > 0: + msg += '%s is modified for %s\n' % ('portal_skins/' + path, ', '.join(name_list)) + if not dry_run: + REQUEST['BODY'] = text + skin.manage_FTPput(REQUEST, REQUEST.RESPONSE) + + # Check the portal types. + for t in self.portal_types.objectValues(): + # Initial view name. + text = t.immediate_view + for info in info_list: + if info.name == text: + msg += 'Initial view name of %s is modified for %s\n' % ('portal_types/' + t.id, text) + if not dry_run: + t.immediate_view = info.new_name + break + # Constructor path. + text = getattr(t, 'constructor_path', None) + if text is not None: + for info in info_list: + if info.name == text: + msg += 'Constructor path of %s is modified for %s\n' % ('portal_types/' + t.id, text) + if not dry_run: + t.constructor_path = info.new_name + break + # Actions. + for action in t.listActions(): + text = action.action.text + for info in info_list: + if info.regexp.search(text) is not None: + text = info.regexp.sub(info.new_name, text) + msg += 'Action %s of %s is modified for %s\n' % (action.getId(), 'portal_types/' + t.id, info.name) + if not dry_run: + action.action.text = text + break + + # Check the portal templates. + template_tool = getattr(self, 'portal_templates', None) + # Check the existence of template tool, because an older version of ERP5 does not have it. + if template_tool is not None: + for template in template_tool.contentValues(filter={'portal_type':'Business Template'}): + # Skins. + skin_id_list = [] + name_list = [] + for skin_id in template.getTemplateSkinIdList(): + for info in info_list: + if info.name == skin_id: + name_list.append(skin_id) + skin_id = info.new_name + break + skin_id_list.append(skin_id) + if len(name_list) > 0: + msg += 'Skins of %s is modified for %s\n' % ('portal_templates/' + template.getId(), ', '.join(name_list)) + if not dry_run: + template.setTemplateSkinIdList(skin_id_list) + # Paths. + path_list = [] + name_list = [] + for path in template.getTemplatePathList(): + for info in info_list: + if info.regexp.search(path): + name_list.append(skin_id) + path = info.regexp.sub(info.new_name, path) + break + path_list.append(path) + if len(name_list) > 0: + msg += 'Paths of %s is modified for %s\n' % ('portal_templates/' + template.getId(), ', '.join(name_list)) + if not dry_run: + template.setTemplatePathList(path_list) + + # Workflows. + for wf in self.portal_workflow.objectValues(): + # Transitions. + for id in wf.transitions.objectIds(): + transition = wf.transitions._getOb(id) + text = transition.actbox_url + for info in info_list: + if info.regexp.search(text) is not None: + text = info.regexp.sub(info.new_name, text) + msg += 'Transition %s of %s is modified for %s\n' % (id, 'portal_workflow/' + wf.id, info.name) + if not dry_run: + transition.actbox_url = text + break + # Worklists. + for id in wf.worklists.objectIds(): + worklist = wf.worklists._getOb(id) + text = worklist.actbox_url + for info in info_list: + if info.regexp.search(text) is not None: + text = info.regexp.sub(info.new_name, text) + msg += 'Worklist %s of %s is modified for %s\n' % (id, 'portal_workflow/' + wf.id, info.name) + if not dry_run: + worklist.actbox_url = text + break + # Scripts. + for id in wf.scripts.objectIds(): + script = wf.scripts._getOb(id) + text = script.manage_FTPget() + name_list = [] + for info in info_list: + if info.regexp.search(text) is not None: + text = info.regexp.sub(info.new_name, text) + name_list.append(info.name) + if len(name_list) > 0: + msg += 'Script %s of %s is modified for %s\n' % (id, 'portal_workflow/' + wf.id, ', '.join(name_list)) + if not dry_run: + REQUEST['BODY'] = text + script.manage_FTPput(REQUEST, REQUEST.RESPONSE) + + # Rename the skins. + if not dry_run: + for info in info_list: + try: + folder = self.portal_skins[info.folder] + folder.manage_renameObjects([info.name], [info.new_name]) + except: + type, value, traceback = sys.exc_info() + msg += 'WARNING: the skin %s could not be renamed to %s because of the exception %s: %s\n' % (info.name, info.new_name, str(type), str(value)) + + return msg \ No newline at end of file -- 2.30.9