Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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')])
Beispiel #9
0
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)
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
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)
Beispiel #13
0
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)
Beispiel #14
0
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')
Beispiel #15
0
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)
Beispiel #16
0
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)
Beispiel #17
0
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)
Beispiel #18
0
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)
Beispiel #19
0
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)
Beispiel #20
0
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)
Beispiel #21
0
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)
Beispiel #22
0
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)
Beispiel #23
0
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)
Beispiel #24
0
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)
Beispiel #25
0
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)
Beispiel #26
0
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)
Beispiel #27
0
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)
Beispiel #28
0
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)
Beispiel #29
0
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)
Beispiel #30
0
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)