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

9
10
ACCESS_DENIED = "access denied"

11
12
## return patient file list
##
Marc Duez's avatar
Marc Duez committed
13
def info():
14
15
16

    if 'next' in request.vars:
        try:
17
18
19
20
21
22
23
24
            current_id = request.vars["id"]
            go_next = int(request.vars['next'])
            if go_next > 0:
                res = db(db.patient.id > current_id).select(db.patient.id, orderby=db.patient.id, limitby=(0,1))
            else:
                res = db(db.patient.id < current_id).select(db.patient.id, orderby=~db.patient.id, limitby=(0,1))
            if (len(res) > 0):
                request.vars["id"] = str(res[0].id)
25
26
        except:
            pass
27
28
29
30
31

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

    if request.vars["config_id"] and request.vars["config_id"] != "-1" :
        config_id = long(request.vars["config_id"])
32
        patient_name = vidjil_utils.anon_names(patient.id, patient.first_name, patient.last_name)
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
        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 :
65
66
67
	query =[]
	
        query2 = db(
68
69
70
71
72
73
74
                (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) )
                ), 
75
                orderby = db.sequence_file.id|~db.results_file.run_date
76
            )
77
78
79
80
81
	previous=-1
	for row in query2 :
	    if row.sequence_file.id != previous : 
		query.append(row)
		previous=row.sequence_file.id
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

    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) )
                )
            )


    
97
    log.debug('patient (%s)' % request.vars["id"])
98
    if (auth.can_view_patient(request.vars["id"]) ):
99
100
        return dict(query=query,
                    patient=patient,
101
                    birth=vidjil_utils.anon_birth(request.vars["id"], auth.user.id),
102
103
104
105
106
107
108
109
110
111
                    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)
    
    
112
    else :
113
        res = {"message": ACCESS_DENIED}
114
        log.error(res)
115
116
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

Marc Duez's avatar
Marc Duez committed
117

118
119
120
121
122
123
124
def custom():
    if request.vars["config_id"] and request.vars["config_id"] != "-1" :
        config_id = long(request.vars["config_id"])
        config_name = db.config[request.vars["config_id"]].name
        config = True
        
    else:
125
        request.vars["config_id"] = -1
126
        config_id = -1
127
        config_name = None
128
        config = False
129
130
131
132
133
134
        
    if "custom_list" not in request.vars :
        request.vars["custom_list"] = []
    if type(request.vars["custom_list"]) is str :
        request.vars["custom_list"] = [request.vars["custom_list"]]
        
135

136
137
    q = ((auth.accessible_query('read', db.patient)) 
                & (auth.accessible_query('read', db.config)) 
138
139
                & (db.sequence_file.patient_id==db.patient.id)
                & (db.results_file.sequence_file_id==db.sequence_file.id)
140
                & (db.results_file.data_file != '')
141
                & (db.config.id==db.results_file.config_id)
142
143
            )

144
    query = db(q).select(
145
                db.patient.id, db.patient.info, db.patient.first_name, db.patient.last_name, db.results_file.id, db.results_file.config_id, db.sequence_file.sampling_date,
146
                db.sequence_file.pcr, db.config.name, db.results_file.run_date, db.results_file.data_file, db.sequence_file.filename,
147
148
                db.sequence_file.patient_id, db.sequence_file.data_file, db.sequence_file.id, db.sequence_file.info,
                db.sequence_file.size_file,
149
150
151
                orderby = ~db.sequence_file.patient_id|db.sequence_file.id|db.results_file.run_date,
                groupby = db.sequence_file.id|db.results_file.config_id,
            )
152

153
154
155
156
157
158
159
160
    ##filter
    if "filter" not in request.vars :
        request.vars["filter"] = ""
        
    for row in query :
        row.checked = False
        if (str(row.results_file.id) in request.vars["custom_list"]) :
            row.checked = True
