Пример #1
0
    def _log_action(self, action, status, symbol, entry, min_level=3):
        if self.verbose < min_level:
            return

        if len(symbol) > 1 and symbol[0] in (">", "<"):
            symbol = (
                " " + symbol
            )  # make sure direction characters are aligned at 2nd column

        color = ""
        final = ""
        if not self.options.get("no_color"):
            # CM = self.COLOR_MAP
            # color = CM.get((action, status),
            #                CM.get(("*", status),
            #                       CM.get((action, "*"),
            #                              "")))
            if action in ("copy", "restore"):
                if "<" in symbol:
                    if status == "new":
                        color = ansi_code("Fore.GREEN") + ansi_code(
                            "Style.BRIGHT")
                    else:
                        color = ansi_code("Fore.GREEN")
                else:
                    if status == "new":
                        color = ansi_code("Fore.CYAN") + ansi_code(
                            "Style.BRIGHT")
                    else:
                        color = ansi_code("Fore.CYAN")
            elif action == "delete":
                color = ansi_code("Fore.RED")
            elif status == "conflict":
                color = ansi_code("Fore.LIGHTRED_EX")
            elif action == "skip" or status == "equal" or status == "visit":
                color = ansi_code("Fore.LIGHTBLACK_EX")

            final = ansi_code("Style.RESET_ALL")

        if colorama:
            # Clear line"ESC [ mode K" mode 0:to-right, 2:all
            final += colorama.ansi.clear_line(0)
        else:
            final += " " * 10
        prefix = ""
        if self.dry_run:
            prefix = DRY_RUN_PREFIX

        if action and status:
            tag = ("{} {}".format(action, status)).upper()
        else:
            assert status
            tag = ("{}".format(status)).upper()

        name = entry.get_rel_path()
        if entry.is_dir():
            name = "[{}]".format(name)

        write("{}{}{:<16} {:^3} {}{}".format(prefix, color, tag, symbol, name,
                                             final))
Пример #2
0
    def _print_pair_diff(self, pair):
        any_entry = pair.any_entry

        has_meta = any_entry.get_sync_info("m") is not None

        # write("pair", pair)
        # print("pair.local", pair.local)
        # print("pair.remote", pair.remote)

        write(
            (
                VT_ERASE_LINE
                + ansi_code("Fore.LIGHTRED_EX")
                + "CONFLICT: {!r} was modified on both targets since last sync ({})."
                + ansi_code("Style.RESET_ALL")
            ).format(any_entry.get_rel_path(), _ts(any_entry.get_sync_info("u")))
        )
        if has_meta:
            write(
                "    Original modification time: {}, size: {:,d} bytes.".format(
                    _ts(any_entry.get_sync_info("m")), any_entry.get_sync_info("s")
                )
            )
        else:
            write("    (No meta data available.)")

        write("    Local:  {}".format(pair.local.as_string() if pair.local else "n.a."))
        write(
            "    Remote: {}".format(
                pair.remote.as_string(pair.local) if pair.remote else "n.a."
            )
        )
