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))
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." ) )
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))
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
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
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
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
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
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))
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." ) )
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
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
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