161
162
163

        row.names = vidjil_utils.anon_names(row.patient.id, row.patient.first_name, row.patient.last_name)
        row.string = (row.names + row.sequence_file.filename +
Marc Duez's avatar
Marc Duez committed
164
                      str(row.sequence_file.sampling_date) + str(row.sequence_file.pcr) + str(row.config.name) + str(row.results_file.run_date)).lower()
165
166
167
    query = query.find(lambda row : ( vidjil_utils.filter(row.string,request.vars["filter"]) or row.checked) )
    
    if config :
Marc Duez's avatar
Marc Duez committed
168
        query = query.find(lambda row : ( row.results_file.config_id==config_id or (str(row.results_file.id) in request.vars["custom_list"])) )
169
    
170
171
    res = {"message": "custom list (%s)" % config_name}
    log.debug(res)
172

173
174
175
176
    return dict(query=query,
                config_id=config_id,
                config=config)
    
177

178
STATS_READLINES = 1000 # approx. size in which the stats are searched
179
180

def stats():
181
182
183
    import time
    start = time.time()

184
185
186
    d = custom()

    stats_regex = [
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        # found 771265 40-windows in 2620561 segments (85.4%) inside 3068713 sequences
        'in (?P<seg>\d+) segments \((?P<seg_ratio>.*?)\) inside (?P<reads>\d+) sequences',

        # locus
        'log.* TRG.*?->\s*?(?P<TRG_reads>\d+)\s+(?P<TRG_av_len>[0-9.]+)\s+(?P<TRG_clones>\d+)\s+(?P<TRG_av_reads>[0-9.]+)\s*.n',
        'log.* IGH.*?->\s*?(?P<IGH_reads>\d+)\s+(?P<IGH_av_len>[0-9.]+)\s+(?P<IGH_clones>\d+)\s+(?P<IGH_av_reads>[0-9.]+)\s*.n',

        # segmentation causes
        'log.* SEG_[+].*?-> (?P<SEG_plus>.*?).n',
        'log.* SEG_[-].*?-> (?P<SEG_minus>.*?).n',

        # main clone
        '"name".*"(?P<main_clone>.*)"',
        '"reads" :  [[] (?P<main_clone_reads>\d+) ',
201
202
    ]

203
204
205
206
207
    json_paths = {'reads distribution [>= 10%]': 'reads/distribution/0.1',
                  'reads distribution [>= 1% < 10%]': 'reads/distribution/0.01',
                  'reads distribution [>= .01% < 1%]': 'reads/distribution/0.001',
                  'reads distribution [>= .001% < .01%]': 'reads/distribution/0.0001',
                  'reads distribution [>= .0001% < .001%]': 'reads/distribution/0.00001',
208
209
210
                  'producer': 'samples/producer',
    }

211
212
    keys_patient = [ 'info' ]

213
    keys = []
214
215
    keys += keys_patient

216
217
218
219
220
221
    regex = []
    for sr in stats_regex:
        r = re.compile(sr)
        regex += [r]
        keys += r.groupindex.keys()

222
    keys += sorted(json_paths.keys())
223
    found = {}
224
225

    for row in d['query']:
226
227
        results_f = row.results_file.data_file
        row_result = vidjil_utils.search_first_regex_in_file(regex, defs.DIR_RESULTS + results_f, STATS_READLINES)
228

229
230
231
232
233
234
235
        fused_file = db((db.fused_file.sequence_file_list.contains('%d_' % row.sequence_file.id)) & (db.fused_file.config_id == row.results_file.config_id)).select(orderby = ~db.fused_file.id, limitby=(0,1))
        if len(fused_file) > 0:
            index_of_id = fused_file[0].sequence_file_list.find('%d_' % row.sequence_file.id)
            pos_in_list = fused_file[0].sequence_file_list.count('_', 0, index_of_id)
            row_fused = vidjil_utils.extract_fields_from_json(json_paths, pos_in_list, defs.DIR_RESULTS + fused_file[0].fused_file)
        else:
            row_fused = {}
