def upload_courses_flat(): """Upload "flat" courses file, one row per course""" require_auth('admin') if request.method == 'POST': reset_memo_cache() clear_course_pref_data() errors = [] reader = csv.DictReader(request.files['courses_file']) for row in reader: course = Course() course.crn = row['CRN'] if not course.crn: errors.append('Course missing a CRN, row=%r' % row) ## Theme ## theme_name = row['Theme'] #clean theme name, for example turn "GLOBAL PERSPECTIVES: EUROPE" into simply "GLOBAL PERSPECTIVES" if ': ' in theme_name: theme_name = theme_name.rsplit(': ')[0] theme_name = theme_name.strip() if not theme_name: errors.append('Theme name missing for course with CRN %s' % course.crn) else: course.prefs.append( get_pref('Theme', theme_name) ) ## Faculty ## faculty_name = '' last_name = row['Faculty Last Name'].strip() first_name = row['Faculty First Name'].strip() if first_name and last_name: faculty_name = last_name + ', ' + first_name elif last_name or first_name: faculty_name = last_name or first_name if faculty_name: course.prefs.append( get_pref('Faculty', faculty_name) ) else: errors.append('Both first and last faculty name for course with CRN %s is empty' % course.crn) ## Time ## time = TimePref() time_name = row['Corresponding Time'] if time.parse_name(time_name): time = get_time_by_obj(time) course.time = time course.prefs.append(course.time) else: errors.append('Time with name %s not parseable, must be in format, MTWRF 000-2459 with optional trailing' % time_name) if 'Assigned Mentor' in row and row['Assigned Mentor'].strip(): course.pre_assn_mentor_odin = row['Assigned Mentor'].strip() sess.add(course) #all missing errors app.logger.debug('Course Upload Errors: %r' % errors) sess.commit() return redirect(url_for('list_courses')) else: return render_response('upload_courses_flat.html')