@@ -10,6 +10,7 @@ import (
10
10
"path/filepath"
11
11
"runtime"
12
12
"strconv"
13
+ "strings"
13
14
"time"
14
15
15
16
"github.com/cozy/cozy-stack/model/account"
@@ -35,6 +36,7 @@ type File struct {
35
36
DocID string `json:"id,omitempty"`
36
37
Type string `json:"type"`
37
38
Name string `json:"name"`
39
+ Path string `json:"path"`
38
40
Size uint64 `json:"size,omitempty"`
39
41
Mime string `json:"mime,omitempty"`
40
42
Class string `json:"class,omitempty"`
@@ -62,6 +64,7 @@ var _ jsonapi.Object = (*File)(nil)
62
64
type NextCloud struct {
63
65
inst * instance.Instance
64
66
accountID string
67
+ userID string
65
68
webdav * webdav.Client
66
69
}
67
70
@@ -99,48 +102,68 @@ func New(inst *instance.Instance, accountID string) (*NextCloud, error) {
99
102
Host : u .Host ,
100
103
Username : username ,
101
104
Password : password ,
105
+ BasePath : "/remote.php/dav" ,
102
106
Logger : logger ,
103
107
}
104
108
nc := & NextCloud {
105
109
inst : inst ,
106
110
accountID : accountID ,
107
111
webdav : webdav ,
108
112
}
109
- if err := nc .fillBasePath (& doc ); err != nil {
113
+ if err := nc .fillUserID (& doc ); err != nil {
110
114
return nil , err
111
115
}
112
116
return nc , nil
113
117
}
114
118
115
119
func (nc * NextCloud ) Download (path string ) (* webdav.Download , error ) {
116
- return nc .webdav .Get (path )
120
+ return nc .webdav .Get ("/files/" + nc . userID + "/" + path )
117
121
}
118
122
119
123
func (nc * NextCloud ) Upload (path , mime string , contentLength int64 , body io.Reader ) error {
120
124
headers := map [string ]string {
121
125
echo .HeaderContentType : mime ,
122
126
}
127
+ path = "/files/" + nc .userID + "/" + path
123
128
return nc .webdav .Put (path , contentLength , headers , body )
124
129
}
125
130
126
131
func (nc * NextCloud ) Mkdir (path string ) error {
127
- return nc .webdav .Mkcol (path )
132
+ return nc .webdav .Mkcol ("/files/" + nc . userID + "/" + path )
128
133
}
129
134
130
135
func (nc * NextCloud ) Delete (path string ) error {
131
- return nc .webdav .Delete (path )
136
+ return nc .webdav .Delete ("/files/" + nc . userID + "/" + path )
132
137
}
133
138
134
139
func (nc * NextCloud ) Move (oldPath , newPath string ) error {
140
+ oldPath = "/files/" + nc .userID + "/" + oldPath
141
+ newPath = "/files/" + nc .userID + "/" + newPath
135
142
return nc .webdav .Move (oldPath , newPath )
136
143
}
137
144
138
145
func (nc * NextCloud ) Copy (oldPath , newPath string ) error {
146
+ oldPath = "/files/" + nc .userID + "/" + oldPath
147
+ newPath = "/files/" + nc .userID + "/" + newPath
139
148
return nc .webdav .Copy (oldPath , newPath )
140
149
}
141
150
151
+ func (nc * NextCloud ) Restore (path string ) error {
152
+ path = "/trashbin/" + nc .userID + "/" + path
153
+ dst := "/trashbin/" + nc .userID + "/restore/" + filepath .Base (path )
154
+ return nc .webdav .Move (path , dst )
155
+ }
156
+
157
+ func (nc * NextCloud ) DeleteTrash (path string ) error {
158
+ return nc .webdav .Delete ("/trashbin/" + nc .userID + "/" + path )
159
+ }
160
+
161
+ func (nc * NextCloud ) EmptyTrash () error {
162
+ return nc .webdav .Delete ("/trashbin/" + nc .userID + "/trash" )
163
+ }
164
+
142
165
func (nc * NextCloud ) ListFiles (path string ) ([]jsonapi.Object , error ) {
143
- items , err := nc .webdav .List (path )
166
+ items , err := nc .webdav .List ("/files/" + nc . userID + "/" + path )
144
167
if err != nil {
145
168
return nil , err
146
169
}
@@ -155,6 +178,7 @@ func (nc *NextCloud) ListFiles(path string) ([]jsonapi.Object, error) {
155
178
DocID : item .ID ,
156
179
Type : item .Type ,
157
180
Name : item .Name ,
181
+ Path : "/" + filepath .Join (path , filepath .Base (item .Href )),
158
182
Size : item .Size ,
159
183
Mime : mime ,
160
184
Class : class ,
@@ -167,7 +191,38 @@ func (nc *NextCloud) ListFiles(path string) ([]jsonapi.Object, error) {
167
191
return files , nil
168
192
}
169
193
194
+ func (nc * NextCloud ) ListTrashed (path string ) ([]jsonapi.Object , error ) {
195
+ path = "/trash/" + path
196
+ items , err := nc .webdav .List ("/trashbin/" + nc .userID + path )
197
+ if err != nil {
198
+ return nil , err
199
+ }
200
+
201
+ var files []jsonapi.Object
202
+ for _ , item := range items {
203
+ var mime , class string
204
+ if item .Type == "file" {
205
+ mime , class = vfs .ExtractMimeAndClassFromFilename (item .TrashedName )
206
+ }
207
+ file := & File {
208
+ DocID : item .ID ,
209
+ Type : item .Type ,
210
+ Name : item .TrashedName ,
211
+ Path : filepath .Join (path , filepath .Base (item .Href )),
212
+ Size : item .Size ,
213
+ Mime : mime ,
214
+ Class : class ,
215
+ UpdatedAt : item .LastModified ,
216
+ ETag : item .ETag ,
217
+ url : nc .buildTrashedURL (item , path ),
218
+ }
219
+ files = append (files , file )
220
+ }
221
+ return files , nil
222
+ }
223
+
170
224
func (nc * NextCloud ) Downstream (path , dirID string , kind OperationKind , cozyMetadata * vfs.FilesCozyMetadata ) (* vfs.FileDoc , error ) {
225
+ path = "/files/" + nc .userID + "/" + path
171
226
dl , err := nc .webdav .Get (path )
172
227
if err != nil {
173
228
return nil , err
@@ -215,6 +270,7 @@ func (nc *NextCloud) Downstream(path, dirID string, kind OperationKind, cozyMeta
215
270
}
216
271
217
272
func (nc * NextCloud ) Upstream (path , from string , kind OperationKind ) error {
273
+ path = "/files/" + nc .userID + "/" + path
218
274
fs := nc .inst .VFS ()
219
275
doc , err := fs .FileByID (from )
220
276
if err != nil {
@@ -238,18 +294,18 @@ func (nc *NextCloud) Upstream(path, from string, kind OperationKind) error {
238
294
return nil
239
295
}
240
296
241
- func (nc * NextCloud ) fillBasePath (accountDoc * couchdb.JSONDoc ) error {
297
+ func (nc * NextCloud ) fillUserID (accountDoc * couchdb.JSONDoc ) error {
242
298
userID , _ := accountDoc .M ["webdav_user_id" ].(string )
243
299
if userID != "" {
244
- nc .webdav . BasePath = "/remote.php/dav/files/" + userID
300
+ nc .userID = userID
245
301
return nil
246
302
}
247
303
248
304
userID , err := nc .fetchUserID ()
249
305
if err != nil {
250
306
return err
251
307
}
252
- nc .webdav . BasePath = "/remote.php/dav/files/" + userID
308
+ nc .userID = userID
253
309
254
310
// Try to persist the userID to avoid fetching it for every WebDAV request
255
311
accountDoc .M ["webdav_user_id" ] = userID
@@ -266,6 +322,28 @@ func (nc *NextCloud) buildURL(item webdav.Item, path string) string {
266
322
Path : "/apps/files/files/" + item .ID ,
267
323
RawQuery : "dir=/" + path ,
268
324
}
325
+ if item .Type == "directory" {
326
+ if ! strings .HasSuffix (u .RawQuery , "/" ) {
327
+ u .RawQuery += "/"
328
+ }
329
+ u .RawQuery += item .Name
330
+ }
331
+ return u .String ()
332
+ }
333
+
334
+ func (nc * NextCloud ) buildTrashedURL (item webdav.Item , path string ) string {
335
+ u := & url.URL {
336
+ Scheme : nc .webdav .Scheme ,
337
+ Host : nc .webdav .Host ,
338
+ Path : "/apps/files/trashbin/" + item .ID ,
339
+ RawQuery : "dir=" + strings .TrimPrefix (path , "/trash" ),
340
+ }
341
+ if item .Type == "directory" {
342
+ if ! strings .HasSuffix (u .RawQuery , "/" ) {
343
+ u .RawQuery += "/"
344
+ }
345
+ u .RawQuery += item .TrashedName
346
+ }
269
347
return u .String ()
270
348
}
271
349
0 commit comments