#!/usr/bin/python import datetime import sys import os import copy try: import json except ImportError: import simplejson as json sys.path.insert(0, "../API") import fp def parse_json_dump(jfile, cut): codes = json.load(open(jfile)) bigeval = {} fullcodes = [] for c in codes: if "code" not in c: continue code = c["code"] m = c["metadata"] if "track_id" in m: trid = m["track_id"].encode("utf-8") else: trid = fp.new_track_id() length = m["duration"] version = m["version"] artist = m.get("artist", None) title = m.get("title", None) release = m.get("release", None) decoded_full = fp.decode_code_string(code) now = datetime.datetime.utcnow() import_date = now.strftime("%Y-%m-%dT%H:%M:%SZ") bigeval[trid] = m data = {} if artist: data["artist"] = artist if release: data["release"] = release if title: data["track"] = title data["length"] = length data["codever"] = "%.2f" % version data["import_date"] = import_date data["source"] = "local" if cut: decoded_codes = cut_code_string_length(decoded_full) for decoded in decoded_codes: data_copy = copy.copy(data) data_copy["track_id"] = fp.new_track_id() data_copy["fp"] = decoded fullcodes.append(data_copy) else: data["track_id"] = trid data["fp"] = decoded_full fullcodes.append(data) return (fullcodes, bigeval) def load(files, write_bigeval=False, split=False, cut=False, local=False, reload_amount=99999999): key_size = 0 for (i, f) in enumerate(files): codes, bigeval = parse_json_dump(f, cut) code_size = len(codes) if key_size < reload_amount: print "%d/%d %s" % (i+1, len(files), f) if code_size + key_size > reload_amount: index = reload_amount - key_size else: index = code_size fp.ingest(codes[:index], do_commit=False, split=split, local=local) key_size += index else: break if write_bigeval: bename = "bigeval.json" if not os.path.exists(bename): be = {} else: be = json.load(open(bename)) be.update(bigeval) json.dump(be, open(bename, "w")) fp.commit() def cut_code_string_length(code_string): """ Remove all codes from a codestring that are > 60 seconds in length. Because we can only match 60 sec, everything else is unnecessary """ split = code_string.split() if len(split) < 2: return code_string # If we use the codegen on a file with start/stop times, the first timestamp # is ~= the start time given. There might be a (slightly) earlier timestamp # in another band, but this is good enough first_timestamp = int(split[1]) sixty_seconds = int(60.0 * 1000.0 / 23.2 + first_timestamp) parts = [] cut_codes = [] for (code, t) in zip(split[::2], split[1::2]): tstamp = int(t) if tstamp <= sixty_seconds: parts.append(code) parts.append(t) else: cut_codes.append(" ".join(parts)) sixty_seconds = sixty_seconds + tstamp parts = [] return cut_codes if __name__ == "__main__": if len(sys.argv) < 2: print >>sys.stderr, "Usage: %s [-b] [-s] [json dump] ..." % sys.argv[0] print >>sys.stderr, " -b: write a file to disk for bigeval" sys.exit(1) write_bigeval = False split = False pos = 1 if sys.argv[1] == "-b": write_bigeval = True pos = 2 if sys.argv[2] == "-s": split = True pos = 3 elif sys.argv[1] == "-s": split = True pos = 2 load(sys.argv[pos:], write_bigeval, split)