Example #1
0
def wait_for_upload(tg_client, msg, net_speed):
    """
        This function blocks current thread until a specified
        file has finished uploading.
    """

    state = msg["sending_state"]["@type"]
    doc = msg["content"]["document"]["document"]

    while doc and state == "messageSendingStatePending":
        left = doc["size"] - doc["remote"]["uploaded_size"]
        time.sleep(ceil(left / net_speed))

        task = tg_client.call_method("getMessage", {
            "chat_id": msg["chat_id"],
            "message_id": msg["id"]
        })
        task.wait()

        if task.error_info is not None or not task.update:
            get_logger().error("Error waiting for file %s", task.error_info)
            break

        msg = task.update
        doc = msg["content"]["document"]["document"]
        state = msg["sending_state"]["@type"]
Example #2
0
def search(tg_client, chat_id, _):
    """
        This function searches for uploaded file using the
        RegEx provide by the user.
    """

    search_reg = freetext(
        "Enter the file path to browse for ( RegEx supported )")
    print("Searching...")
    files = []
    file_names = ["Select All"]

    try:
        for (msg_id, file_id, caption) in get_messages(tg_client, chat_id):
            if re_search(search_reg, caption):
                files.append((msg_id, file_id, caption))
                file_names.append(caption)
    except re_error as re_er:
        get_logger().warning("Error searching %s", re_er)

    if len(files) == 0:
        return freetext("No files matched your browse")

    choice = long_choice("Select files", file_names, False)

    if file_names[0] == choice:
        use_files(files, tg_client, chat_id)
    else:
        use_files(files[file_names.index(choice)], tg_client, chat_id)
