patient.py 15.2 KB
Newer Older
Marc Duez's avatar
Marc Duez committed
1
# coding: utf8
2 3 4 5 6 7
import gluon.contrib.simplejson, datetime
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

8 9
ACCESS_DENIED = "access denied"

10 11
## return patient file list
##
Marc Duez's avatar
Marc Duez committed
12
def info():
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    

    patient = db.patient[request.vars["id"]]

    if request.vars["config_id"] and request.vars["config_id"] != "-1" :
        config_id = long(request.vars["config_id"])
        patient_name = patient.first_name + " " + patient.last_name
        config_name = db.config[request.vars["config_id"]].name

        fused = db(
            (db.fused_file.patient_id == patient)
            & (db.fused_file.config_id == config_id)
        )

        analysis = db(
            (db.analysis_file.patient_id == patient)
            & (db.analysis_file.config_id == config_id)
        )
        
        
        config = True
        fused_count = fused.count()
        fused_file = fused.select()
        fused_filename = patient_name +"_"+ config_name + ".data"
        analysis_count = analysis.count()
        analysis_file = analysis.select()
        analysis_filename = patient_name +"_"+ config_name + ".analysis"
        
    else:
        config_id = -1
        config = False
        fused_count = 0
        fused_file = ""
        fused_filename = ""
        analysis_count = 0
        analysis_file = ""
        analysis_filename = ""



    if config :

        query = db(
                (db.sequence_file.patient_id==db.patient.id)
                & (db.patient.id==request.vars["id"])
            ).select(
                left=db.results_file.on(
                    (db.results_file.sequence_file_id==db.sequence_file.id)
                    & (db.results_file.config_id==str(config_id) )
                ), 
                orderby = db.sequence_file.id|db.results_file.run_date,
                groupby = db.sequence_file.id,
            )

    else:

        query = db(
                (db.sequence_file.patient_id==db.patient.id)
                & (db.patient.id==request.vars["id"])
            ).select(
                left=db.results_file.on(
                    (db.results_file.sequence_file_id==db.sequence_file.id)
                    & (db.results_file.config_id==str(config_id) )
                )
            )


    
81
    log.debug('patient (%s)' % request.vars["id"])
82
    if (auth.has_permission('read', 'patient', request.vars["id"]) ):
83 84 85 86 87 88 89 90 91 92 93 94
        return dict(query=query,
                    patient=patient,
                    config_id=config_id,
                    fused_count=fused_count,
                    fused_file=fused_file,
                    fused_filename=fused_filename,
                    analysis_count=analysis_count,
                    analysis_file = analysis_file,
                    analysis_filename = analysis_filename,
                    config=config)
    
    
95
    else :
96
        res = {"message": ACCESS_DENIED}
97
        log.error(res)
98 99
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

Marc Duez's avatar
Marc Duez committed
100

101 102

## return patient list
Marc Duez's avatar
Marc Duez committed
103
def index():
104
    if not auth.user : 
105 106 107 108
        res = {"redirect" : URL('default', 'user', args='login', scheme=True, host=True,
                            vars=dict(_next=URL('patient', 'index', scheme=True, host=True)))
            }
        
109
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
110
    log.debug('patient list')
111

112 113 114
    count = db.sequence_file.id.count()
    isAdmin = auth.has_membership("admin")
    
115
    ##retrieve patient list 
116 117 118 119 120 121 122 123 124
    query = db(
        (auth.accessible_query('read', db.patient) | auth.accessible_query('admin', db.patient) ) 
    ).select(
        db.patient.ALL,
        count,
        left=db.sequence_file.on(db.patient.id == db.sequence_file.patient_id),
        groupby=db.patient.id
    )
    
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    for row in query :
        
        ##add confs info for each patient
        row.confs=""
        co = db.fused_file.id.count()
        query_conf = db( db.fused_file.patient_id == row.patient.id ).select(db.fused_file.config_id, co, groupby=db.fused_file.config_id).sort(lambda row: co)
        
        for row2 in query_conf:
            row.confs += " " + db.config[row2.fused_file.config_id].name
        
        row.most_used_conf = -1
        if len(query_conf) > 0 :
            row.most_used_conf = query_conf[0].fused_file.config_id

        ##add groups info for each patient
        row.groups=""
        for row3 in db( 
           (db.auth_permission.name == "read") &
           (db.auth_permission.table_name == "patient") &
           (db.auth_permission.record_id == row.patient.id)
          ).select( orderby=db.auth_permission.group_id, distinct=True )  :
            if db.auth_permission[row3.id].group_id > 2:
                row.groups += " " + str(db.auth_permission[row3.id].group_id)
148
                
149 150 151 152 153
        row.size = 0
        query_size = db( db.sequence_file.patient_id == row.patient.id ).select()
        
        for row4 in query_size:
            row.size += row4.size_file
