import os from wtforms.validators import ValidationError import platform, re, readline currOS = platform.platform() if currOS.find('Windows') == 0: LOCALBASE = 'D:/website/' else: LOCALBASE = '/mnt/d/website/' #LOCALBASE would normally be '' (a contributors directory) when this is #in production mode. #This would be a separate app from the main website, launched in a #separate directory, with perhaps a few links to certain files in #the main website base directory. The user would have read access #to template.ft3 but rw access only to files in their own subdirectory. # GLOBALS NAMESFILE = LOCALBASE + "names.tsv" INSTSFILE = LOCALBASE + "insts.tsv" TYPESFILE = LOCALBASE + "types.tsv" CONTRIBDIR = LOCALBASE + 'contributors/' #This will change when everything is debugged #PERSONALDIR = CONTRIBDIR + lastName + firstName[0] PERSONDIR = CONTRIBDIR TEMPLATE = LOCALBASE + 'contributors/template.ft3' def make_list(flList): liOut = [] stList = flList.read() lsIn = stList.split('\n') for line in lsIn: stOut = '' line = line.strip() lsRec = line.split('\t') if flList == flNames: if len(lsRec) < 2: stOut = lsRec[0] else: stOut = lsRec[1] + ' ' + lsRec[0] liOut.append(stOut) elif flList == flInsts: # it's an instrument list if len(lsRec) >= 2: liOut.append(lsRec[1]) else: #it's a music type list liOut.append(lsRec[0]) return liOut flNames = open(NAMESFILE, 'r', encoding='latin1') if not flNames: print("Cannot open ", NAMESFILE) else: liNames = make_list(flNames) flInsts = open(INSTSFILE, 'r', encoding='latin1') if not flInsts: print("Cannot open ", INSTSFILE) else: liInsts = make_list(flInsts) flTypes = open(TYPESFILE, 'r', encoding='latin1') if not flTypes: print("Cannot open ", TYPESFILE) else: liTypes = make_list(flTypes) def strip_list(liIn): n = 0 for item in liIn: item = item.strip() liIn[n] = item n += 1 return liIn def key_val(form, field): stIn = field.data stIn = stIn.strip() liKeyList = strip_list(stIn.split(',')) badKeys = [] goodKeys = [] for mKey in liKeyList: if not re.fullmatch('[A-G][#b]?[Mm]', mKey): badKeys.append(mKey) else: goodKeys.append(mKey) if len(badKeys) > 0: stErr = ','.join(badKeys) stErr = 'Bad Keys: ' + stErr raise ValidationError(stErr) def type_val(form, field): global liTypes stTypes = field.data typeList = stTypes.strip() liTypeList = typeList.split(',') liTypeList = strip_list(liTypeList) badTypes = [] goodTypes = [] for mtype in liTypeList: if not mtype in liTypes: badTypes.append(mtype) else: goodTypes.append(mtype) if len(badTypes) > 0: stBad = ','.join(badTypes) stErr = 'Invalid music type[s]: ' + stBad raise ValidationError(stErr) def ensemble_val(form, field): global liInsts stInsts = field.data stInsts = stInsts.strip() liEnsemble = stInsts.split(',') liEnsemble = strip_list(liEnsemble) badInsts = [] goodInsts = [] for inst in liEnsemble: if not inst in liInsts: badInsts.append(inst) else: goodInsts.append(inst) if len(badInsts) > 0: stBad = ','.join(badInsts) stErr = 'Invalid instrument[s]: ' + stBad raise ValidationError(stErr) def source_val(form, field): stIn = field.data stIn = stIn.strip() # if not re.fullmatch('A', stIn): if re.match('[A-Z]{1,2}-', stIn): if not re.match('[A-Z]{1,2}-[A-Z]{1,3}[a-z]*:?', stIn): stErr = 'Mangled library siglum: ' + stIn raise ValidationError(stErr) def page_val(form, field): stIn = field.data stIn = stIn.strip() liPageList = strip_list(stIn.split(',')) badPages = [] goodPages = [] for stPage in liPageList: if re.match('[0-9]', stPage): if not re.fullmatch('[0-9]+v?[a-m]?', stPage): badPages.append(stPage) else: goodPages.append(stPage) elif re.match('[%#]', stPage): if not re.fullmatch('[%#][0-9]*', stPage): badPages.append(stPage) else: goodPages.append(stPage) elif re.match('[a-zA-Z]', stPage): val = re.fullmatch('([a-zA-Z])([a-zA-Z]?)[1-8]v?[a-m]?', stPage) if not val: badPages.append(stPage) elif val.group(2) and (val.group(1) != val.group(2)): badPages.append(stPage) else: goodPages.append(stPage) else: badPages.append(stPage) if len(badPages) > 0: stErr = ','.join(badPages) stErr = 'Bad pages: ' + stErr raise ValidationError(stErr) def section_val(form, field): stIn = field.data stIn = stIn.strip() if not re.fullmatch('[1-9][0-9]*\. [A-Z].*', stIn): raise ValidationError("Section name must start with a number, followed by a . and a space") def find_file(stFile): return os.path.exists(stFile) def name_val(form, field): return True stInput = latin1_to_ascii(field.data) val = re.search('([^ ][^ ]*) *([A-Za-z])..*', stInput) if not val: stErr = 'Cannot parse name: "' + stInput + '". Need + space + .' raise ValidationError(stErr) stInput =val.group(2) + val.group(1).upper()[0] if os.path_writeable(stInput): return True else: print('No home directory for ', stInput) return False def output_val(form, field): stOutput = field.data if stOutput.find('/') != -1 or stOutput.find('\\') != -1: stErr = 'Cannot have a slash in the file name.' raise ValidationError(stErr) stOutput = PERSONDIR + stOutput if not stOutput.endswith('.ft3'): stOutput = stOutput + '.ft3' if os.access(PERSONDIR, os.F_OK) and os.access(PERSONDIR, os.W_OK): f = open(stOutput, 'w') if not f: stErr = 'Camnnot write to ' + stOutput + '.' raise ValidationError(stErr) else: # Close here and remove, because it will be opened in proc.py f.close() os.remove(stOutput) else: stErr = 'Directory ' + PERSONDIR + 'not writable or executable.' raise ValidationError(stErr) def input_val(form, field): stInput = field.data if stInput == '': stInput = TEMPLATE if not find_file(stInput): stErr = 'Input file: ' + stInput + ' not found.' raise ValidationError(stErr)