Beispiel #1
0
def submit_document_external():
    knows_what_they_are_doing = get_user() and get_user().has_permission(
            'info_protokolle',
            'info_klausuren',
            'mathe_protokolle',
            'mathe_klausuren')
    submit_documents(validated=bool(knows_what_they_are_doing))
Beispiel #2
0
def submit_document_external():
    knows_what_they_are_doing = get_user() and get_user().has_permission(
            'info_protokolle',
            'info_klausuren',
            'mathe_protokolle',
            'mathe_klausuren')
    return submit_documents(validated=bool(knows_what_they_are_doing))
Beispiel #3
0
def submit_documents(validated):
    """Student document submission endpoint

    POST data must be multipart, with the `json` part conforming to
    DocumentLoadSchema and the `file` part being a pdf file.

    Uploaded files are stored in subdirectories below config.DOCUMENT_DIRECTORY.

    This method may raise AssertionErrors when the user sends invalid data.
    """
    # we can't use @deserialize because this endpoint uses multipart form data
    data = json.loads(request.form['json'])
    if get_user():
        (data, errors) = FullDocumentLoadSchema().load(data)
        if (data.get('document_type') == 'written' and data.get('solution') not in ['official', 'inofficial', 'none']
                or data.get('document_type') != 'written' and data.get('solution') is not None):
            errors['solution'] = 'Invalid value.'
    else:
        (data, errors) = DocumentLoadSchema().load(data)
    if errors:
        raise ClientError(*errors)
    assert 'file' in request.files
    file = request.files['file']
    if not _allowed_file(file.filename):
        raise ClientError('file extension not allowed', status=406)
    lectures = _match_lectures(data['lectures'], validated)
    examinants = _match_examinants(data['examinants'], validated)
    date = data['date']
    if not get_user():
        assert date <= datetime.date.today()
    new_doc = Document(
            department=data['department'],
            lectures=lectures,
            examinants=examinants,
            date=date,
            number_of_pages=0,  # will be filled in later or upon validation
            document_type=data['document_type'],
            validated=validated,
            validation_time=datetime.datetime.now() if validated else None,
            comment=data.get('comment'),
            solution=data.get('solution'),
            submitted_by=data.get('student_name'))
    sqla.session.add(new_doc)

    # we have the db side of things taken care of, now save the file
    # and tell the db where to find the file
    sqla.session.flush()  # necessary for id field to be populated
    save_file(new_doc, file)
    if validated:
        # we don't trust other people's PDFs...
        new_doc.number_of_pages = number_of_pages(new_doc)
    sqla.session.commit()
    app.logger.info("New document submitted (id: {})".format(new_doc.id))
    if validated:
        config.document_validated(document_path(new_doc.id))
    return {}
Beispiel #4
0
class DocumentLoadSchema(Schema):  # used by document submission
    department = fields.Str(required=True, validate=OneOf(['computer science', 'mathematics', 'other']))
    lectures = fields.List(fields.Str(), required=True)
    examinants = fields.List(fields.Str(), required=True)
    date = fields.Date(required=True)
    document_type = fields.Str(required=True, validate=lambda x: get_user() and x == 'written' or x in ['oral', 'oral reexam', 'mock exam'])
    student_name = fields.Str(required=False, allow_none=True)
Beispiel #5
0
def view_document(instance_id):
    if get_user() or is_kiosk():
        doc = Document.query.get(instance_id)
        if doc is None or not doc.has_file:
            raise ClientError('document not found', status=404)
        return send_file(document_path(doc.id))
    else:
        return unauthorized()
Beispiel #6
0
def view_document(instance_id):
    if get_user() or is_kiosk():
        doc = Document.query.get(instance_id)
        if doc is None or not doc.has_file:
            raise ClientError('document not found', status=404)
        return send_file(document_path(doc.id))
    else:
        return unauthorized()
Beispiel #7
0
def view_document(instance_id):
    doc = Document.query.get(instance_id)

    if get_user() or is_kiosk() or doc.publicly_available:
        if doc is None or not doc.has_file:
            raise ClientError('document not found', status=404)
        return send_file(document_path(doc.id), as_attachment=(request.args.get('download') is not None))
    else:
        return unauthorized()
Beispiel #8
0
 def handle_get(instance_id=None):
     if instance_id is None:  # GET MANY
         assert 'GET' in schemas, "GET schema missing"
         schema = schemas['GET']
         allow_insecure = allow_insecure_authenticated and get_user()
         return filtered_results(query_fn(), schema, paginate_many, allow_insecure=allow_insecure)
     else:  # GET SINGLE
         result = query_fn().get(instance_id)
         obj = serialize(result, schema)
         return obj
