def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) ret = dict() directory = request.args.get('directory') if directory is None or directory not in ImportTools.allowed_directories: return respond({'error': 'invalid_directory'}, 400) if request.method == 'GET': pass upload_file = request.files.get('file') if upload_file is None: return respond({'error': 'missing_file'}, 400) if not re.match(r'^[-\w]+\.csv$', upload_file.filename): return respond({'error': 'missing_filename'}, 400) file_path = ImportTools.get_file_path(directory, upload_file.filename) upload_file.save(file_path) DB.UserLog.add_entry('uploadFile', g.username, upload_file.filename) ret['success'] = True return respond(ret, 200)
def handle(): # if request.method == 'POST': # name = request.form['name'] if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) ret = dict() directory = request.args.get('directory') if directory is None or directory not in ImportTools.allowed_directories: return respond({'error': 'invalid_directory'}, 400) if directory == 'studentidents': settings = DB.Settings.load_dict(['unique_student_id']) if len(settings['unique_student_id'] ) > 1 or settings['unique_student_id'][0] != 'ident_original': return respond({'error': 'disabled_directory'}, 400) if directory == 'applicants': settings = DB.Settings.load_dict(['import_applicants']) if not settings['import_applicants']: return respond({'error': 'disabled_directory'}, 400) ret['files_info'] = ImportTools.get_files_info(directory) return respond(ret, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) data = request.get_json() action = data.get('action') if action == 'get_all_definitions': return get_all_definitions() if action == 'get_definition_stats': return get_definition_stats() if action == 'add_query': return add_query(data) if action == 'edit_query': return edit_query(data) if action == 'remove_query': return remove_query(data) if action == 'add_path_element': return add_path_element(data) if action == 'edit_path_element': return edit_path_element(data) if action == 'remove_path_element': return remove_path_element(data) return respond({'error': 'unknown_action'}, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) sortable = DB.Course().__dict__.keys() sortable.append('_id') sortable.append('date') query_types = {'action': 'str', 'user': '******', 'date': 'datetime'} limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='_id,1').split(',') sort2 = request.args.get('sort2', default='stg').split(',') if not 1 <= limit <= 1000: return respond({'error': 'invalid_limit'}, 400) ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None } db_query = dict() db_sort = [] if len(sort1) == 2 and sort1[0] in sortable: db_sort.append((sort1[0], int(sort1[1]))) if len(sort2) == 2 and sort2[0] in sortable: db_sort.append((sort2[0], int(sort2[1]))) ident = request.args.get('ident', default=None) if ident is not None: db_query['_id'] = ident for name in request.args: if name not in query_types: continue try: value = request.args.get(name) db_query[name] = DB.get_db_query_by_type(value, query_types[name]) except ValueError: return respond({'error': 'invalid_filter', name: name}, 400) cursor = DB.UserLog.find(db_query, limit=limit, skip=start, sort=db_sort) ret['count'] = cursor.count() ret['list'] = [s.get_dict() for s in cursor] ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) return respond(ret, 200)
def add_query(data): query = DB.Query() errors = set_query_from_input(query, data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) if query.db_insert(): return respond({'status': 'ok', 'query': query.get_dict()}, 200) else: return respond({'error': 'insert_failed'}, 200)
def remove_query(data): if 'ident' not in data or len(data['ident']) < 2: return respond({'error': 'invalid_ident'}, 200) text_entry = DB.DisplayText.find_one({'_id': data['ident']}) if not text_entry: return respond({'error': 'not_found'}, 200) if text_entry.db_remove(): return respond({'status': 'ok', 'text': text_entry.get_dict()}, 200) else: return respond({'error': 'remove_failed'}, 200)
def add_text(data): errors = validate_data(data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) text_entry = DB.DisplayText() assign_data(data, text_entry) if text_entry.db_insert(): return respond({'status': 'ok', 'text': text_entry.get_dict()}, 200) else: return respond({'error': 'insert_failed'}, 200)
def respond_csv(cursor, ret): if request.method != 'POST' or 'csvcolumns' not in request.form: return respond({'error': 'missing_csvcolumns'}, 400) csvcolumns = request.form['csvcolumns'] # [{name:'',q:'',formatting:''}] if type(csvcolumns) in (unicode, str): try: csvcolumns = json.loads(csvcolumns) except ValueError: return respond({'error': 'unparseable_csvcolumns'}, 400) encoding = request.args.get('encoding', default='utf-8', type=str) if type(csvcolumns) != list: return respond({'error': 'invalid_csvcolumns'}, 400) requiredkeys = {'q', 'name', 'formatting'} columns = [ DB.Query(csvcol['q'], csvcol['name'], None, csvcol['formatting']) for csvcol in csvcolumns if type(csvcol) == dict and requiredkeys <= set(csvcol.keys()) ] csvdelimiter = ';' user_role = g.user_role settings = DB.Settings.load_dict(['lights', 'hide_finished_ident_data']) def generate(): yield csvdelimiter.join([col.name.encode(encoding) for col in columns]) + '\r\n' for student in cursor: data = student.get_dict( user_role, hide_finished_ident_data=settings['hide_finished_ident_data']) strident = str(data['ident']) if 'mlist' in ret and strident in ret['mlist']['comments']: data['comment'] = ret['mlist']['comments'][strident]['text'] yield get_csv_row(data, columns, csvdelimiter, settings, encoding) + '\r\n' return Response(generate(), mimetype='text/csv', headers=[('Content-Description', 'File Transfer'), ('Content-Type', 'application/csv; charset=' + encoding), ('Content-Disposition', 'attachment; filename=students.csv')])
def remove_path_element(data): if not isinstance(data.get('pe_id'), unicode): return respond({'error': 'invalid_pe_id'}, 200) pe_id = long(data.get('pe_id')) pe = DB.PathElement.find_by_id(pe_id) if pe is None: return respond({'error': 'pe_not_found'}, 200) if pe.db_remove(): return respond({'status': 'ok', 'pe': pe.get_dict()}, 200) else: return respond({'error': 'remove_failed'}, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) ret = dict() ret['roles'] = UserTools.user_roles ret['rights'] = UserTools.user_rights ret['users'] = UserTools.get_all_users() ret['stg_list'] = [ d['_id'] for d in DB.Course.get_grouped_values('stg', {'ignore': False}) if d['_id'] is not None ] return respond(ret, 200)
def remove_query(data): if not isinstance(data.get('query_id'), unicode): return respond({'error': 'invalid_query_id'}, 200) query_id = long(data.get('query_id')) query = DB.Query.find_by_id(query_id) if query is None: return respond({'error': 'query_not_found'}, 200) if query.db_remove(): DB.PathElement.remove_by_query_id(query_id) return respond({'status': 'ok', 'query': query.get_dict()}, 200) else: return respond({'error': 'remove_failed'}, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) data = request.get_json() user = data.get('user') if user is None: return respond({'error': 'no_user'}, 200) role = data.get('role') stg_list = data.get('stg_list') if UserTools.save_user(user, role, stg_list): DB.UserLog.add_entry('saveUser', g.username, [user, role, stg_list]) return respond({'status': 'ok'}, 200) return respond({'error': 'not_saved'}, 200)
def edit_query(data): errors = validate_data(data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) text_entry = DB.DisplayText.find_one({'_id': data['ident']}) if not text_entry: return respond({'error': 'not_found'}, 200) assign_data(data, text_entry) if text_entry.db_save(): return respond({'status': 'ok', 'text': text_entry.get_dict()}, 200) else: return respond({'error': 'save_failed'}, 200)
def handle(): # if request.method == 'POST': # name = request.form['name'] if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) file_name = request.args.get('file') if file_name is None or not re.match(r'^[A-Za-z0-9]+(\.\d)?$', file_name): return respond({'error': 'invalid_file'}, 403) return send_from_directory('./logs', file_name + '.log', as_attachment=False, mimetype='text/plain')
def handle(): ret = dict() ret['settings'] = dict() db_query = {'type': 'global'} setting_id = request.args.get('id') setting_type = request.args.get('type', default='global') if setting_type == 'my': db_query['type'] = 'my' db_query['user'] = g.username if setting_id: db_query['_id'] = g.username + '_' + setting_id elif setting_type == 'list': db_query['type'] = 'list' if setting_id: db_query['_id'] = 'list_' + setting_id else: db_query['user'] = g.username elif setting_type == 'shared': db_query['type'] = 'shared' if setting_id: db_query['_id'] = 'shared_' + setting_id elif not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) cursor = DB.Settings.find(db_query) for s in cursor: if setting_type == 'my': ret['settings'][s.id.replace(g.username + '_', '', 1)] = s.data elif setting_type == 'list': ret['settings'][s.id.replace('list_', '', 1)] = s.data elif setting_type == 'shared': ret['settings'][s.id.replace('shared_', '', 1)] = s.data else: if s.id.startswith('sv_') and not g.students_view: continue ret['settings'][s.id] = s.data return respond(ret, 200)
def edit_path_element(data): if not isinstance(data.get('pe_id'), unicode): return respond({'error': 'invalid_pe_id'}, 200) pe_id = long(data.get('pe_id')) pe = DB.PathElement.find_by_id(pe_id) if pe is None: return respond({'error': 'pe_not_found'}, 200) errors = set_path_element_from_input(pe, data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) if pe_id != pe.md5_id(): if pe.db_insert(): DB.PathElement.remove_by_id(pe_id) return respond({'status': 'ok', 'pe': pe.get_dict()}, 200) else: return respond({'status': 'edit_failed', 'pe': pe.get_dict()}, 200) elif pe.db_update(): return respond({'status': 'ok', 'pe': pe.get_dict()}, 200) else: return respond({'error': 'edit_failed'}, 200)
def edit_query(data): if not isinstance(data.get('query_id'), unicode): return respond({'error': 'invalid_query_id'}, 200) query_id = long(data.get('query_id')) query = DB.Query.find_by_id(query_id) if query is None: return respond({'error': 'query_not_found'}, 200) errors = set_query_from_input(query, data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) if query_id != query.md5_id(): if not query.db_insert(): return respond({'error': 'edit_failed_insert'}, 200) DB.PathElement.update_query_id(query_id, query.md5_id()) if not DB.Query.get_collection().delete_one({'_id': query_id}): return respond({'error': 'edit_failed_delete'}, 200) if query.db_update(): return respond({'status': 'ok', 'query': query.get_dict()}, 200) else: return respond({'error': 'edit_failed'}, 200)
def get_all_definitions(): data = {'queries': {}, 'path_elements': {}} for item in DB.Query.find({}): data['queries'][item.md5_id()] = item.get_dict(True) for item in DB.PathElement.find({}): if item.query is not None: data['path_elements'][item.md5_id()] = item.get_dict(True) return respond(data, 200)
def add_path_element(data): if not isinstance(data.get('query_id'), unicode): return respond({'error': 'invalid_query_id'}, 200) query_id = long(data.get('query_id')) query = DB.Query.find_by_id(query_id) if query is None: return respond({'error': 'query_not_found'}, 200) pe = DB.PathElement(query, DB.Condition()) errors = set_path_element_from_input(pe, data) if len(errors) > 0: return respond({'error': 'invalid_data', 'errors': errors}, 200) if pe.db_insert(): return respond({'status': 'ok', 'pe': pe.get_dict()}, 200) else: return respond({'error': 'insert_failed'}, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) data = request.get_json() action = data.get('action') if action == 'get_texts': return get_display_texts(data) if action == 'add_text': return add_text(data) if action == 'edit_text': return edit_query(data) if action == 'remove_text': return remove_query(data) return respond({'error': 'unknown_action'}, 200)
def get_display_texts(data): query = {} if 'filters' in data and type(data['filters']) is list: query['filters'] = {"$all": data['filters']} result = { 'texts': [ text.get_dict() for text in DB.DisplayText.find( query, sort=[('position', 1), ('order', 1)]) ], 'definitions': get_definitions() } return respond(result, 200)
def get_definition_stats(): data = {'path_element_stats': {}} path_elements = {} for item in DB.PathElement.find({}): if item.query is not None: path_elements[item.md5_id()] = item for pe_id, pe in path_elements.iteritems(): pe_list = [pe] if isinstance(pe.query.depends, set): for dep_pe_id in pe.query.depends: if dep_pe_id in path_elements: pe_list.append(path_elements[dep_pe_id]) count = DB.Student.get_matching_students_count(pe_list) data['path_element_stats'][pe_id] = {'count': count} return respond(data, 200)
def handle(): if not UserTools.has_right('admin_access', g.user_role): return respond({'error': 'no_rights'}, 403) apply_data = request.args.get('apply_data', default='false') == 'true' stop_process = request.args.get('stop', default='false') == 'true' if stop_process: stop_file = 'data/request_stop.txt' if os.path.isfile(stop_file): return respond({'error': 'stop_requested'}, 200) with open(stop_file, 'w') as fd: fd.write(str(time.time())) now = time.time() nextup = math.ceil(now / 60) * 60 DB.UserLog.add_entry('stop_update', g.username) return respond({'ok': True, 'wait': nextup - now}, 200) if apply_data: try: DB.ProcessTracking.process_update('apply_data', 0, {'state': 'running'}) DB.swap_temp_to_op() DB.ProcessTracking.process_update('apply_data', 1, {'state': 'done'}) DB.ProcessTracking.process_done('apply_data') except: DB.ProcessTracking.process_failed( 'apply_data', {'error': traceback.format_exc()}) raise return respond({'ok': True}, 200) start_file = 'data/request_start.txt' if os.path.isfile(start_file): return respond({'error': 'start_requested'}, 200) with open(start_file, 'w') as fd: fd.write(str(time.time())) now = time.time() nextup = math.ceil(now / 60) * 60 DB.UserLog.add_entry('run_update', g.username) return respond({'ok': True, 'wait': nextup - now}, 200)
def handle(): ident = request.args.get('ident') is_new = False mlist = DB.MarkedList.find_one({'_id': ident}) if mlist is None: is_new = True mlist = DB.MarkedList() mlist.ident = ''.join( random.choice(string.ascii_uppercase + string.digits) for x in range(10)) mlist.created_by = g.username mlist.updated_by = g.username mlist.owner = g.username else: mlist.date_update = datetime.utcnow() mlist.updated_by = g.username if not mlist.is_writable(g.username, g.user_role): return respond({'error': 'not_allowed'}, 401) data = request.get_json() if data.get('delete') and mlist.deleteable and mlist.owner == g.username: mlist.db_remove() return respond({'mlist': None}, 200) name = data.get('name') if name is not None: mlist.name = name add_idents = data.get('add_idents') if add_idents is not None and type(add_idents) == list: for ident in add_idents: mlist.add_student(ident) remove_idents = data.get('remove_idents') if remove_idents is not None and type(remove_idents) == list: for ident in remove_idents: mlist.remove_student(ident) comments = data.get('comments') if comments is not None and type(comments) == dict: for comment_ident, comment in comments.iteritems(): if comment_ident in mlist.list: mlist.comments[comment_ident] = { 'text': comment, 'by': g.username, 'date': datetime.utcnow() } if mlist.owner == g.username: owner = data.get('owner') if owner is not None and type(owner) == unicode: mlist.owner = owner read_only = data.get('read_only') if read_only is not None and type(read_only) == bool: mlist.read_only = read_only user_roles = data.get('user_roles') if 'user_roles' in data and type(user_roles) == list: mlist.user_roles = user_roles elif 'user_roles' in data: mlist.user_roles = None data['ident'] = ident if is_new: mlist.db_insert() DB.UserLog.add_entry('addMarkedList', g.username, data) else: mlist.db_save() DB.UserLog.add_entry('saveMarkedList', g.username, data) ret = mlist.get_dict() ret['is_writable'] = mlist.is_writable(g.username, g.user_role) return respond({'mlist': mlist.get_dict()}, 200)
def handle(): sortable = DB.CourseSemesterInfo().__dict__.keys() sortable.append('_id') query_types = {'semester_id': 'int', 'stg': 'str'} limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='semeser_id,1').split(',') sort2 = request.args.get('sort2', default='').split(',') if not UserTools.has_right('course_data', g.user_role): return respond({'error': 'no_rights'}, 403) if not 1 <= limit <= 1000: return respond({'error': 'invalid_limit'}, 400) ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None } settings = DB.Settings.load_dict( ['hide_resigned', 'always_display_all_courses', 'import_applicants']) db_query = dict() db_queries = [] # for restrictions db_sort = [] if len(sort1) == 2 and DB.CourseSemesterInfo.db_is_sortable(sort1[0]): db_sort.append((sort1[0], int(sort1[1]))) if len(sort2) == 2 and DB.CourseSemesterInfo.db_is_sortable(sort2[0]): db_sort.append((sort2[0], int(sort2[1]))) ident = request.args.get('ident', default=None) if ident is not None: db_query['_id'] = ident for name in request.args: if name not in query_types: continue try: value = request.args.get(name) db_query[name] = DB.get_db_query_by_type(value, query_types[name]) except ValueError: return respond({'error': 'invalid_filter', name: name}, 400) allowed_stgs = UserTools.get_allowed_stgs(g.user) if allowed_stgs and not settings['always_display_all_courses']: db_queries.append({'stg': {'$in': allowed_stgs}}) if len(db_queries) > 0: db_queries.append(db_query) db_query = {'$and': db_queries} cursor = DB.CourseSemesterInfo.find(db_query, limit=limit, skip=start, sort=db_sort) ret['count'] = cursor.count() ret['list'] = [s.__dict__ for s in cursor] ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) ret['hide_resigned'] = settings['hide_resigned'] ret['import_applicants'] = settings['import_applicants'] return respond(ret, 200)
def handle(): # if request.method == 'POST': # name = request.form['name'] use_preferred_paths = DB.Settings.load('use_preferred_paths') query_types = { '_id': 'long', 'group': 'str', 'value': 'float', 'weight': 'float', 'weighted_value': 'float', 'support': 'float', 'confidence': 'float', 'count': 'int', 'matched': 'int', 'elements': 'intlist', 'filter_elements': 'intlist' } limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='value,-1').split(',') sort2 = request.args.get('sort2', default='').split(',') with_definitions = request.args.get('definitions', default='false') student_id = request.args.get('student_id', default=None, type=str) filter_dim = request.args.get('filter_dim', default=None) in_filter_elements = request.args.get('in_filter_elements', default=None) settings = DB.Settings.load_dict(['student_ident_string']) if not settings['student_ident_string'] and student_id is not None: student_id = int(student_id) ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None } if with_definitions == 'true': ret['definitions'] = get_definitions() ret['metadata'] = {} ret['metadata']['group'] = [ d['_id'] for d in DB.Path.get_grouped_values('group') ] if not 1 <= limit <= 10000: return respond({'error': 'invalid_limit'}, 400) db_query = dict() db_sort = [] if len(sort1) == 2 and sort1[0] in query_types: db_sort.append((sort1[0], int(sort1[1]))) if len(sort2) == 2 and sort2[0] in query_types: db_sort.append((sort2[0], int(sort2[1]))) if filter_dim is not None: db_query['filter_elements'] = { '$size': DB.get_db_query_by_type(filter_dim, 'int') } for name in request.args: if name not in query_types: continue try: value = request.args.get(name) qtype = query_types[name] db_query[name] = DB.get_db_query_by_type(value, qtype) except ValueError: return respond({'error': 'invalid_filter', name: name}, 400) if student_id is not None: student = DB.Student.find_one({'_id': student_id}) if student is None: return respond({'error': 'invalid_student_id'}, 400) # print 'on all', [DataDefinitions.get_element_by_hash(peId).get_str() for peId in student_element_ids] if in_filter_elements is not None: in_fids = in_filter_elements.split(',') in_filter_elements = [long(feid) for feid in in_fids] # print 'one in', [DataDefinitions.get_element_by_hash(peId).get_str() for peId in seids] results = student.get_paths(in_filter_elements, db_sort) result_list = [] element_stats = {} for i in range(len(results)): path = results[i] for pe in path.filter_elements: pe_id = pe.md5_id() if pe_id not in element_stats: element_stats[pe_id] = { 'count': 0, 'value_sum': 0.0, 'support_sum': 0.0 } element_stats[pe_id]['count'] += 1 element_stats[pe_id]['value_sum'] += path.value element_stats[pe_id]['support_sum'] += path.support element_stats[pe_id]['value_mean'] = \ element_stats[pe_id]['value_sum'] / element_stats[pe_id]['count'] element_stats[pe_id]['support_mean'] = \ element_stats[pe_id]['support_sum'] / element_stats[pe_id]['count'] if start <= i < start + limit: result_list.append(path) ret['element_stats'] = element_stats ret['count'] = len(results) ret['list'] = [s.get_dict(True) for s in result_list] ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) else: cursor = DB.Path.find(db_query, limit=limit, skip=start, sort=db_sort) ret['count'] = cursor.count() ret['list'] = [s.get_dict(True) for s in cursor] ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) return respond(ret, 200)
def handle(): global _metadata_cache_examinfos, _metadata_cache_examinfos_prefix # if request.method == 'POST': # name = request.form['name'] if not UserTools.has_right('exams_data', g.user_role): return respond({'error': 'no_rights'}, 403) query_types = { 'exam_info_id': 'str', 'exam_id': 'int', 'name': 'str', 'stg': 'str', 'stg_original': 'str', 'has_grade': 'bool', 'bonus': 'int', 'count_exams': 'int', 'count_successful': 'int', 'count_failed': 'int', 'count_applied': 'int', 'success_perc': 'float', 'failed_perc': 'float', 'semesters': 'int', 'version': 'int', 'semester_data.CURRENT.exams': 'int', 'semester_data.CURRENT.successful': 'int', 'semester_data.CURRENT.failed': 'int', 'semester_data.CURRENT.applied': 'int', 'semester_data.CURRENT.success_perc': 'float', 'semester_data.CURRENT.failed_perc': 'float', 'semester_data.LAST.exams': 'int', 'semester_data.LAST.successful': 'int', 'semester_data.LAST.failed': 'int', 'semester_data.LAST.applied': 'int', 'semester_data.LAST.success_perc': 'float', 'semester_data.LAST.failed_perc': 'float', 'semester_data.PERIOD.exams': 'int', 'semester_data.PERIOD.successful': 'int', 'semester_data.PERIOD.failed': 'int', 'semester_data.PERIOD.applied': 'int', 'semester_data.PERIOD.success_perc': 'float', 'semester_data.PERIOD.failed_perc': 'float' } sortable = query_types.keys() sortable.append('_id') limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='_id,-1').split(',') sort2 = request.args.get('sort2', default='').split(',') with_metadata = request.args.get('metadata', default='false') first_semester, current_semester = DB.Student.get_min_max('start_semester') last_semester = current_semester - 1 if current_semester % 10 == 1: last_semester = (current_semester // 10 - 1) * 10 + 2 current_semester = str(current_semester) last_semester = str(last_semester) def gff(field): field = field.replace('CURRENT', current_semester) field = field.replace('LAST', last_semester) return field if not 1 <= limit <= 1000: return respond({'error': 'invalid_limit'}, 400) ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None } # if with_metadata == 'true': # ret['metadata'] = get_definitions() # TODO implement meta data like name of exam settings = DB.Settings.load_dict([ 'hide_exam_fields' ]) ret['hide_exam_fields'] = settings['hide_exam_fields'] db_query = dict() db_queries = [] # for restrictions db_sort = {} if len(sort1) == 2 and sort1[0] in sortable: db_sort[gff(sort1[0])] = int(sort1[1]) if len(sort2) == 2 and sort2[0] in query_types: db_sort[gff(sort2[0])] = int(sort2[1]) for name in request.args: if name not in query_types: continue dbfield = name if name == 'exam_info_id': dbfield = '_id' try: value = request.args.get(name) qtype = query_types[name] qname = gff(dbfield) db_query[qname] = DB.get_db_query_by_type(value, qtype) except ValueError: return respond({'error': 'invalid_filter', name: name}, 400) allowed_stgs = UserTools.get_allowed_stgs(g.user) if allowed_stgs: db_queries.append({'stg': {'$in': allowed_stgs}}) if len(db_queries) > 0: db_queries.append(db_query) db_query = {'$and': db_queries} pipeline = [{'$match': db_query}] if request.args.has_key('semesters'): cond = DB.get_db_aggregation_condition(request.args.get('semesters'), 'int', {'$toInt': '$$this.k'}) pipeline.append({'$addFields': { 'semester_data.PERIOD': { '$reduce': { 'input': {'$objectToArray': '$semester_data'}, 'initialValue': { 'applied': 0, 'failed': 0, 'exams': 0, 'successful': 0, 'resigned': 0 }, 'in': { '$cond': { 'if': cond, 'then': { 'applied': {'$add': ['$$value.applied', '$$this.v.applied']}, 'failed': {'$add': ['$$value.failed', '$$this.v.failed']}, 'exams': {'$add': ['$$value.exams', '$$this.v.exams']}, 'successful': {'$add': ['$$value.successful', '$$this.v.successful']}, 'resigned': {'$add': ['$$value.resigned', '$$this.v.resigned']}, 'failed_perc': {'$divide': [ {'$add': ['$$value.failed', '$$this.v.failed']}, {'$add': ['$$value.exams', '$$this.v.exams']} ]}, 'success_perc': {'$divide': [ {'$add': ['$$value.successful', '$$this.v.successful']}, {'$add': ['$$value.exams', '$$this.v.exams']} ]}, 'resign_perc': {'$divide': [ {'$add': ['$$value.resigned', '$$this.v.resigned']}, {'$add': ['$$value.exams', '$$this.v.exams']} ]} }, 'else': '$$value' } } } } }}) pipeline.append({'$sort': db_sort}) pipeline.append({'$skip': start}) pipeline.append({'$limit': limit}) cursor = DB.ExamInfo.find(db_query, limit=limit, skip=start) ret['count'] = cursor.count() ret['list'] = [DB.ExamInfo.db_create(d).__dict__ for d in DB.ExamInfo.db_aggregate(pipeline)] ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) ret['current'] = current_semester ret['last'] = last_semester if with_metadata and _metadata_cache_examinfos \ and _metadata_cache_examinfos_prefix == DB.Exam.get_collection_prefix(): ret['metadata'] = _metadata_cache_examinfos if with_metadata: ret['metadata'] = DB.Exam.get_grouped_values(['stg', 'stg_original', 'name']) _metadata_cache_examinfos = ret['metadata'] _metadata_cache_examinfos_prefix = DB.Exam.get_collection_prefix() if ret['metadata'] and allowed_stgs: ret['metadata']['stg'] = [stg for stg in ret['metadata']['stg'] if stg in allowed_stgs] ret['metadata']['stg_original'] = [stg for stg in ret['metadata']['stg_original'] if DB.Course.get_by_stg_original(stg).stg in allowed_stgs] return respond(ret, 200)
def handle(): query_types = { 'ident': 'str', 'owner': 'str', 'created_by': 'str', 'updated_by': 'str', 'name': 'str', 'count': 'int', 'list': 'str', 'read_only': 'bool' } sortable = DB.MarkedList().__dict__.keys() sortable.extend([ '_id' ]) limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='_id,-1').split(',') sort2 = request.args.get('sort2', default='').split(',') if not 1 <= limit <= 1000: return respond({'error': 'invalid_limit'}, 400) ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None, 'user_roles': UserTools.user_roles.keys() } db_query = dict() db_sort = [] if len(sort1) == 2 and sort1[0] in sortable: db_sort.append((sort1[0], int(sort1[1]))) if len(sort2) == 2 and sort2[0] in sortable: db_sort.append((sort2[0], int(sort2[1]))) for name in request.args: if name in query_types: dbfield = name if name == 'ident': dbfield = '_id' try: value = request.args.get(name) db_query[dbfield] = DB.get_db_query_by_type(value, query_types[name]) except ValueError: return respond({'error': 'invalid_filter', name: name}, 400) db_user_cond = {'$or': [{'owner': g.username}, {'user_roles': g.user_role}]} db_query = {'$and': [db_user_cond, db_query]} cursor = DB.MarkedList.find(db_query, limit=limit, skip=start, sort=db_sort) ret['list'] = [] for s in cursor: entry = s.get_dict() entry['is_writable'] = s.is_writable(g.username, g.user_role) ret['list'].append(entry) ret['count'] = cursor.count() ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) return respond(ret, 200)
def handle(): # if request.method == 'POST': # name = request.form['name'] status = 200 if 'ident' not in request.args: return respond({'error': 'missing_ident'}, 400) with_definitions = request.args.get('definitions', default='false') with_semesters = request.args.get('semesters', default='false') with_course_semester = request.args.get('course_semester', default='false') user_role = g.user_role if not UserTools.has_right('students_data', user_role): return respond({'error': 'no_rights'}, 403) ret = {} settings = DB.Settings.load_dict([ 'hide_finished_ident_data', 'student_ident_string' ]) ident = request.args.get('ident') if not settings['student_ident_string']: ident = int(ident) if with_definitions == 'true': ret['definitions'] = get_definitions() db_query = { '_id': ident } allowed_stgs = UserTools.get_allowed_stgs(g.user) if allowed_stgs: db_query['stg'] = {'$in': allowed_stgs} try: student = DB.Student.find_one(db_query) if not student: return respond({'error': 'not_found'}, 404) ret['student'] = student.get_dict(user_role, hide_finished_ident_data=settings['hide_finished_ident_data']) if with_course_semester == 'true': course_semester = DB.CourseSemesterInfo.get_by_stg_and_semid(student.stg, student.start_semester) ret['course_semester'] = course_semester.__dict__ if with_semesters == 'true': ret['semesters'] = [] for sem_nr in range(1, len(student.study_semesters) + 1): s = student.get_student_in_semester(sem_nr) risk = s.calculate_risk() if 'failed' in risk: s.risk = risk['failed'] ret['semesters'].append(s.get_dict(user_role, hide_finished_ident_data=settings['hide_finished_ident_data'])) except DB.errors.OperationFailure as e: ret['count'] = 0 ret['error'] = e.message status = 500 return respond(ret, status)
def handle(): # if request.method == 'POST': # name = request.form['name'] status = 200 query_types = { 'admitted': 'bool', 'student': 'bool', 'age': 'int', 'appl_date': 'datetime', 'birth_date': 'datetime', 'degree_type': 'str', 'student_ident': 'str', 'email': 'str', 'eu': 'bool', 'forename': 'str', 'gender': 'str', 'hzb_appl_time': 'int', 'hzb_date': 'datetime', 'hzb_grade': 'int', 'hzb_type': 'str', 'ident': 'str', 'country': 'str', 'zip': 'str', 'citship': 'str', 'start_semester': 'int', 'stg': 'str', 'stg_original': 'str', 'surname': 'str', 'adm_date': 'datetime' } sortable = DB.Applicant().__dict__.keys() sortable.extend([ '_id' ]) limit = request.args.get('limit', default=20, type=int) start = request.args.get('start', default=0, type=int) sort1 = request.args.get('sort1', default='_id,-1').split(',') sort2 = request.args.get('sort2', default='').split(',') with_definitions = request.args.get('definitions', default='false') do_calc = request.args.get('do_calc', default=None) groups = request.args.get('groups', default=None) single_groups = request.args.get('single_groups', default=None) calculations = request.args.get('calculations', default=None) is_csv = request.args.get('output', default='json') == 'csv' user_role = g.user_role ret = { 'start': start, 'limit': limit, 'count': 0, 'list': None, 'query': None, 'sort': None } # if with_definitions == 'true': # ret['definitions'] = get_definitions() settings = DB.Settings.load_dict([ 'hide_applicant_fields' ]) ret['hide_applicant_fields'] = settings['hide_applicant_fields'] ret['list_identification_data'] = UserTools.has_right('list_identification_data', user_role) db_query = dict() db_queries = [] # for restrictions db_sort = [] if len(sort1) == 2 and sort1[0] in sortable: db_sort.append((sort1[0], int(sort1[1]))) if len(sort2) == 2 and sort2[0] in sortable: db_sort.append((sort2[0], int(sort2[1]))) for name in request.args: if name in query_types: dbfield = name if name == 'ident': dbfield = '_id' try: value = request.args.get(name) db_query[dbfield] = DB.get_db_query_by_type(value, query_types[name]) continue except ValueError: return respond({'error': 'invalid_filter', 'name': name}, 400) allowed_stgs = UserTools.get_allowed_stgs(g.user) if allowed_stgs: db_queries.append({'stg': {'$in': allowed_stgs}}) if len(db_queries) > 0: db_queries.append(db_query) db_query = {'$and': db_queries} if groups is not None: if not UserTools.has_right('applicant_data', user_role) \ and not UserTools.has_right('applicant_analytics', user_role): return respond({'error': 'no_rights'}, 403) allowed_groups = [] if not isinstance(groups, unicode): return respond({'error': 'invalid_groups'}, 400) for name in groups.split(','): allowed_groups.append(name) allowed_calculations = list() allowed_ops = ['sum', 'avg', 'max', 'min', 'addToSet'] if isinstance(calculations, unicode): for full_name in calculations.split(','): op, name = full_name.split('.', 2) if op not in allowed_ops: continue allowed_calculations.append({'field': name, 'op': op}) ret['groups'] = allowed_groups ret['calculations'] = allowed_calculations ret['group_results'] = DB.Applicant.calc_groups(allowed_groups, db_query, allowed_calculations) elif single_groups is not None: if not UserTools.has_right('applicant_data', user_role) \ and not UserTools.has_right('applicant_analytics', user_role): return respond({'error': 'no_rights'}, 403) allowed_groups = [] if not isinstance(single_groups, unicode): return respond({'error': 'invalid_groups'}, 400) for name in single_groups.split(','): allowed_groups.append(name) allowed_calculations = list() allowed_ops = ['sum', 'avg', 'max', 'min', 'addToSet'] if isinstance(calculations, unicode): for full_name in calculations.split(','): op, name = full_name.split('.', 2) if op not in allowed_ops: continue allowed_calculations.append({'field': name, 'op': op}) ret['single_groups'] = allowed_groups ret['calculations'] = allowed_calculations ret['group_results'] = DB.Applicant.calc_single_groups(allowed_groups, db_query, allowed_calculations) elif do_calc == 'sums': if not UserTools.has_right('applicant_data', user_role) \ and not UserTools.has_right('applicant_analytics', user_role): return respond({'error': 'no_rights'}, 403) ret['sums'] = DB.Applicant.calc_sums(db_query) elif do_calc == 'avgs': if not UserTools.has_right('applicant_data', user_role) \ and not UserTools.has_right('applicant_analytics', user_role): return respond({'error': 'no_rights'}, 403) ret['avgs'] = None avgs = DB.Applicant.calc_avgs(db_query) if avgs: ret['avgs'] = {} for key, value in avgs.iteritems(): ret['avgs'][key] = value elif is_csv: if not UserTools.has_right('applicant_data', user_role): return respond({'error': 'no_rights'}, 403) cursor = DB.Applicant.find(db_query, sort=db_sort) return respond_csv(cursor, ret) else: if not UserTools.has_right('applicant_data', user_role): return respond({'error': 'no_rights'}, 403) if not 1 <= limit <= 1000: return respond({'error': 'invalid_limit'}, 400) try: cursor = DB.Applicant.find(db_query, limit=limit, skip=start, sort=db_sort) ret['count'] = cursor.count() ret['list'] = [s.get_dict() for s in cursor] except DB.errors.OperationFailure as e: ret['count'] = 0 ret['error'] = e.message status = 500 ret['query'] = repr(db_query) ret['sort'] = repr(db_sort) return respond(ret, status)