def create_sound_for_remote_track(activity: Activity) -> int: sound = Sound() sound.title = activity.payload.get("object", {}).get("name", None) sound.description = activity.payload.get("object", {}).get("content", None) sound.private = False sound.transcode_needed = activity.payload.get("object", {}).get("transcoded", False) if sound.transcode_needed: sound.remote_uri = activity.payload.get("object", {}).get("transcode_url", None) else: sound.remote_uri = activity.payload.get("object", {}).get("url", {}).get("href", None) sound.transcode_state = 0 # Get user through actor sound.user_id = activity.actor.user.id sound.activity_id = activity.id # custom from AP sound.remote_artwork_uri = activity.payload.get("object", {}).get("artwork", None) sound.genre = activity.payload.get("object", {}).get("genre", None) sound.licence = activity.payload.get("object", {}).get("licence", {}).get("id", 0) if not sound.remote_uri: print("Error: track has no remote_uri available") return None # reject if no file available # Tags handling. Since it's a new track, no need to do magic tags recalculation. tags = [ t.strip() for t in activity.payload.get("object", {}).get("tags", []) ] for tag in tags: dbt = SoundTag.query.filter(SoundTag.name == tag).first() if not dbt: dbt = SoundTag(name=tag) db.session.add(dbt) sound.tags.append(dbt) db.session.add(sound) db.session.commit() return sound.id
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
def edit(username, soundslug): """ Edit track. --- tags: - Tracks security: - OAuth2: - write parameters: - name: username in: path type: string required: true description: User username - name: soundslug in: path type: string required: true description: Track slug responses: 200: description: Returns a Status with extra reel2bits params. """ current_user = current_token.user if not current_user: return jsonify({"error": "Unauthorized"}), 403 # Get the track sound = Sound.query.filter(Sound.user_id == current_user.id, Sound.slug == soundslug).first() if not sound: return jsonify({"error": "Not found"}), 404 album = request.json.get("album") description = request.json.get("description") licence = request.json.get("licence") private = request.json.get("private") title = request.json.get("title") genre = request.json.get("genre") tags = request.json.get("tags") if sound.private and not private: return jsonify({"error": "Cannot change to private: track already federated"}) if not title: title, _ = splitext(sound.filename_orig) else: sound.title = title sound.description = description sound.licence = licence sound.genre = genre # First remove tags which have been removed for tag in sound.tags: if tag.name not in tags: sound.tags.remove(tag) # Then add the new ones if new for tag in tags: if tag not in [a.name for a in sound.tags]: dbt = SoundTag.query.filter(SoundTag.name == tag).first() if not dbt: dbt = SoundTag(name=tag) db.session.add(dbt) sound.tags.append(dbt) # Purge orphaned tags for otag in SoundTag.query.filter(and_(~SoundTag.sounds.any(), ~SoundTag.albums.any())).all(): db.session.delete(otag) # Fetch album, and associate if owner if album and (album != "__None"): db_album = Album.query.filter(Album.id == album).first() if db_album and (db_album.user_id == current_user.id): sound.album_id = db_album.id if not db_album.sounds: sound.album_order = 0 else: sound.album_order = db_album.sounds.count() + 1 elif album == "__None": sound.album_id = None sound.album_order = 0 db.session.commit() # trigger a sound update send_update_sound(sound) relationship = False if current_token and current_token.user: relationship = to_json_relationship(current_token.user, sound.user) account = to_json_account(sound.user, relationship) return jsonify(to_json_track(sound, account))
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
def edit(username, albumslug): """ Edit album. --- tags: - Albums security: - OAuth2: - write parameters: - name: username in: path type: string required: true description: User username - name: albumslug in: path type: string required: true description: Album slug responses: 200: description: Returns a Status with extra reel2bits params. """ current_user = current_token.user if not current_user: return jsonify({"error": "Unauthorized"}), 403 # Get the album album = Album.query.filter(Album.user_id == current_user.id, Album.slug == albumslug).first() if not album: return jsonify({"error": "Not found"}), 404 description = request.json.get("description") private = request.json.get("private") title = request.json.get("title") genre = request.json.get("genre") tags = request.json.get("tags") if album.private and not private: return jsonify( {"error": "Cannot change to private: album already federated"}) if not title: return jsonify({"error": "Album title is required"}), 400 album.title = title album.description = description album.genre = genre # First remove tags which have been removed for tag in album.tags: if tag.name not in tags: album.tags.remove(tag) # Then add the new ones if new for tag in tags: if tag not in [a.name for a in album.tags]: dbt = SoundTag.query.filter(SoundTag.name == tag).first() if not dbt: dbt = SoundTag(name=tag) db.session.add(dbt) album.tags.append(dbt) # Purge orphaned tags for otag in SoundTag.query.filter( and_(~SoundTag.sounds.any(), ~SoundTag.albums.any())).all(): db.session.delete(otag) db.session.commit() relationship = False if current_token and current_token.user: relationship = to_json_relationship(current_token.user, album.user) account = to_json_account(album.user, relationship) return jsonify(to_json_album(album, account))