file.py 12.1 KB
Newer Older
Marc Duez's avatar
Marc Duez committed
1
# coding: utf8
Marc Duez's avatar
Marc Duez committed
2
import gluon.contrib.simplejson
Marc Duez's avatar
Marc Duez committed
3
import defs
4
import vidjil_utils
Marc Duez's avatar
Marc Duez committed
5
import os
6 7
import os.path
import datetime
8 9
from controller_utils import error_message

Marc Duez's avatar
Marc Duez committed
10 11 12 13 14
if request.env.http_origin:
    response.headers['Access-Control-Allow-Origin'] = request.env.http_origin  
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    response.headers['Access-Control-Max-Age'] = 86400

Marc Duez's avatar
Marc Duez committed
15 16

def add(): 
17
    if not auth.can_modify_patient(request.vars['id'], auth.user_id):
18
        return error_message("you need admin permission on this patient to add files")
19
    elif not auth.can_upload_file(request.vars['id']):
20
        return error_message("you don't have right to upload files")
21
    else:
22
        query = db((db.patient.id == request.vars['id'])
23
                &(db.sample_set_membership.sample_set_id == db.patient.sample_set_id)
24 25
                &(db.sequence_file.id == db.sample_set_membership.sequence_file_id)
            ).select(db.sequence_file.ALL)
26 27 28 29 30 31 32 33 34 35
        if len(query) != 0 :
            pcr = query[0].pcr
            sequencer = query[0].sequencer
            producer = query[0].producer
        else:
            pcr = sequencer = producer = ""
        return dict(message=T('add file'),
                    pcr=pcr,
                    sequencer=sequencer,
                    producer=producer)
36

Marc Duez's avatar
Marc Duez committed
37 38
#TODO check data
def add_form(): 
Marc Duez's avatar
Marc Duez committed
39
    error = ""
40
    
41
    if request.vars['sampling_date'] != '' :
Marc Duez's avatar
Marc Duez committed
42 43 44
        try:
            datetime.datetime.strptime(""+request.vars['sampling_date'], '%Y-%m-%d')
        except ValueError:
45
            error += "date (wrong format), "
46 47
    if request.vars['filename'] == None :
        error += " missing filename"
48
            
Marc Duez's avatar
Marc Duez committed
49
    if error=="" :
50
        query = db((db.patient.id == request.vars['patient_id'])
51
                &(db.sample_set_membership.sample_set_id == db.patient.sample_set_id)
52 53
                &(db.sequence_file.id == db.sample_set_membership.sequence_file_id)
            ).select(db.sequence_file.ALL)
54
        for row in query :
55
            if row.filename == request.vars['filename'] :
56
                return error_message("this sequence file already exists for this patient")
57
            
58 59
        id = db.sequence_file.insert(sampling_date=request.vars['sampling_date'],
                            info=request.vars['file_info'],
60 61 62
                            pcr=request.vars['pcr'],
                            sequencer=request.vars['sequencer'],
                            producer=request.vars['producer'],
63
                            patient_id=request.vars['patient_id'],
64 65
                            filename=request.vars['filename'],
                            provider=auth.user_id)
66 67 68 69 70
        
        id_sample_set = db.sample_set.insert(sample_type="sequence_file")
        
        id_sample_set_membership = db.sample_set_membership.insert(sample_set_id=id_sample_set,
                                                                  sequence_file_id=id)
71 72
        id_sample_set_membership_patient = db.sample_set_membership.insert(sample_set_id=db.patient[request.vars['patient_id']].sample_set_id,
                                                                  sequence_file_id=id)
Marc Duez's avatar
Marc Duez committed
73
    
74
        res = {"file_id" : id,
75
               "message": "file %s (%s): upload started: %s" % (id, request.vars['patient_id'], request.vars['filename']),
76 77 78
               "redirect": "patient/info",
               "args" : {"id" : request.vars['patient_id']}
               }
79 80
        log.info(res)

Marc Duez's avatar
Marc Duez committed
81 82 83
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
        
    else :
84
        return error_message(error)
85 86 87


def edit(): 
88
    if auth.can_modify_patient(request.vars['patient_id']):
89
        return dict(message=T('edit file'))
90
    #elif not auth.can_upload_file(request.vars['id']):
91 92 93
    #    res = {"success" : "false", "message" : "you don't have right to upload files"}
    #    return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
    else:
94
        return error_message("you need admin permission to edit files")
