コード例 #1
0
ファイル: rest.py プロジェクト: weblate/sonar
    def post(pid=None):
        """Save the file and associate it to the deposit record."""
        deposit = DepositRecord.get_record_by_pid(pid)

        if not deposit:
            abort(400)

        if 'key' not in request.args or 'type' not in request.args:
            abort(400)

        # Type must be either "main" or "additional"
        if request.args['type'] not in ['main', 'additional']:
            abort(400)

        key = request.args['key']

        # Store document
        deposit.files[key] = BytesIO(request.get_data())
        deposit.files[key]['label'] = re.search(r'(.*)\..*$', key).group(1)
        deposit.files[key]['category'] = request.args['type']
        deposit.files[key]['type'] = 'file'

        deposit.commit()
        db.session.commit()

        return make_response(jsonify(deposit.files[key].dumps()))
コード例 #2
0
ファイル: rest.py プロジェクト: weblate/sonar
    def put(pid=None, key=None):
        """Update metadata linked to file."""
        deposit = DepositRecord.get_record_by_pid(pid)

        if not deposit:
            abort(400)

        json = request.get_json()

        if key not in deposit.files:
            abort(400)

        for item in json.items():
            deposit.files[key][item[0]] = item[1]

        if not deposit.files[key].get('embargoDate'):
            deposit.files[key].data.pop('embargoDate')

        try:
            deposit.commit()
            db.session.commit()
        except Exception:
            abort(400)

        return make_response(jsonify(deposit.files[key].dumps()))
コード例 #3
0
ファイル: permissions.py プロジェクト: weblate/sonar
    def read(cls, user, record):
        """Read permission check.

        :param user: Logged user.
        :param recor: Record to check.
        :returns: True is action can be done.
        """
        # At least for submitters logged users.
        if not current_user_record or not current_user_record.is_submitter:
            return False

        # Superuser is allowd
        if current_user_record.is_superuser:
            return True

        deposit = DepositRecord.get_record_by_pid(record['pid'])
        deposit = deposit.replace_refs()

        # Moderators are allowed only for their organisation's deposits.
        if current_user_record.is_moderator:
            return current_organisation['pid'] == deposit['user'][
                'organisation']['pid']

        # Submitters have only access to their own deposits.
        return current_user_record['pid'] == deposit['user']['pid']
コード例 #4
0
def publish(pid=None):
    """Publish a deposit or send a message for review."""
    deposit = DepositRecord.get_record_by_pid(pid)

    if not deposit or deposit[
            'step'] != DepositRecord.STEP_DIFFUSION or deposit[
                'status'] not in [
                    DepositRecord.STATUS_IN_PROGRESS,
                    DepositRecord.STATUS_ASK_FOR_CHANGES
                ]:
        abort(400)

    user = UserRecord.get_record_by_ref_link(deposit['user']['$ref'])

    # Deposit can be validated directly
    if user.is_granted(UserRecord.ROLE_MODERATOR):
        deposit['status'] = DepositRecord.STATUS_VALIDATED

        # Create document based on deposit
        deposit.create_document()
    else:
        deposit['status'] = DepositRecord.STATUS_TO_VALIDATE

        subdivision = SubdivisionRecord.get_record_by_ref_link(
            user['subdivision']['$ref']) if user.get('subdivision') else None

        moderators_emails = user.get_moderators_emails(
            subdivision['pid'] if subdivision else None)

        email_subject = _('Deposit to validate')
        if subdivision:
            email_subject += f' ({get_language_value(subdivision["name"])})'

        if moderators_emails:
            # Send an email to validators
            send_email(
                moderators_emails, email_subject, 'deposits/email/validation',
                {
                    'deposit': deposit,
                    'user': user,
                    'link': current_app.config.get('SONAR_APP_ANGULAR_URL')
                }, False)

    deposit.log_action(user, 'submit')

    deposit.commit()
    deposit.reindex()
    db.session.commit()

    return make_response()
