diff --git a/contrib/systemd/copyparty.conf b/contrib/systemd/copyparty.conf index 29f9677b..8ed2fc89 100644 --- a/contrib/systemd/copyparty.conf +++ b/contrib/systemd/copyparty.conf @@ -10,7 +10,14 @@ e2dsa # enable file indexing and filesystem scanning e2ts # and enable multimedia indexing ansi # and colors in log messages - # i: 127.0.0.1 # only allow connections from localhost + + # disable logging to stdout/journalctl and log to a file instead; + # $LOGS_DIRECTORY is usually /var/log/copyparty (comes from systemd) + # and copyparty replaces %Y-%m%d with Year-MonthDay, so the + # full path will be something like /var/log/copyparty/2023-1130.txt + # (note: enable compression by adding .xz at the end) + q, lo: $LOGS_DIRECTORY/%Y-%m%d.log + # p: 80,443,3923 # listen on 80/443 as well (requires CAP_NET_BIND_SERVICE) # i: 127.0.0.1 # only allow connections from localhost (reverse-proxies) diff --git a/contrib/systemd/copyparty.service b/contrib/systemd/copyparty.service index 9dfe4548..e39cfc6c 100644 --- a/contrib/systemd/copyparty.service +++ b/contrib/systemd/copyparty.service @@ -13,7 +13,9 @@ # systemctl daemon-reload && systemctl enable --now copyparty # # if it fails to start, first check this: systemctl status copyparty -# then try starting it while viewing logs: journalctl -fan 100 +# then try starting it while viewing logs: +# journalctl -fan 100 +# tail -Fn 100 /var/log/copyparty/$(date +%Y-%m%d.log) # # you may want to: # - change "User=copyparty" and "/var/lib/copyparty/" to another user @@ -27,10 +29,6 @@ # python disabling line-buffering, so messages are out-of-order: # https://user-images.githubusercontent.com/241032/126040249-cb535cc7-c599-4931-a796-a5d9af691bad.png # -# unless you add -q to disable logging, you may want to remove the -# following line to allow buffering (slightly better performance): -# Environment=PYTHONUNBUFFERED=x -# ######################################################################## ######################################################################## @@ -77,6 +75,11 @@ RestrictNamespaces=true RestrictRealtime=true RestrictSUIDSGID=true +## create a directory for logfiles; +## this defines $LOGS_DIRECTORY which is used in copyparty.conf +## +LogsDirectory=copyparty + ## finally, start copyparty and give it the config file: ## ExecStart=/usr/bin/python3 /usr/local/bin/copyparty-sfx.py -c /etc/copyparty.conf diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 9a5f626c..857d8082 100755 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1093,6 +1093,7 @@ def add_logging(ap): ap2.add_argument("-lo", metavar="PATH", type=u, help="logfile, example: \033[32mcpp-%%Y-%%m%%d-%%H%%M%%S.txt.xz") ap2.add_argument("--no-ansi", action="store_true", default=not VT100, help="disable colors; same as environment-variable NO_COLOR") ap2.add_argument("--ansi", action="store_true", help="force colors; overrides environment-variable NO_COLOR") + ap2.add_argument("--no-logflush", action="store_true", help="don't flush the logfile after each write; tiny bit faster") ap2.add_argument("--no-voldump", action="store_true", help="do not list volumes and permissions on startup") ap2.add_argument("--log-tdec", metavar="N", type=int, default=3, help="timestamp resolution / number of timestamp decimals") ap2.add_argument("--log-badpwd", metavar="N", type=int, default=1, help="log failed login attempt passwords: 0=terse, 1=plaintext, 2=hashed") diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index 61799ff5..726a529d 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -414,7 +414,7 @@ class VFS(object): hist = flags.get("hist") if hist and hist != "-": zs = "{}/{}".format(hist.rstrip("/"), name) - flags["hist"] = os.path.expanduser(zs) if zs.startswith("~") else zs + flags["hist"] = os.path.expandvars(os.path.expanduser(zs)) return flags @@ -947,9 +947,7 @@ class AuthSrv(object): if vp is not None and ap is None: ap = ln - if ap.startswith("~"): - ap = os.path.expanduser(ap) - + ap = os.path.expandvars(os.path.expanduser(ap)) ap = absreal(ap) self._l(ln, 2, "bound to filesystem-path [{}]".format(ap)) self._map_volume(ap, vp, mount, daxs, mflags) @@ -1259,9 +1257,7 @@ class AuthSrv(object): if vflag == "-": pass elif vflag: - if vflag.startswith("~"): - vflag = os.path.expanduser(vflag) - + vflag = os.path.expandvars(os.path.expanduser(vflag)) vol.histpath = uncyg(vflag) if WINDOWS else vflag elif self.args.hist: for nch in range(len(hid)): diff --git a/copyparty/smbd.py b/copyparty/smbd.py index fb1192ad..1e97386d 100644 --- a/copyparty/smbd.py +++ b/copyparty/smbd.py @@ -406,6 +406,7 @@ class SMB(object): smbserver.os.path.abspath = self._hook smbserver.os.path.expanduser = self._hook + smbserver.os.path.expandvars = self._hook smbserver.os.path.getatime = self._hook smbserver.os.path.getctime = self._hook smbserver.os.path.getmtime = self._hook diff --git a/copyparty/svchub.py b/copyparty/svchub.py index e2f6905d..20897958 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -411,13 +411,14 @@ class SvcHub(object): if not vl: continue - vl = [os.path.expanduser(x) if x.startswith("~") else x for x in vl] + vl = [os.path.expandvars(os.path.expanduser(x)) for x in vl] setattr(al, k, vl) for k in "lo hist ssl_log".split(" "): vs = getattr(al, k) - if vs and vs.startswith("~"): - setattr(al, k, os.path.expanduser(vs)) + if vs: + vs = os.path.expandvars(os.path.expanduser(vs)) + setattr(al, k, vs) for k in "sus_urls nonsus_urls".split(" "): vs = getattr(al, k) @@ -522,6 +523,7 @@ class SvcHub(object): import lzma lh = lzma.open(fn, "wt", encoding="utf-8", errors="replace", preset=0) + self.args.no_logflush = True else: lh = open(fn, "wt", encoding="utf-8", errors="replace") except: @@ -751,7 +753,24 @@ class SvcHub(object): (zd.hour * 100 + zd.minute) * 100 + zd.second, zd.microsecond // self.log_div, ) - self.logf.write("@%s [%s\033[0m] %s\n" % (ts, src, msg)) + + if c and not self.args.no_ansi: + if isinstance(c, int): + msg = "\033[3%sm%s\033[0m" % (c, msg) + elif "\033" not in c: + msg = "\033[%sm%s\033[0m" % (c, msg) + else: + msg = "%s%s\033[0m" % (c, msg) + + if "\033" in src: + src += "\033[0m" + + if "\033" in msg: + msg += "\033[0m" + + self.logf.write("@%s [%s] %s\n" % (ts, src, msg)) + if not self.args.no_logflush: + self.logf.flush() now = time.time() if now >= self.next_day: @@ -827,6 +846,8 @@ class SvcHub(object): if self.logf: self.logf.write(msg) + if not self.args.no_logflush: + self.logf.flush() def pr(self, *a: Any, **ka: Any) -> None: try: diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 88598819..5d37b962 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -882,7 +882,9 @@ class Up2k(object): try: if bos.makedirs(histpath): hidedir(histpath) - except: + except Exception as ex: + t = "failed to initialize volume '/%s': %s" + self.log(t % (vpath, ex), 1) return None try: diff --git a/copyparty/util.py b/copyparty/util.py index 7d3dab91..e4c8964c 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -2717,8 +2717,7 @@ def _parsehook( "capture": cap, } - if cmd.startswith("~"): - cmd = os.path.expanduser(cmd) + cmd = os.path.expandvars(os.path.expanduser(cmd)) return chk, fork, jtxt, wait, sp_ka, cmd @@ -2857,9 +2856,7 @@ def loadpy(ap: str, hot: bool) -> Any: depending on what other inconveniently named files happen to be in the same folder """ - if ap.startswith("~"): - ap = os.path.expanduser(ap) - + ap = os.path.expandvars(os.path.expanduser(ap)) mdir, mfile = os.path.split(absreal(ap)) mname = mfile.rsplit(".", 1)[0] sys.path.insert(0, mdir)