Ejemplo n.º 1
0
 def _handle_internal(self, params):
     import time
     t = time.time()
     searcher = FingerprintSearcher(self.conn, self.index)
     if params.batch:
         fingerprints = params.fingerprints
     else:
         fingerprints = params.fingerprints[:1]
     all_matches = []
     for p in fingerprints:
         if p['track_gid']:
             track_id = resolve_track_gid(self.conn, p['track_gid'])
             matches = [(0, track_id, p['track_gid'], 1.0)]
         else:
             matches = searcher.search(p['fingerprint'], p['duration'])
         all_matches.append(matches)
     response = {}
     if params.batch:
         response['fingerprints'] = fps = []
         result_map = {}
         for p, matches in zip(fingerprints, all_matches):
             results = []
             fps.append({'index': p['index'], 'results': results})
             track_ids = self._inject_results(results, result_map, matches)
             logger.info("Lookup from %s: %s", params.application_id, list(track_ids))
     else:
         response['results'] = results = []
         result_map = {}
         self._inject_results(results, result_map, all_matches[0])
         logger.info("Lookup from %s: %s", params.application_id, result_map.keys())
     if params.meta and result_map:
         self.inject_metadata(params.meta, result_map)
     logger.info("Lookup took %s", time.time() - t)
     return response
Ejemplo n.º 2
0
def toggle_track_mbid():
    fingerprint_db = db.get_fingerprint_db()
    ingest_db = db.get_ingest_db()
    app_db = db.get_app_db()
    user = require_user()
    track_id = request.values.get('track_id', type=int)
    if track_id:
        query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
        track_gid = fingerprint_db.execute(query).scalar()
    else:
        track_gid = request.values.get('track_gid')
        track_id = resolve_track_gid(fingerprint_db, track_gid)
    state = bool(request.values.get('state', type=int))
    mbid = request.values.get('mbid')
    if not track_id or not mbid or not track_gid:
        return redirect(url_for('general.index'))
    if not is_moderator(app_db, user.id):
        title = 'MusicBrainz account required'
        return render_template('toggle_track_mbid_login.html', title=title)
    query = sql.select([schema.track_mbid.c.id, schema.track_mbid.c.disabled],
                       sql.and_(schema.track_mbid.c.track_id == track_id,
                                schema.track_mbid.c.mbid == mbid))
    rows = fingerprint_db.execute(query).fetchall()
    if not rows:
        return redirect(url_for('general.index'))
    id, current_state = rows[0]
    if state == current_state:
        return redirect(url_for('.track', track_id_or_gid=track_id))
    if request.form.get('submit'):
        note = request.values.get('note')
        update_stmt = schema.track_mbid.update().where(
            schema.track_mbid.c.id == id).values(disabled=state)
        fingerprint_db.execute(update_stmt)
        insert_stmt = schema.track_mbid_change.insert().values(
            track_mbid_id=id,
            account_id=session['id'],
            disabled=state,
            note=note)
        ingest_db.execute(insert_stmt)
        db.session.commit()
        return redirect(url_for('.track', track_id_or_gid=track_id))
    if state:
        title = 'Unlink MBID'
    else:
        title = 'Link MBID'
    return render_template('toggle_track_mbid.html',
                           title=title,
                           track_gid=track_gid,
                           mbid=mbid,
                           state=state,
                           track_id=track_id)
