From 043c3e3d646adf661367c576346393a11d5aec09 Mon Sep 17 00:00:00 2001 From: Dawson Jeane Date: Fri, 28 Nov 2025 22:29:56 -0600 Subject: [PATCH] Adding configuration support for title and description formatting in RSS feeds --- copyparty/__main__.py | 2 ++ copyparty/httpcli.py | 49 ++++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/copyparty/__main__.py b/copyparty/__main__.py index f8dcffb1..46ea633f 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -1695,6 +1695,8 @@ def add_rss(ap): ap2.add_argument("--rss-nf", metavar="HITS", type=int, default=250, help="default number of files to return (url-param 'nf')") ap2.add_argument("--rss-fext", metavar="E,E", type=u, default="", help="default list of file extensions to include (url-param 'fext'); blank=all") ap2.add_argument("--rss-sort", metavar="ORD", type=u, default="m", help="default sort order (url-param 'sort'); [\033[32mm\033[0m]=last-modified [\033[32mu\033[0m]=upload-time [\033[32mn\033[0m]=filename [\033[32ms\033[0m]=filesize; Uppercase=oldest-first. Note that upload-time is 0 for non-uploaded files") + ap2.add_argument("--rss-title", metavar="FMT", type=u, default="{filename}", help="format for RSS item title; available tags: {title}, {artist}, {album}, {.tn}, {date}, {filename}; default is '{title}' (falls back to filename if tag missing)") + ap2.add_argument("--rss-desc", metavar="FMT", type=u, default="{filename}", help="format for RSS item description; available tags: {title}, {artist}, {album}, {.tn}, {date}, {filename}; default is '{artist} - {title}' (falls back to filename if all tags missing)") def add_db_general(ap, hcores): diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index ad1b2950..9d0a2eac 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -1540,27 +1540,48 @@ class HttpCli(object): ap = "" use_magic = "rmagic" in self.vn.flags + # Get format templates from config or URL params + title_fmt = self.uparam.get("title_fmt", self.args.rss_title) + desc_fmt = self.uparam.get("desc_fmt", self.args.rss_desc) + for i in hits: if use_magic: ap = os.path.join(self.vn.realpath, i["rp"]) iurl = html_escape("%s%s" % (baseurl, i["rp"]), True, True) fn_title = unquotep(i["rp"].split("?")[0].split("/")[-1]) - fn_title = html_escape(fn_title, True, True) - self.log("tags: %s" % (i["tags"],), 7) - tag_t = str(i["tags"].get("title") or "") - tag_track = str(i["tags"].get(".tn") or "") - - tag_a = str(i["tags"].get("artist") or "") - title = html_escape(tag_t, True, True) if tag_t else fn_title - if tag_track: - desc = "%s - %s - %s" % (tag_a,tag_track, tag_t) if tag_t and tag_a and tag_track else (tag_t or tag_a) - else: - desc = "%s - %s" % (tag_a, tag_t) if tag_t and tag_a else (tag_t or tag_a) - desc = html_escape(desc, True, True) if desc else fn_title - mime = html_escape(guess_mime(title, ap)) + fn_title_esc = html_escape(fn_title, True, True) + + # Build tag dictionary for substitution + tag_dict = { + "filename": fn_title, + "title": str(i["tags"].get("title") or ""), + "artist": str(i["tags"].get("artist") or ""), + "album": str(i["tags"].get("album") or ""), + ".tn": str(i["tags"].get(".tn") or ""), + "date": str(i["tags"].get("date") or ""), + } + + # Format title using template + title = title_fmt + for tag_name, tag_value in tag_dict.items(): + title = title.replace("{" + tag_name + "}", tag_value) + # If title is empty or only contains empty placeholders, use filename + if not title.strip() or title == title_fmt: + title = fn_title + title = html_escape(title, True, True) + + # Format description using template + desc = desc_fmt + for tag_name, tag_value in tag_dict.items(): + desc = desc.replace("{" + tag_name + "}", tag_value) + # If desc is empty or only contains empty placeholders, use filename + if not desc.strip() or desc == desc_fmt: + desc = fn_title + desc = html_escape(desc, True, True) + + mime = html_escape(guess_mime(fn_title, ap)) lmod = formatdate(max(0, i["ts"])) - tag_date = i["tags"].get("date") zsa = (iurl, iurl, title, desc, lmod, iurl, mime, i["sz"]) zs = (