OpenCores
URL https://opencores.org/ocsvn/radiohdl/radiohdl/trunk

Subversion Repositories radiohdl

[/] [radiohdl/] [trunk/] [core/] [modify_configfiles] - Rev 4

Compare with Previous | Blame | View Log

#!/usr/bin/env python3
###############################################################################
#
# Copyright (C) 2014-2018
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# $Id: configfile_modifier.py 18609 2018-07-18 08:06:30Z overeem $
#
###############################################################################

"""
Interactive program to modify all configfiles found in the hierarchical directory
structure under the given top directory.
"""

from argparse import ArgumentParser
from hdl_raw_access import RawConfigTree

# Define a simple menu system that is based on a dict that contains the menu actions:
#   the keys are the valid strings the user may enter
#   the values are lists: the first element is the menu tekst, the second the function to call and
#                         the remaining elememts (if any) are the arguments to ask the user
#   All arguments are stored in a kwargs structure and passed to the functions that is called.


def get_menu_choice(menu, title):
    """
    Iterate over the menu dict, show the menu choices and ask for input till valid input is received.
    """
    print("\n", title)
    print("-" * len(title))
    input_ok = False
    while not input_ok:
        for key in sorted(menu.keys()):
            print("{}  {}".format(key, menu[key][0]))
        choice = input("\n >>: ")
        if choice not in list(menu.keys()):
            print("ERROR: This input is not a valid menu choice. Try again.")
        else:
            input_ok = True
    return menu[choice]


def execute_menu_line(line_spec, verbose):
    """
    Given a menu line specification it asks the user for the specified arguments, stores the values in a
    kwargs structure and finally call the specified function with this kwargs.
    """
    print("\n--- {} ---".format(line_spec[0]))
    nr_args = len(line_spec) - 2
    if nr_args < 0:
        raise SyntaxError("Invalid formatted menuline definition: {}.\nNeed at least two items in the list".format(line_spec))
    if nr_args == 0:
        return line_spec[1]()
    # Iterate over the remaining items and get values for them
    kwargs = {"verbose": verbose}
    for spec_idx in range(2, len(line_spec)):
        answer = input(line_spec[spec_idx].capitalize().replace("_", " ") + ": ")
        kwargs[line_spec[spec_idx]] = answer
    line_spec[1](**kwargs)


# ## Implementation of the menu commands
# Note: cleaner would to implement this with the Strategy pattern but we want to keep the code
#       to be readable for everyone. ;-)
def change_value_of_key(**kwargs):
    key       = kwargs.pop("key")
    new_value = kwargs.pop("new_value")
    verbose   = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].change_value(key, new_value, verbose)


def append_key_value(**kwargs):
    key       = kwargs.pop("new_key")
    new_value = kwargs.pop("new_value")
    verbose   = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].append_key_value(key, new_value, verbose)


def insert_key_at_linenr(**kwargs):
    new_key    = kwargs.pop("new_key")
    new_value  = kwargs.pop("new_value")
    linenumber = int(kwargs.pop("linenumber"))
    verbose    = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].insert_key_at_linenr(new_key, new_value, linenumber, verbose)


def insert_key_value_before_key(**kwargs):
    new_key    = kwargs.pop("new_key")
    new_value  = kwargs.pop("new_value")
    before_key = kwargs.pop("before_key")
    verbose    = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].insert_key_value_before_key(new_key, new_value, before_key, verbose)


def rename_key(**kwargs):
    old_key = kwargs.pop("old_key")
    new_key = kwargs.pop("new_key")
    verbose = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].rename_key(old_key, new_key, verbose)


def remove_key(**kwargs):
    key     = kwargs.pop("key")
    verbose = kwargs.pop("verbose")
    global tree
    for filename in sorted(tree.configfiles.keys()):
        tree.configfiles[filename].remove_key(key, verbose)


def end_menu():
    global running
    running = False


if __name__ == '__main__':
    # setup parser and parse the arguments.
    argparser = ArgumentParser(description='Options and arguments for modifying collections of configfiles.')
    argparser.add_argument('filename', help="Filename like 'hdl_buildset_<boardtype>.cfg'")
    argparser.add_argument('rootdir', help="Top directory to start the search for configfiles.")
    argparser.add_argument('-v', '--verbose', help="Show more information on what happens.", action="store_true")
    args = argparser.parse_args()

    tree = RawConfigTree(args.rootdir, args.filename)
    print("Found {} configfiles in {}".format(len(tree.configfiles), args.rootdir))
    if args.verbose:
        for filename in sorted(tree.configfiles.keys()):
            print(filename)

    # define the menu including actions
    #     choice    choice description            function to call             arguments to ask for
    menu = {'1': ["Change value",                change_value_of_key,         "key",     "new_value"],
            '2': ["Append key",                  append_key_value,            "new_key", "new_value"],
            '3': ["Insert key at linenr",        insert_key_at_linenr,        "new_key", "new_value", "linenumber"],
            '4': ["Insert key before other key", insert_key_value_before_key, "new_key", "new_value", "before_key"],
            '5': ["Rename key",                  rename_key,                  "old_key", "new_key"],
            '6': ["Remove key",                  remove_key,                  "key"],
            'q': ["Exit",                        end_menu]
            }

    running = True
    while running:
        execute_menu_line(get_menu_choice(menu, "Menu for changing multiple configfiles"), args.verbose)

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.