commit 2bc7f5208cd19650e67c6fb0a35e4819c55564aa
parent a785c24bfe289a232ff0066c8362f044506285b2
Author: breadcat <breadcat@users.noreply.github.com>
Date: Sun, 19 Apr 2026 14:07:23 +0100
Support !123 for copying all tags from file index 123
Diffstat:
| M | include-viewer.go | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
1 file changed, 57 insertions(+), 8 deletions(-)
diff --git a/include-viewer.go b/include-viewer.go
@@ -8,6 +8,7 @@ import (
"net"
"net/http"
"net/url"
+ "strconv"
"strings"
)
@@ -66,6 +67,33 @@ func getPreviousFileTags(excludeFileID int) ([]struct{ cat, val string }, error)
return tags, nil
}
+func getFileTagsByID(fileID int) ([]struct{ cat, val string }, error) {
+ rows, err := db.Query(`
+ SELECT c.name, t.value
+ FROM tags t
+ JOIN categories c ON c.id = t.category_id
+ JOIN file_tags ft ON ft.tag_id = t.id
+ WHERE ft.file_id = ?
+ `, fileID)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ var tags []struct{ cat, val string }
+ for rows.Next() {
+ var cat, val string
+ if err := rows.Scan(&cat, &val); err != nil {
+ return nil, err
+ }
+ tags = append(tags, struct{ cat, val string }{cat, val})
+ }
+ if len(tags) == 0 {
+ return nil, fmt.Errorf("no tags found on file id %d", fileID)
+ }
+ return tags, nil
+}
+
func fileHandler(w http.ResponseWriter, r *http.Request) {
idStr := strings.TrimPrefix(r.URL.Path, "/file/")
if strings.Contains(idStr, "/") {
@@ -116,26 +144,47 @@ func fileHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/file/"+idStr, http.StatusSeeOther)
return
}
+
cat := strings.TrimSpace(r.FormValue("category"))
val := strings.TrimSpace(r.FormValue("value"))
- if cat == "!" {
- prevTags, err := getPreviousFileTags(f.ID)
- if err != nil {
- http.Redirect(w, r, "/file/"+idStr+"?error="+url.QueryEscape("Could not copy tags from previous file: "+err.Error()), http.StatusSeeOther)
- return
+ if cat == "!" || (strings.HasPrefix(cat, "!") && len(cat) > 1) {
+ var sourceTags []struct{ cat, val string }
+ var sourceDesc string
+
+ if cat == "!" {
+ var err error
+ sourceTags, err = getPreviousFileTags(f.ID)
+ if err != nil {
+ http.Redirect(w, r, "/file/"+idStr+"?error="+url.QueryEscape("Could not copy tags from previous file: "+err.Error()), http.StatusSeeOther)
+ return
+ }
+ sourceDesc = "previous file"
+ } else {
+ sourceID, err := strconv.Atoi(cat[1:])
+ if err != nil {
+ http.Redirect(w, r, "/file/"+idStr+"?error="+url.QueryEscape("Invalid file ID in category: "+cat), http.StatusSeeOther)
+ return
+ }
+ sourceTags, err = getFileTagsByID(sourceID)
+ if err != nil {
+ http.Redirect(w, r, "/file/"+idStr+"?error="+url.QueryEscape(fmt.Sprintf("Could not copy tags from file %d: %s", sourceID, err.Error())), http.StatusSeeOther)
+ return
+ }
+ sourceDesc = fmt.Sprintf("file %d", sourceID)
}
- for _, tag := range prevTags {
+
+ for _, tag := range sourceTags {
_, tagID, err := getOrCreateCategoryAndTag(tag.cat, tag.val)
if err != nil {
- log.Printf("Error: fileHandler: failed to create tag %s:%s while copying from previous file for file id=%d: %v", tag.cat, tag.val, f.ID, err)
+ log.Printf("Error: fileHandler: failed to create tag %s:%s while copying from %s for file id=%d: %v", tag.cat, tag.val, sourceDesc, f.ID, err)
continue
}
if _, err = db.Exec("INSERT OR IGNORE INTO file_tags(file_id, tag_id) VALUES (?, ?)", f.ID, tagID); err != nil {
log.Printf("Error: fileHandler: failed to add tag %s:%s to file id=%d: %v", tag.cat, tag.val, f.ID, err)
}
}
- http.Redirect(w, r, "/file/"+idStr+"?success="+url.QueryEscape(fmt.Sprintf("Copied %d tag(s) from previous file", len(prevTags))), http.StatusSeeOther)
+ http.Redirect(w, r, "/file/"+idStr+"?success="+url.QueryEscape(fmt.Sprintf("Copied %d tag(s) from %s", len(sourceTags), sourceDesc)), http.StatusSeeOther)
return
}