236
        for key in keys:
237
238
            if key in row_result:
                row[key] = row_result[key]
239
                found[key] = True
240
241
            elif key in row_fused:
                row[key] = row_fused[key]
242
                found[key] = True
243
244
245
            elif key in keys_patient:
                row[key] = row.patient.info # todo, should not be hardcoded
                found[key] = True
246
247
            else:
                row[key] = ''
248

249
250
251
    # Re-process some data
    keys += ['IGH_av_clones']
    for row in d['query']:
252
        row['IGH_av_clones'] = ''
253
254
255
256
257
258
259
        if 'IGH_av_reads' in row:
            try:
                row['IGH_av_clones'] = '%.4f' % (1.0 / float(row['IGH_av_reads']))
                found['IGH_av_clones'] = True
            except:
                pass

260
261
262
263
264
265
    # Keep only non-empty columns
    d['stats'] = []
    for key in keys:
        if key in found:
            d['stats'] += [key]

266
    log.debug("patient/stats (%.3fs) %s" % (time.time()-start, request.vars["filter"]))
267
268
    return d

269
## return patient list
Marc Duez's avatar
Marc Duez committed
270
def index():
Marc Duez's avatar
Marc Duez committed
271
272
273
    import time
    
    start = time.time()
274
    if not auth.user : 
275
276
277
278
        res = {"redirect" : URL('default', 'user', args='login', scheme=True, host=True,
                            vars=dict(_next=URL('patient', 'index', scheme=True, host=True)))
            }
        
279
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
Marc Duez's avatar
Marc Duez committed
280
    
281
    isAdmin = auth.is_admin()
282
    
283
    ##retrieve patient list 
284
    query = db(
Marc Duez's avatar
Marc Duez committed
285
286
287
288
289
290
291
292
293
294
295
296
297
        auth.accessible_query('read', db.patient)
    ).select(
        db.patient.ALL,
        orderby = ~db.patient.id
    )
    result = {}
    
    for i, row in enumerate(query) :
        result[row.id] = {
            "id" :int(row.id),
            "last_name" : row.last_name,
            "first_name" : row.first_name,
            "has_permission" : False,
298
            "anon_allowed": False,
Marc Duez's avatar
Marc Duez committed
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
            "birth" : row.birth,
            "info" : row.info,
            "creator" : row.creator,
            "confs" : "",
            "conf_list" : [],
            "conf_id_list" : [-1],
            "most_used_conf" : "",
            "groups" : "",
            "group_list" : [],
            "file_count" : 0,
            "size" : 0
        }
        
    keys = result.keys() 
    
    query = db(
        (db.auth_permission.name == "admin") & 
        (db.auth_permission.table_name == "patient") &
        (db.patient.id == db.auth_permission.record_id ) &
        (auth.user_group() == db.auth_permission.group_id )
319
    ).select(
Marc Duez's avatar
Marc Duez committed
320
        db.patient.ALL, db.auth_permission.ALL
321
    )
322

Marc Duez's avatar
Marc Duez committed
323
324
325
326
    for i, row in enumerate(query) :
        if row.patient.id in keys :
            result[row.patient.id]['has_permission'] = True
            
Vidjil Team's avatar
Vidjil Team committed
327
    query1 = db(
Marc Duez's avatar
Marc Duez committed
328
329
        db.patient.creator == db.auth_user.id
    ).select(
Vidjil Team's avatar
Vidjil Team committed
330
        db.patient.id, db.auth_user.last_name
Marc Duez's avatar
Marc Duez committed
331
    )
Vidjil Team's avatar
Vidjil Team committed
332
    for i, row in enumerate(query1) :
Marc Duez's avatar
Marc Duez committed
333
334
        if row.patient.id in keys :
            result[row.patient.id]['creator'] = row.auth_user.last_name
