def run_merge(filenames): """Merges all Skype databases to a new database.""" dbs = [skypedata.SkypeDatabase(f) for f in filenames] db_base = dbs.pop() counts = collections.defaultdict(lambda: collections.defaultdict(int)) postbacks = Queue.Queue() postfunc = lambda r: postbacks.put(r) worker = workers.MergeThread(postfunc) name, ext = os.path.splitext(os.path.split(db_base.filename)[-1]) now = datetime.datetime.now().strftime("%Y%m%d") filename_final = util.unique_path("%s.merged.%s%s" % (name, now, ext)) print("Creating %s, using %s as base." % (filename_final, db_base)) shutil.copyfile(db_base.filename, filename_final) db2 = skypedata.SkypeDatabase(filename_final) chats2 = db2.get_conversations() db2.get_conversations_stats(chats2) for db1 in dbs: chats = db1.get_conversations() db1.get_conversations_stats(chats) bar_total = sum(c["message_count"] for c in chats) bar_text = " Processing %.*s.." % (30, db1) bar = ProgressBar(max=bar_total, afterword=bar_text) bar.start() args = {"db1": db1, "db2": db2, "chats": chats, "type": "diff_merge_left"} worker.work(args) while True: result = postbacks.get() if "error" in result: print("Error merging %s:\n\n%s" % (db1, result["error"])) worker = None # Signal for global break break # break while True if "done" in result: break # break while True if "diff" in result: counts[db1]["chats"] += 1 counts[db1]["msgs"] += len(result["diff"]["messages"]) msgcounts = sum(c["message_count"] for c in result["chats"]) bar.update(bar.value + msgcounts) if result["output"]: log(result["output"]) if not worker: break # break for db1 in dbs bar.stop() bar.afterword = " Processed %s." % db1 bar.update(bar_total) print if not counts: print("Nothing new to merge.") db2.close() os.unlink(filename_final) else: for db1 in dbs: print("Merged %s in %s from %s." % (util.plural("message", counts[db1]["msgs"]), util.plural("chat", counts[db1]["chats"]), db1)) print("Merge into %s complete." % db2)
def run_diff(filename1, filename2): """Compares the first database for changes with the second.""" if os.path.realpath(filename1) == os.path.realpath(filename2): output("Error: cannot compare %s with itself." % filename1) return db1, db2 = map(skypedata.SkypeDatabase, [filename1, filename2]) counts = collections.defaultdict(lambda: collections.defaultdict(int)) postbacks = Queue.Queue() bar_text = "%.*s.." % (50, " Scanning %s vs %s" % (db1, db2)) bar = ProgressBar(afterword=bar_text) bar.start() chats1, chats2 = db1.get_conversations(), db2.get_conversations() db1.get_conversations_stats(chats1), db2.get_conversations_stats(chats2) args = {"db1": db1, "db2": db2, "chats": chats1, "type": "diff_left"} worker = workers.MergeThread(postbacks.put) try: worker.work(args) while True: result = postbacks.get() if "error" in result: output("Error scanning %s and %s:\n\n%s" % (db1, db2, result["error"])) break # break while True if "done" in result: break # break while True if "chats" in result and result["chats"]: counts[db1]["chats"] += 1 msgs = len(result["chats"][0]["diff"]["messages"]) msgs_text = util.plural("new message", msgs) contacts_text = util.plural( "new participant", result["chats"][0]["diff"]["participants"]) text = ", ".join(filter(None, [msgs_text, contacts_text])) bar.afterword = (" %s, %s." % (result["chats"][0]["chat"]["title"], text)) counts[db1]["msgs"] += msgs if "index" in result: bar.max = result["count"] bar.update(result["index"]) if result.get("output"): log(result["output"]) finally: worker and (worker.stop(), worker.join()) bar.stop() bar.afterword = " Scanned %s and %s." % (db1, db2) bar.update(bar.max) output()
def run_diff(filename1, filename2): """Compares the first database for changes with the second.""" if os.path.realpath(filename1) == os.path.realpath(filename2): print("Error: cannot compare %s with itself." % filename1) return db1, db2 = map(skypedata.SkypeDatabase, [filename1, filename2]) counts = collections.defaultdict(lambda: collections.defaultdict(int)) postbacks = Queue.Queue() postfunc = lambda r: postbacks.put(r) worker = workers.MergeThread(postfunc) chats1, chats2 = db1.get_conversations(), db2.get_conversations() db1.get_conversations_stats(chats1), db2.get_conversations_stats(chats2) for db in [db1, db2]: db.get_conversations_stats(db.get_conversations()) bar_total = sum(c["message_count"] for c in chats1) bar_text = "%.*s.." % (50, " Scanning %s vs %s" % (db1, db2)) bar = ProgressBar(max=bar_total, afterword=bar_text) bar.start() args = {"db1": db1, "db2": db2, "chats": chats1, "type": "diff_left"} worker.work(args) while True: result = postbacks.get() if "error" in result: print("Error scanning %s and %s:\n\n%s" % (db1, db2, result["error"])) worker = None # Signal for global break break # break while True if "done" in result: break # break while True if "chats" in result and result["chats"]: counts[db1]["chats"] += 1 msgs = len(result["chats"][0]["diff"]["messages"]) msgs_text = util.plural("new message", msgs) contacts_text = util.plural("new participant", result["chats"][0]["diff"]["participants"]) text = ", ".join(filter(None, [msgs_text, contacts_text])) print("%s, %s." % (result["chats"][0]["chat"]["title_long"], text)) counts[db1]["msgs"] += msgs bar.update(bar.value + result["chats"][0]["chat"]["message_count"]) if result["output"]: log(result["output"]) bar.stop() bar.afterword = " Scanned %s and %s." % (db1, db2) bar.update(bar_total) print
def run_merge(filenames, output_filename=None): """Merges all Skype databases to a new database.""" dbs = [skypedata.SkypeDatabase(f) for f in filenames] db_base = dbs.pop() counts = collections.defaultdict(lambda: collections.defaultdict(int)) postbacks = Queue.Queue() name, ext = os.path.splitext(os.path.split(db_base.filename)[-1]) now = datetime.datetime.now().strftime("%Y%m%d") if not output_filename: output_filename = util.unique_path("%s.merged.%s%s" % (name, now, ext)) output("Creating %s, using %s as base." % (output_filename, db_base)) bar = ProgressBar() bar.start() shutil.copyfile(db_base.filename, output_filename) db2 = skypedata.SkypeDatabase(output_filename) chats2 = db2.get_conversations() db2.get_conversations_stats(chats2) args = {"db2": db2, "type": "diff_merge_left"} worker = workers.MergeThread(postbacks.put) try: for db1 in dbs: chats = db1.get_conversations() db1.get_conversations_stats(chats) bar.afterword = " Processing %.*s.." % (30, db1) worker.work(dict(args, db1=db1, chats=chats)) while True: result = postbacks.get() if "error" in result: output("Error merging %s:\n\n%s" % (db1, result["error"])) db1 = None # Signal for global break break # break while True if "done" in result: break # break while True if "diff" in result: counts[db1]["chats"] += 1 counts[db1]["msgs"] += len(result["diff"]["messages"]) if "index" in result: bar.max = result["count"] bar.update(result["index"]) if result.get("output"): log(result["output"]) if not db1: break # break for db1 in dbs bar.stop() bar.afterword = " Processed %s." % db1 bar.update(bar.max) output() finally: worker and (worker.stop(), worker.join()) if not counts: output("Nothing new to merge.") db2.close() os.unlink(output_filename) else: for db1 in dbs: output("Merged %s in %s from %s." % (util.plural("message", counts[db1]["msgs"]), util.plural("chat", counts[db1]["chats"]), db1)) output("Merge into %s complete." % db2)