filesystem.py 8.48 KB
Newer Older
1
2
# -*- coding: utf-8 -*-

Marcel's avatar
Marcel committed
3
# imports
4
5
import vispa
import cherrypy
murban's avatar
murban committed
6
7
import os
import json
8
9
10
from vispa.controller import AbstractController
import xmlrpclib

Marcel's avatar
Marcel committed
11

12
class FSController(AbstractController):
13
14

    @cherrypy.expose
Marcel's avatar
Marcel committed
15
    @cherrypy.tools.allow(methods=['GET'])
16
17
    def getfile(self, path, download=None, rnd=None):
        try:
Marcel's avatar
Marcel committed
18
19
20
21
22
            if not download or str(download).lower() not in ['true', '1', 'yes']:
                download = False
            else:
                download = True
            data, contenttype, isbrowserfile = self.handleDownload(str(path))
23
24
            cherrypy.response.headers['Content-Type'] = contenttype
            if download or not isbrowserfile:
murban's avatar
murban committed
25
26
                cherrypy.response.headers[
                    'Content-Disposition'] = 'attachment; filename=%s' % path.split('/')[-1]
27
28
            return data
        except Exception, e:
murban's avatar
murban committed
29
30
31
32
            cherrypy.session['error_data'] = {'status': 404,
                                              'message': str(e), 'traceback': '', 'version': ''}
            raise cherrypy.HTTPRedirect(
                vispa.url.dynamic(os.path.join('error/filenotfound')))
33

Marcel's avatar
Marcel committed
34
35
36
37
    def handleDownload(self, path):
        self.get('fs')
        if not fs.exists(path, 'file'):
            raise Exception('The file \'%s\' does not exist' % path)
38

Marcel's avatar
Marcel committed
39
        content = fs.get_file_content(path)
murban's avatar
murban committed
40
41
        data = xmlrpclib.Binary(
            content).data  # TODO: remove xmlrpclib dependency
42
43

        # get the content type depending on the file extension
Marcel's avatar
Marcel committed
44
        ext = path.split('.')[-1]
45
        mimetype = fs.get_mime_type(path)
46
        if mimetype is None:
murban's avatar
murban committed
47
48
            raise Exception(
                'The file extension \'%s\' is not supported by this server' % ext)
49

50
        return data, mimetype, fs.is_browser_file(path)
51

Marcel's avatar
Marcel committed
52

53
class FSAjaxController(AbstractController):
54
55

    @cherrypy.expose
56
    @cherrypy.tools.allow(methods=["POST", 'GET'])
57
    @cherrypy.tools.json_out()
58
    @cherrypy.tools.sessions()
Marcel's avatar
Marcel committed
59
    def exists(self, path, type=None):
60
        try:
Marcel's avatar
Marcel committed
61
            fs = self.get('fs')
Marcel's avatar
Marcel committed
62
            path = str(path)
Marcel's avatar
Marcel committed
63
64
            type = str(type) if type else type
            target_type = fs.exists(path, type=type)
Marcel's avatar
Marcel committed
65
66
            if target_type:
                return self.success({'type': target_type})
Marcel's avatar
Marcel committed
67
68
69
70
71
            else:
                return self.fail()
        except:
            return self.fail()

72
    @cherrypy.expose
73
    @cherrypy.tools.allow(methods=['POST', 'GET'])
74
    def filelist(self, path, deep=False, filter=[], reverse=False):
Marcel's avatar
Marcel committed
75
76
        try:
            fs = self.get('fs')
77

78
79
            cherrypy.session.save()
            cherrypy.session.loaded = False
80

81
82
83
            deep = self.convert(deep, 'boolean')
            reverse = self.convert(reverse, 'boolean')

Marcel's avatar
Marcel committed
84
            # get the files with the filter
85
            files = fs.get_file_list(path, deep=deep, filter=filter, reverse=reverse, encode_json=True)
86

87
            return self.success(files, encode_json=True)
88
        except Exception, e:
Gero Müller's avatar
Gero Müller committed
89
            vispa.log_exception()
90
            return self.fail(msg='Couldn\'t load files: %s' % str(e), encode_json=True)
91
92

    @cherrypy.expose
93
    @cherrypy.tools.allow(methods=['POST', 'GET'])
94
    @cherrypy.tools.json_out()
95
    def createfolder(self, path, name):
96
        try:
Marcel's avatar
Marcel committed
97
            fs = self.get('fs')
98
            fs.create_folder(str(path), str(name))
Marcel's avatar
Marcel committed
99
            return self.success()
100
        except Exception, e:
Marcel's avatar
Marcel committed
101
            return self.fail(msg='Couldn\'t create the folder: %s' % str(e))
102
103
104
105

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
106
    def createfile(self, path, name):
107
        try:
Marcel's avatar
Marcel committed
108
            fs = self.get('fs')
109
            fs.create_file(str(path), str(name))
Marcel's avatar
Marcel committed
110
            return self.success()
111
        except Exception, e:
Marcel's avatar
Marcel committed
112
            return self.fail(msg='Couldn\'t create the file: %s' % str(e))
113
114
115
116

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
117
    def renamefolder(self, path, name):
118
        try:
Marcel's avatar
Marcel committed
119
            fs = self.get('fs')
120
            fs.rename_folder(str(path), str(name))
Marcel's avatar
Marcel committed
121
            return self.success()
122
        except Exception, e:
Marcel's avatar
Marcel committed
123
            return self.fail(msg='Couldn\'t rename the folder: %s' % str(e))
124
125
126
127

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
128
    def renamefile(self, path, name):
129
        try:
Marcel's avatar
Marcel committed
130
            fs = self.get('fs')
131
            fs.rename_file(str(path), str(name))
Marcel's avatar
Marcel committed
132
            return self.success()
133
        except Exception, e:
Marcel's avatar
Marcel committed
134
            return self.fail(msg='Couldn\'t rename the file: %s' % str(e))
135
136
137
138

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
139
    def remove(self, path):
140
        try:
Marcel's avatar
Marcel committed
141
142
143
144
145
            fs = self.get('fs')
            # 'path' can be a unicode/string or list of unicodes/strings
            # so convert it with the convert function
            fs.remove(self.convert(path, 'string'))
            return self.success()
146
        except Exception, e:
Marcel's avatar
Marcel committed
147
            return self.fail(msg='Couldn\'t remove the file(s): %s' % str(e))
148
149
150
151

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
152
    def compress(self, path, paths, name):
153
        try:
Marcel's avatar
Marcel committed
154
155
156
157
158
            fs = self.get('fs')
            # 'paths' can be a unicode/string or list of unicodes/strings
            # so convert it with the convert function
            fs.compress(str(path), self.convert(path, 'string'), str(name))
            return self.success()
159
        except Exception, e:
Marcel's avatar
Marcel committed
160
            return self.fail(msg='Couldn\'t compress the file(s): %s' % str(e))
161
162
163
164

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
165
    def paste(self, path, paths, cut):
166
        try:
Marcel's avatar
Marcel committed
167
168
169
            fs = self.get('fs')
            # 'paths' can be a unicode/string or list of unicodes/strings
            # so convert it with the convert function
murban's avatar
murban committed
170
171
            fs.paste(str(path), self.convert(
                path, 'string'), self.convert(cut, 'boolean'))
Marcel's avatar
Marcel committed
172
            return self.success()
173
        except Exception, e:
Marcel's avatar
Marcel committed
174
175
            action = 'cut' if self.convert(cut, 'boolean') else 'copy'
            return self.fail(msg='Couldn\'t %s the file(s): %s' % (action, str(e)))
176
177
178
179
180
181
182
183
184
185

    @cherrypy.expose
    @cherrypy.tools.allow(methods=['POST'])
    @cherrypy.tools.json_out()
    def upload(self, *args, **kwargs):
        # the html5 uploader provides following kwargs:
        # index, type, name, size, uploadedfiles[]
        # Since "uploadedfiles[]" ends with "[]"-brackets
        # we have to use kwargs instead of args
        try:
186
            # extract the path
Marcel's avatar
Marcel committed
187
            path = str(kwargs['path'])
188
189

            # prepare the parts
Marcel's avatar
Marcel committed
190
191
192
193
            parts = kwargs['uploadedfiles[]']
            # force parrts to be a list
            if not isinstance(parts, list):
                parts = [parts]
194
195

            # upload
Marcel's avatar
Marcel committed
196
            self.handleUpload(path, parts)
197

Marcel's avatar
Marcel committed
198
            return self.success()
199
        except Exception, e:
Marcel's avatar
Marcel committed
200
            return self.fail(msg='Couldn\'t upload the file(s): %s' % str(e))
201

Marcel's avatar
Marcel committed
202
203
    def handleUpload(self, path, parts):
        fs = self.get('fs')
204
205
206
207
        for part in parts:
            f = part.file
            name = str(part.filename)

murban's avatar
murban committed
208
209
            # check mime type, i.e. get the content type depending on the file
            # extension
210
            mimetype = fs.get_mime_type(name)
211
            if mimetype is None:
Marcel's avatar
Marcel committed
212
                ext = name.split('.')[-1]
murban's avatar
murban committed
213
214
                raise Exception(
                    'The file extension \'%s\' is not supported by this server' % ext)
215

murban's avatar
murban committed
216
217
218
            # save the content using the fs
            fs.save_file_content(
                os.path.join(path, name), xmlrpclib.Binary(f), force=True)
219
220
221
222
223

    @cherrypy.expose
    @cherrypy.tools.allow(methods=["POST"])
    @cherrypy.tools.json_out()
    def isbrowserfile(self, path):
Marcel's avatar
Marcel committed
224
225
226
227
228
229
230
231
232
        try:
            fs = self.get('fs')
            is_bf = fs.is_browser_file(str(path))
            if is_bf:
                return self.success()
            else:
                return self.fail()
        except Exception, e:
            return self.fail()
Marcel's avatar
Marcel committed
233
234
235
236

    @cherrypy.expose
    @cherrypy.tools.allow(methods=["POST"])
    @cherrypy.tools.json_out()
Marcel's avatar
Marcel committed
237
    def getsuggestions(self, path, length=10, append_hidden=True):
murban's avatar
murban committed
238
239
        #try:
        if True:
Marcel's avatar
Marcel committed
240
241
            fs = self.get('fs')
            length = length or 1
murban's avatar
murban committed
242
243
            suggestions = fs.get_suggestions(str(path), length=int(
                length), append_hidden=self.convert(append_hidden, 'boolean'))
Marcel's avatar
Marcel committed
244
            return self.success({'suggestions': suggestions})
murban's avatar
murban committed
245
246
        #except Exception, e:
        #    return self.fail(msg=str(e))