Exemple #1
0
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)
Exemple #2
0
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()
Exemple #3
0
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
Exemple #4
0
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)