Ejemplo n.º 3
0
 def _handle_internal(self, params):
     import time
     t = time.time()
     update_user_agent_counter(self.redis, params.application_id,
                               self.user_agent, self.user_ip)
     searcher = FingerprintSearcher(self.conn, self.index)
     searcher.max_length_diff = params.max_duration_diff
     if params.batch:
         fingerprints = params.fingerprints
     else:
         fingerprints = params.fingerprints[:1]
     all_matches = []
     for p in fingerprints:
         if p['track_gid']:
             track_id = resolve_track_gid(self.conn, p['track_gid'])
             matches = [(0, track_id, p['track_gid'], 1.0)]
         else:
             matches = searcher.search(p['fingerprint'], p['duration'])
         all_matches.append(matches)
     response = {}
     if params.batch:
         response['fingerprints'] = fps = []
         result_map = {}
         for p, matches in zip(fingerprints, all_matches):
             results = []
             fps.append({'index': p['index'], 'results': results})
             track_ids = self._inject_results(results, result_map, matches)
             update_lookup_counter(self.redis, params.application_id,
                                   bool(track_ids))
             logger.debug("Lookup from %s: %s", params.application_id,
                          list(track_ids))
     else:
         response['results'] = results = []
         result_map = {}
         self._inject_results(results, result_map, all_matches[0])
         update_lookup_counter(self.redis, params.application_id,
                               bool(result_map))
         logger.debug("Lookup from %s: %s", params.application_id,
                      result_map.keys())
     if params.meta and result_map:
         self.inject_metadata(params.meta, result_map)
     if fingerprints:
         time_per_fp = (time.time() - t) / len(fingerprints)
         update_lookup_avg_time(self.redis, time_per_fp)
     return response
Ejemplo n.º 4
0
 def _handle_request(self, req):
     self.require_user(req)
     track_id = req.values.get('track_id', type=int)
     if track_id:
         query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
         track_gid = self.conn.execute(query).scalar()
     else:
         track_gid = req.values.get('track_gid')
         track_id = resolve_track_gid(self.conn, track_gid)
         print track_gid, track_id
     state = bool(req.values.get('state', type=int))
     mbid = req.values.get('mbid')
     if not track_id or not mbid or not track_gid:
         return redirect(self.config.base_url)
     if not is_moderator(self.conn, self.session['id']):
         title = 'MusicBrainz account required'
         return self.render_template('toggle_track_mbid_login.html', title=title)
     query = sql.select([schema.track_mbid.c.id, schema.track_mbid.c.disabled],
         sql.and_(schema.track_mbid.c.track_id == track_id,
                  schema.track_mbid.c.mbid == mbid))
     rows = self.conn.execute(query).fetchall()
     if not rows:
         return redirect(self.config.base_url)
     id, current_state = rows[0]
     if state == current_state:
         return redirect(self.config.base_url + 'track/%d' % (track_id,))
     if req.form.get('submit'):
         note = req.values.get('note')
         with self.conn.begin():
             update_stmt = schema.track_mbid.update().where(schema.track_mbid.c.id == id).values(disabled=state)
             self.conn.execute(update_stmt)
             insert_stmt = schema.track_mbid_change.insert().values(track_mbid_id=id, account_id=self.session['id'],
                                                                    disabled=state, note=note)
             self.conn.execute(insert_stmt)
         return redirect(self.config.base_url + 'track/%d' % (track_id,))
     if state:
         title = 'Unlink MBID'
     else:
         title = 'Link MBID'
     return self.render_template('toggle_track_mbid.html', title=title, track_gid=track_gid, mbid=mbid, state=state, track_id=track_id)
Ejemplo n.º 5
0
def toggle_track_mbid():
    conn = db.session.connection()
    user = require_user()
    track_id = request.values.get('track_id', type=int)
    if track_id:
        query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
        track_gid = conn.execute(query).scalar()
    else:
        track_gid = request.values.get('track_gid')
        track_id = resolve_track_gid(conn, track_gid)
    state = bool(request.values.get('state', type=int))
    mbid = request.values.get('mbid')
    if not track_id or not mbid or not track_gid:
        return redirect(url_for('general.index'))
    if not is_moderator(conn, user.id):
        title = 'MusicBrainz account required'
        return render_template('toggle_track_mbid_login.html', title=title)
    query = sql.select([schema.track_mbid.c.id, schema.track_mbid.c.disabled],
        sql.and_(schema.track_mbid.c.track_id == track_id,
                 schema.track_mbid.c.mbid == mbid))
    rows = conn.execute(query).fetchall()
    if not rows:
        return redirect(url_for('general.index'))
    id, current_state = rows[0]
    if state == current_state:
        return redirect(url_for('.track', track_id=track_id))
    if request.form.get('submit'):
        note = request.values.get('note')
        update_stmt = schema.track_mbid.update().where(schema.track_mbid.c.id == id).values(disabled=state)
        conn.execute(update_stmt)
        insert_stmt = schema.track_mbid_change.insert().values(track_mbid_id=id, account_id=session['id'],
                                                               disabled=state, note=note)
        conn.execute(insert_stmt)
        db.session.commit()
        return redirect(url_for('.track', track_id=track_id))
    if state:
        title = 'Unlink MBID'
    else:
        title = 'Link MBID'
    return render_template('toggle_track_mbid.html', title=title, track_gid=track_gid, mbid=mbid, state=state, track_id=track_id)