Vidjil Team's avatar
Vidjil Team committed
335
336
       
    query2 = db(
Marc Duez's avatar
Marc Duez committed
337
338
        db.patient.id == db.sequence_file.patient_id
    ).select(
Vidjil Team's avatar
Vidjil Team committed
339
        db.patient.id, db.sequence_file.size_file
Marc Duez's avatar
Marc Duez committed
340
    )
Vidjil Team's avatar
Vidjil Team committed
341
    for i, row in enumerate(query2) :
Marc Duez's avatar
Marc Duez committed
342
343
344
345
        if row.patient.id in keys :
            result[row.patient.id]['file_count'] += 1
            result[row.patient.id]['size'] += row.sequence_file.size_file
    
Vidjil Team's avatar
Vidjil Team committed
346
    query3 = db(
Marc Duez's avatar
Marc Duez committed
347
348
349
        (db.patient.id == db.fused_file.patient_id) &
        (db.fused_file.config_id == db.config.id)
    ).select(
Vidjil Team's avatar
Vidjil Team committed
350
        db.patient.id, db.config.name, db.config.id
Marc Duez's avatar
Marc Duez committed
351
    )
Vidjil Team's avatar
Vidjil Team committed
352
    for i, row in enumerate(query3) :
Marc Duez's avatar
Marc Duez committed
353
354
355
        if row.patient.id in keys :
            result[row.patient.id]['conf_list'].append(row.config.name)
            result[row.patient.id]['conf_id_list'].append(row.config.id)
Vidjil Team's avatar
Vidjil Team committed
356
357
    
    query4 = db(
Marc Duez's avatar
Marc Duez committed
358
359
360
361
362
        ((db.patient.id == db.auth_permission.record_id) | (db.auth_permission.record_id == 0)) &
        (db.auth_permission.table_name == 'patient') &
        (db.auth_permission.name == 'read') &
        (db.auth_group.id == db.auth_permission.group_id)
    ).select(
Vidjil Team's avatar
Vidjil Team committed
363
        db.patient.id, db.auth_group.role
Marc Duez's avatar
Marc Duez committed
364
    )
Vidjil Team's avatar
Vidjil Team committed
365
    for i, row in enumerate(query4) :
Marc Duez's avatar
Marc Duez committed
366
        if row.patient.id in keys :
367
            result[row.patient.id]['group_list'].append(row.auth_group.role.replace('user_','u'))
368

Vidjil Team's avatar
Vidjil Team committed
369
    query5 = db(
370
        (db.auth_permission.name == "anon") &
Marc Duez's avatar
Marc Duez committed
371
372
        (db.auth_permission.table_name == "patient") &
        (db.patient.id == db.auth_permission.record_id ) &
373
374
375
        (db.auth_group.id == db.auth_permission.group_id ) &
        (db.auth_membership.user_id == auth.user_id) &
        (db.auth_membership.group_id == db.auth_group.id)
Marc Duez's avatar
Marc Duez committed
376
    ).select(
377
        db.patient.id
Marc Duez's avatar
Marc Duez committed
378
    )
Vidjil Team's avatar
Vidjil Team committed
379
    for i, row in enumerate(query5) :
Marc Duez's avatar
Marc Duez committed
380
        if row.id in keys :
381
            result[row.id]['anon_allowed'] = True
382
        
Marc Duez's avatar
Marc Duez committed
383
384
    for key, row in result.iteritems():
        row['most_used_conf'] = max(set(row['conf_id_list']), key=row['conf_id_list'].count)
Vidjil Team's avatar
Vidjil Team committed
385
        row['confs'] = ", ".join(list(set(row['conf_list']))) 
386
        row['groups'] = ", ".join(filter(lambda g: g != 'admin', set(row['group_list'])))
Marc Duez's avatar
Marc Duez committed
387
388
389
        
    result = result.values()