コード例 #5
0
    def read(cls, user, record):
        """Read permission check.

        :param user: Current user record.
        :param record: Record to check.
        :returns: True is action can be done.
        """
        # At least for submitters logged users.
        if not user or not user.is_submitter:
            return False

        if user.is_superuser:
            return True

        deposit = DepositRecord.get_record_by_pid(record['pid'])
        deposit = deposit.replace_refs()

        # Admin is allowed only for same organisation's records
        if user.is_admin:
            return current_organisation['pid'] == deposit['user'][
                'organisation']['pid']

        # Special rules for moderators
        if user.is_moderator:
            user = user.replace_refs()

            # Deposit does not belong to user's organisation
            if current_organisation['pid'] != deposit['user']['organisation'][
                    'pid']:
                return False

            # Moderator has no subdivision, he can read the deposit
            if not user.get('subdivision'):
                return True

            # User has a subdivision, he can only read his own deposits and
            # deposits from the same subdivision
            return user['pid'] == deposit['user'][
                'pid'] or deposit.has_subdivision(
                    user.get('subdivision', {}).get('pid'))

        # Submitters have only access to their own deposits.
        return user['pid'] == deposit['user']['pid']
コード例 #6
0
ファイル: rest.py プロジェクト: weblate/sonar
def extract_metadata(pid=None):
    """Publish a deposit or send a message for review."""
    deposit = DepositRecord.get_record_by_pid(pid)

    if not deposit:
        abort(400)

    main_file = [
        file for file in deposit.files
        if file['category'] == 'main' and file.mimetype == 'application/pdf'
    ]

    if not main_file:
        abort(500)

    # Get file content
    with main_file[0].file.storage().open() as pdf_file:
        content = pdf_file.read()

    # Extract data from pdf
    pdf_extractor = PDFExtractor()
    pdf_metadata = format_extracted_data(pdf_extractor.process_raw(content))

    return make_response(jsonify(pdf_metadata))
コード例 #7
0
 def get_deposit(cls, parent_record):
     """Get the deposit from the parent record."""
     return DepositRecord.get_record_by_pid(parent_record.get('pid'))
コード例 #8
0
ファイル: rest.py プロジェクト: weblate/sonar
 def get(pid=None):
     """Get list of files associated with bucket."""
     deposit = DepositRecord.get_record_by_pid(pid)
     return make_response(jsonify(deposit.files.dumps()))
コード例 #9
0
ファイル: rest.py プロジェクト: weblate/sonar
def review(pid=None):
    """Review a deposit and change the deposit status depending on action."""
    deposit = DepositRecord.get_record_by_pid(pid)

    if not deposit or deposit['status'] != DepositRecord.STATUS_TO_VALIDATE:
        abort(400)

    payload = request.get_json()

    if not payload:
        abort(400)

    if 'action' not in payload or 'user' not in payload or payload[
            'action'] not in [
                DepositRecord.REVIEW_ACTION_APPROVE,
                DepositRecord.REVIEW_ACTION_REJECT,
                DepositRecord.REVIEW_ACTION_ASK_FOR_CHANGES
            ]:
        abort(400)

    user = UserRecord.get_record_by_ref_link(payload['user']['$ref'])

    if not user or not user.is_moderator:
        abort(403)

    subject = None
    status = None

    if payload['action'] == DepositRecord.REVIEW_ACTION_APPROVE:
        subject = _('Deposit approval')
        status = DepositRecord.STATUS_VALIDATED

        # Create document based on deposit
        deposit.create_document()
    elif payload['action'] == DepositRecord.REVIEW_ACTION_REJECT:
        subject = _('Deposit rejection')
        status = DepositRecord.STATUS_REJECTED
    else:
        subject = _('Ask for changes on deposit')
        status = DepositRecord.STATUS_ASK_FOR_CHANGES

    deposit['status'] = status

    # Log action
    deposit.log_action(payload['user'], payload['action'], payload['comment'])

    # Load user who creates the deposit
    deposit_user = UserRecord.get_record_by_ref_link(deposit['user']['$ref'])

    send_email(
        [deposit_user['email']], subject,
        'deposits/email/{action}'.format(action=payload['action']), {
            'deposit': deposit,
            'deposit_user': deposit_user,
            'user': user,
            'date': datetime.now().strftime('%d.%m.%Y %H:%M:%S'),
            'comment': payload['comment'],
            'link': current_app.config.get('SONAR_APP_ANGULAR_URL')
        }, False)

    deposit.commit()
    deposit.reindex()
    db.session.commit()

    return make_response(jsonify(deposit))