Ejemplo n.º 1
0
def test_get_hashed_filename():
    a = get_hashed_filename("foo bar baz.mp3")
    time.sleep(3)
    b = get_hashed_filename("foo bar baz.mp3")
    time.sleep(1)
    c = get_hashed_filename("foo bar baz.mp3")
    time.sleep(0.4)
    d = get_hashed_filename("foo bar baz.mp3")
    assert a != b != c != d
Ejemplo n.º 2
0
def artwork(username, trackslug):
    """
    Change track artwork.
    ---
    tags:
        - Tracks
    security:
        - OAuth2:
            - write
    parameters:
        - name: username
          in: path
          type: string
          required: true
          description: User username
        - name: trackslug
          in: path
          type: string
          required: true
          description: Track slug
    responses:
        200:
            description: Returns ok or not.
    """
    current_user = current_token.user
    if not current_user:
        return jsonify({"error": "Unauthorized"}), 403

    # Get the track
    track = Sound.query.filter(Sound.user_id == current_user.id, Sound.slug == trackslug).first()
    if not track:
        return jsonify({"error": "Not found"}), 404

    # Check artwork file size
    if "artwork" not in request.files:
        return jsonify({"error": "Artwork file missing"}), 503

    artwork_uploaded = request.files["artwork"]
    artwork_uploaded.seek(0, os.SEEK_END)
    artwork_size = artwork_uploaded.tell()
    artwork_uploaded.seek(0)
    if artwork_size > Reel2bitsDefaults.artwork_size_limit:
        return jsonify({"error": "artwork too big, 2MB maximum"}), 413  # Request Entity Too Large

    # Delete old artwork if any
    if track.artwork_filename:
        old_artwork = os.path.join(current_app.config["UPLOADED_ARTWORKSOUNDS_DEST"], track.path_artwork())
        if os.path.isfile(old_artwork):
            os.unlink(old_artwork)
        else:
            print(f"Error: cannot delete old track artwork: {track.id} / {track.artwork_filename}")

    # Save new artwork
    artwork_filename = get_hashed_filename(artwork_uploaded.filename)
    artworksounds.save(artwork_uploaded, folder=current_user.slug, name=artwork_filename)

    track.artwork_filename = artwork_filename

    db.session.commit()

    # trigger a sound update
    send_update_sound(track)

    return jsonify({"status": "ok", "path": track.path_artwork()})
Ejemplo n.º 3
0
def upload():
    """
    Create a new track.
    ---
    tags:
        - Tracks
    security:
        - OAuth2:
            - write
    responses:
        200:
            description: Returns the track id and slug.
    """
    errors = {}

    current_user = current_token.user
    if not current_user:
        return jsonify({"error": "Unauthorized"}), 403

    if "file" not in request.files:
        errors["file"] = "No file present"

    if len(errors) > 0:
        return jsonify({"error": errors}), 400

    # Check for user quota already reached
    if current_user.quota_count >= current_user.quota:
        return jsonify({"error": "quota limit reached"}), 507  # Insufficient storage
        # or 509 Bandwitdh Limit Exceeded...

    # Get file, and file size
    file_uploaded = request.files["file"]
    file_uploaded.seek(0, os.SEEK_END)  # ff to the end
    file_size = file_uploaded.tell()
    file_uploaded.seek(0)  # rewind

    if (current_user.quota_count + file_size) > current_user.quota:
        return jsonify({"error": "quota limit reached"}), 507  # Insufficient storage

    # Do the same with the artwork
    if "artwork" in request.files:
        artwork_uploaded = request.files["artwork"]
        artwork_uploaded.seek(0, os.SEEK_END)
        artwork_size = artwork_uploaded.tell()
        artwork_uploaded.seek(0)
        if artwork_size > Reel2bitsDefaults.artwork_size_limit:  # Max size of 2MB
            return jsonify({"error": "artwork too big, 2MB maximum"}), 413  # Request Entity Too Large
    else:
        artwork_uploaded = None

    form = SoundUploadForm()

    if form.validate_on_submit():
        filename_orig = file_uploaded.filename
        filename_hashed = get_hashed_filename(filename_orig)

        # Save the track file
        sounds.save(file_uploaded, folder=current_user.slug, name=filename_hashed)

        rec = Sound()
        rec.filename = filename_hashed
        rec.filename_orig = filename_orig

        # Save the artwork
        if artwork_uploaded:
            artwork_filename = get_hashed_filename(artwork_uploaded.filename)
            artworksounds.save(artwork_uploaded, folder=current_user.slug, name=artwork_filename)
            rec.artwork_filename = artwork_filename

        rec.licence = form.licence.data
        if form.album.data:
            rec.album_id = form.album.data.id
            if not form.album.data.sounds:
                rec.album_order = 0
            else:
                rec.album_order = form.album.data.sounds.count() + 1

        rec.user_id = current_user.id
        if not form.title.data:
            rec.title, _ = splitext(filename_orig)
        else:
            rec.title = form.title.data
        rec.description = form.description.data
        rec.private = form.private.data
        rec.file_size = file_size
        rec.transcode_file_size = 0  # will be filled, if needed in transcoding workflow
        rec.genre = form.genre.data

        # Handle tags
        tags = form.tags.data.split(",")
        # Clean
        tags = [t.strip() for t in tags if t]
        # For each tag get it or create it
        for tag in tags:
            dbt = SoundTag.query.filter(SoundTag.name == tag).first()
            if not dbt:
                dbt = SoundTag(name=tag)
                db.session.add(dbt)
            rec.tags.append(dbt)

        if "flac" in file_uploaded.mimetype or "ogg" in file_uploaded.mimetype or "wav" in file_uploaded.mimetype:
            rec.transcode_state = Sound.TRANSCODE_WAITING
            rec.transcode_needed = True

        db.session.add(rec)

        # recompute user quota
        current_user.quota_count = current_user.quota_count + rec.file_size

        db.session.commit()

        # push the job in queue
        from tasks import upload_workflow

        upload_workflow.delay(rec.id)

        # log
        add_user_log(rec.id, current_user.id, "sounds", "info", "Uploaded {0} -- {1}".format(rec.id, rec.title))

        return jsonify({"id": rec.flake_id, "slug": rec.slug})

    return jsonify({"error": json.dumps(form.errors)}), 400
