@@ -3,12 +3,15 @@ package main
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "image"
6
7
"io/ioutil"
7
8
"log"
8
9
"net/http"
9
10
"os"
10
11
"path/filepath"
11
12
"strings"
13
+
14
+ "github.com/disintegration/imaging"
12
15
)
13
16
14
17
type ShortcodeConfig struct {
@@ -21,10 +24,19 @@ type ServerConfig struct {
21
24
ShowURLOnStart bool `json:"showURLOnStart"`
22
25
GermanFolder string `json:"germanFolder"`
23
26
EnglishFolder string `json:"englishFolder"`
27
+ MediaFolder string `json:"mediaFolder"`
28
+ AssetFolder string `json:"assetFolder"`
29
+ ImageResize struct {
30
+ Method string `json:"method"`
31
+ MaxWidth int `json:"maxWidth"`
32
+ } `json:"imageResize"`
33
+ ThumbnailResize struct {
34
+ Method string `json:"method"`
35
+ MaxWidth int `json:"maxWidth"`
36
+ } `json:"thumbnailResize"`
24
37
}
25
38
26
39
type Config struct {
27
- // Shortcodes ShortcodeConfig `json:"shortcodes"`
28
40
Shortcodes map [string ]string `json:"shortcodes"`
29
41
Icons map [string ]string `json:"icons"`
30
42
Server ServerConfig `json:"server"`
@@ -36,25 +48,17 @@ func main() {
36
48
// Load configuration
37
49
loadConfig ()
38
50
39
- port := config .Server .Port
40
-
41
51
// Serve static files from the "static" directory
42
52
fs := http .FileServer (http .Dir ("static" ))
43
53
http .Handle ("/" , fs )
44
54
45
- // Start the server on localhost with the specified port
46
- address := fmt .Sprintf ("http://localhost:%d" , port )
47
- fmt .Printf ("Starting server at %s\n " , address )
48
- err := http .ListenAndServe (address , nil )
49
- if err != nil {
50
- fmt .Printf ("Error starting server: %s\n " , err )
51
- }
52
-
53
55
// API endpoints
54
56
http .HandleFunc ("/api/config" , handleConfig )
55
57
http .HandleFunc ("/api/save" , handleSave )
56
58
http .HandleFunc ("/api/load" , handleLoad )
57
59
http .HandleFunc ("/api/list" , handleList )
60
+ http .HandleFunc ("/api/media-list" , handleMediaList )
61
+ http .HandleFunc ("/api/process-media" , handleProcessMedia )
58
62
59
63
// Determine the address to listen on
60
64
addr := fmt .Sprintf (":%d" , config .Server .Port )
@@ -66,6 +70,7 @@ func main() {
66
70
log .Printf ("Server starting on port %d" , config .Server .Port )
67
71
}
68
72
73
+ // Start the server
69
74
log .Fatal (http .ListenAndServe (addr , nil ))
70
75
}
71
76
@@ -92,14 +97,17 @@ func loadConfig() {
92
97
}
93
98
94
99
// Convert relative paths to absolute paths
95
- absPath , err := filepath .Abs (config .Server .GermanFolder )
96
- if err = = nil {
97
- config . Server . GermanFolder = absPath
100
+ absGermanFolder , err := filepath .Abs (config .Server .GermanFolder )
101
+ if err ! = nil {
102
+ log . Fatalf ( "Error converting relative path to absolute path for German folder: %v" , err )
98
103
}
99
- absPath , err = filepath .Abs (config .Server .EnglishFolder )
100
- if err == nil {
101
- config .Server .EnglishFolder = absPath
104
+ config .Server .GermanFolder = absGermanFolder
105
+
106
+ absEnglishFolder , err := filepath .Abs (config .Server .EnglishFolder )
107
+ if err != nil {
108
+ log .Fatalf ("Error converting relative path to absolute path for English folder: %v" , err )
102
109
}
110
+ config .Server .EnglishFolder = absEnglishFolder
103
111
}
104
112
105
113
func handleConfig (w http.ResponseWriter , r * http.Request ) {
@@ -181,9 +189,6 @@ func handleList(w http.ResponseWriter, r *http.Request) {
181
189
func listFiles (dir string ) ([]string , error ) {
182
190
var files []string
183
191
err := filepath .Walk (dir , func (path string , info os.FileInfo , err error ) error {
184
- if err != nil {
185
- return err
186
- }
187
192
if ! info .IsDir () && strings .HasSuffix (info .Name (), ".md" ) {
188
193
relPath , err := filepath .Rel (dir , path )
189
194
if err != nil {
@@ -193,7 +198,10 @@ func listFiles(dir string) ([]string, error) {
193
198
}
194
199
return nil
195
200
})
196
- return files , err
201
+ if err != nil {
202
+ return nil , err
203
+ }
204
+ return files , nil
197
205
}
198
206
199
207
func getFullPath (filename string ) string {
@@ -212,3 +220,85 @@ func getFullPath(filename string) string {
212
220
return filename
213
221
}
214
222
}
223
+
224
+ func handleMediaList (w http.ResponseWriter , r * http.Request ) {
225
+ files , err := ioutil .ReadDir (config .Server .MediaFolder )
226
+ if err != nil {
227
+ http .Error (w , "Error reading media directory" , http .StatusInternalServerError )
228
+ return
229
+ }
230
+
231
+ var mediaFiles []string
232
+ for _ , file := range files {
233
+ if ! file .IsDir () {
234
+ mediaFiles = append (mediaFiles , file .Name ())
235
+ }
236
+ }
237
+
238
+ w .Header ().Set ("Content-Type" , "application/json" )
239
+ json .NewEncoder (w ).Encode (mediaFiles )
240
+ }
241
+
242
+ func handleProcessMedia (w http.ResponseWriter , r * http.Request ) {
243
+ var request struct {
244
+ File string `json:"file"`
245
+ NewName string `json:"newName"`
246
+ }
247
+
248
+ err := json .NewDecoder (r .Body ).Decode (& request )
249
+ if err != nil {
250
+ http .Error (w , "Invalid request" , http .StatusBadRequest )
251
+ return
252
+ }
253
+
254
+ sourceFile := filepath .Join (config .Server .MediaFolder , request .File )
255
+ ext := filepath .Ext (request .File )
256
+ newFileName := request .NewName + ext
257
+ destFile := filepath .Join (config .Server .AssetFolder , newFileName )
258
+
259
+ // Open the source image
260
+ src , err := imaging .Open (sourceFile )
261
+ if err != nil {
262
+ http .Error (w , "Error opening source image" , http .StatusInternalServerError )
263
+ return
264
+ }
265
+
266
+ // Resize the image
267
+ var resized image.Image
268
+ if config .Server .ImageResize .Method == "fit" {
269
+ resized = imaging .Fit (src , config .Server .ImageResize .MaxWidth , 0 , imaging .Lanczos )
270
+ } else {
271
+ resized = imaging .Fill (src , config .Server .ImageResize .MaxWidth , 0 , imaging .Center , imaging .Lanczos )
272
+ }
273
+
274
+ // Save the resized image
275
+ err = imaging .Save (resized , destFile )
276
+ if err != nil {
277
+ http .Error (w , "Error saving resized image" , http .StatusInternalServerError )
278
+ return
279
+ }
280
+
281
+ // Create and save thumbnail
282
+ var thumbnail image.Image
283
+ if config .Server .ThumbnailResize .Method == "fit" {
284
+ thumbnail = imaging .Fit (src , config .Server .ThumbnailResize .MaxWidth , 0 , imaging .Lanczos )
285
+ } else {
286
+ thumbnail = imaging .Fill (src , config .Server .ThumbnailResize .MaxWidth , 0 , imaging .Center , imaging .Lanczos )
287
+ }
288
+
289
+ thumbnailFile := filepath .Join (config .Server .AssetFolder , "thumb_" + newFileName )
290
+ err = imaging .Save (thumbnail , thumbnailFile )
291
+ if err != nil {
292
+ http .Error (w , "Error saving thumbnail" , http .StatusInternalServerError )
293
+ return
294
+ }
295
+
296
+ response := struct {
297
+ Filename string `json:"filename"`
298
+ }{
299
+ Filename : newFileName ,
300
+ }
301
+
302
+ w .Header ().Set ("Content-Type" , "application/json" )
303
+ json .NewEncoder (w ).Encode (response )
304
+ }
0 commit comments