1 | /** |
||
2 | * Nextcloud - Gallery |
||
3 | * |
||
4 | * |
||
5 | * This file is licensed under the Affero General Public License version 3 or |
||
6 | * later. See the COPYING file. |
||
7 | * |
||
8 | * @author Olivier Paroz <[email protected]> |
||
9 | * |
||
10 | * @copyright Olivier Paroz 2017 |
||
11 | */ |
||
12 | /* global _, Gallery, Thumbnails */ |
||
13 | /** |
||
14 | * OCA.FileList methods needed for file uploading |
||
15 | * |
||
16 | * This hack makes it possible to use the Files scripts as is, without having to import and |
||
17 | * maintain them in Gallery |
||
18 | * |
||
19 | * Empty methods are for the "new" button, if we want to implement that one day |
||
20 | * |
||
21 | * @type {{findFile: FileList.findFile, createFile: FileList.createFile, |
||
22 | * getCurrentDirectory: FileList.getCurrentDirectory, getUploadUrl: |
||
23 | * FileList.getUploadUrl}} |
||
24 | */ |
||
25 | var FileList = { |
||
26 | /** |
||
27 | * Makes sure the filename does not exist |
||
28 | * |
||
29 | * Gives an early chance to the user to abort the action, before uploading everything to the |
||
30 | * server. |
||
31 | * Albums are not supported as we don't have a full list of images contained in a sub-album |
||
32 | * |
||
33 | * @param fileName |
||
34 | * @returns {*} |
||
35 | */ |
||
36 | findFile: function (fileName) { |
||
37 | "use strict"; |
||
38 | var path = Gallery.currentAlbum + '/' + fileName; |
||
39 | var galleryImage = Gallery.imageMap[path]; |
||
40 | if (galleryImage) { |
||
41 | var fileInfo = { |
||
42 | name: fileName, |
||
43 | directory: Gallery.currentAlbum, |
||
44 | path: path, |
||
45 | etag: galleryImage.etag, |
||
46 | mtime: galleryImage.mTime * 1000, // Javascript gives the Epoch time in milliseconds |
||
47 | size: galleryImage.size |
||
48 | }; |
||
49 | return fileInfo; |
||
50 | } else { |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
![]() |
|||
51 | return null; |
||
52 | } |
||
53 | }, |
||
54 | |||
55 | /** |
||
56 | * Create an empty file inside the current album. |
||
57 | * |
||
58 | * @param {string} name name of the file |
||
59 | * |
||
60 | * @return {Promise} promise that will be resolved after the |
||
61 | * file was created |
||
62 | * |
||
63 | */ |
||
64 | createFile: function(name) { |
||
65 | var self = this; |
||
66 | var deferred = $.Deferred(); |
||
67 | var promise = deferred.promise(); |
||
68 | |||
69 | OCA.Files.isFileNameValid(name); |
||
70 | |||
71 | var targetPath = this.getCurrentDirectory() + '/' + name; |
||
72 | |||
73 | //Check if file already exists |
||
74 | if(Gallery.imageMap[targetPath]) { |
||
75 | OC.Notification.showTemporary( |
||
76 | t('files', 'Could not create file "{file}" because it already exists', {file: name}) |
||
77 | ); |
||
78 | deferred.reject(); |
||
79 | return promise; |
||
80 | } |
||
81 | |||
82 | Gallery.filesClient.putFileContents( |
||
83 | targetPath, |
||
84 | '', |
||
85 | { |
||
86 | contentType: 'text/plain', |
||
87 | overwrite: true |
||
88 | } |
||
89 | ) |
||
90 | .done(function() { |
||
91 | // TODO: error handling / conflicts |
||
92 | Gallery.filesClient.getFileInfo( |
||
93 | targetPath, { |
||
94 | properties: self.findFile(targetPath) |
||
95 | } |
||
96 | ) |
||
97 | .then(function(status, data) { |
||
98 | deferred.resolve(status, data); |
||
99 | }) |
||
100 | .fail(function(status) { |
||
101 | OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name})); |
||
102 | deferred.reject(status); |
||
103 | }); |
||
104 | }) |
||
105 | .fail(function(status) { |
||
106 | if (status === 412) { |
||
107 | OC.Notification.showTemporary( |
||
108 | t('files', 'Could not create file "{file}" because it already exists', {file: name}) |
||
109 | ); |
||
110 | } else { |
||
111 | OC.Notification.showTemporary(t('files', 'Could not create file "{file}"', {file: name})); |
||
112 | } |
||
113 | deferred.reject(status); |
||
114 | }); |
||
115 | |||
116 | return promise; |
||
117 | }, |
||
118 | |||
119 | |||
120 | /** |
||
121 | * Retrieves the current album |
||
122 | * |
||
123 | * @returns {string} |
||
124 | */ |
||
125 | getCurrentDirectory: function () { |
||
126 | "use strict"; |
||
127 | |||
128 | // In Files, dirs start with a / |
||
129 | return '/' + Gallery.currentAlbum; |
||
130 | }, |
||
131 | |||
132 | /** |
||
133 | * Retrieves the WebDAV upload URL |
||
134 | * |
||
135 | * @param {string} fileName |
||
136 | * @param {string} dir |
||
137 | * |
||
138 | * @returns {string} |
||
139 | */ |
||
140 | getUploadUrl: function (fileName, dir) { |
||
141 | if (_.isUndefined(dir)) { |
||
142 | dir = this.getCurrentDirectory(); |
||
143 | } |
||
144 | |||
145 | var pathSections = dir.split('/'); |
||
146 | if (!_.isUndefined(fileName)) { |
||
147 | pathSections.push(fileName); |
||
148 | } |
||
149 | var encodedPath = ''; |
||
150 | _.each(pathSections, function (section) { |
||
151 | if (section !== '') { |
||
152 | encodedPath += '/' + encodeURIComponent(section); |
||
153 | } |
||
154 | }); |
||
155 | return OC.linkToRemoteBase('webdav') + encodedPath; |
||
156 | } |
||
157 | }; |
||
158 | |||
159 | /** |
||
160 | * OCA.Files methods needed for file uploading |
||
161 | * |
||
162 | * This hack makes it possible to use the Files scripts as is, without having to import and |
||
163 | * maintain them in Gallery |
||
164 | * |
||
165 | * @type {{isFileNameValid: Files.isFileNameValid, generatePreviewUrl: Files.generatePreviewUrl}} |
||
166 | */ |
||
167 | var Files = { |
||
168 | App: {fileList: {}}, |
||
169 | |||
170 | isFileNameValid: function (name) { |
||
171 | "use strict"; |
||
172 | var trimmedName = name.trim(); |
||
173 | if (trimmedName === '.' || trimmedName === '..') { |
||
174 | throw t('files', '"{name}" is an invalid file name.', {name: name}); |
||
175 | } else if (trimmedName.length === 0) { |
||
176 | throw t('files', 'File name cannot be empty.'); |
||
177 | } else if (OC.fileIsBlacklisted(trimmedName)) { |
||
178 | throw t('files', '"{name}" is not an allowed filetype', {name: name}); |
||
179 | } |
||
180 | |||
181 | return true; |
||
182 | |||
183 | }, |
||
184 | |||
185 | /** |
||
186 | * Generates a preview for the conflict dialogue |
||
187 | * |
||
188 | * Since Gallery uses the fileId and Files uses the path, we have to use the preview endpoint |
||
189 | * of Files |
||
190 | */ |
||
191 | generatePreviewUrl: function (urlSpec) { |
||
192 | "use strict"; |
||
193 | var previewUrl; |
||
194 | var path = urlSpec.file; |
||
195 | |||
196 | // In Files, root files start with // |
||
197 | if (path.indexOf('//') === 0) { |
||
198 | path = path.substring(2); |
||
199 | } else { |
||
200 | // Directories start with / |
||
201 | path = path.substring(1); |
||
202 | } |
||
203 | |||
204 | if (Gallery.imageMap[path]) { |
||
205 | var fileId = Gallery.imageMap[path].fileId; |
||
206 | var thumbnail = Thumbnails.map[fileId]; |
||
207 | previewUrl = thumbnail.image.src; |
||
208 | } else { |
||
209 | var previewDimension = 96; |
||
210 | urlSpec.x = Math.ceil(previewDimension * window.devicePixelRatio); |
||
211 | urlSpec.y = Math.ceil(previewDimension * window.devicePixelRatio); |
||
212 | urlSpec.forceIcon = 0; |
||
213 | previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec); |
||
214 | } |
||
215 | |||
216 | return previewUrl; |
||
217 | } |
||
218 | }; |
||
219 | |||
220 | OCA.Files = Object.assign({}, OCA.Files, Files); |
||
221 | OCA.Files.App.fileList = Object.assign({}, OCA.Files.App.fileList, FileList); |
||
222 |