95
        
96 97 98 99


#TODO check data
def edit_form(): 
Marc Duez's avatar
Marc Duez committed
100
    error = ""
101 102 103
    
    if request.vars['id'] == None :
        error += "missing id"
104 105
    if request.vars['filename'] == None :
        error += " missing filename"
106 107 108 109 110
    if request.vars['sampling_date'] != '' :
        try:
            datetime.datetime.strptime(""+request.vars['sampling_date'], '%Y-%m-%d')
        except ValueError:
            error += "date (wrong format), "
111
            
Marc Duez's avatar
Marc Duez committed
112
    if error=="" :
113
        mes = "file " + str(request.vars['id']) + " : "
Marc Duez's avatar
Marc Duez committed
114 115 116
        filename = db.sequence_file[request.vars['id']].filename
        if request.vars['filename'] != "":
            filename = request.vars['filename']
117 118 119 120 121
        if request.vars['sampling_date'] != None and request.vars['file_info'] != None :
            db.sequence_file[request.vars["id"]] = dict(sampling_date=request.vars['sampling_date'],
                                                        info=request.vars['file_info'],
                                                        pcr=request.vars['pcr'],
                                                        sequencer=request.vars['sequencer'],
Marc Duez's avatar
Marc Duez committed
122
                                                        producer=request.vars['producer'],
123 124
                                                        filename=filename,
                                                        provider=auth.user_id)
125
            
126 127
        patient_id = db((db.sequence_file.id == request.vars["id"])
                        &(db.sample_set_membership.sequence_file_id == db.sequence_file.id)
128
                        &(db.patient.sample_set_id == db.sample_set_membership.sample_set_id)
129
                        ).select(db.patient.id).first().id
130 131 132 133
        
        res = {"file_id" : request.vars['id'],
               "redirect": "patient/info",
               "args" : { "id" : patient_id},
134
               "message": "file %s: metadata saved" % request.vars["id"]}
135
        log.info(res)
Marc Duez's avatar
Marc Duez committed
136 137
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

138
def upload(): 
Marc Duez's avatar
Marc Duez committed
139
    session.forget(response)
140
    mes = ""
141
    error = ""
142

143 144
    if request.vars['id'] == None :
        error += "missing id"
145 146
    elif db.sequence_file[request.vars["id"]] is None:
        error += "no sequence file with this id"
147

148
    if not error:
149 150
        patient_id = db((db.sequence_file.id == request.vars["id"])
                        &(db.sample_set_membership.sequence_file_id == db.sequence_file.id)
151
                        &(db.patient.sample_set_id == db.sample_set_membership.sample_set_id)
152
                        ).select(db.patient.id).first()
Mikaël Salson's avatar
Mikaël Salson committed
153
        mes += " file %s (patient %s) " % (db.sequence_file[request.vars['id']].filename, patient_id['id'])
154
        res = {"message": mes + "processing uploaded file",
Mikaël Salson's avatar
Mikaël Salson committed
155 156 157
               "redirect": "patient/info",
               "args" : {"id" : request.vars['id']}
               }
158
        log.debug(res)
159
        if request.vars.file != None :
Marc Duez's avatar
Marc Duez committed
160
            f = request.vars.file
161 162 163 164 165
            try:
                db.sequence_file[request.vars["id"]] = dict(data_file = db.sequence_file.data_file.store(f.file, f.filename))
                mes += "upload finished"
            except IOError as e:
                if str(e).find("File name too long") > -1:
Mikaël Salson's avatar
Mikaël Salson committed
166
                    error += 'Your filename is too long, please shorten it.'
167
                else:
Mikaël Salson's avatar
Mikaël Salson committed
168
                    error += "System error during processing of uploaded file."
169
                    log.error(str(e))
170
        
171 172
        data_file = db.sequence_file[request.vars["id"]].data_file

Mikaël Salson's avatar
Mikaël Salson committed
173
        if len(error) == 0 and data_file is None:
174 175 176 177 178 179
            error += "no data file"

    if not error:
        seq_file = defs.DIR_SEQUENCES + data_file

        # Compute and store file size
180
        size = os.path.getsize(seq_file)
181
        mes += ' (%s)' % vidjil_utils.format_size(size)
Marc Duez's avatar
Marc Duez committed
182
        db.sequence_file[request.vars["id"]] = dict(size_file = size)
183 184

    # Log and exit