Ejemplo n.º 6
0
 def _handle_internal(self, params):
     import time
     t = time.time()
     update_user_agent_counter(self.redis, params.application_id, self.user_agent, self.user_ip)
     searcher = FingerprintSearcher(self.conn, self.index)
     searcher.max_length_diff = params.max_duration_diff
     if params.batch:
         fingerprints = params.fingerprints
     else:
         fingerprints = params.fingerprints[:1]
     all_matches = []
     for p in fingerprints:
         if p['track_gid']:
             track_id = resolve_track_gid(self.conn, p['track_gid'])
             matches = [(0, track_id, p['track_gid'], 1.0)]
         else:
             matches = searcher.search(p['fingerprint'], p['duration'])
         all_matches.append(matches)
     response = {}
     if params.batch:
         response['fingerprints'] = fps = []
         result_map = {}
         for p, matches in zip(fingerprints, all_matches):
             results = []
             fps.append({'index': p['index'], 'results': results})
             track_ids = self._inject_results(results, result_map, matches)
             update_lookup_counter(self.redis, params.application_id, bool(track_ids))
             logger.debug("Lookup from %s: %s", params.application_id, list(track_ids))
     else:
         response['results'] = results = []
         result_map = {}
         self._inject_results(results, result_map, all_matches[0])
         update_lookup_counter(self.redis, params.application_id, bool(result_map))
         logger.debug("Lookup from %s: %s", params.application_id, result_map.keys())
     if params.meta and result_map:
         self.inject_metadata(params.meta, result_map)
     if fingerprints:
         time_per_fp = (time.time() - t) / len(fingerprints)
         update_lookup_avg_time(self.redis, time_per_fp)
     return response
Ejemplo n.º 7
0
    def _handle_internal(self, params):
        # type: (APIHandlerParams) -> Dict[str, Any]
        assert isinstance(params, LookupHandlerParams)

        import time
        t = time.time()

        update_user_agent_counter(self.ctx.redis, params.application_id,
                                  str(self.user_agent), self.user_ip)

        searcher = FingerprintSearcher(
            self.ctx.db.get_fingerprint_db(read_only=True), self.ctx.index)
        assert params.max_duration_diff is not None
        searcher.max_length_diff = params.max_duration_diff

        if params.batch:
            fingerprints = params.fingerprints
        else:
            fingerprints = params.fingerprints[:1]

        all_matches = []
        for p in fingerprints:
            if isinstance(p, TrackLookupQuery):
                track_id = resolve_track_gid(
                    self.ctx.db.get_fingerprint_db(read_only=True),
                    p.track_gid)
                if track_id:
                    matches = [
                        FingerprintMatch(fingerprint_id=0,
                                         track_id=track_id,
                                         track_gid=p.track_gid,
                                         score=1.0)
                    ]
                else:
                    matches = []
            elif isinstance(p, FingerprintLookupQuery):
                matches = searcher.search(p.fingerprint, p.duration)
            all_matches.append(matches)

        response = {}  # type: Dict[str, Any]
        if params.batch:
            response['fingerprints'] = fps = []
            result_map = {}  # type: ignore
            for p, matches in zip(fingerprints, all_matches):
                results = []  # type: ignore
                fps.append({'index': p.index, 'results': results})
                track_ids = self._inject_results(results, result_map, matches)
                update_lookup_counter(self.ctx.redis, params.application_id,
                                      bool(track_ids))
                logger.debug("Lookup from %s: %s", params.application_id,
                             list(track_ids))
        else:
            response['results'] = results = []
            result_map = {}
            self._inject_results(results, result_map, all_matches[0])
            update_lookup_counter(self.ctx.redis, params.application_id,
                                  bool(result_map))
            logger.debug("Lookup from %s: %s", params.application_id,
                         result_map.keys())

        if params.meta and result_map:
            self.inject_metadata(params.meta, result_map)

        if fingerprints:
            time_per_fp = (time.time() - t) / len(fingerprints)
            update_lookup_avg_time(self.ctx.redis, time_per_fp)

        return response