390
    ##sort result
391
392
393
    reverse = False
    if request.vars["reverse"] == "true" :
        reverse = True
394
    if request.vars["sort"] == "configs" :
Marc Duez's avatar
Marc Duez committed
395
        result = sorted(result, key = lambda row : row['confs'], reverse=reverse)
396
    elif request.vars["sort"] == "groups" :
Marc Duez's avatar
Marc Duez committed
397
        result = sorted(result, key = lambda row : row['groups'], reverse=reverse)
398
    elif request.vars["sort"] == "files" :
Marc Duez's avatar
Marc Duez committed
399
        result = sorted(result, key = lambda row : row['file_count'], reverse=reverse)
400
    elif "sort" in request.vars:
Marc Duez's avatar
Marc Duez committed
401
        result = sorted(result, key = lambda row : row[request.vars["sort"]], reverse=reverse)
402
403
404
    else:
        result = sorted(result, key = lambda row : row['id'], reverse=not reverse)

405
    ##filter
406
    if "filter" not in request.vars :
407
        request.vars["filter"] = ""
408

Marc Duez's avatar
Marc Duez committed
409
410
411
    for row in result :
        row['string'] = (row['last_name']+row['first_name']+row['confs']+row['groups']+str(row['birth'])).lower()+str(row['info'])
    result = filter(lambda row : vidjil_utils.filter(row['string'],request.vars["filter"]), result )
412
    log.debug("patient list (%.3fs) %s" % (time.time()-start, request.vars["filter"]))
413
    return dict(query = result,
414
                isAdmin = isAdmin,
415
                reverse = reverse)
Marc Duez's avatar
Marc Duez committed
416

417

418

419
## return form to create new patient
Marc Duez's avatar
Marc Duez committed
420
def add(): 
421
    if (auth.can_create_patient()):
422
423
        return dict(message=T('add patient'))
    else :
424
425
        res = {"message": ACCESS_DENIED}
        log.error(res)
426
427
428
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


Marc Duez's avatar
Marc Duez committed
429

430
431
432
433
## 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
434
def add_form(): 
435
    if (auth.can_create_patient()):
Marc Duez's avatar
Marc Duez committed
436
437
438
439
440
441
        
        error = ""
        if request.vars["first_name"] == "" :
            error += "first name needed, "
        if request.vars["last_name"] == "" :
            error += "last name needed, "
442
443
444
445
446
        if request.vars["birth"] != "" :
            try:
                datetime.datetime.strptime(""+request.vars['birth'], '%Y-%m-%d')
            except ValueError:
                error += "date (wrong format)"
447

Marc Duez's avatar
Marc Duez committed
448
449
450
451
        if error=="" :
            id = db.patient.insert(first_name=request.vars["first_name"],
                                   last_name=request.vars["last_name"],
                                   birth=request.vars["birth"],
452
                                   info=request.vars["info"],
453
454
                                   id_label=request.vars["id_label"],
                                   creator=auth.user_id)
455
456


457
458
            user_group = auth.user_group(auth.user.id)
            admin_group = db(db.auth_group.role=='admin').select().first().id
459
            
460
            #patient creator automaticaly has all rights 
461
            auth.add_permission(user_group, 'admin', db.patient, id)
462
            auth.add_permission(user_group, 'read', db.patient, id)
463
            auth.add_permission(user_group, 'anon', db.patient, id)
464
            
465
466
            patient_name = request.vars["first_name"] + ' ' + request.vars["last_name"]

467
468
            res = {"redirect": "patient/info",
                   "args" : { "id" : id },
469
                   "message": patient_name + ": patient added"}
470
            log.info(res)
Marc Duez's avatar
Marc Duez committed
471
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
472

Marc Duez's avatar
Marc Duez committed
473
        else :
474
475
            res = {"success" : "false",
                   "message" : error}
476
            log.error(res)
Marc Duez's avatar
Marc Duez committed
477
478
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
        