Пример #3
0
    def _log_action(self, action, status, symbol, entry, min_level=3):
        if self.verbose < min_level:
            return

        if len(symbol) > 1 and symbol[0] in (">", "<"):
            symbol = (
                " " + symbol
            )  # make sure direction characters are aligned at 2nd column

        color = ""
        final = ""
        if not self.options.get("no_color"):
            # CM = self.COLOR_MAP
            # color = CM.get((action, status),
            #                CM.get(("*", status),
            #                       CM.get((action, "*"),
            #                              "")))
            if action in ("copy", "restore"):
                if "<" in symbol:
                    if status == "new":
                        color = ansi_code("Fore.GREEN") + ansi_code("Style.BRIGHT")
                    else:
                        color = ansi_code("Fore.GREEN")
                else:
                    if status == "new":
                        color = ansi_code("Fore.CYAN") + ansi_code("Style.BRIGHT")
                    else:
                        color = ansi_code("Fore.CYAN")
            elif action == "delete":
                color = ansi_code("Fore.RED")
            elif status == "conflict":
                color = ansi_code("Fore.LIGHTRED_EX")
            elif action == "skip" or status == "equal" or status == "visit":
                color = ansi_code("Fore.LIGHTBLACK_EX")

            final = ansi_code("Style.RESET_ALL")

        if colorama:
            # Clear line"ESC [ mode K" mode 0:to-right, 2:all
            final += colorama.ansi.clear_line(0)
        else:
            final += " " * 10
        prefix = ""
        if self.dry_run:
            prefix = DRY_RUN_PREFIX

        if action and status:
            tag = ("{} {}".format(action, status)).upper()
        else:
            assert status
            tag = ("{}".format(status)).upper()

        name = entry.get_rel_path()
        if entry.is_dir():
            name = "[{}]".format(name)

        write("{}{}{:<16} {:^3} {}{}".format(prefix, color, tag, symbol, name, final))
Пример #4
0
 def on_error(self, e, pair):
     """Called for pairs that don't match `match` and `exclude` filters."""
     RED = ansi_code("Fore.LIGHTRED_EX")
     R = ansi_code("Style.RESET_ALL")
     # any_entry = pair.any_entry
     write((RED + "ERROR: {}\n    {}" + R).format(e, pair))
     # Return True to ignore this error (instead of raising and terminating the app)
     if "[Errno 92] Illegal byte sequence" in "{}".format(e) and compat.PY2:
         write(RED + "This _may_ be solved by using Python 3." + R)
         # return True
     return False
Пример #5
0
 def on_error(self, e, pair):
     """Called for pairs that don't match `match` and `exclude` filters."""
     RED = ansi_code("Fore.LIGHTRED_EX")
     R = ansi_code("Style.RESET_ALL")
     # any_entry = pair.any_entry
     write((RED + "ERROR: {}\n    {}" + R).format(e, pair))
     # Return True to ignore this error (instead of raising and terminating the app)
     if "[Errno 92] Illegal byte sequence" in "{}".format(e) and compat.PY2:
         write(RED + "This _may_ be solved by using Python 3." + R)
         # return True
     return False
