from datetime import datetime import json import subprocess from fpcapture.connectors import db from fpcapture.model.codegen_error import CodegenError from fpcapture.model.track_fp import TrackFp def encode(db_session, filename, tuid, upc, file_upload_time, correlation_id, track_source): """Generates an audio fingerprint and captures the results to the database Args: db_session (sqlalchemy.orm.session.Session): DB session filename (str): Full path (including host share prefix) of audio file tuid (int): Unique ID of the corresponding track in art_relations upc (int): Optional UPC of the corresponding release file_upload_time (int): Timestamp when the file was uploaded to RB correlation_id (str): Correlation ID string for logging/forensics track_source (str): Source of the request for given track. E.g. backfill, direct_delivery, or sweeper Returns: bool: True if successful, False otherwise """ results = run_codegen(filename) result = results[0] timestamp_utc = datetime.utcnow() db_user = db.current_user() if 'error' in result: success = False model = db_session.query(CodegenError).filter_by(tuid=tuid).first() if not model: model = CodegenError() model.created_by = db_user model.datetime_added_utc = timestamp_utc model.error_message = result.get('error') else: metadata = result.get('metadata') model = db_session.query(TrackFp).filter_by(tuid=tuid).first() if not model: model = TrackFp() model.created_by = db_user model.datetime_added_utc = timestamp_utc model.sample_rate_hertz = metadata.get('sample_rate') model.duration_seconds = metadata.get('duration') model.samples_decoded = metadata.get('samples_decoded') model.given_duration_seconds = metadata.get('given_duration') model.start_offset_seconds = metadata.get('start_offset') model.codegen_version = metadata.get('version') model.codegen_time_seconds = metadata.get('codegen_time') model.decode_time_seconds = metadata.get('decode_time') model.code_count = result.get('code_count') model.fingerprint = result.get('code') success = True model.tuid = tuid model.upc = upc model.filename = filename model.datetime_updated_utc = timestamp_utc model.updated_by = db_user model.file_upload_time_utc = datetime.utcfromtimestamp(file_upload_time) model.correlation_id = correlation_id model.track_source = track_source db_session.add(model) # @todo: maybe let the caller handle the commit db_session.commit() return success def run_codegen(filename): """Runs the codegen binary on the given file Args: filename (str): Full path (including host share prefix) of audio file Returns: List[dict]: Decoded JSON output from codegen """ pipe = subprocess.Popen( 'codegen {}'.format(filename), stdout=subprocess.PIPE, shell=True) output, errors = pipe.communicate() return json.loads(output.decode())