From 4fbd6853f4767103b2bd0151cc6dc0b8bf17138b Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 12 Sep 2023 19:56:05 +0000 Subject: [PATCH] add msg-log.py initially by @clach04, closes #35 --- bin/hooks/msg-log.py | 115 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100755 bin/hooks/msg-log.py diff --git a/bin/hooks/msg-log.py b/bin/hooks/msg-log.py new file mode 100755 index 00000000..bd419466 --- /dev/null +++ b/bin/hooks/msg-log.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# coding: utf-8 +# vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab +from __future__ import print_function, unicode_literals + +import json +import os +import sys +import time +from datetime import datetime + + +""" +use copyparty as a dumb messaging server / guestbook thing; +initially contributed by @clach04 in https://github.com/9001/copyparty/issues/35 (thanks!) + +Sample usage: + + python copyparty-sfx.py --xm j,bin/hooks/msg-log.py + +Where: + + xm = execute on message-to-server-log + j = provide message information as json; not just the text - this script REQUIRES json + t10 = timeout and kill download after 10 secs +""" + + +# output filename +FILENAME = os.environ.get("COPYPARTY_MESSAGE_FILENAME", "") or "README.md" + +# set True to write in descending order (newest message at top of file); +# note that this becomes very slow/expensive as the file gets bigger +DESCENDING = True + +# the message template; the following parameters are provided by copyparty and can be referenced below: +# 'ap' = absolute filesystem path where the message was posted +# 'vp' = virtual path (URL 'path') where the message was posted +# 'mt' = 'at' = unix-timestamp when the message was posted +# 'datetime' = ISO-8601 time when the message was posted +# 'sz' = message size in bytes +# 'host' = the server hostname which the user was accessing (URL 'host') +# 'user' = username (if logged in), otherwise '*' +# 'txt' = the message text itself +# (uncomment the print(msg_info) to see if additional information has been introduced by copyparty since this was written) +TEMPLATE = """ +🕒 %(datetime)s, 👤 %(user)s @ %(ip)s +%(txt)s +""" + + +def write_ascending(filepath, msg_text): + with open(filepath, "a", encoding="utf-8", errors="replace") as outfile: + outfile.write(msg_text) + + +def write_descending(filepath, msg_text): + lockpath = filepath + ".lock" + got_it = False + for _ in range(16): + try: + os.mkdir(lockpath) + got_it = True + break + except: + time.sleep(0.1) + continue + + if not got_it: + return sys.exit(1) + + try: + oldpath = filepath + ".old" + os.rename(filepath, oldpath) + with open(oldpath, "r", encoding="utf-8", errors="replace") as infile, open( + filepath, "w", encoding="utf-8", errors="replace" + ) as outfile: + outfile.write(msg_text) + while True: + buf = infile.read(4096) + if not buf: + break + outfile.write(buf) + finally: + try: + os.unlink(oldpath) + except: + pass + os.rmdir(lockpath) + + +def main(argv=None): + if argv is None: + argv = sys.argv + + msg_info = json.loads(sys.argv[1]) + # print(msg_info) + + dt = datetime.utcfromtimestamp(msg_info["at"]) + msg_info["datetime"] = dt.strftime("%Y-%m-%d, %H:%M:%S") + + msg_text = TEMPLATE % msg_info + + filepath = os.path.join(msg_info["ap"], FILENAME) + + if DESCENDING and os.path.exists(filepath): + write_descending(filepath, msg_text) + else: + write_ascending(filepath, msg_text) + + print(msg_text) + + +if __name__ == "__main__": + main()