Ejemplo n.º 4
0
def accounts_update_credentials():
    """
    Update user’s own account.
    ---
    tags:
        - Accounts
    security:
        - OAuth2:
            - write
    responses:
        200:
            description: Returns Account with extra Source and Pleroma attributes.
            schema:
                allOf:
                    - $ref: '#/definitions/Account'
                    - $ref: '#/definitions/Source'
                    - $ref: '#/definitions/AccountPleroma'
    """
    current_user = current_token.user

    if not current_user:
        # WTF ?
        return jsonify({"error": "User not found"}), 404

    # Update fields like bio, language, etc.
    if request.json:
        r_lang = request.json.get("lang", None)
        r_fullname = request.json.get("fullname", None)
        r_bio = request.json.get("bio", None)

        if r_lang:
            current_user.locale = r_lang
        if r_fullname:
            current_user.display_name = r_fullname
        if r_bio:
            current_user.actor[0].summary = r_bio
    elif request.files:
        # Update things like user background, profile picture, etc.
        if "avatar" in request.files:
            avatar_uploaded = request.files["avatar"]
            avatar_uploaded.seek(0, os.SEEK_END)
            avatar_size = avatar_uploaded.tell()
            avatar_uploaded.seek(0)
            if avatar_size > Reel2bitsDefaults.avatar_size_limit:
                return jsonify({"error": "artwork too big, 2MB maximum"
                                }), 413  # Request Entity Too Large

            # Delete old avatar if any
            if current_user.avatar_filename:
                old_avatar = os.path.join(
                    current_app.config["UPLOADED_AVATARS_DEST"],
                    current_user.path_avatar())
                if os.path.isfile(old_avatar):
                    os.unlink(old_avatar)
                else:
                    print(
                        f"Error: cannot delete old avatar: {current_user.id} / {current_user.avatar_filename}"
                    )

            # Save new avatar
            avatar_filename = get_hashed_filename(avatar_uploaded.filename)
            avatars.save(avatar_uploaded,
                         folder=current_user.slug,
                         name=avatar_filename)
            current_user.avatar_filename = avatar_filename

    # commit changes
    db.session.commit()

    # log action
    add_user_log(current_user.id, current_user.id, "user", "info",
                 "Edited user profile")

    # trigger a profile update
    send_update_profile(current_user)

    return jsonify(to_json_account(current_user))
Ejemplo n.º 5
0
def new():
    """
    Create a new album.
    ---
    tags:
        - Albums
    security:
        - OAuth2:
            - write
    responses:
        200:
            description: Returns id and slug.
    """
    current_user = current_token.user
    if not current_user:
        return jsonify({"error": "Unauthorized"}), 403

    # Check artwork file size
    if "artwork" in request.files:
        artwork_uploaded = request.files["artwork"]
        artwork_uploaded.seek(0, os.SEEK_END)
        artwork_size = artwork_uploaded.tell()
        artwork_uploaded.seek(0)
        if artwork_size > Reel2bitsDefaults.artwork_size_limit:
            return jsonify({"error": "artwork too big, 2MB maximum"
                            }), 413  # Request Entity Too Large
    else:
        artwork_uploaded = None

    form = AlbumForm()

    if form.validate_on_submit():
        rec = Album()
        rec.user_id = current_user.id
        rec.title = form.title.data
        rec.private = form.private.data
        rec.description = form.description.data
        rec.genre = form.genre.data

        # Save the artwork
        if artwork_uploaded:
            artwork_filename = get_hashed_filename(artwork_uploaded.filename)
            artworkalbums.save(artwork_uploaded,
                               folder=current_user.slug,
                               name=artwork_filename)
            rec.artwork_filename = artwork_filename

        # Handle tags
        tags = form.tags.data.split(",")
        # Clean
        tags = [t.strip() for t in tags if t]
        # For each tag get it or create it
        for tag in tags:
            dbt = SoundTag.query.filter(SoundTag.name == tag).first()
            if not dbt:
                dbt = SoundTag(name=tag)
                db.session.add(dbt)
            rec.tags.append(dbt)

        db.session.add(rec)
        db.session.commit()

        # log
        add_user_log(rec.id, rec.user_id, "albums", "info",
                     "Created {0} -- {1}".format(rec.id, rec.title))

        return jsonify({"id": rec.flake_id, "slug": rec.slug})

    return jsonify({"error": json.dumps(form.errors)}), 400