@@ -3,17 +3,14 @@ package feed
3
3
import (
4
4
"fmt"
5
5
"io"
6
- "io/fs"
7
6
"net/http"
8
7
"net/url"
9
8
"os"
10
9
"path"
11
10
"path/filepath"
12
- "sort"
13
11
"strings"
14
12
"time"
15
13
16
- "github.com/google/uuid"
17
14
"golang.org/x/exp/slog"
18
15
)
19
16
@@ -46,8 +43,9 @@ type PublicFeed struct {
46
43
// Feed is the internal representation of a Feed and contains all the
47
44
// informations needed to perform its tasks
48
45
type Feed struct {
49
- Path string
50
- Config FeedConfig
46
+ Path string
47
+ Config FeedConfig
48
+ WebSocketManager * WebSocketManager
51
49
}
52
50
53
51
type PublicFeedItem struct {
@@ -57,141 +55,42 @@ type PublicFeedItem struct {
57
55
Feed * PublicFeed `json:"-"`
58
56
}
59
57
60
- func NewFeed (basePath string , feedName string ) (* Feed , error ) {
61
- slog .Info ("Creating new feed" , slog .String ("feed" , feedName ))
62
- feedPath := path .Join (basePath , feedName )
63
-
64
- _ , err := os .Stat (feedPath )
65
- if err == nil {
66
- return nil , & FeedError {
67
- Code : 400 ,
68
- Message : "Feed already exists" ,
69
- }
70
- }
71
-
72
- err = os .Mkdir (feedPath , 0700 )
73
- if err != nil {
74
- slog .Error ("Error creating feed directory" , slog .String ("feed" , feedName ), slog .String ("directory" , feedPath ))
75
- return nil , err
76
- }
77
-
78
- feed := Feed {
79
- Path : feedPath ,
80
- Config : FeedConfig {
81
- Secret : uuid .NewString (),
82
- },
83
- }
84
-
85
- feed .Config .feed = & feed
86
-
87
- err = feed .Config .Write ()
88
-
89
- if err != nil {
90
- slog .Error ("Unable to write config %s" , err .Error ())
91
- return nil , err
92
- }
93
-
94
- return & feed , nil
58
+ func (feed * Feed ) Name () string {
59
+ return path .Base (feed .Path )
95
60
}
96
- func GetFeed (feedPath string ) (* Feed , error ) {
97
- if _ , err := os .Stat (feedPath ); os .IsNotExist (err ) {
98
- return nil , & FeedError {
99
- Code : 404 ,
100
- Message : "Feed does not exists" ,
101
- }
102
- }
61
+ func (feed * Feed ) GetPublicItem (i string ) (* PublicFeedItem , error ) {
62
+ feedLog := slog .Default ().With (slog .String ("feed" , feed .Name ()))
103
63
104
- result := & Feed { Path : feedPath }
64
+ s , err := os . Stat ( path . Join ( feed . Path , i ))
105
65
106
- c , err := FeedConfigForFeed (result )
107
66
if err != nil {
108
- return nil , & FeedError {
109
- Code : 404 ,
110
- Message : "Feed does not exists" ,
111
- }
112
- }
113
- c .feed = result
114
-
115
- result .Config = * c
116
-
117
- return result , nil
118
- }
119
-
120
- func GetPublicFeed (basePath string , feedName string , secret string ) (* PublicFeed , error ) {
121
- feedPath := path .Join (basePath , feedName )
122
-
123
- feedLog := slog .Default ().With (slog .String ("feed" , feedName ))
124
-
125
- feedLog .Debug ("Getting feed" , slog .Int ("secret_len" , len (secret )))
126
-
127
- f , err := GetFeed (feedPath )
67
+ code := 500
68
+ e := "Unable to read file info"
128
69
129
- err = f . IsSecretValid ( secret )
70
+ feedLog . Error ( e , slog . Int ( "return" , code ) )
130
71
131
- if err != nil {
132
72
return nil , err
133
73
}
134
74
135
- publicFeed := & PublicFeed {
136
- Name : feedName ,
137
- Secret : f .Config .Secret ,
138
- }
139
- var d []fs.DirEntry
140
- if d , err = os .ReadDir (feedPath ); err != nil {
141
- code := 500
142
- feedLog .Error ("Unable to feed content" , slog .Int ("return" , code ))
143
-
144
- return nil , & FeedError {
145
- Code : code ,
146
- Message : "Unable to open directory for read" ,
147
- }
148
- }
149
-
150
- items := []PublicFeedItem {}
151
- for _ , f := range d {
152
- if f .Name () == "secret" || f .Name () == "pin" || f .Name () == "config.json" {
153
- continue
154
- }
155
- info , err := f .Info ()
156
- if err != nil {
157
- code := 500
158
- e := "Unable to read file info"
159
-
160
- feedLog .Error (e , slog .Int ("return" , code ))
161
-
162
- return nil , & FeedError {
163
- Code : code ,
164
- Message : e ,
165
- }
166
- }
167
-
168
- var itemType FeedItemType
169
- if strings .HasSuffix (f .Name (), ".txt" ) {
170
- itemType = Text
171
- } else if strings .HasSuffix (f .Name (), ".png" ) || strings .HasSuffix (f .Name (), ".jpg" ) {
172
- itemType = Image
173
- } else {
174
- itemType = Binary
175
- }
176
- items = append (items , PublicFeedItem {
177
- Name : f .Name (),
178
- Date : info .ModTime (),
179
- Type : itemType ,
180
- Feed : publicFeed ,
181
- })
75
+ var itemType FeedItemType
76
+ if strings .HasSuffix (i , ".txt" ) {
77
+ itemType = Text
78
+ } else if strings .HasSuffix (i , ".png" ) || strings .HasSuffix (i , ".jpg" ) {
79
+ itemType = Image
80
+ } else {
81
+ itemType = Binary
182
82
}
183
- sort .Slice (items , func (i , j2 int ) bool {
184
- return items [i ].Date .After (items [j2 ].Date )
185
- })
186
-
187
- publicFeed .Items = items
188
-
189
- return publicFeed , nil
190
- }
191
- func (feed * Feed ) Name () string {
192
- return path .Base (feed .Path )
83
+ return & PublicFeedItem {
84
+ Name : i ,
85
+ Date : s .ModTime (),
86
+ Type : itemType ,
87
+ Feed : & PublicFeed {
88
+ Name : feed .Name (),
89
+ Secret : feed .Config .Secret ,
90
+ },
91
+ }, nil
193
92
}
194
- func (feed * Feed ) GetItem (item string ) ([]byte , error ) {
93
+ func (feed * Feed ) GetItemData (item string ) ([]byte , error ) {
195
94
// Read item content
196
95
slog .Info ("Getting Item" , slog .String ("feed" , feed .Name ()), slog .String ("name" , item ))
197
96
var content []byte
@@ -241,8 +140,8 @@ func (feed *Feed) IsSecretValid(secret string) error {
241
140
return nil
242
141
}
243
142
244
- func (feed * Feed ) AddItem (contentType string , f io.ReadCloser ) error {
245
- slog .Debug ("Adding Item" , slog .String ("feed" , feed .Name ()), slog .String ("content-type" , contentType ))
143
+ func (f * Feed ) AddItem (contentType string , r io.ReadCloser ) error {
144
+ slog .Debug ("Adding Item" , slog .String ("feed" , f .Name ()), slog .String ("content-type" , contentType ))
246
145
fileExtensions := map [string ]string {
247
146
"image/png" : "png" ,
248
147
"image/jpeg" : "jpg" ,
@@ -265,7 +164,7 @@ func (feed *Feed) AddItem(contentType string, f io.ReadCloser) error {
265
164
}
266
165
}
267
166
268
- content , err := io .ReadAll (f )
167
+ content , err := io .ReadAll (r )
269
168
if err != nil {
270
169
_ , ok := err .(* http.MaxBytesError )
271
170
if ok {
@@ -291,7 +190,7 @@ func (feed *Feed) AddItem(contentType string, f io.ReadCloser) error {
291
190
var filename string
292
191
for {
293
192
filename = fmt .Sprintf ("%s %d" , template , fileIndex )
294
- matches , err := filepath .Glob (path .Join (feed .Path , filename ) + ".*" )
193
+ matches , err := filepath .Glob (path .Join (f .Path , filename ) + ".*" )
295
194
if err != nil {
296
195
return & FeedError {
297
196
Code : 500 ,
@@ -304,24 +203,45 @@ func (feed *Feed) AddItem(contentType string, f io.ReadCloser) error {
304
203
fileIndex ++
305
204
}
306
205
307
- err = os .WriteFile (path .Join (feed .Path , filename + "." + ext ), content , 0600 )
206
+ err = os .WriteFile (path .Join (f .Path , filename + "." + ext ), content , 0600 )
308
207
if err != nil {
309
208
return & FeedError {
310
209
Code : 500 ,
311
210
Message : "Unable to write file" ,
312
211
}
313
212
}
314
213
315
- slog .Info ("Added Item" , slog .String ("name" , filename + "." + ext ), slog .String ("feed" , feed .Path ), slog .String ("content-type" , contentType ))
214
+ publicItem , err := f .GetPublicItem (filename + "." + ext )
215
+
216
+ if err != nil {
217
+ return err .(* FeedError )
218
+ }
219
+
220
+ if err = f .WebSocketManager .NotifyAdd (publicItem ); err != nil {
221
+ return & FeedError {
222
+ Code : 500 ,
223
+ Message : err .Error (),
224
+ }
225
+ }
226
+
227
+ slog .Info ("Added Item" , slog .String ("name" , filename + "." + ext ), slog .String ("feed" , f .Path ), slog .String ("content-type" , contentType ))
316
228
317
229
return nil
318
230
}
319
231
320
- func (feed * Feed ) RemoveItem (item string ) error {
321
- slog .Debug ("Remove Item" , slog .String ("name" , item ), slog .String ("feed" , feed .Path ))
322
- itemPath := path .Join (feed .Path , item )
232
+ func (f * Feed ) RemoveItem (item string ) error {
233
+ slog .Debug ("Remove Item" , slog .String ("name" , item ), slog .String ("feed" , f .Path ))
234
+ itemPath := path .Join (f .Path , item )
323
235
324
- err := os .Remove (itemPath )
236
+ publicItem , err := f .GetPublicItem (item )
237
+ if err != nil {
238
+ return & FeedError {
239
+ Code : 500 ,
240
+ Message : err .Error (),
241
+ }
242
+ }
243
+
244
+ err = os .Remove (itemPath )
325
245
if err != nil {
326
246
if os .IsNotExist (err ) {
327
247
return & FeedError {
@@ -334,7 +254,15 @@ func (feed *Feed) RemoveItem(item string) error {
334
254
Message : err .Error (),
335
255
}
336
256
}
337
- slog .Info ("Removed Item" , slog .String ("name" , item ), slog .String ("feed" , feed .Name ()))
257
+
258
+ if err = f .WebSocketManager .NotifyRemove (publicItem ); err != nil {
259
+ return & FeedError {
260
+ Code : 500 ,
261
+ Message : err .Error (),
262
+ }
263
+ }
264
+
265
+ slog .Info ("Removed Item" , slog .String ("name" , item ), slog .String ("feed" , f .Name ()))
338
266
return nil
339
267
}
340
268
0 commit comments