Beispiel #9
0
def log_deposit_return(data):
    if 'document_id' in data:
        doc = Document.query.get(data['document_id'])
        # data privacy, yo
        doc.submitted_by = None

    dep = Deposit.query.get(data['id'])
    sqla.session.delete(dep)
    db.accounting.log_deposit_return(dep, get_user(), data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #10
0
def log_deposit_return(data):
    if 'document_id' in data:
        doc = Document.query.get(data['document_id'])
        # data privacy, yo
        doc.submitted_by = None

    dep = Deposit.query.get(data['id'])
    if Deposit.query.filter(Deposit.id == data['id']).delete() == 0:
        raise ClientError('deposit not found')
    db.accounting.log_deposit_return(dep, get_user(), data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #11
0
def scanner(location, id):
    assert location in config.FS_CONFIG['OFFICES']
    assert 0 <= id <= len(config.LASER_SCANNERS[location])
    (host, port) = config.LASER_SCANNERS[location][id]
    bs = barcode.BarcodeScanner(host, port, get_user().first_name)
    yield None  # exit application context, start event stream

    for doc in bs:
        if doc is None:
            # socket read has timeouted, try to write to output stream
            yield (None, None)
        else:
            yield (None, serialize(doc, DocumentDumpSchema))
Beispiel #12
0
def scanner(location, id):
    assert location in config.FS_CONFIG['OFFICES']
    assert 0 <= id <= len(config.LASER_SCANNERS[location])
    (host, port) = config.LASER_SCANNERS[location][id]
    bs = barcode.BarcodeScanner(host, port, get_user().first_name)
    schema = DocumentDumpSchema()  # __init__ requires application context
    yield None  # exit application context, start event stream

    for doc in bs:
        if doc is None:
            # socket read has timeouted, try to write to output stream
            yield (None, None)
        else:
            yield (None, serialize(doc, lambda: schema))
Beispiel #13
0
def jsonify(*args, **kwargs):
    # http://flask.pocoo.org/snippets/45/
    def request_wants_json():
        best = request.accept_mimetypes \
            .best_match(['application/json', 'text/html'])
        return best == 'application/json' and \
            request.accept_mimetypes[best] > \
            request.accept_mimetypes['text/html']

    data = json.dumps(dict(*args, **kwargs), indent=None if request.is_xhr else 2)
    if not get_user() or request_wants_json():
        return Response(data, mimetype='application/json')
    else:
        # provide some HTML for flask-debugtoolbar to inject into
        return '<html><body><pre>{}</pre></body></html>'.format(data)
Beispiel #14
0
def jsonify(*args, **kwargs):
    # http://flask.pocoo.org/snippets/45/
    def request_wants_json():
        best = request.accept_mimetypes \
            .best_match(['application/json', 'text/html'])
        return best == 'application/json' and \
            request.accept_mimetypes[best] > \
            request.accept_mimetypes['text/html']

    data = json.dumps(dict(*args, **kwargs))
    if not get_user() or request_wants_json():
        return Response(data, mimetype='application/json')
    else:
        # provide some HTML for flask-debugtoolbar to inject into
        return '<html><body><pre>{}</pre></body></html>'.format(data)
def log_early_document_reward(data):
    doc = Document.query.get(data['id'])
    if doc is None:
        raise ClientError('document not found')
    if not doc.early_document_eligible:
        raise ClientError('document not eligible for early document reward')

    doc.early_document_eligible = False
    # data privacy, yo
    if not doc.deposit_return_eligible:
        doc.submitted_by = None

    db.accounting.log_early_document_disburse(get_user(), data['cash_box'])
    sqla.session.commit()

    return {'disbursal': config.FS_CONFIG['EARLY_DOCUMENT_REWARD']}
Beispiel #16
0
def log_early_document_reward(data):
    doc = Document.query.get(data['id'])
    if doc is None:
        raise ClientError('document not found')
    if not doc.early_document_eligible:
        raise ClientError('document not eligible for early document reward')

    doc.early_document_eligible = False
    # data privacy, yo
    if not doc.deposit_return_eligible:
        doc.submitted_by = None

    db.accounting.log_early_document_disburse(get_user(), data['cash_box'])
    sqla.session.commit()

    return {'disbursal': config.FS_CONFIG['EARLY_DOCUMENT_REWARD']}
Beispiel #17
0
    def merge(self, ids):
        lectures = Lecture.query.filter(Lecture.id.in_(ids)).all()
        first = next(lecture for lecture in lectures if lecture.id == int(ids[0]))
        all_docs = set()
        for lecture in lectures:
            all_docs |= set(lecture.documents)
            if lecture != first:
                sqla.session.delete(lecture)
        first.documents = list(all_docs)
        sqla.session.commit()
        flash('Vorlesungen in "{}" zusammengefügt'.format(first.name))

        config.log_admin_audit(self, first,
                               '\n\n'.join(['Lectures merged by {}'.format(get_user().full_name),
                                            '{}->{}'.format([l.name for l in lectures], first.name),
                                            url_for('lecture.edit_view', id=first.id, _external=True)]))
def log_deposit_return(data):
    if 'document_id' in data:
        doc = Document.query.get(data['document_id'])
        if doc is None:
            raise ClientError('document not found')
        doc.deposit_return_eligible = False
        # data privacy, yo
        if not doc.early_document_eligible:
            doc.submitted_by = None

    dep = Deposit.query.get(data['id'])
    if Deposit.query.filter(Deposit.id == data['id']).delete() == 0:
        raise ClientError('deposit not found')
    db.accounting.log_deposit_return(dep, get_user(), data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #19
0
    def _log_model_changes(self, model, state):
        if state == 'changed' and not sqla.session.is_modified(model):
            return

        msg = '{} {} by {}\n\n'.format(model.__class__.__name__, state,
                                       get_user().full_name)
        view = model_views[model.__class__]
        attrs = inspect(model).attrs
        for (col, _) in self.get_list_columns():
            attr = attrs[col]
            prop = model.__class__.__mapper__.attrs[col]
            is_list = isinstance(prop, RelationshipProperty) and prop.uselist
            changed = state == 'changed' and attr.history.has_changes()
            if changed and isinstance(attr.value, datetime.datetime):
                old = attr.history.deleted[0]
                val = attr.value
                if old:
                    # special case: convert attr.value from naive to aware datetime
                    val = val.replace(tzinfo=old.tzinfo)
                changed = val != old

            if changed:
                if is_list:
                    msg += '**{}: {}**\n'.format(
                        attr.key, ', '.join(
                            list(map(str, attr.history.unchanged)) + [
                                '-{}'.format(val)
                                for val in attr.history.deleted
                            ] +
                            ['+{}'.format(val) for val in attr.history.added]))
                else:
                    msg += '**{}: {} -> {}**\n'.format(attr.key,
                                                       attr.history.deleted[0],
                                                       attr.history.added[0])
            else:
                if is_list:
                    msg += '{}: {}\n'.format(attr.key,
                                             ', '.join(map(str, attr.value)))
                else:
                    msg += '{}: {}\n'.format(attr.key, attr.value)

        if state != 'deleted':
            msg += '\n' + url_for(
                view.endpoint + '.edit_view', id=model.id, _external=True)

        config.log_admin_audit(self, model, msg)
Beispiel #20
0
    def print_all(self):
        folders = list(self._get_folders_with_counts())
        for folder, _ in folders:
            documents = self._query_unprinted(folder).all()
            config.print_documents(
                doc_paths=[document_path(doc.id) for doc in documents],
                cover_text=None,
                printer=config.FS_CONFIG['OFFICES'][self._get_location()]['printers'][0],
                user=get_user().username,
                usercode=config.PRINTER_USERCODES['internal'],
                job_title='Odie-Druck: Ordnerdruck'
            )
            folder.printed_docs += documents
            sqla.session.commit()

        return self.render('print_for_folder.html',
                           printed_folders=folders,
                           examinants_without_folders=Examinant.query.filter(~Examinant.folders.any()).sort_by(Examinant.name).all())
Beispiel #21
0
    def merge(self, ids):
        lectures = Lecture.query.filter(Lecture.id.in_(ids)).all()
        first = next(lecture for lecture in lectures
                     if lecture.id == int(ids[0]))
        all_docs = set()
        for lecture in lectures:
            all_docs |= set(lecture.documents)
            if lecture != first:
                sqla.session.delete(lecture)
        first.documents = list(all_docs)
        sqla.session.commit()
        flash('Vorlesungen in "{}" zusammengefügt'.format(first.name))

        config.log_admin_audit(
            self, first, '\n\n'.join([
                'Lectures merged by {}'.format(get_user().full_name),
                '{}->{}'.format([l.name for l in lectures], first.name),
                url_for('lecture.edit_view', id=first.id, _external=True)
            ]))
Beispiel #22
0
    def print_all(self):
        folders = list(self._get_folders_with_counts())
        for folder, _ in folders:
            documents = self._query_unprinted(folder).all()
            config.print_documents(
                doc_paths=[document_path(doc.id) for doc in documents],
                cover_text=None,
                printer=config.FS_CONFIG['OFFICES'][
                    self._get_location()]['printers'][0],
                user=get_user().username,
                usercode=config.PRINTER_USERCODES['internal'],
                job_title='Odie-Druck: Ordnerdruck')
            folder.printed_docs += documents
            sqla.session.commit()

        return self.render('print_for_folder.html',
                           printed_folders=folders,
                           examinants_without_folders=Examinant.query.filter(
                               ~Examinant.folders.any()).sort_by(
                                   Examinant.name).all())
Beispiel #23
0
    def _log_model_changes(self, model, state):
        if state == 'changed' and not sqla.session.is_modified(model):
            return

        msg = '{} {} by {}\n\n'.format(model.__class__.__name__, state, get_user().full_name)
        view = model_views[model.__class__]
        attrs = inspect(model).attrs
        for (col, _) in self.get_list_columns():
            attr = attrs[col]
            prop = model.__class__.__mapper__.attrs[col]
            is_list = isinstance(prop, RelationshipProperty) and prop.uselist
            changed = state == 'changed' and attr.history.has_changes()
            if changed and isinstance(attr.value, datetime.datetime):
                old = attr.history.deleted[0]
                val = attr.value
                if old:
                    # special case: convert attr.value from naive to aware datetime
                    val = val.replace(tzinfo=old.tzinfo)
                changed = val != old

            if changed:
                if is_list:
                    msg += '**{}: {}**\n'.format(attr.key, ', '.join(
                        list(map(str, attr.history.unchanged)) +
                        ['-{}'.format(val) for val in attr.history.deleted] +
                        ['+{}'.format(val) for val in attr.history.added]
                    ))
                else:
                    msg += '**{}: {} -> {}**\n'.format(
                        attr.key, attr.history.deleted[0], attr.history.added[0]
                    )
            else:
                if is_list:
                    msg += '{}: {}\n'.format(attr.key, ', '.join(map(str, attr.value)))
                else:
                    msg += '{}: {}\n'.format(attr.key, attr.value)

        if state != 'deleted':
            msg += '\n' + url_for(view.endpoint + '.edit_view', id=model.id, _external=True)

        config.log_admin_audit(self, model, msg)
Beispiel #24
0
def documents_query():
    query = Document.query.options(subqueryload('lectures'), subqueryload('examinants'))
    param_filters = json.loads(request.args.get('filters', '{}'))
    for id_ in param_filters.get('includes_lectures', []):
        query = query.filter(Document.lectures.any(Lecture.id == id_))
    for id_ in param_filters.get('includes_examinants', []):
        query = query.filter(Document.examinants.any(Examinant.id == id_))

    # From the documentselection view (which can be accessed anonymously) we usually get a GET parameter 'q' like this:
    # {"operator":"order_by_desc","column":"date","value":{"operator":"and","value":[{"column":"document_type","operator":"in_","value":["written","oral","oral reexam","mock exam"]}]},"page":1}
    # We need to parse and create the SQLAlchemy Query manually to avoid data leaks.
    # (If we were instead using jsonquery, anonymous users were able to efficiently extract submitted_by names by
    #  performing bisection with the submitted_by parameter and `like` operator.
    #  See https://github.com/fsmi/odie-server/pull/168 for details.)
    # For logged in users, we have set allow_insecure_authenticated=True on the /api/documents view to allow
    # the `submitted_by` filter in the depositreturn view; logged in users have access to all the data anyway.
    # Note that the `page` parameter is taken into account by endpoint()/filtered_results() in either case.
    if not get_user():
        param_q = json.loads(request.args.get('q', '{}'))
        # While it looks ugly, we validate all parameters to ensure that the JSON structure is as expected and that only
        # whitelisted values work.
        if param_q.get('operator') in ('order_by_desc', 'order_by_asc') and \
                param_q.get('column') in ('date', 'number_of_pages', 'validation_time'):
            sort_fn = asc if param_q.get('operator') == 'order_by_asc' else desc
            query = query.order_by(sort_fn(param_q['column']))

        if isinstance(param_q.get('value'), dict) and \
                param_q['value'].get('operator') == 'and' and \
                isinstance(param_q['value'].get('value'), list) and \
                len(param_q['value']['value']) == 1 and \
                param_q['value']['value'][0].get('column') == 'document_type' and \
                param_q['value']['value'][0].get('operator') == 'in_' and \
                isinstance(param_q['value']['value'][0].get('value'), list) and \
                all(value in ('written', 'oral', 'oral reexam', 'mock exam') for value in param_q['value']['value'][0]['value']):
            query = query.filter(Document.document_type.in_(param_q['value']['value'][0]['value']))

    return query
def accept_erroneous_sale(data):
    db.accounting.log_erroneous_sale(data['amount'], get_user(),
                                     data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #26
0
 def is_accessible(self):
     return bool(get_user()
                 and get_user().has_permission(*self.allowed_roles))
Beispiel #27
0
 def _get_location(self):
     # Nobody would ever be a member of both groups at the same time, right?
     if get_user().has_permission('info_protokolle'):
         return 'FSI'
     if get_user().has_permission('mathe_protokolle'):
         return 'FSM'
def log_donation(data):
    db.accounting.log_donation(get_user(), data['amount'], data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #29
0
def user_info():
    # Explicitly pass the csrf token cookie value for cross-origin clients.
    return serialize({
        'user': get_user(),
        'token': csrf._get_token()
    }, LoginDumpSchema)
Beispiel #30
0
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from login import get_user

SEARCH_URL = "https://www.facebook.com/search/videos/?q={}"
LOGIN_URL = "https://www.facebook.com/"
DRIVER_DIR = '/Users/temp/Project_FC/chromedriver'

ID, PW = get_user()

def facebook_scrap(keyword):
    try:
        driver = webdriver.Chrome(DRIVER_DIR)
        driver.implicitly_wait(10)
        driver.get(LOGIN_URL)
        time.sleep(1)
        e = driver.find_element_by_id('email')
        e.clear()
        e.send_keys(ID)
        e = driver.find_element_by_id('pass')
        e.clear()
        e.send_keys(PW)
        e.send_keys(Keys.ENTER)
        print('로그인')
        
        driver.get(SEARCH_URL.format(keyword))
                
        links = [] 
        for link in driver.find_elements_by_css_selector('div._14ax > a'): # 링크 a 태그 찾기             
            links.append(link.get_attribute('href'))
def logout():
    Cookie.query.filter_by(user_id=get_user().id).delete()
    sqla.session.commit()
    response = app.make_response(redirect(request.args.get('target_path')))
    response.set_cookie(AUTH_COOKIE, value='', expires=0)
    return response
Beispiel #32
0
def log_donation(data):
    db.accounting.log_donation(get_user(), data['amount'], data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #33
0
def accept_erroneous_sale(data):
    db.accounting.log_erroneous_sale(data['amount'], get_user(), data['cash_box'])
    sqla.session.commit()
    return {}
Beispiel #34
0
 def is_accessible(self):
     return bool(get_user() and get_user().has_permission(*self.allowed_roles))
Beispiel #35
0
 def _get_location(self):
     # Nobody would ever be a member of both groups at the same time, right?
     if get_user().has_permission('info_protokolle'):
         return 'FSI'
     if get_user().has_permission('mathe_protokolle'):
         return 'FSM'
Beispiel #36
0
def print_documents():
    # GET params could be too limited. therefore, cookies.
    try:
        data = PrintJobLoadSchema().loads(urllib.parse.unquote(request.cookies['print_data']))
    except marshmallow.exception.ValidationError as e:
        raise ClientError(str(e), status=500)
    document_ids = data['document_ids']
    app.logger.info("Printing document ids {} ({} in total) on {} for {}".format(document_ids, len(document_ids), data['printer'], data['cover_text']))

    document_objs = Document.query.filter(Document.id.in_(document_ids)).all()
    if any(not doc.has_file for doc in document_objs):
        raise ClientError('Tried to print at least one document without file', status=400)
    # sort the docs into the same order they came in the request
    docs_by_id = {doc.id: doc for doc in document_objs}
    documents = [docs_by_id[id] for id in document_ids]

    assert data['deposit_count'] >= 0
    print_price = sum(doc.price for doc in documents)
    # round up to next 10 cents
    print_price = 10 * (print_price//10 + (1 if print_price % 10 else 0))
    assert print_price + data['deposit_count'] * config.FS_CONFIG['DEPOSIT_PRICE'] == data['price']

    # pull current user out of app context
    user = get_user()
    yield None  # exit application context, start event stream

    num_pages = sum(doc.number_of_pages for doc in documents)

    try:
        if documents:
            db.accounting.log_exam_sale(num_pages, print_price, user, data['cash_box'])
        for _ in range(data['deposit_count']):
            lectures = Lecture.query.filter(Lecture.documents.any(Document.id.in_(document_ids))).all()
            dep = Deposit(
                    price=config.FS_CONFIG['DEPOSIT_PRICE'],
                    name=data['cover_text'],
                    by_user=user.full_name,
                    lectures=lectures)
            sqla.session.add(dep)
            db.accounting.log_deposit(dep, user, data['cash_box'])
            if documents:
                try:
                    name = data['cover_text'].split(' ')[0]
                    for _ in config.print_documents(
                        doc_paths=[document_path(doc.id) for doc in documents],
                        cover_text=data['cover_text'],
                        printer=data['printer'],
                        user=user.username,
                        usercode=config.PRINTER_USERCODES[data['cash_box']],
                        job_title="Odie-Druck für {} [{} Seiten]".format(name, num_pages)):
                            pass
                except Exception as e:
                    sqla.session.rollback()
                    raise NonConfidentialException('printing failed. Exception: ' + str(e)) from e
        sqla.session.commit()
        yield('accounting succeeded', '')
    except NonConfidentialException as e:
        raise NonConfidentialException(str(e)) from e
    except Exception as e:
        # in case of network troubles, we've just printed a set of documents but screwed up accounting.
        raise NonConfidentialException('accounting failed. Exception: ' + str(e)) from e
    yield ('complete', '')
Beispiel #37
0
def submit_documents(validated):
    """Student document submission endpoint

    POST data must be multipart, with the `json` part conforming to
    DocumentLoadSchema and the `file` part being a pdf file.

    Uploaded files are stored in subdirectories below config.DOCUMENT_DIRECTORY.

    This method may raise AssertionErrors when the user sends invalid data.
    """
    # we can't use @deserialize because this endpoint uses multipart form data
    data = json.loads(request.form['json'])
    if get_user():
        try:
            data = FullDocumentLoadSchema().load(data)
        except marshmallow.exceptions.ValidationError as e:
            raise ClientError(str(e), status=500)
        if (data.get('document_type') == 'written' and data.get('solution')
                not in ['official', 'inofficial', 'none']
                or data.get('document_type') != 'written'
                and data.get('solution') is not None):
            raise ClientError('Invalid value.', status=400)
    else:
        try:
            data = DocumentLoadSchema().load(data)
        except marshmallow.exceptions.ValidationError as e:
            raise ClientError(str(e), status=400)
    assert 'file' in request.files
    file = request.files['file']
    if not _allowed_file(file.filename):
        raise ClientError('file extension not allowed', status=406)
    lectures = _match_lectures(data['lectures'], validated)
    examinants = _match_examinants(data['examinants'], validated)
    date = data['date']
    if not get_user():
        assert date <= datetime.date.today()

    doc_type = data.get('document_type')
    student_name = data.get('student_name')
    if student_name is None or student_name.isspace():
        student_name = None
    deposit_return_eligible = student_name is not None
    early_document_eligible = student_name is not None and doc_type == 'oral' and any(
        lecture.early_document_eligible for lecture in lectures)

    new_doc = Document(
        department=data['department'],
        lectures=lectures,
        examinants=examinants,
        date=date,
        number_of_pages=0,  # will be filled in later or upon validation
        document_type=doc_type,
        validation_time=datetime.datetime.now() if validated else None,
        comment=data.get('comment'),
        solution=data.get('solution'),
        submitted_by=student_name,
        early_document_eligible=early_document_eligible,
        deposit_return_eligible=deposit_return_eligible)
    sqla.session.add(new_doc)

    # we have the db side of things taken care of, now save the file
    # and tell the db where to find the file
    sqla.session.flush()  # necessary for id field to be populated
    save_file(new_doc, file)
    if validated:
        # we don't trust other people's PDFs...
        new_doc.number_of_pages = number_of_pages(new_doc)
    sqla.session.commit()
    app.logger.info("New document submitted (id: {})".format(new_doc.id))
    if validated:
        config.document_validated(document_path(new_doc.id))
    return {'early_document_eligible': early_document_eligible}
Beispiel #38
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # cache DB operation
        self._authenticated = bool(get_user())
Beispiel #39
0
def user_info():
    # Explicitly pass the csrf token cookie value for cross-origin clients.
    return serialize({'user': get_user(), 'token': csrf._get_token()}, LoginDumpSchema)