Ejemplo n.º 8
0
    def _handle_internal(self, params):
        # type: (APIHandlerParams) -> Dict[str, Any]
        assert isinstance(params, LookupHandlerParams)

        import time
        t = time.time()

        if self.ctx.statsd is not None:
            statsd = self.ctx.statsd.pipeline()
        else:
            statsd = None

        update_user_agent_counter(self.ctx.redis, params.application_id,
                                  str(self.user_agent), self.user_ip)

        searcher = FingerprintSearcher(
            self.ctx.db.get_fingerprint_db(read_only=True),
            self.ctx.index,
            timeout=self.ctx.config.website.search_timeout,
        )
        assert params.max_duration_diff is not None
        searcher.max_length_diff = params.max_duration_diff

        if params.batch:
            fingerprints = params.fingerprints
        else:
            fingerprints = params.fingerprints[:1]

        max_results = 10

        all_matches = []
        for p in fingerprints:
            if isinstance(p, TrackLookupQuery):
                track_id = resolve_track_gid(
                    self.ctx.db.get_fingerprint_db(read_only=True),
                    p.track_gid)
                if track_id:
                    matches = [
                        FingerprintMatch(fingerprint_id=0,
                                         track_id=track_id,
                                         track_gid=p.track_gid,
                                         score=1.0)
                    ]
                else:
                    matches = []
            elif isinstance(p, FingerprintLookupQuery):
                fingerprint_search_t0 = time.time()
                matches = searcher.search(p.fingerprint,
                                          p.duration,
                                          max_results=max_results)
                fingerprint_search_t1 = time.time()
                if statsd is not None:
                    statsd.incr('api.lookup.matches', len(matches))
                    statsd.timing(
                        'api.lookup.fingerprint_search',
                        fingerprint_search_t1 - fingerprint_search_t0)
            all_matches.append(matches)

        self.ctx.db.session.close()

        response = {}  # type: Dict[str, Any]
        if params.batch:
            response['fingerprints'] = fps = []
            result_map = {}  # type: ignore
            for p, matches in zip(fingerprints, all_matches):
                results = []  # type: ignore
                fps.append({'index': p.index, 'results': results})
                track_ids = self._inject_results(results, result_map, matches)
                update_lookup_counter(self.ctx.redis, params.application_id,
                                      bool(track_ids))
                logger.debug("Lookup from %s: %s", params.application_id,
                             list(track_ids))
        else:
            response['results'] = results = []
            result_map = {}
            self._inject_results(results, result_map, all_matches[0])
            update_lookup_counter(self.ctx.redis, params.application_id,
                                  bool(result_map))
            logger.debug("Lookup from %s: %s", params.application_id,
                         result_map.keys())

        if self.ctx.config.website.search_return_metadata:
            if params.meta and result_map:
                inject_metadata_t0 = time.time()
                self.inject_metadata(params.meta, result_map)
                inject_metadata_t1 = time.time()
                if statsd is not None:
                    statsd.timing('api.lookup.inject_metadata',
                                  inject_metadata_t1 - inject_metadata_t0)

        if fingerprints:
            time_total = (time.time() - t)
            time_per_fp = time_total / len(fingerprints)
            update_lookup_avg_time(self.ctx.redis, time_per_fp)
            if statsd is not None:
                statsd.timing('api.lookup.total', time_total)

        if statsd is not None:
            statsd.send()

        return response
