I have a script, which take input from the user and I want to validate the input first then convert the user-input to a predefined format. The input should be like this:
my_script -c 'formatDate(%d/%m) == 23/5 && userName == John Dee && status == c
At the moment I'm dealing with formatDate() bit only. The main rules are:
- The format string for
year,month,daycan come in any order - if m [or y or d] is missing that will be added using
current_month; same for others - the same delimiter must be used for the format strings and the values
- the keys and values must be separated by
== - the different constraint must be separated by
&& - single or multiple constraints are allowed
So, for the given example, it should return 20110523 as a valid constraint. After a bit of work, this is what I come up with, which is pretty much working:
#!/usr/bin/env python
#
import sys, re
from time import localtime, strftime
theDy = strftime('%d', localtime())
theMn = strftime('%m', localtime())
theYr = strftime('%Y', localtime())
def main(arg):
print "input string: %s" % arg
arg = "".join(arg.split()).lower()
if arg.startswith('=') or re.search('===', arg) or "==" not in arg:
sys.exit("Invalid query string!")
else: my_arg = arg.split('&&')
c_dict = {}
for ix in range(len(my_arg)):
LL = my_arg[ix].split('==')
#LL = dict(zip(LL[:-1:2], LL[1::2]))
# don't add duplicate key
if not c_dict.has_key(LL[0]):
c_dict[LL[0]] = LL[1]
for k,v in sorted(c_dict.items()):
if k.startswith('formatdate') :
ymd = re.sub(r'[(,)]', ' ', k).replace('formatdate','')
ymd = (str(ymd).strip()).split('/')
if len(ymd) <= 3 and len(ymd) == len(v.split('/')):
d_dict = dict(zip(ymd, v.split('/')))
if not d_dict.has_key('%y'):
d_dict['%y'] = theYr
if not d_dict.has_key('%m'):
d_dict['%m'] = theMn
if not d_dict.has_key('%d'):
d_dict['%d'] = theDy
else: sys.exit('date format mismatched!!')
Y = d_dict['%y'];
if d_dict['%m'].isdigit() and int(d_dict['%m']) <=12:
M = d_dict['%m'].zfill(2)
else: sys.exit("\"Month\" is not numeric or out of range.\nExiting...\n")
if d_dict['%d'].isdigit() and int(d_dict['%d']) <=31:
D = d_dict['%d'].zfill(2)
else: sys.exit("\"Day\" is not numeric or out of range.\nExiting...\n")
# next line needed for future use
fmtFile = re.compile('%s%s%s' % (Y,M,D))
print "file_name is: %s" % Y+M+D
if __name__ == "__main__":
main('formatDate(%d/%m)== 23/5')
My questions are:
- Am I making it unnecessarily complected or expensive? Is there any easier way?
- How to identify which "delimiter" user has used [as opposed to using a fixed one]?
Thanks for your time. Cheers!!