154 155 156 157 158 159 160 161 162 163 164
    
    ##sort result
    if request.vars["sort"] == "configs" :
        query = query.sort(lambda row : row.confs)
    elif request.vars["sort"] == "groups" :
        query = query.sort(lambda row : row.groups)
    elif request.vars["sort"] == "files" :
        query = query.sort(lambda row : row[count])
    elif "sort" in request.vars:
        query = query.sort(lambda row : row.patient[request.vars["sort"]])
    
165 166 167 168 169 170 171 172
    ##filter
    if "filter" in request.vars and request.vars["filter"] != "":
        for row in query :
            row.string = (row.confs+row.groups+row.patient.last_name+row.patient.first_name+str(row.patient.birth)).lower()
        query = query.find(lambda row : row.string.find(request.vars["filter"].lower()) != -1)
    else :
        request.vars["filter"] = ""
        
173
    return dict(query = query,
174 175
                count = count,
                isAdmin = isAdmin)
Marc Duez's avatar
Marc Duez committed
176

177

178

179
## return form to create new patient
Marc Duez's avatar
Marc Duez committed
180
def add(): 
181 182 183
    if (auth.has_permission('create', 'patient') ):
        return dict(message=T('add patient'))
    else :
184 185
        res = {"message": ACCESS_DENIED}
        log.error(res)
186 187 188
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


Marc Duez's avatar
Marc Duez committed
189

190 191 192 193
## create a patient if the html form is complete
## need ["first_name", "last_name", "birth_date", "info"]
## redirect to patient list if success
## return a flash error message if fail
Marc Duez's avatar
Marc Duez committed
194
def add_form(): 
195
    if (auth.has_permission('create', 'patient') ):
Marc Duez's avatar
Marc Duez committed
196 197 198 199 200 201
        
        error = ""
        if request.vars["first_name"] == "" :
            error += "first name needed, "
        if request.vars["last_name"] == "" :
            error += "last name needed, "
Marc Duez's avatar
Marc Duez committed
202 203 204 205
        try:
            datetime.datetime.strptime(""+request.vars['birth'], '%Y-%m-%d')
        except ValueError:
            error += "date missing or wrong format"
206

Marc Duez's avatar
Marc Duez committed
207 208 209 210
        if error=="" :
            id = db.patient.insert(first_name=request.vars["first_name"],
                                   last_name=request.vars["last_name"],
                                   birth=request.vars["birth"],
211
                                   info=request.vars["info"],
212 213
                                   id_label=request.vars["id_label"],
                                   creator=auth.user_id)
214 215


216 217
            user_group = auth.user_group(auth.user.id)
            admin_group = db(db.auth_group.role=='admin').select().first().id
218
            
219
            #patient creator automaticaly has all rights 
220
            auth.add_permission(user_group, 'admin', db.patient, id)
221
            auth.add_permission(user_group, 'read', db.patient, id)
222
            auth.add_permission(user_group, 'anon', db.patient, id)
223 224 225 226 227 228
            
            #tmp: share rights with users of the same group
            for g in auth.user_groups :
                auth.add_permission(g, 'admin', db.patient, id)
                auth.add_permission(g, 'read', db.patient, id)
            
229

230 231
            patient_name = request.vars["first_name"] + ' ' + request.vars["last_name"]

232 233
            res = {"redirect": "patient/info",
                   "args" : { "id" : id },
234
                   "message": patient_name + ": patient added"}
235
            log.info(res)
Marc Duez's avatar
Marc Duez committed
236
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
237

Marc Duez's avatar
Marc Duez committed
238
        else :
239 240
            res = {"success" : "false",
                   "message" : error}
241
            log.error(res)
Marc Duez's avatar
Marc Duez committed
242 243
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
        
244
    else :
245 246
        res = {"message": ACCESS_DENIED}
        log.error(res)
247 248 249
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


250

251
## return edit form 
252
def edit(): 
253 254 255
    if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
        return dict(message=T('edit patient'))
    else :
256 257
        res = {"message": ACCESS_DENIED}
        log.error(res)
258 259 260
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


261

262 263 264 265
## check edit form
## need ["first_name", "last_name", "birth_date", "info"]
## redirect to patient list if success
## return a flash error message if fail
266
def edit_form(): 
267
    if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
268 269 270 271 272
        error = ""
        if request.vars["first_name"] == "" :
            error += "first name needed, "
        if request.vars["last_name"] == "" :
            error += "last name needed, "
Marc Duez's avatar
Marc Duez committed
273 274 275 276
        try:
            datetime.datetime.strptime(""+request.vars['birth'], '%Y-%m-%d')
        except ValueError:
            error += "date missing or wrong format"
