Created
March 31, 2014 22:44
-
-
Save seanupton/9904076 to your computer and use it in GitHub Desktop.
Recursive checker for Plone 3 to Plone 4 product upgrade
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import sys | |
import urllib2 | |
from z3c.pt.language import Parser | |
defines = { | |
'template_id' : 'template/getId', | |
'normalizeString' : 'nocall:context/@@plone/normalizeString', | |
'toLocalizedTime' : 'nocall:context/@@plone/toLocalizedTime', | |
'portal_properties' : 'context/portal_properties', | |
'site_properties' : 'context/portal_properties/site_properties', | |
'here_url' : 'context/@@plone_context_state/object_url', | |
'portal' : 'context/@@plone_portal_state/portal', | |
'isAnon' : 'context/@@plone_portal_state/anonymous', | |
'member' : 'context/@@plone_portal_state/member', | |
'actions' : 'python:context.portal_actions.listFilteredActionsFor(context)', | |
'mtool' : 'context/portal_membership', | |
'wtool' : 'context/portal_workflow', | |
'wf_state' : 'context/@@plone_context_state/workflow_state', | |
'default_language' : 'context/@@plone_portal_state/default_language', | |
'is_editable' : 'context/@@plone_context_state/is_editable', | |
'isContextDefaultPage' : 'context/@@plone_context_state/is_default_page', | |
'object_title' : 'context/@@plone_context_state/object_title', | |
'putils' : 'context/plone_utils', | |
'ztu' : 'modules/ZTUtils', | |
'acl_users' : 'context/acl_users', | |
'ifacetool' : 'context/portal_interface', | |
'syntool' : 'context/portal_syndication', | |
} | |
literal_tokens = ( | |
'template_id', 'normalizeString', 'toLocalizedTime', | |
'portal_properties', 'site_properties', 'here_url', | |
'isAnon', 'mtool', 'wtool', 'wf_state', 'default_language', | |
'is_editable', 'isContextDefaultPage', 'object_title', | |
'putils', 'ztu', 'acl_users', 'ifacetool', 'syntool', | |
) | |
re_tokens = { | |
re.compile('portal[.]') : 'portal', | |
re.compile('portal[/]') : 'portal', | |
re.compile('member[.]') : 'member', | |
re.compile('member[/]') : 'member', | |
re.compile('actions[/]') : 'actions', | |
re.compile('actions[.]') : 'actions', | |
} | |
LINEBR = re.compile('[\r\n]+') | |
parser = Parser() | |
def main(prod_dir, suggest_fix=False): | |
""" | |
Parse and grep for possible Plone 4 template issues in a Product/package | |
designed for Plone 3. | |
Attempt xml parsing ZPT template with z3c.pt, grep for | |
identifier names relying on Plone 3 global defines that no | |
longer exist in Plone 4. | |
If suggest_fix is True, print a suggested div tag fragment with | |
necessary defines to copy and paste into the problem template. | |
""" | |
v = [ | |
[os.path.realpath( | |
os.path.join(e[0], i)) | |
for i in e[2] if i.endswith('pt')] | |
for e in os.walk(prod_dir) ] | |
template_files = reduce(lambda x,y: x+y, v) | |
for fname in template_files: | |
content = urllib2.urlopen('file://%s' % fname).read() | |
dname = fname.replace(prod_dir, '') #display name relative path | |
marked = [] | |
try: | |
chameleon_doc = parser.parse(content) #parse | |
except: | |
print 'XML well-formedness parsing error: %s' % fname | |
# fun grep-like scanning: | |
lines = LINEBR.split(content) | |
lineno = 1 | |
for line in lines: | |
for token in literal_tokens: | |
if token in line: | |
marked.append((lineno, token, line)) | |
for expr,token in re_tokens.items(): | |
if expr.search(line): | |
marked.append((lineno, token, line)) | |
lineno += 1 | |
if marked: | |
print dname | |
print '-'*len(dname) | |
if suggest_fixes: | |
block = '<div tal:define="' | |
indent = 0 | |
for token in set([m[1] for m in marked]): | |
block += (' '*indent) + '%s %s;\n' % (token, defines[token]) | |
indent = 17 | |
block += '">\n' | |
print block | |
print '---' | |
for instance in marked: | |
print '[Line %s] matched token: %s\n\t%s' % instance | |
print '='*78 | |
if __name__ == '__main__': | |
if len(sys.argv) < 2 or (len(sys.argv)==2 and sys.argv[-1]=='--fix'): | |
print >> sys.stderr, 'Usage: check.py [--fix] <product_dir>' | |
exit(0) | |
prod_dir = sys.argv[-1] | |
suggest_fixes = '--fix' in sys.argv | |
main(prod_dir, suggest_fixes) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment