Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] More/better name template functions #676

Open
hafeoz opened this issue Jul 10, 2024 · 0 comments
Open

[Feat] More/better name template functions #676

hafeoz opened this issue Jul 10, 2024 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@hafeoz
Copy link

hafeoz commented Jul 10, 2024

Proposal

Name templates currently have a rather limited functionality set. Following is a list of functions I personally believed to be useful:

  • Truncate, where STRING longer than LEN will be truncated. This allows more rich, longer templates to be used without worrying OS filename character limit.
  • SafeString, where unsafe characters (invalid filename characters) will be removed/replaced from STRING. The guide's example using Replace works, but is a bit too long and is prone to accidental breakage (mistype, accidental character delete, etc.).
  • Extension and Stem, where STRING will be parsed as a filename and the extension/non-extension part of the string will be returned.
  • Pad, where NUMBER will be padded to LEN digits (e.g. {{ Pad 1 3 }} will return a string 001)

Background

I'm using tdl in a script to automatically backup my chat. The core logic of the script now looks something like this:

if tdl dl --continue --rewrite-ext --dir "$output_dir" "$cmd" "$cmd_arg" --skip-same \
    --template '{{ .DialogID }}_{{ .MessageID }}_{{ replace .FileCaption `\n` `_` `/` `_` `\\` `_` `:` `_` `*` `_` `?` `_` `<` `_` `>` `_` `|` `_` ` ` `_` }}_{{ replace .FileName `/` `_` `\` `_` `:` `_` `*` `_` `?` `_` `<` `_` `>` `_` `|` `_` ` ` `_` }}'; then
    break
fi
# tdl failed. Try again with shorter name. 
if tdl dl --continue --rewrite-ext --dir "$output_dir" "$cmd" "$cmd_arg" --skip-same \
    --template '{{ .DialogID }}_{{ .MessageID }}_{{ replace .FileCaption `\n` `_` `/` `_` `\\` `_` `:` `_` `*` `_` `?` `_` `<` `_` `>` `_` `|` `_` ` ` `_` }}'; then
    break
fi
# Try again with even shorter name.
if tdl dl --continue --rewrite-ext --dir "$output_dir" "$cmd" "$cmd_arg" --skip-same \
    --template '{{ .DialogID }}_{{ .MessageID }}_{{ replace .FileName `/` `_` `\` `_` `:` `_` `*` `_` `?` `_` `<` `_` `>` `_` `|` `_` ` ` `_` }}'; then
    break
fi
# Last attempt.
if tdl dl --continue --rewrite-ext --dir "$output_dir" "$cmd" "$cmd_arg" --skip-same \
    --template '{{ .DialogID }}_{{ .MessageID }}'; then
    break
fi
>&2 echo "Failed to download media"
return 1

Which is fairly long and isn't very elegant. I also have to download one file at a time because the whole batch will fail even if only one file is having a long name, and I want most of the file to have a descriptive name instead of plain DialogID_MessageID.

Workarounds

I've made a small patch to add Truncate() and Pad() function because I need it desperately:

diff --git a/pkg/tplfunc/string.go b/pkg/tplfunc/string.go
index a4f9a93..514907d 100644
--- a/pkg/tplfunc/string.go
    b/pkg/tplfunc/string.go
@@ -3,6  3,7 @@ package tplfunc
 import (
 	"strings"
 	"text/template"
 	"fmt"
 
 	"github.com/iancoleman/strcase"
 )
@@ -11,6  12,7 @@ var String = []Func{
 	Repeat(), Replace(),
 	ToUpper(), ToLower(),
 	SnakeCase(), CamelCase(), KebabCase(),
 	Truncate(), Pad(),
 }
 
 func Repeat() Func {
@@ -64,3  66,27 @@ func KebabCase() Func {
 		}
 	}
 }
 
 func Truncate() Func {
 	return func(funcMap template.FuncMap) {
 		funcMap["truncate"] = func(s string, n int) string {
 			// Handle Unicode correctly - https://stackoverflow.com/a/76502408
 			trunc := ""
 			for index, val := range s {
 				if index >= n {
 					break
 				}
 				trunc  = string(val)
 			}
 			return trunc
 		}
 	}
 }
 
 func Pad() Func {
 	return func(funcMap template.FuncMap) {
 		funcMap["pad"] = func(n, l int) string {
 			return fmt.Sprintf("%*d", l, n)
 		}
 	}
 }

SafeString function is nice-to-have, but I think people should live OK without it :)

A possible solution to implement Truncate outside tdl using pure shell code is to write a jq spaghetti code to find all media with longer-than-legal filenames. It's going to be a bit fragile and really complicated though. Please paste the code below if anyone have the dare to write it.

@hafeoz hafeoz added the enhancement New feature or request label Jul 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants