import os from wtforms.validators import InputRequired, Length, NumberRange, Optional, Regexp, ValidationError, InputRequired, DataRequired import platform, re, readline from proc import add_prefix_and_suffix, del_prefix_and_suffix 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 = PERSONDIR +'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 volume_val(form, field): stVol = field.data if stVol.isdigit(): vol = int(stVol) if not vol in range(1,99): raise ValidationError('Invalid volume number. Must be 1-99.') else: return True elif stVol != '': raise ValidationError('Must be blank, or a number 1-99') else: return True 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() input() 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 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) if not os.access(PERSONDIR, os.F_OK) and os.access(PERSONDIR, os.W_OK): stErr = 'Directory ' + PERSONDIR + 'not writable or executable.\ \n Therefore cannnot write to ' + field.data + '.' raise ValidationError(stErr) def input_val(form, field): stInput = field.data if stInput == '': stInput = TEMPLATE stInput = add_prefix_and_suffix(stInput) if not os.path.exists(stInput): stErr = 'Input file: ' + field.data + ' not found.' raise ValidationError(stErr)