277 278
        if request.vars["id"] == "" :
            error += "patient id needed, "
279

280 281 282 283
        if error=="" :
            db.patient[request.vars["id"]] = dict(first_name=request.vars["first_name"],
                                                   last_name=request.vars["last_name"],
                                                   birth=request.vars["birth"],
284 285
                                                   info=request.vars["info"],
                                                   id_label=request.vars["id_label"]
286
                                                   )
287

288
            res = {"redirect": "back",
289 290
                   "message": "patient %s %s edited" % (request.vars["first_name"], request.vars["last_name"])}
            log.info(res)
291
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
292

293
        else :
294
            res = {"success" : "false", "message" : error}
295
            log.error(res)
296
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
297
    else :
298 299
        res = {"message": ACCESS_DENIED}
        log.error(res)
300 301 302
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


303
def download():
304
        return response.download(request, db)
305

306 307

#
308
def confirm():
309
    if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
310
        log.debug('request patient deletion')
311 312
        return dict(message=T('confirm patient deletion'))
    else :
313 314
        res = {"message": ACCESS_DENIED}
        log.error(res)
315
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
316

317 318

#
319
def delete():
320 321 322 323 324
    if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
        import shutil, os.path
        #delete data file 
        query = db( (db.sequence_file.patient_id==request.vars["id"])).select() 
        for row in query :
325
            db(db.results_file.sequence_file_id == row.id).delete()
326 327 328 329 330 331 332 333 334 335

        #delete sequence file
        db(db.sequence_file.patient_id == request.vars["id"]).delete()

        #delete patient
        db(db.patient.id == request.vars["id"]).delete()

        res = {"redirect": "patient/index",
               "success": "true",
               "message": "patient ("+request.vars["id"]+") deleted"}
336
        log.info(res)
337 338
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
    else :
339
        res = {"message": ACCESS_DENIED}
340
        log.error(res)
341
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
342

343
    
344
#
345
def permission(): 
346
    if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
        
        query = db( db.auth_group.role != 'admin' ).select()
        
        for row in query :
            row.owner = row.role
            if row.owner[:5] == "user_" :
                id = int(row.owner[5:])
                row.owner = db.auth_user[id].first_name + " " + db.auth_user[id].last_name 

            row.admin = False
            if db(   (db.auth_permission.name == "admin")
                  & (db.auth_permission.record_id == request.vars["id"])
                  & (db.auth_permission.group_id == row.id)
                  & (db.auth_permission.table_name == db.patient)
              ).count() > 0 :
                row.admin = True
                
            row.anon = False
            if db(   (db.auth_permission.name == "anon")
                  & (db.auth_permission.record_id == request.vars["id"])
                  & (db.auth_permission.group_id == row.id)
                  & (db.auth_permission.table_name == db.patient)
              ).count() > 0 :
                row.anon = True
                
            row.read = False
            if db(   (db.auth_permission.name == "read")
                  & (db.auth_permission.record_id == request.vars["id"])
                  & (db.auth_permission.group_id == row.id)
                  & (db.auth_permission.table_name == db.patient)
              ).count() > 0 :
                row.read = True
        
        return dict(query=query)
381
    else :
382 383
        res = {"message": ACCESS_DENIED}
        log.error(res)
384 385
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

386

387
#
388
def change_permission():
Marc Duez's avatar
Marc Duez committed
389
    if (auth.has_permission('admin', 'patient', request.vars["patient_id"]) ):
390 391 392 393 394
        error = ""
        if request.vars["group_id"] == "" :
            error += "missing group_id, "
        if request.vars["patient_id"] == "" :
            error += "missing patient_id, "
395 396
        if request.vars["permission"] == "" :
            error += "missing permission, "
397 398

        if error=="":
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
            if db(   (db.auth_permission.name == request.vars["permission"])
                      & (db.auth_permission.record_id == request.vars["patient_id"])
                      & (db.auth_permission.group_id == request.vars["group_id"])
                      & (db.auth_permission.table_name == db.patient)
                  ).count() > 0 :
                auth.del_permission(request.vars["group_id"], request.vars["permission"], db.patient, request.vars["patient_id"])
                res = {"message" : "access '%s' deleted to '%s'" % (request.vars["permission"], db.auth_group[request.vars["group_id"]].role)}
            else :
                auth.add_permission(request.vars["group_id"], request.vars["permission"], db.patient, request.vars["patient_id"])
                res = {"message" : "access '%s' granted to '%s'" % (request.vars["permission"], db.auth_group[request.vars["group_id"]].role)}
            
            log.info(res)
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
        else :
            res = {"message": "incomplete request : "+error }
            log.error(res)
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
416
    else :
417 418
        res = {"message": ACCESS_DENIED}
        log.error(res)
419
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))