|
28 | 28 | import json |
29 | 29 | import os |
30 | 30 | import shutil |
| 31 | +import uuid |
31 | 32 | import stat |
32 | 33 | import zipfile |
33 | 34 | import tornado.web |
@@ -116,21 +117,35 @@ def rename(self, request): |
116 | 117 | def copy(self, request): |
117 | 118 | try: |
118 | 119 | items = request['items'] |
| 120 | + path = os.path.abspath(self.root + request['newPath']) |
119 | 121 | if len(items) == 1 and 'singleFilename' in request: |
120 | 122 | src = os.path.abspath(self.root + items[0]) |
121 | | - dst = os.path.abspath(self.root + request['singleFilename']) |
122 | | - if not (os.path.exists(src) and src.startswith(self.root) and dst.startswith(self.root)): |
| 123 | + if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)): |
123 | 124 | return {'result': {'success': 'false', 'error': 'File not found'}} |
124 | 125 |
|
125 | | - shutil.move(src, dst) |
| 126 | + shutil.copy(src, path) |
126 | 127 | else: |
127 | | - path = os.path.abspath(self.root + request['newPath']) |
128 | 128 | for item in items: |
129 | 129 | src = os.path.abspath(self.root + item) |
130 | 130 | if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)): |
131 | 131 | return {'result': {'success': 'false', 'error': 'Invalid path'}} |
132 | 132 |
|
133 | | - shutil.move(src, path) |
| 133 | + shutil.copy(src, path) |
| 134 | + except Exception as e: |
| 135 | + return {'result': {'success': 'false', 'error': e.message}} |
| 136 | + |
| 137 | + return {'result': {'success': 'true', 'error': ''}} |
| 138 | + |
| 139 | + def move(self, request): |
| 140 | + try: |
| 141 | + items = request['items'] |
| 142 | + path = os.path.abspath(self.root + request['newPath']) |
| 143 | + for item in items: |
| 144 | + src = os.path.abspath(self.root + item) |
| 145 | + if not (os.path.exists(src) and src.startswith(self.root) and path.startswith(self.root)): |
| 146 | + return {'result': {'success': 'false', 'error': 'Invalid path'}} |
| 147 | + |
| 148 | + shutil.move(src, path) |
134 | 149 | except Exception as e: |
135 | 150 | return {'result': {'success': 'false', 'error': e.message}} |
136 | 151 |
|
@@ -226,14 +241,15 @@ def compress(self, request): |
226 | 241 | continue |
227 | 242 |
|
228 | 243 | if os.path.isfile(path): |
229 | | - zip_file.write(path) |
| 244 | + zip_file.write(path, item) |
230 | 245 | else: |
| 246 | + zip_file.write(path, arcname=os.path.basename(path)) |
| 247 | + |
231 | 248 | for root, dirs, files in os.walk(path): |
232 | | - for f in files: |
233 | | - zip_file.write( |
234 | | - f, |
235 | | - os.path.relpath(os.path.join(root, f), os.path.join(path, '..')) |
236 | | - ) |
| 249 | + if root != path: |
| 250 | + zip_file.write(root, arcname=os.path.relpath(root, os.path.dirname(path))) |
| 251 | + for filename in files: |
| 252 | + zip_file.write(os.path.join(root, filename), arcname=os.path.join(os.path.relpath(root, os.path.dirname(path)), filename)) |
237 | 253 |
|
238 | 254 | zip_file.close() |
239 | 255 | except Exception as e: |
@@ -274,28 +290,65 @@ def upload(self, handler): |
274 | 290 |
|
275 | 291 | def download(self, path): |
276 | 292 | path = os.path.abspath(self.root + path) |
277 | | - print(path) |
278 | 293 | content = '' |
279 | 294 | if path.startswith(self.root) and os.path.isfile(path): |
280 | | - print(path) |
281 | 295 | try: |
282 | 296 | with open(path, 'rb') as f: |
283 | 297 | content = f.read() |
284 | 298 | except Exception as e: |
285 | 299 | pass |
286 | 300 | return content |
287 | 301 |
|
| 302 | + def downloadMultiple(self, items, filename): |
| 303 | + temp_zip_filename = str(uuid.uuid4()) |
| 304 | + zipfile_path = os.path.abspath(os.path.join(self.root, temp_zip_filename)) |
| 305 | + zip_file = zipfile.ZipFile(zipfile_path, 'w', zipfile.ZIP_DEFLATED) |
| 306 | + for item in items: |
| 307 | + path = os.path.abspath(self.root + item) |
| 308 | + if not (os.path.exists(path) and path.startswith(self.root)): |
| 309 | + continue |
| 310 | + |
| 311 | + if os.path.isfile(path): |
| 312 | + zip_file.write(path, item) |
| 313 | + else: |
| 314 | + pass |
| 315 | + zip_file.close() |
| 316 | + |
| 317 | + content = '' |
| 318 | + f = open(zipfile_path,'rb') |
| 319 | + content = f.read() |
| 320 | + f.close() |
| 321 | + os.remove(zipfile_path) |
| 322 | + return content |
| 323 | + |
288 | 324 |
|
289 | 325 | class FileManagerHandler(tornado.web.RequestHandler): |
290 | 326 | def initialize(self, root='/', show_dotfiles=True): |
291 | 327 | self.filemanager = FileManager(root, show_dotfiles) |
292 | 328 |
|
293 | 329 | def get(self): |
| 330 | + |
294 | 331 | action = self.get_query_argument('action', '') |
295 | 332 | path = self.get_query_argument('path', '') |
| 333 | + items = self.get_query_arguments('items') |
| 334 | + toFilename = self.get_query_argument('toFilename', '') |
| 335 | + |
296 | 336 | if action == 'download' and path: |
297 | 337 | result = self.filemanager.download(path) |
298 | 338 | self.write(result) |
| 339 | + |
| 340 | + file_name = os.path.basename(path) |
| 341 | + self.set_header('Content-Type', 'application/force-download') |
| 342 | + self.set_header('Content-Disposition', 'attachment; filename=%s' % file_name) |
| 343 | + elif action == 'downloadMultiple' and len(items) > 0 and toFilename: |
| 344 | + result = self.filemanager.downloadMultiple(items,toFilename) |
| 345 | + self.write(result) |
| 346 | + |
| 347 | + file_name = os.path.basename(toFilename) |
| 348 | + self.set_header('Content-Type', 'application/force-download') |
| 349 | + self.set_header('Content-Disposition', 'attachment; filename=%s' % file_name) |
| 350 | + else: |
| 351 | + pass |
299 | 352 |
|
300 | 353 | def post(self): |
301 | 354 | if self.request.headers.get('Content-Type').find('multipart/form-data') >= 0: |
|
0 commit comments