Ejemplo n.º 9
0
 def _handle_request(self, req):
     from acoustid.data.musicbrainz import lookup_recording_metadata
     from acoustid.utils import is_uuid
     track_id = self.url_args['id']
     if is_uuid(track_id):
         track_gid = track_id
         track_id = resolve_track_gid(self.conn, track_id)
     else:
         track_id = int(track_id)
         query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
         track_gid = self.conn.execute(query).scalar()
     title = 'Track "%s"' % (track_gid,)
     track = {
         'id': track_id
     }
     #matrix = get_track_fingerprint_matrix(self.conn, track_id)
     #ids = sorted(matrix.keys())
     #if not ids:
     #    title = 'Incorrect Track'
     #    return self.render_template('track-not-found.html', title=title,
     #        track_id=track_id)
     #fingerprints = [{'id': id, 'i': i + 1} for i, id in enumerate(ids)]
     #color1 = (172, 0, 0)
     #color2 = (255, 255, 255)
     #for id1 in ids:
     #    for id2 in ids:
     #        sim = matrix[id1][id2]
     #        color = [color1[i] + (color2[i] - color1[i]) * sim for i in range(3)]
     #        matrix[id1][id2] = {
     #            'value': sim,
     #            'color': '#%02x%02x%02x' % tuple(color),
     #        }
     query = sql.select(
         [schema.fingerprint.c.id,
          schema.fingerprint.c.length,
          schema.fingerprint.c.submission_count],
         schema.fingerprint.c.track_id == track_id)
     fingerprints = self.conn.execute(query).fetchall()
     query = sql.select(
         [schema.track_puid.c.puid,
          schema.track_puid.c.submission_count],
         schema.track_puid.c.track_id == track_id)
     puids = list(self.conn.execute(query).fetchall())
     query = sql.select(
         [schema.track_mbid.c.mbid,
          schema.track_mbid.c.submission_count,
          schema.track_mbid.c.disabled],
         schema.track_mbid.c.track_id == track_id)
     mbids = self.conn.execute(query).fetchall()
     metadata = lookup_recording_metadata(self.conn, [r['mbid'] for r in mbids])
     recordings = []
     for mbid in mbids:
         recording = metadata.get(mbid['mbid'], {})
         recording['mbid'] = mbid['mbid']
         recording['submission_count'] = mbid['submission_count']
         recording['disabled'] = mbid['disabled']
         recordings.append(recording)
     recordings.sort(key=lambda r: r.get('name', r.get('mbid')))
     moderator = is_moderator(self.conn, self.session.get('id'))
     return self.render_template('track.html', title=title,
         fingerprints=fingerprints, recordings=recordings, puids=puids,
         moderator=moderator, track=track)