Mikaël Salson's avatar
Mikaël Salson committed
185
    res = {"message": error + mes}
186
    if error:
Mikaël Salson's avatar
Mikaël Salson committed
187
        res['success'] = 'false'
188
        res['priority'] = 3
189 190
        log.error(res)
    else:
Mathieu Giraud's avatar
Mathieu Giraud committed
191
        log.info(res)
192
    return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
Marc Duez's avatar
Marc Duez committed
193
  
194

195
def confirm():
196 197 198 199 200 201
    '''
    Request parameters:
    \param delete_results: (optional) boolean
    \param id: sequence file ID
    \param patient_id: patient id
    '''
202 203 204 205
    delete_only_sequence = ('delete_only_sequence' in request.vars and request.vars['delete_only_sequence'] == 'True')
    delete_results = ('delete_results' in request.vars and request.vars['delete_results'] == 'True')
    sequence_file = db.sequence_file[request.vars['id']]
    if sequence_file == None:
206
        return error_message("The requested file doesn't exist")
207 208
    if sequence_file.data_file == None:
        delete_results = True
209
    if auth.can_modify_patient(request.vars['patient_id']):
210 211 212
        return dict(message=T('choose what you would like to delete'),
                    delete_only_sequence = delete_only_sequence,
                    delete_results = delete_results)
213
    else:
214
        return error_message("you need admin permission to delete this file")
215

216 217 218
def delete_sequence_file(seq_id):
    sequence = db.sequence_file[seq_id]
    seq_filename = sequence.data_file
219 220 221 222
    patient_id = db((db.sample_set_membership.sequence_file_id == seq_id)
                    &(db.patient.sample_set_id == db.sample_set_membership.sample_set_id)
                    ).select(db.patient.id).first().id
    if auth.can_modify_patient(patient_id):
223 224
        if seq_filename is not None:
            log.debug('Deleting '+defs.DIR_SEQUENCES+seq_filename+' with ID'+str(seq_id))
225 226 227 228
        db.sequence_file[seq_id] = dict(data_file = None)
    else:
        return error_message('you need admin permission to delete this file')

229
def delete():
230 231 232 233 234 235
    '''
    Called (via request) with:
    \param: id (the sequence ID)
    \param: patient_id
    \param: delete_results: (optional) boolean stating if we also want to delete the results.
    '''
236
    patient_id = request.vars["patient_id"]
237 238
    delete_results = ('delete_results' in request.vars and request.vars['delete_results'] == 'True')

239
    if auth.can_modify_patient(patient_id):
240 241 242 243 244
        if not(delete_results):
            delete_sequence_file(request.vars['id'])
        else:
            db(db.sequence_file.id == request.vars["id"]).delete()
            db(db.results_file.sequence_file_id == request.vars["id"]).delete()
245 246 247

        res = {"redirect": "patient/info",
               "args" : { "id" : patient_id},
248
               "message": "file %s (%s): sequence file deleted" % (request.vars["id"], patient_id)}
249
        log.info(res)
250 251
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
    else:
252
        return error_message("you need admin permission to delete this file")
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

def sequencer_list():
    sequencer_list = []
    for row in db(db.sequence_file.sequencer != None).select(db.sequence_file.sequencer, distinct=True):
        if row.sequencer is not "null" :
            sequencer_list.append(row.sequencer)
            
    res = {"sequencer": sequencer_list}
    return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

def pcr_list():
    pcr_list = []
    for row in db(db.sequence_file.pcr != None).select(db.sequence_file.pcr, distinct=True):
        if row.pcr is not "null" :
            pcr_list.append(row.pcr)
            
    res = {"pcr": pcr_list}
    return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

def producer_list():
    producer_list = []
    for row in db(db.sequence_file.producer != None).select(db.sequence_file.producer, distinct=True):
        if row.producer is not "null" :
            producer_list.append(row.producer)
            
    res = {"producer": producer_list}
    return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298

def save_info():
    sequence_file_id = request.vars["id"]
    row = db.sequence_file[sequence_file_id]
    if row is not None:
        if auth.can_modify_patient(row.patient_id):
            row = dict(info = request.vars["info"])

            res = {"success": True,
                   "message": "The changes have been saved"}
        else:
            res = {"success": False,
                   "message": "You do not have permission to do that"}
    else:
        res = {"success": False,
               "message": "An error occured"}
    return gluon.contrib.simplejson.dumps(res, separators=(',', ':'))