v4.1: BiliBili Live filename auto-rename
- Add a '✨ Rename' button and live preview to the Output Settings section - Convert BiliBili Live recording stems of the form '[YYYY-MM-DD HH-MM-SS][streamer][title]' into 'YYYY年MM月DD日【直播回放】title' - Preview shows the converted result and enables/disables the button based on whether the current name matches the pattern - On auto-fill, keep the raw stem (no '_concat' suffix) so the pattern can match; strip a trailing '_concat' before matching as well Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -316,7 +316,7 @@ class App(_BaseClass): # type: ignore[valid-type]
|
||||
|
||||
# Name row
|
||||
r1 = ctk.CTkFrame(body, fg_color="transparent")
|
||||
r1.pack(fill="x", pady=(0, 8))
|
||||
r1.pack(fill="x", pady=(0, 4))
|
||||
ctk.CTkLabel(r1, text="File name:", width=96, anchor="w").pack(side="left")
|
||||
ctk.CTkEntry(r1, textvariable=self.out_name_var).pack(side="left", fill="x", expand=True)
|
||||
ctk.CTkOptionMenu(
|
||||
@@ -324,6 +324,24 @@ class App(_BaseClass): # type: ignore[valid-type]
|
||||
variable=self.out_ext_var, width=84
|
||||
).pack(side="left", padx=(8, 0))
|
||||
|
||||
# Auto-rename button — converts BiliBili Live filename to readable format
|
||||
self.rename_btn = ctk.CTkButton(
|
||||
r1, text="✨ Rename", width=110,
|
||||
fg_color=("#EDE9FE", "#3B1F6E"),
|
||||
text_color=("#5B21B6", "#C4B5FD"),
|
||||
hover_color=("#DDD6FE", "#4C2889"),
|
||||
command=self._apply_bililive_rename
|
||||
)
|
||||
self.rename_btn.pack(side="left", padx=(8, 0))
|
||||
|
||||
# Preview label: shows what the rename will produce before applying
|
||||
self.rename_preview_lbl = ctk.CTkLabel(
|
||||
body, text="",
|
||||
font=ctk.CTkFont(size=11), text_color=("#7C3AED", "#A78BFA"),
|
||||
anchor="w"
|
||||
)
|
||||
self.rename_preview_lbl.pack(fill="x", pady=(0, 4))
|
||||
|
||||
# Directory row
|
||||
r2 = ctk.CTkFrame(body, fg_color="transparent")
|
||||
r2.pack(fill="x")
|
||||
@@ -504,8 +522,61 @@ class App(_BaseClass): # type: ignore[valid-type]
|
||||
self.out_path_lbl.configure(
|
||||
text=f"Output path: {out}" if out else "Output path: —"
|
||||
)
|
||||
self._refresh_rename_preview()
|
||||
self._refresh_start()
|
||||
|
||||
def _refresh_rename_preview(self):
|
||||
"""Show a live preview of what the rename button will produce."""
|
||||
if not hasattr(self, "rename_preview_lbl"):
|
||||
return
|
||||
current = self.out_name_var.get().strip()
|
||||
renamed = self._bililive_rename(current)
|
||||
if renamed and renamed != current:
|
||||
self.rename_preview_lbl.configure(
|
||||
text=f" → {renamed}"
|
||||
)
|
||||
self.rename_btn.configure(state="normal")
|
||||
else:
|
||||
self.rename_preview_lbl.configure(text="")
|
||||
# Only disable if the name cannot be converted
|
||||
self.rename_btn.configure(state="disabled" if not renamed else "normal")
|
||||
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
# BiliBili Live filename auto-rename
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
# Pattern: [2025-06-28 20-31-15][纳豆nado][title content]
|
||||
_BILILIVE_RE = re.compile(
|
||||
r"^\[(\d{4})-(\d{2})-(\d{2}) \d{2}-\d{2}-\d{2}\]\[[^\]]*\]\[(.+)\]$"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _bililive_rename(stem: str) -> str:
|
||||
"""
|
||||
Convert a BiliBili Live recording stem to a readable name.
|
||||
Input: [2026-03-14 22-46-37][纳豆nado][【点歌专场】今晚九点来捏]
|
||||
Output: 2026年03月14日【直播回放】【点歌专场】今晚九点来捏
|
||||
Returns the converted string, or "" if the stem does not match.
|
||||
"""
|
||||
# Strip any trailing _concat suffix before matching
|
||||
test = stem.removesuffix("_concat").strip()
|
||||
m = App._BILILIVE_RE.match(test)
|
||||
if not m:
|
||||
return ""
|
||||
year, month, day, title = m.groups()
|
||||
return f"{year}年{month}月{day}日【直播回放】{title}"
|
||||
|
||||
def _apply_bililive_rename(self):
|
||||
"""Apply the rename conversion to the current output name."""
|
||||
current = self.out_name_var.get().strip()
|
||||
renamed = self._bililive_rename(current)
|
||||
if not renamed:
|
||||
return
|
||||
self.out_name_var.set(renamed)
|
||||
self.rename_preview_lbl.configure(text=" ✓ Renamed!")
|
||||
self.rename_btn.configure(state="disabled")
|
||||
|
||||
def _refresh_start(self):
|
||||
if not hasattr(self, "start_btn"):
|
||||
return # UI not fully built yet
|
||||
@@ -572,7 +643,8 @@ class App(_BaseClass): # type: ignore[valid-type]
|
||||
if not self.out_dir_var.get().strip():
|
||||
self.out_dir_var.set(str(Path(self.items[0]["path"]).parent))
|
||||
if self.out_name_var.get() in ("", "output_concat"):
|
||||
self.out_name_var.set(Path(self.items[0]["path"]).stem + "_concat")
|
||||
# Keep the raw BiliBili stem so the rename pattern can match it
|
||||
self.out_name_var.set(Path(self.items[0]["path"]).stem)
|
||||
|
||||
self._rebuild_list()
|
||||
self._update_count()
|
||||
|
||||
Reference in New Issue
Block a user