pida-main / tools /

from __future__ import print_function
import sys

class ActionCall(object):
    def __init__(self, name, type, tooltip, doc, stock, callback=None, accel=None, glob=False): = name
        self.type = type
        self.tooltip = tooltip
        self.doc = doc
        self.stock = stock
        self.callback = callback and callback[5:] # strip self.
        self.accel = accel
        self.glob = bool(glob)

    def needs_rename(self):
        return '-' in

    def new_name(self):

    def needs_handler_rename(self):
        return self.callback is not None and 'on_' + self.new_name != self.callback

print('automated action rewrite of', sys.argv[1])
with open(sys.argv[1]) as fp:
    lines = list(fp)
old_lines = lines[:]

def findrange(lines, startcond, stopcond, pos=0, last=None, finalize=False):
    start = None
    for i in range(pos, last or len(lines)):
        line = lines[i]
        if start is None and startcond(line):
            start = i
        if start is not None and stopcond(line):
            end = i
            return start, end
    if finalize and start is not None:
        return start, last
    return None, None

def find_iter(lines, startcond, stopcond, pos=0, last=None):
    last = last or len(lines)
    pos, end = findrange(lines, startcond, stopcond, pos, last)
    while end is not None:
        yield pos, end
        pos, end = findrange(lines, startcond, stopcond, end, last, finalize=True)

def parse_action(lines):
    lines = [x.strip(' \n,') for x in lines]
    name = lines[0].strip('"\'')
    type = lines[1]
    tooltip = lines[2]
    doc = lines[3]
    stock = lines[4]
    if len(lines) > 5:
        callback = lines[5]
        if callback == 'None':
            callback = None
        callback = None
    return ActionCall(name, type, tooltip, doc, stock, callback,
                      # accel, global

start, end = findrange(lines,
    startcond = lambda line: '(ActionsConfig)' in line,
    stopcond = lambda line: line.startswith('class') or line[0] == '#',

print("actionsconfig:", start, end)

c_start, c_end = findrange(lines,
    startcond=lambda line: 'create_actions' in line,
    stopcond=lambda line: ' def ' in line,
    pos=start, last=end)

actions = []

renames = {}
for a_start, a_end in find_iter(lines,
    startcond=lambda line:'create_action(' in line,
    stopcond=lambda line: line.strip() == ')',
    pos=c_start, last=c_end):
        action = parse_action(lines[a_start+1: a_end])
        print('  ',, action.callback, end=' ')
        print('h' if action.needs_handler_rename else '', 'n' if action.needs_rename else '', sep='')
        if action.needs_handler_rename:
            renames[action.callback] = action

for m_start, m_end in find_iter(lines,
    startcond=lambda line: 'def' in line,
    stopcond=lambda line: 'def' in line,
    pos=start, last=end):
    funcdef = lines[m_start].strip()
    func_name = funcdef[4:].split('(')[0]
    if func_name in renames:
        print('  ', funcdef, '->', renames[func_name].name)
        lines[m_start] = lines[m_start].replace(
            'on_' + renames[func_name].new_name,
        print('  ', funcdef)

new_action_lines = []
a = new_action_lines.append
a('    actions = [\n')

for action in actions:
    a('        %s(\'%s\',\n' % (action.type, action.new_name))
    a('            %s,\n' % action.tooltip)
    a('            %s,\n' % action.doc)
    a('            %s),\n' % action.stock)

a('    ]\n')

all_accels = [action for action in actions if action.accel is not None]
accels = [action for action in all_accels if not action.glob]

if accels:
    a('    accels = {\n')
    for action in accels:
            a('        \'%s\': %s,\n' % (, action.accel) )
    a('    }\n')

global_accels = [action for action in all_accels if action.glob]
if global_accels:
    a('    global_accels = {\n')
    for action in global_accels:
        if action.accel is not None and action.glob:
            a('        \'%s\': %s,\n' % (, action.accel) )
    a('    }\n')

lines[c_start:c_end] = new_action_lines

import difflib

print(''.join(difflib.unified_diff(old_lines, lines,