Пример #6
0
    def _interactive_resolve(self, pair):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        if self.resolve_all:
            if self.verbose >= 5:
                self._print_pair_diff(pair)
            return self.resolve_all

        resolve = self.options.get("resolve", "skip")
        assert resolve in ("remote", "ask", "skip")

        if resolve == "ask" or self.verbose >= 5:
            self._print_pair_diff(pair)

        if resolve in ("remote", "skip"):
            # self.resolve_all = resolve
            return resolve

        # self._print_pair_diff(pair)

        self._inc_stat("interactive_ask")

        prompt = (
            "Use {m}R{r}emote, {m}S{r}kip, {m}B{r}inary compare, {m}H{r}elp ? "
        ).format(
            m=ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE"),
            r=ansi_code("Style.RESET_ALL"),
        )

        while True:
            r = input(prompt).strip()
            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'b': Binary compare")
                print("  'r': Download remote file")
                print("  's': Skip this file (leave both targets unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all "
                    "remaining conflicts."
                )
                print("Hit Ctrl+C to abort.")
                continue
            elif r in ("B", "b"):
                self._compare_file(pair.local, pair.remote)
                continue
            elif r in ("R", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break
            elif r in ("r", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r
Пример #7
0
    def _interactive_resolve(self, pair):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        # RED = ansi_code("Fore.LIGHTRED_EX")
        M = ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE")
        R = ansi_code("Style.RESET_ALL")

        resolve = self.options.get("resolve", "skip")
        assert resolve in ("local", "ask", "skip")

        if self.resolve_all:
            if self.verbose >= 5:
                self._print_pair_diff(pair)
            return self.resolve_all

        if resolve == "ask" or self.verbose >= 5:
            self._print_pair_diff(pair)

        if resolve in ("local", "skip"):
            # self.resolve_all = resolve
            return resolve

        self._inc_stat("interactive_ask")

        while True:
            prompt = ("Use " + M + "L" + R + "ocal, " + M + "S" + R + "kip, " +
                      M + "B" + R + "inary compare, " + M + "H" + R + "elp ? ")

            r = compat.console_input(prompt).strip()

            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'b': Binary compare")
                print("  'l': Upload local file")
                print("  's': Skip this file (leave both targets unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all "
                    "remaining conflicts.")
                print("Hit Ctrl+C to abort.")
                continue
            elif r in ("B", "b"):
                self._compare_file(pair.local, pair.remote)
                continue
            elif r in ("L", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break
            elif r in ("l", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r
Пример #8
0
    def _interactive_resolve(self, local, remote):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        RED = ansi_code("Fore.LIGHTRED_EX")
        M = ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE")
        R = ansi_code("Style.RESET_ALL")

        print(
            (VT_ERASE_LINE + RED +
             "CONFLICT: {!r} was modified on both targets since last sync ({})"
             + R).format(local.name, _ts(local.get_sync_info("u"))))
        print("    original modification time: {}, size: {:,} bytes".format(
            _ts(local.get_sync_info("m")), local.get_sync_info("s")))
        print("    local:  {}".format(local.as_string()))
        print("    remote: {}".format(
            remote.as_string(local) if remote else "n.a."))

        if self.resolve_all:
            return self.resolve_all
        resolve = self.options.get("resolve", "skip")
        assert resolve in ("local", "ask", "skip")

        if resolve in ("local", "skip"):
            self.resolve_all = resolve
            return resolve

        while True:
            prompt = "Use " + M + "L" + R + "ocal, " + M + "S" + R + "kip, " + M + "B" + R + "inary compare, " + M + "H" + R + "elp)? "
            r = console_input(prompt).strip()
            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'l': Upload local file")
                print("  's': Skip this file (leave both versions unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all remaining conflicts."
                )
                print("Hit Ctrl+C to abort.")
                continue
            elif r in ("B", "b"):
                self._compare_file(local, remote)
                continue
            elif r in ("L", "R", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break
            elif r in ("l", "r", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r
Пример #9
0
 def on_error(self, exc, pair):
     """Called for pairs that don't match `match` and `exclude` filters."""
     # any_entry = pair.any_entry
     msg = "{red}ERROR: {exc}\n    {pair}{reset}".format(
         exc=exc,
         pair=pair,
         red=ansi_code("Fore.LIGHTRED_EX"),
         reset=ansi_code("Style.RESET_ALL"),
     )
     write(msg)
     # Return True to ignore this error (instead of raising and terminating the app)
     # if "[Errno 92] Illegal byte sequence" in "{}".format(e) and compat.PY2:
     #     write(RED + "This _may_ be solved by using Python 3." + R)
     #     # return True
     return False
Пример #10
0
    def _log_action(self, action, status, symbol, entry, min_level=3):
        if self.verbose < min_level:
            return

        if len(symbol) > 1 and symbol[0] in (">", "<"):
            symbol = " " + symbol  # make sure direction characters are aligned at 2nd column
        if self.options.get("no_color"):
            color = ""
            final = ""
        else:
            #             CM = self.COLOR_MAP
            #             color = CM.get((action, status),
            #                            CM.get(("*", status),
            #                                   CM.get((action, "*"),
            #                                          "")))
            if action in ("copy", "restore"):
                if "<" in symbol:
                    color = ansi_code("Fore.GREEN") + ansi_code(
                        "Style.BRIGHT") if status == "new" else ansi_code(
                            "Fore.GREEN")
                else:
                    color = ansi_code("Fore.CYAN") + ansi_code(
                        "Style.BRIGHT") if status == "new" else ansi_code(
                            "Fore.CYAN")
            elif action == "delete":
                color = ansi_code("Fore.RED")
            elif status == "conflict":
                color = ansi_code("Fore.LIGHTRED_EX")
            elif action == "skip" or status == "equal":
                color = ansi_code("Fore.LIGHTBLACK_EX")

            final = ansi_code("Style.RESET_ALL")

        final += " " * 10
        prefix = ""
        if self.dry_run:
            prefix = DRY_RUN_PREFIX
        if action and status:
            tag = ("%s %s" % (action, status)).upper()
        else:
            tag = ("%s%s" % (action, status)).upper()
        name = entry.get_rel_path()
        if entry.is_dir():
            name = "[%s]" % name

#         print("{}{:<16} {:^3} {}".format(prefix, tag, symbol, name))
        print("{}{}{:<16} {:^3} {}{}".format(prefix, color, tag, symbol, name,
                                             final))
Пример #11
0
    def _print_pair_diff(self, pair):
        RED = ansi_code("Fore.LIGHTRED_EX")
        # M = ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE")
        R = ansi_code("Style.RESET_ALL")

        any_entry = pair.any_entry

        has_meta = any_entry.get_sync_info("m") is not None

        # write("pair", pair)
        # print("pair.local", pair.local)
        # print("pair.remote", pair.remote)

        write(
            (
                VT_ERASE_LINE
                + RED
                + "CONFLICT: {!r} was modified on both targets since last sync ({})."
                + R
            ).format(any_entry.get_rel_path(), _ts(any_entry.get_sync_info("u")))
        )
        if has_meta:
            write(
                "    Original modification time: {}, size: {:,d} bytes.".format(
                    _ts(any_entry.get_sync_info("m")), any_entry.get_sync_info("s")
                )
            )
        else:
            write("    (No meta data available.)")

        write("    Local:  {}".format(pair.local.as_string() if pair.local else "n.a."))
        write(
            "    Remote: {}".format(
                pair.remote.as_string(pair.local) if pair.remote else "n.a."
            )
        )
Пример #12
0
    def _interactive_resolve(self, pair):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        if self.resolve_all:
            # A resolution strategy was selected using Shift+MODE
            resolve = self.resolve_all
        else:
            # A resolution strategy was configured
            resolve = self.options.get("resolve", "skip")

        if resolve in ("new", "old") and pair.is_same_time():
            # We cannot apply this resolution: force an alternative
            print("Cannot resolve using '{}' strategy: {}".format(resolve, pair))
            resolve = "ask" if self.is_script else "skip"

        if resolve == "ask" or self.verbose >= 5:
            self._print_pair_diff(pair)

        if resolve in ("local", "remote", "old", "new", "skip"):
            # self.resolve_all = resolve
            return resolve

        self._inc_stat("interactive_ask")

        prompt = (
            "Use {m}L{r}ocal, {m}R{r}emote, {m}O{r}lder, {m}N{r}ewer, "
            + "{m}S{r}kip, {m}B{r}inary compare, {m}H{r}elp ? "
        ).format(
            m=ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE"),
            r=ansi_code("Style.RESET_ALL"),
        )
        while True:
            r = input(prompt).strip()

            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'b': Binary compare")
                print("  'n': Use newer file")
                print("  'o': Use older file")
                print("  'l': Use local file")
                print("  'r': Use remote file")
                print("  's': Skip this file (leave both targets unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all "
                    "remaining conflicts."
                )
                print("Hit Ctrl+C to abort.")
                self._print_pair_diff(pair)
                continue

            elif r in ("b", "B"):
                # TODO: we could (offer to) set both mtimes to the same value
                # if files are identical
                self._compare_file(pair.local, pair.remote)
                # self._print_pair_diff(pair)
                continue

            elif r in ("o", "O", "n", "N") and pair.is_same_time():
                # Ignore 'old' or 'new' selection if times are the same
                print("Files have identical modification times.")
                continue

            elif r in ("L", "R", "O", "N", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break

            elif r in ("l", "r", "o", "n", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r
Пример #13
0
    def _interactive_resolve(self, pair):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        if self.resolve_all:
            # A resolution strategy was selected using Shift+MODE
            resolve = self.resolve_all
        else:
            # A resolution strategy was configured
            resolve = self.options.get("resolve", "skip")

        if resolve in ("new", "old") and pair.is_same_time():
            # We cannot apply this resolution: force an alternative
            print("Cannot resolve using '{}' strategy: {}".format(resolve, pair))
            resolve = "ask" if self.is_script else "skip"

        if resolve == "ask" or self.verbose >= 5:
            self._print_pair_diff(pair)

        if resolve in ("local", "remote", "old", "new", "skip"):
            # self.resolve_all = resolve
            return resolve

        # RED = ansi_code("Fore.LIGHTRED_EX")
        M = ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE")
        R = ansi_code("Style.RESET_ALL")

        self._inc_stat("interactive_ask")

        while True:
            prompt = (
                "Use "
                + M
                + "L"
                + R
                + "ocal, "
                + M
                + "R"
                + R
                + "emote, "
                + M
                + "O"
                + R
                + "lder, "
                + M
                + "N"
                + R
                + "ewer, "
                + M
                + "S"
                + R
                + "kip, "
                + M
                + "B"
                + R
                + "inary compare, "
                + M
                + "H"
                + R
                + "elp ? "
            )

            r = compat.console_input(prompt).strip()

            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'b': Binary compare")
                print("  'n': Use newer file")
                print("  'o': Use older file")
                print("  'l': Use local file")
                print("  'r': Use remote file")
                print("  's': Skip this file (leave both targets unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all "
                    "remaining conflicts."
                )
                print("Hit Ctrl+C to abort.")
                self._print_pair_diff(pair)
                continue

            elif r in ("b", "B"):
                # TODO: we could (offer to) set both mtimes to the same value
                # if files are identical
                self._compare_file(pair.local, pair.remote)
                # self._print_pair_diff(pair)
                continue

            elif r in ("o", "O", "n", "N") and pair.is_same_time():
                # Ignore 'old' or 'new' selection if times are the same
                print("Files have identical modification times.")
                continue

            elif r in ("L", "R", "O", "N", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break

            elif r in ("l", "r", "o", "n", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r
Пример #14
0
    def _interactive_resolve(self, pair):
        """Return 'local', 'remote', or 'skip' to use local, remote resource or skip."""
        if self.resolve_all:
            if self.verbose >= 5:
                self._print_pair_diff(pair)
            return self.resolve_all

        resolve = self.options.get("resolve", "skip")
        assert resolve in ("remote", "ask", "skip")

        if resolve == "ask" or self.verbose >= 5:
            self._print_pair_diff(pair)

        if resolve in ("remote", "skip"):
            # self.resolve_all = resolve
            return resolve

        # RED = ansi_code("Fore.LIGHTRED_EX")
        M = ansi_code("Style.BRIGHT") + ansi_code("Style.UNDERLINE")
        R = ansi_code("Style.RESET_ALL")

        # self._print_pair_diff(pair)

        self._inc_stat("interactive_ask")

        while True:
            prompt = (
                "Use "
                + M
                + "R"
                + R
                + "emote, "
                + M
                + "S"
                + R
                + "kip, "
                + M
                + "B"
                + R
                + "inary compare, "
                + M
                + "H"
                + R
                + "elp? "
            )

            r = compat.console_input(prompt).strip()
            if r in ("h", "H", "?"):
                print("The following keys are supported:")
                print("  'b': Binary compare")
                print("  'r': Download remote file")
                print("  's': Skip this file (leave both targets unchanged)")
                print(
                    "Hold Shift (upper case letters) to apply choice for all "
                    "remaining conflicts."
                )
                print("Hit Ctrl+C to abort.")
                continue
            elif r in ("B", "b"):
                self._compare_file(pair.local, pair.remote)
                continue
            elif r in ("R", "S"):
                r = self._resolve_shortcuts[r.lower()]
                self.resolve_all = r
                break
            elif r in ("r", "s"):
                r = self._resolve_shortcuts[r]
                break

        return r