Ejemplo n.º 10
0
def track(track_id_or_gid):
    # xtype: (str) -> str

    fingerprint_db = db.get_fingerprint_db()
    musicbrainz_db = db.get_musicbrainz_db()

    if is_uuid(track_id_or_gid):
        track_gid = track_id_or_gid
        track_id = resolve_track_gid(fingerprint_db, track_gid)
    else:
        try:
            track_id = int(track_id_or_gid)
        except ValueError:
            track_id = None
        query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
        track_gid = fingerprint_db.execute(query).scalar()

    if track_id is None or track_gid is None:
        abort(404)

    title = 'Track "%s"' % (track_gid, )
    track = {'id': track_id}

    query = sql.select([
        schema.fingerprint.c.id, schema.fingerprint.c.length,
        schema.fingerprint.c.submission_count
    ], schema.fingerprint.c.track_id == track_id).order_by(
        schema.fingerprint.c.length)
    fingerprints = fingerprint_db.execute(query).fetchall()

    query = sql.select([
        schema.track_mbid.c.id, schema.track_mbid.c.mbid,
        schema.track_mbid.c.submission_count, schema.track_mbid.c.disabled
    ], schema.track_mbid.c.track_id == track_id)
    mbids = fingerprint_db.execute(query).fetchall()

    metadata = lookup_recording_metadata(musicbrainz_db,
                                         [r['mbid'] for r in mbids])

    recordings = []
    for mbid in mbids:
        recording = metadata.get(mbid['mbid'], {})
        recording['mbid'] = mbid['mbid']
        recording['submission_count'] = mbid['submission_count']
        recording['disabled'] = mbid['disabled']
        recordings.append(recording)
    recordings.sort(key=lambda r: r.get('name', r.get('mbid')))

    user_metadata = (db.session.query(
        Meta.track, Meta.artist, Meta.album,
        sql.func.sum(TrackMeta.submission_count)).select_from(TrackMeta).join(
            Meta).filter(TrackMeta.track_id == track_id).group_by(
                Meta.track, Meta.artist,
                Meta.album).order_by(sql.func.min(TrackMeta.created)).all())

    edits = db.session.query(TrackMBIDChange).\
        filter(TrackMBIDChange.track_mbid_id.in_(m.id for m in mbids)).\
        order_by(TrackMBIDChange.created.desc()).all()

    edits_accounts = db.session.query(Account).options(load_only('mbuser', 'name')).\
        filter(Account.id.in_(e.account_id for e in edits)).all()
    edits_accounts_by_id = {}
    for account in edits_accounts:
        edits_accounts_by_id[account.id] = account

    edits_track_mbids = db.session.query(TrackMBID).options(load_only('mbid')).\
        filter(TrackMBID.id.in_(e.track_mbid_id for e in edits)).all()
    edits_track_mbids_by_id = {}
    for track_mbid in edits_track_mbids:
        edits_track_mbids_by_id[track_mbid.id] = track_mbid

    for edit in edits:
        account = edits_accounts_by_id.get(edit.account_id)
        if account is not None:
            edit.account = account
        track_mbid = edits_track_mbids_by_id.get(edit.track_mbid_id)
        if track_mbid is not None:
            edit.track_mbid = track_mbid

    moderator = is_moderator(db.get_app_db(), session.get('id'))

    return render_template('track.html',
                           title=title,
                           fingerprints=fingerprints,
                           recordings=recordings,
                           moderator=moderator,
                           track=track,
                           edits=edits,
                           user_metadata=user_metadata)
Ejemplo n.º 11
0
def track(track_id):
    conn = db.session.connection()

    if is_uuid(track_id):
        track_gid = track_id
        track_id = resolve_track_gid(conn, track_id)
    else:
        track_id = int(track_id)
        query = sql.select([schema.track.c.gid], schema.track.c.id == track_id)
        track_gid = conn.execute(query).scalar()

    title = 'Track "%s"' % (track_gid,)
    track = {
        'id': track_id
    }

    query = sql.select(
        [schema.fingerprint.c.id,
         schema.fingerprint.c.length,
         schema.fingerprint.c.submission_count],
        schema.fingerprint.c.track_id == track_id).order_by(schema.fingerprint.c.length)
    fingerprints = conn.execute(query).fetchall()

    query = sql.select(
        [schema.track_mbid.c.id,
         schema.track_mbid.c.mbid,
         schema.track_mbid.c.submission_count,
         schema.track_mbid.c.disabled],
        schema.track_mbid.c.track_id == track_id)
    mbids = conn.execute(query).fetchall()

    metadata = lookup_recording_metadata(conn, [r['mbid'] for r in mbids])

    recordings = []
    for mbid in mbids:
        recording = metadata.get(mbid['mbid'], {})
        recording['mbid'] = mbid['mbid']
        recording['submission_count'] = mbid['submission_count']
        recording['disabled'] = mbid['disabled']
        recordings.append(recording)
    recordings.sort(key=lambda r: r.get('name', r.get('mbid')))

    user_metadata = db.session.query(TrackMeta).\
        options(joinedload('meta', innerjoin=True)).\
        filter(TrackMeta.track_id == track_id).\
        order_by(TrackMeta.created).all()

    edits = db.session.query(TrackMBIDChange).\
        options(joinedload('account', innerjoin=True).load_only('mbuser', 'name')).\
        options(joinedload('track_mbid', innerjoin=True).load_only('mbid')).\
        filter(TrackMBIDChange.track_mbid_id.in_(m.id for m in mbids)).\
        order_by(TrackMBIDChange.created.desc()).all()

    moderator = is_moderator(conn, session.get('id'))

    return render_template('track.html', title=title,
        fingerprints=fingerprints, recordings=recordings,
        moderator=moderator, track=track,
        edits=edits,
        user_metadata=user_metadata,
        )