HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Edit configuration files script

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scripteditconfigurationfiles

Problem

Script designed to avoid manually edit configuration files by support.

Config file example:

$ cat ../secure/test.property
[Connection settings]
jdbc.main.url = jdbc:oracle:thin:@host1
jdbc.main.username = USER
jdbc.main.password = pass

[Mail settings]
mail.smtp.host=127.0.0.1
mail.smtp.port=25
mail.smtp.on=false
mail.cronExpression=0 0/2 * ? * MON-SUN

[Import limits cron expressions]
gateKeeper.cronExpression=0 0 5 ? * MON-SUN
cleanup.compress.cronExpression=0 0 12 ? * SUN
send.mails.to.group.cronExpression = 0 0 12 ? * MON-SUN
exc_tckt_d.cronExpression=0 30 22 ? * MON-FRI

[Gate keeper settings]
gk.homedir=gate_keeper_report
sftp.useLocalFileIfAvailable=true
sftp.downloadBaseDir=~/download
sftp.maxRetryLimit=3

[TCP Report Extract Properties]
usePrecalculatedAggregation=true

[Other settings]
bean.datasource.query_log_wrapper=mainDataSourceWrapper
log.client.exception = false
time.to.keep.domain=7*12
time.to.keep.uncompress=1
dao.batch.size.max=30


The script uses the ConfigParser module, to select and update values. As it is quite large in total, I'll place only a few main functions here.

```
...
ENV = os.environ['ENV']
CONF_DIR = os.path.join(os.environ['HOME'], 'secure')
LOG = os.path.join(os.environ['HOME'], 'logs/settings.log')

logging.basicConfig(format = '%(filename)s[LINE:%(lineno)d] - %(levelname)-3s [%(asctime)s] %(message)s ', filename=LOG, level=logging.DEBUG)
...

def select_conf(path):

'''Used to select configuration file from directory in CONF_DIR variable.
Return filename without full path.'''

while True:

list = []

for file in os.listdir(path):
list.append(file)
print('%s %s' % ((list.index(file)), file))

try:
res_file = int(raw_input('\nPlease, select file to edit: '))
print('You selected: %s' % list[res_file])
except ValueError as e:
print('Please, enter correct value: %s\n' % e)
sys.exit(2)

if answe

Solution

select_conf

In the while loop, you are going through the directory and printing out a list of all the file in the directory so that the user can select the configuration file that they would like to work with.

You are going to end up doing this every time you go through the loop. It would be a better idea to stick this right before the loop so you aren't re-scanning the directory for files each time.

What if the user makes a mistake in their typing and accidently enters invalid input? Instead of exiting the program, you should just run the loop and ask for input again.

print('%s %s' % ((list.index(file)), file))


I believe that the first %s should be a %d or a %i because you are formatting a number, not a string.

select_section

Same things as last section: don't just exit the program if the user enters invalid input; loop again and give them another chance. Also, put the scanning for sections outside the loop for the same reason as above.

edit_option

Could this fail?

Config.read(file)


You did some error catching around this call in select_section, but you didn't do it here.

Same things go for this while loop as for the above ones.

The repeat loops

You expressed a concern for these in your post.

Yes, you could move these to a function, but the function would require copious areguments.

Here is what I tried:

def get_answer_loop(to_iterate, list, prompt, err_code):
    while True:
        for element in to_iterate:
            list.append(element)
            print('%s %s' % ((list.index(element)), section))
    
        try:
            choice = int(raw_input('\nPlease, ' + prompt + ': '))
            print('You selected: %s' % list[choice])
        except ValueError as e:
            print('Please, enter correct value: %s\n' %e)
            sys.exit(err_code) # either exit, or loop again as I recommended
    
        if answer('Is it OK? [y/n] '):
            logging.info('Selected %s section to work with.' % list[choice])
            return(list[choice], element) #element if needed; return if needed


Please excuse the naming.

General

-
Near the top of your code or in documentation about the application, you should create a list of all the exit codes and what errors go along with them.

-
At the end of those while loops where the user selects something, you don't need to have a break after a return().

Code Snippets

print('%s %s' % ((list.index(file)), file))
Config.read(file)
def get_answer_loop(to_iterate, list, prompt, err_code):
    while True:
        for element in to_iterate:
            list.append(element)
            print('%s %s' % ((list.index(element)), section))
    
        try:
            choice = int(raw_input('\nPlease, ' + prompt + ': '))
            print('You selected: %s' % list[choice])
        except ValueError as e:
            print('Please, enter correct value: %s\n' %e)
            sys.exit(err_code) # either exit, or loop again as I recommended
    
        if answer('Is it OK? [y/n] '):
            logging.info('Selected %s section to work with.' % list[choice])
            return(list[choice], element) #element if needed; return if needed

Context

StackExchange Code Review Q#75226, answer score: 5

Revisions (0)

No revisions yet.