Example #3
0
def restore(tg_client_client, chat_id):
    """
        This function starts the restore process.
    """
    errors = ""

    try:
        (restored, failed, errors) = download_files(tg_client_client, chat_id)

        print("\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
        print(f"{restored} files restored to ~/Restored")
        print(f"{failed} failed \n")
        print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")

    except KeyboardInterrupt:
        failed = 0
        print("\nRestoration paused.")

    try:
        rmtree(MESGS_DIR)
    except FileNotFoundError:
        get_logger().error("Messages directory not found.")

    if failed > 0 and input(
            "Do you want to see the error log (y/N) ? : ").lower() == "y":
        print(errors)

    input("Press enter to continue.")
Example #4
0
def change_folder(_):
    """
        This function allows user to change backup folder.
    """

    file_log = get_logger()

    try:
        with open(DATA_FILE, "rb") as db_file:
            db_dict = pickle.load(db_file)

    except FileNotFoundError:
        file_log.warning("No backup folders to change")
        db_dict = {}

    if not confirm(f"Currently {','.join(db_dict['back_up_folders'])} are backed-up. Do you want to change this?"):
        return

    db_dict["back_up_folders"] = get_folders()

    with open(DATA_FILE, "wb") as db_file:
        pickle.dump(db_dict, db_file)

    file_log.info("Backup Folders changed.")
    input("Backup Folders changed. Press any enter to continue.")
Example #5
0
def logout(tg_client):
    """
        This function logs the user out.
    """

    file_log = get_logger()

    if not confirm("Are you sure you want to Logout?"):
        return

    task = tg_client.call_method("logOut", {})
    task.wait()

    if task.error_info:
        print("Oops something went wrong")
        file_log.error(task.error_info)
        return

    try:
        rmtree(GRAMUP_DIR)
    except FileNotFoundError:
        file_log.warning("Cache already cleared")

    file_log.info("Logged out")
    input("Logged out. Press enter to continue.")
    sys.exit(0)
Example #6
0
def use_files(files, tg_client, chat_id):
    options = ["View", "Delete", "Go Back"]
    functions = [show_file, delete_files]

    while True:
        try:
            chose = choose("What do you want to do?", options)
            if chose == options[2]:
                break

            if functions[options.index(chose)](tg_client, chat_id, files):
                break

        except (ValueError, IndexError) as v_er:
            get_logger().warning("Error reading index %s", v_er)
            print(f"Please enter number between 1 and {len(files)}")
Example #7
0
def delete_files(tg_client, chat_id, files):
    """
        This function deletes the file with id file_id.
    """

    if len(files) == 0:
        return False

    file_log = get_logger()

    question = "\n".join(
        [f"  {caption_text}" for (_, _, caption_text) in files])
    question += "\n\nAre you sure you want to delete these files?"

    if choose(question, ["Yes", "No"]) == "No":
        return False

    task = tg_client.call_method(
        "deleteMessages", {
            "chat_id": chat_id,
            "message_ids": [msg_id for (msg_id, _, _) in files],
            "revoke": True
        })

    print("Deleting... Please wait.")
    task.wait()

    if task.error_info:
        file_log.error("Error showing file %s", task.error_info)
        freetext("Oops... Something went wrong.")
        return False

    freetext("Files deleted.")
    return True
Example #8
0
def show_file(tg_client, chat_id, files):
    """
        This function downloads and displays the file
        with id file_id.
    """

    for (msg_id, file_id, caption) in files:

        task = download_file(
            tg_client,
            file_id if file_id else get_file_id(tg_client, chat_id, msg_id))

        if task.error_info is None:
            temp_file = join(gettempdir(), basename(caption))
            move(task.update["local"]["path"], temp_file)
            webbrowser.open(f"file://{temp_file}", new=2)
        else:
            get_logger().error("Error showing file %s", task.error_info)
            freetext("Oops... Something went wrong.")
Example #9
0
def download_files(tg_client, chat_id):
    """
        This function downloads and moves files to the
        appropriate directories in RE_FOLDER
    """
    print("Getting file list...")
    files = get_messages(tg_client, chat_id)
    restored, failed, total = (0, 0, len(files))
    errors, file_log = "", get_logger()

    file_log.info("%s files to restore", total)
    print("Restoring files\nPress ctrl+c to save progress and stop.\n")

    if total <= 0:
        return 0, 0, ""

    print_progress_bar(0, total)

    for (msg_id, file_id, path) in files:

        if isfile(join(RE_FOLDER, path)):
            restored += 1
            print_progress_bar(restored + failed,
                               total,
                               "",
                               suffix=f"{restored + failed} of {total} done")
            continue

        task = download_file(
            tg_client,
            file_id if file_id else get_file_id(tg_client, chat_id, msg_id))

        if not (path and dirname(path)):
            path = join(OTHER_FOLDER, str(file_id))

        if task.error_info is None:
            makedirs(dirname(join(RE_FOLDER, path)), exist_ok=True)
            copyfile(task.update["local"]["path"], join(RE_FOLDER, path))
            restored += 1
        else:
            file_log.error("Error restoring file %s", task.error_info)
            errors += str(task.error_info) + "\n"
            failed += 1

        print_progress_bar(restored + failed,
                           total,
                           "",
                           suffix=f"{restored + failed} of {total} done")

    return restored, failed, errors
Example #10
0
def clear_cache(_):
    """
        This function clears all local caches.
    """

    if not confirm("Are you sure you want to clear all cache?"):
        return

    file_log = get_logger()

    try:
        rmtree(CACHE_DIR)
    except FileNotFoundError:
        file_log.warning("Cache already cleared")

    file_log.info("Cache cleared")
    input("Cache cleared. Press any enter to continue.")
Example #11
0
def change_chat(tg_client):
    """
        This function allows user to change backup folder.
    """

    file_log = get_logger()

    try:
        with open(DATA_FILE, "rb") as db_file:
            db_dict = pickle.load(db_file)

    except FileNotFoundError:
        file_log.warning("No backup folders to change")
        db_dict = {}
    if not confirm("If you change chat you will not be able to access previously backed-up files without changing back."
                   "Are you sure you want to change?"):
        return

    get_chat_id(tg_client, db_dict["phone_number"], db_dict["back_up_folders"])

    input("backup chat changed. Press any enter to continue.")
Example #12
0
def client_ready(tg_client, chat_id, bup_folders):
    """
        This function is called once required data is
        loaded and Telegram client is initialized.
    """
    if not (tg_client or chat_id or bup_folders):
        sys.exit(3)

    file_log = get_logger()

    file_log.info("Client ready.")

    options = ["Backup", "Restore", "Browse", "Settings", "Help", "Quit"]

    try:
        while True:
            print_banner()
            choice = choose("What do you want to do?", options)

            if choice == options[0]:
                backup(tg_client, chat_id, bup_folders)
            elif choice == options[1]:
                restore(tg_client, chat_id)
            elif choice == options[2]:
                browse(tg_client, chat_id, bup_folders)
            elif choice == options[3]:
                settings(tg_client)
            elif choice == options[4]:
                gramupHelp()
            else:
                break

    except KeyboardInterrupt:
        print_banner()
        file_log.warning("Keyboard interrupt received.")

    file_log.info("End of execution.")
    sys.exit(0)
Example #13
0
def backup(tg_client, chat_id, back_up_folders):
    """
        This function starts the backup process.
    """

    async_result = ThreadPool(processes=1).apply_async(
        lambda: speedtest.Speedtest().upload() / 8, ())

    file_log = get_logger()

    print("\nGetting list of uploaded files")
    old_files = get_uploaded_files(tg_client, chat_id, back_up_folders)
    file_log.info("Found %s files already uploaded", len(old_files))

    new_files = []
    print("Getting list of files to upload")

    for folder in back_up_folders:
        new_files.extend(get_new_files(folder, old_files))

    file_log.info("Found %s new files to upload", len(new_files))

    if len(new_files) == 0:
        return show_results(0, 0, "")

    total_files = len(new_files)
    net_speed = async_result.get()
    (done, failed, errors) = (0, 0, "")

    file_log.info("Measured internet speed to be %s Bps", net_speed)

    print_progress_bar(0, total_files)
    tg_client.send_message(
        chat_id=chat_id,
        text=
        f"Backup started on {datetime.today().strftime('%Y-%m-%d %I:%M %p')}")
    tg_client.send_message(
        chat_id=chat_id,
        text=f"Backing up {total_files} files @ {net_speed / 1000000} MBps.")

    for (new_file, folder) in new_files:
        task = send_file(tg_client, chat_id, new_file, folder)
        if task.error_info is None:
            wait_for_upload(tg_client, task.update, net_speed)
            done += 1
        else:
            failed += 1
            errors += str(task.error_info) + "\n\n"
            file_log.error("Error uploading %s %s", new_file, task.error_info)

        print_progress_bar(done + failed,
                           total_files,
                           "",
                           suffix=f"{done + failed} of {total_files} done")

    tg_client.send_message(
        chat_id=chat_id,
        text=f"Backup ended on {datetime.today().strftime('%Y-%m-%d %I:%M %p')}"
    ).wait()

    return show_results(done, failed, errors)