1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import compiler
import compiler.ast
import compiler.visitor
class Visitor(compiler.visitor.ASTVisitor):
def __init__(self, func_name):
self.func_name = func_name
compiler.visitor.ASTVisitor.__init__(self)
self.result = []
def visitCallFunc(self, node, *args):
if ((isinstance(node.node, compiler.ast.Name) and
node.node.name==self.func_name)
or
(isinstance(node.node, compiler.ast.Getattr) and
node.node.attrname==self.func_name)
):
arg = node.args[0]
value = None
if isinstance(arg, compiler.ast.Const):
value = arg.value
elif isinstance(arg, compiler.ast.Add):
value = concatenate_add_const_value(arg)
if value is not None:
self.result.append(value)
for child_node in node.args:
self.preorder(child_node, self)
def concatenate_add_const_value(node):
def iterate(nodes):
if not nodes:
return ''
node = nodes[0]
if isinstance(node, compiler.ast.Const):
return node.value + iterate(nodes[1:])
elif isinstance(node, compiler.ast.Add):
if getattr(node, 'nodes', None):
children_nodes = node.nodes
else:
children_nodes = (node.left, node.right)
return iterate(children_nodes)+iterate(nodes[1:])
elif isinstance(node, compiler.ast.Mod):
# we can't handle Mod node statically.
pass
return iterate((node,))
def getFunctionFirstArgumentValue(func_name, source):
ast = compiler.parse(source)
visitor = Visitor(func_name)
compiler.walk(ast, visitor)
return visitor.result
#
# Collect translation message from products
#
import os.path
import Products.ERP5
def findMessageListFromPythonInProduct(function_name_list):
product_dir = os.path.dirname(Products.ERP5.__path__[0])
erp5_product_list = ('CMFActivity', 'CMFCategory',
'ERP5', 'ERP5Banking', 'ERP5Catalog', 'ERP5Configurator',
'ERP5Form', 'ERP5OOo', 'ERP5Security', 'ERP5Vcs',
'ERP5SyncML', 'ERP5Type', 'ERP5Wizard', 'ERP5Workflow',
'HBTreeFolder2', 'MailTemplates', 'TimerService',
'ZMySQLDA', 'ZMySQLDDA', 'ZSQLCatalog',
)
result = []
def findStaticMessage(file_path):
source = open(file_path).read()
for func_name in function_name_list:
call_func_name = '%s(' % func_name
if call_func_name in source:
for m in getFunctionFirstArgumentValue(func_name, source):
result.append((m, file_path))
def visit(arg, dirname, filename_list):
for filename in filename_list:
if filename.endswith('.py'):
findStaticMessage(os.path.join(dirname, filename))
for product_name in erp5_product_list:
os.path.walk(os.path.join(product_dir, product_name), visit, None)
return result