479
    else :
480
481
        res = {"message": ACCESS_DENIED}
        log.error(res)
482
483
484
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


485

486
## return edit form 
487
def edit(): 
488
    if (auth.can_modify_patient(request.vars["id"]) ):
489
490
        return dict(message=T('edit patient'))
    else :
491
492
        res = {"message": ACCESS_DENIED}
        log.error(res)
493
494
495
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


496

497
498
499
500
## check edit form
## need ["first_name", "last_name", "birth_date", "info"]
## redirect to patient list if success
## return a flash error message if fail
501
def edit_form(): 
502
    if (auth.can_modify_patient(request.vars["id"]) ):
503
504
505
506
507
        error = ""
        if request.vars["first_name"] == "" :
            error += "first name needed, "
        if request.vars["last_name"] == "" :
            error += "last name needed, "
508
509
510
511
512
        if request.vars["birth"] != "" :
            try:
                datetime.datetime.strptime(""+request.vars['birth'], '%Y-%m-%d')
            except ValueError:
                error += "date (wrong format)"
513
514
        if request.vars["id"] == "" :
            error += "patient id needed, "
515

516
517
518
519
        if error=="" :
            db.patient[request.vars["id"]] = dict(first_name=request.vars["first_name"],
                                                   last_name=request.vars["last_name"],
                                                   birth=request.vars["birth"],
520
521
                                                   info=request.vars["info"],
                                                   id_label=request.vars["id_label"]
522
                                                   )
523

524
            res = {"redirect": "back",
525
                   "message": "%s %s (%s): patient edited" % (request.vars["first_name"], request.vars["last_name"], request.vars["id"])}
526
            log.info(res)
527
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
528

529
        else :
530
            res = {"success" : "false", "message" : error}
531
            log.error(res)
532
            return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
533
    else :
534
535
        res = {"message": ACCESS_DENIED}
        log.error(res)
536
537
538
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))


539
def download():
Marc Duez's avatar
Marc Duez committed
540
    return response.download(request, db)
541

542
543

#
544
def confirm():
545
    if (auth.can_modify_patient(request.vars["id"]) ):
546
        log.debug('request patient deletion')
547
548
        return dict(message=T('confirm patient deletion'))
    else :
549
550
        res = {"message": ACCESS_DENIED}
        log.error(res)
551
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
552

553
554

#
555
def delete():
556
    if (auth.can_modify_patient(request.vars["id"]) ):
557
558
559
560
        import shutil, os.path
        #delete data file 
        query = db( (db.sequence_file.patient_id==request.vars["id"])).select() 
        for row in query :
561
            db(db.results_file.sequence_file_id == row.id).delete()
562
563
564
565
566
567
568
569
570

        #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",
Marc Duez's avatar
Marc Duez committed
571
               "message": "patient ("+str(request.vars["id"])+") deleted"}
572
        log.info(res)
573
574
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
    else :
575
        res = {"message": ACCESS_DENIED}
576
        log.error(res)
577
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
578

579
    
580
#
581
def permission(): 
582
    if (auth.can_modify_patient(request.vars["id"]) ):
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
        
        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)
617
    else :
618
619
        res = {"message": ACCESS_DENIED}
        log.error(res)
620
621
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))

622

623
#
624
def change_permission():
625
    if (auth.can_modify_patient(request.vars["patient_id"]) ):
626
627
628
629
630
        error = ""
        if request.vars["group_id"] == "" :
            error += "missing group_id, "
        if request.vars["patient_id"] == "" :
            error += "missing patient_id, "
631
632
        if request.vars["permission"] == "" :
            error += "missing permission, "
633
634

        if error=="":
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
            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=(',',':'))
652
    else :
653
654
        res = {"message": ACCESS_DENIED}
        log.error(res)
655
        return gluon.contrib.simplejson.dumps(res, separators=(',',':'))