From 4294738337af70290ed0d3c0bf350abffd53a242 Mon Sep 17 00:00:00 2001 From: mappu Date: Wed, 17 May 2023 18:52:13 +1200 Subject: [PATCH] albums: basic support (json array using contented/album mime-type) --- Server.go | 2 ++ preview.go | 84 +++++++++++++++++++++++++++++++++++++++++++-------- static/sdk.js | 41 +++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 13 deletions(-) diff --git a/Server.go b/Server.go index 7d61016..d8cd393 100644 --- a/Server.go +++ b/Server.go @@ -22,6 +22,8 @@ var SERVER_HEADER string = `contented/0.0.0-dev` const DEFAULT_MAX_CONCURRENT_THUMBS = 16 +const ALBUM_MIMETYPE = `contented/album` + type ServerPublicProperties struct { AppTitle string MaxUploadBytes int64 diff --git a/preview.go b/preview.go index a7e8bde..c3422e2 100644 --- a/preview.go +++ b/preview.go @@ -1,11 +1,13 @@ package contented import ( + "encoding/json" "fmt" "html" "log" "net/http" "os" + "path/filepath" "strings" "time" ) @@ -56,6 +58,19 @@ html, body { line-height: 0; width: 340px; text-align: center; + position: relative; +} +.thumbnail-overlay { + position: absolute; + bottom: 4px; + right: 4px; + padding: 4px 8px; + line-height: 1.5em; + + pointer-events: none; + + background: red; + color: white; } .properties { background: #000; @@ -82,21 +97,64 @@ html, body { return } - tmpl += ` -
-
- + if m.MimeType == ALBUM_MIMETYPE { + // Special handling for albums + f, err := os.Open(filepath.Join(this.opts.DataDirectory, m.FileHash)) + if err != nil { + log.Printf("Opening file '%s' for preview of album '%s': %s", m.FileHash, fileID, err.Error()) + http.Error(w, "Internal error", 500) + return + } + + var childIDs []string + err = json.NewDecoder(f).Decode(&childIDs) + f.Close() + if err != nil { + log.Printf("Failed to parse album '%s': %s", fileID, err) + http.Error(w, "Internal error", 500) + return + } + + if len(childIDs) == 0 { + log.Printf("Failed to parse album '%s': no entries in album", fileID) + http.Error(w, "Internal error", 500) + return + } + + tmpl += ` +
+
+ +
` + fmt.Sprintf("%d", len(childIDs)) + ` image(s)
+
+
+ Name: ` + html.EscapeString(m.Filename) + `
+ Hash: hover
+ File type: Album
+ Size: ` + fmt.Sprintf("%d", len(childIDs)) + ` image(s)
+ Uploader: ` + html.EscapeString(m.UploadIP) + `
+ Uploaded at: ` + html.EscapeString(m.UploadTime.Format(time.RFC3339)) + `
+
-
- Name: ` + html.EscapeString(m.Filename) + `
- Hash: hover
- File type: ` + html.EscapeString(m.MimeType) + `
- Size: ` + html.EscapeString(fmt.Sprintf("%d", m.FileSize)) + `
- Uploader: ` + html.EscapeString(m.UploadIP) + `
- Uploaded at: ` + html.EscapeString(m.UploadTime.Format(time.RFC3339)) + `
+ ` + + } else { + tmpl += ` +
+
+ +
+
+ Name: ` + html.EscapeString(m.Filename) + `
+ Hash: hover
+ File type: ` + html.EscapeString(m.MimeType) + `
+ Size: ` + html.EscapeString(fmt.Sprintf("%d", m.FileSize)) + `
+ Uploader: ` + html.EscapeString(m.UploadIP) + `
+ Uploaded at: ` + html.EscapeString(m.UploadTime.Format(time.RFC3339)) + `
+
-
- ` + ` + } } if this.opts.EnableHomepage { diff --git a/static/sdk.js b/static/sdk.js index d3423c7..bee2cba 100644 --- a/static/sdk.js +++ b/static/sdk.js @@ -178,6 +178,12 @@
+ +
+ + + +
@@ -204,6 +210,15 @@
+ +
+ +

+ +
`; @@ -307,6 +322,32 @@ handleUploadFrom([blob]); }); + // Album + + $f.find(".contented-album-upload").on("click", function(e) { + e.preventDefault(); + e.stopPropagation(); + + var childIDs = $(".contented-album-input").val().split(","); + + for (var i = 0; i < childIDs.length; ++i) { + childIDs[i] = childIDs[i].trim(); // Basic validation - can't really perform full validation here + + if (childIDs[i].length == 0) { + alert("Entry " + (i+1) + " is too short, expected non-zero length"); + return; + } + + if (! childIDs[i].match(/^[a-zA-Z0-9]+$/)) { + alert("Entry " + (i+1) + " contains unexpected character"); + return; + } + } + + var blob = new Blob([JSON.stringify(childIDs)], {type : 'contented/album'}); + handleUploadFrom([blob]); + }); + // Ctrl+V uploads var pasteHandler = function(e) {