Commit d5af7194 authored by Marc Duez's avatar Marc Duez
parents 31163b5e 7264fb3f
......@@ -51,7 +51,7 @@
<row name="info" null="1" autoincrement="0">
<datatype>VARCHAR</datatype>
<default>NULL</default></row>
<row name="data_file" null="1" autoincrement="0">
<row name="results_file" null="1" autoincrement="0">
<datatype>BLOB</datatype>
<default>NULL</default></row>
<row name="PCR" null="1" autoincrement="0">
......@@ -87,7 +87,7 @@
<part>id</part>
</key>
</table>
<table x="432" y="404" name="data_file">
<table x="432" y="404" name="results_file">
<row name="id" null="1" autoincrement="1">
<datatype>TINYINT</datatype>
<default>NULL</default></row>
......@@ -105,7 +105,7 @@
<row name="status" null="1" autoincrement="0">
<datatype>CHAR</datatype>
<default>NULL</default></row>
<row name="data_file" null="1" autoincrement="0">
<row name="results_file" null="1" autoincrement="0">
<datatype>BLOB</datatype>
<default>NULL</default></row>
<key type="PRIMARY" name="">
......
# coding: utf8
import gluon.contrib.simplejson
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
## return admin_panel
def index():
if auth.has_membership("admin"):
return dict(message=T(''))
def result():
if auth.has_membership("admin"):
return dict(message=T(''))
def run_all():
if auth.has_membership("admin"):
query = db(
(db.data_file.sequence_file_id==db.sequence_file.id)
& (db.data_file.config_id==db.config.id)
).select()
for row in query:
schedule_run(row.sequence_file.id, row.config.id)
res = {"success" : "true",
"message" : "rerun all"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -52,56 +52,9 @@ def run_request():
if not auth.has_permission('admin', 'patient', id_patient) :
error += "you don't have permission to run request for this patient ("+str(id_patient)+"), "
row2 = db( ( db.scheduler_task.args == '["'+request.vars["sequence_file_id"]+'", "'+request.vars["config_id"]+'"]' )
& ( db.scheduler_task.status != "FAILED" )
& ( db.scheduler_task.status != "EXPIRED" )
& ( db.scheduler_task.status != "TIMEOUT" )
& ( db.scheduler_task.status != "COMPLETED" )
).select()
if len(row2) > 0 :
error += "run already registered, "
if error == "" :
## create or update data file state
row = db( ( db.data_file.config_id == request.vars["config_id" ] )
& ( db.data_file.sequence_file_id == request.vars["sequence_file_id"] )
).select()
if len(row) > 0 : ## update
data_id = row[0].id
else: ## create
data_id = db.data_file.insert(sequence_file_id = request.vars['sequence_file_id'],
config_id = request.vars['config_id'],
)
## create or update fuse file state
row = db( ( db.fused_file.config_id == request.vars["config_id"] ) &
( db.fused_file.patient_id == id_patient )
).select()
if len(row) > 0 : ## update
fuse_id = row[0].id
else: ## create
fuse_id = db.fused_file.insert(patient_id = id_patient,
config_id = request.vars['config_id'])
##add task to scheduller
task = scheduler.queue_task('run', [request.vars["sequence_file_id"],request.vars["config_id"], data_id, fuse_id]
, repeats = 1, timeout = 6000)
db.data_file[data_id] = dict(scheduler_task_id = task.id)
(filename, str) = db.sequence_file.data_file.retrieve(db.sequence_file[request.vars["sequence_file_id"]].data_file)
config_name = db.config[request.vars["config_id"]].name
patient_name = db.patient[id_patient].first_name + " " + db.patient[id_patient].last_name
res = {"redirect": "patient/info",
"args" : { "id" : id_patient,
"config_id" : request.vars["config_id"]},
"message": "default/run_request : request added to run config " + config_name + " on " + filename + " for " + patient_name }
res = schedule_run(request.vars["sequence_file_id"], request.vars["config_id"])
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -110,6 +63,7 @@ def run_request():
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## return .data file
# need patient_id, config_id
......@@ -135,12 +89,26 @@ def get_data():
fused_file = "applications/vidjil/uploads/"+row.fused_file
if error == "" :
f = open(fused_file, "r")
output=f.readlines()
data = gluon.contrib.simplejson.loads(f.read())
f.close()
## récupération des infos stockées sur la base de données
query = db( ( db.patient.id == db.sequence_file.patient_id )
& ( db.data_file.sequence_file_id == db.sequence_file.id )
& ( db.patient.id == request.vars["patient_id"] )
& ( db.data_file.config_id == request.vars["config_id"] )
).select( orderby=db.sequence_file.sampling_date )
return output
data["samples"]["original_names"] = []
data["samples"]["info"] = []
for row in query :
filename = row.sequence_file.filename
data["samples"]["original_names"].append(filename)
data["samples"]["info"].append(row.sequence_file.info)
return gluon.contrib.simplejson.dumps(data, separators=(',',':'))
else :
res = {"success" : "false",
......@@ -163,16 +131,21 @@ def get_analysis():
error += "you don't have permission to consult this patient ("+id_patient+")"
## empty analysis file
res = {"custom": [],
"cluster" : [],
res = {"samples": {"number": 0,
"original_names": [],
"order": [],
"info_sequence_file" : []
},
"custom": [],
"clones" : [],
"tags": [],
"info_patient" : "test info patient",
"patient" : "",
"info_sequence_file" : [],
"time": [],
"time_order": []
"patient" : ""
}
if error == "" :
"""
## récupération des infos stockées sur la base de données
query = db( ( db.patient.id == db.sequence_file.patient_id )
& ( db.data_file.sequence_file_id == db.sequence_file.id )
......@@ -183,11 +156,9 @@ def get_analysis():
order = 0
for row in query :
(filename, str) = db.sequence_file.data_file.retrieve(row.sequence_file.data_file)
res["time"].append(filename)
res["time_order"].append(order)
res["info_sequence_file"].append(row.sequence_file.info)
order = order+1
res["samples"]["original_names"].append(filename)
res["samples"]["info_sequence_file"].append(row.sequence_file.info)
"""
res["info_patient"] = db.patient[request.vars["patient_id"]].info
res["patient"] = db.patient[request.vars["patient_id"]].first_name + " " + db.patient[request.vars["patient_id"]].last_name + " (" + db.config[request.vars["config_id"]].name + ")"
......@@ -201,10 +172,13 @@ def get_analysis():
analysis = gluon.contrib.simplejson.loads(f.read())
f.close()
res["custom"] = analysis["custom"]
analysis["info_patient"] = db.patient[request.vars["patient_id"]].info
analysis["patient"] = db.patient[request.vars["patient_id"]].first_name + " " + db.patient[request.vars["patient_id"]].last_name + " (" + db.config[request.vars["config_id"]].name + ")"
res["cluster"] = analysis["cluster"]
res["clones"] = analysis["clones"]
res["samples"]["order"] = analysis["samples"]["order"]
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
return gluon.contrib.simplejson.dumps(analysis, separators=(',',':'))
else :
res = {"success" : "false",
"message" : "default/get_analysis : " + error}
......
......@@ -32,11 +32,7 @@ def add_form():
if error=="" :
query = db((db.sequence_file.patient_id==request.vars['patient_id'])).select()
for row in query :
if row.data_file is None :
filename= " "
else:
(filename, str) = db.sequence_file.data_file.retrieve(row.data_file)
if filename == request.vars['filename'] :
if row.filename == request.vars['filename'] :
res = {"message": "this sequence file already exists for this patient"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......@@ -45,13 +41,15 @@ def add_form():
pcr=request.vars['pcr'],
sequencer=request.vars['sequencer'],
producer=request.vars['producer'],
patient_id=request.vars['patient_id'])
patient_id=request.vars['patient_id'],
filename=request.vars['filename'])
res = {"file_id" : id,
"message": request.vars['filename'] + ": upload started",
"redirect": "patient/info",
"args" : {"id" : request.vars['patient_id']}
}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
......@@ -84,11 +82,7 @@ def edit_form():
if error=="" :
query = db((db.sequence_file.patient_id==db.sequence_file[request.vars['id']].patient_id)).select()
for row in query :
if row.data_file is None :
filename = " "
else:
(filename, str) = db.sequence_file.data_file.retrieve(row.data_file)
if filename == request.vars['filename'] :
if row.filename == request.vars['filename'] :
res = {"message": "this sequence file already exists for this patient"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
......
......@@ -174,8 +174,43 @@ def delete():
res = {"message": "acces denied"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
## display run page result
## need ["data_file_id"]
def result_info():
if (auth.has_permission('admin', 'patient', db.sequence_file[db.data_file[request.vars["data_file_id"]].sequence_file_id].patient_id ) ):
return dict(message=T('result info'))
else :
res = {"message": "acces denied"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
def result_confirm():
if (auth.has_permission('admin', 'patient', db.sequence_file[db.data_file[request.vars["data_file_id"]].sequence_file_id].patient_id )
& auth.has_permission("run", "data_file") ):
return dict(message=T('result confirm'))
else :
res = {"message": "acces denied"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#
def result_delete():
if (auth.has_permission('admin', 'patient', db.sequence_file[db.data_file[request.vars["data_file_id"]].sequence_file_id].patient_id )
& auth.has_permission("run", "data_file") ):
config_id = db.data_file[request.vars["data_file_id"]].config_id
patient_id = db.sequence_file[db.data_file[request.vars["data_file_id"]].sequence_file_id].patient_id
db(db.data_file.id == request.vars["data_file_id"]).delete()
res = {"redirect": "patient/info",
"args" : { "id" : patient_id,
"config_id" : config_id},
"success": "true",
"message": "run ("+str(request.vars["id"])+") deleted"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"message": "acces denied"}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#
def permission():
if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
......
# coding: utf8
def schedule_run(id_sequence, id_config):
import time, datetime, sys, os.path
from subprocess import Popen, PIPE, STDOUT, os
id_patient = db.sequence_file[id_sequence].patient_id
#check data_file
row = db( ( db.data_file.config_id == id_config ) &
( db.data_file.sequence_file_id == id_sequence )
).select()
if len(row) > 0 : ## update
data_id = row[0].id
else: ## create
data_id = db.data_file.insert(sequence_file_id = id_sequence,
config_id = id_config )
## check fused_file
row2 = db( ( db.fused_file.config_id == id_config ) &
( db.fused_file.patient_id == id_patient )
).select()
if len(row2) > 0 : ## update
fuse_id = row2[0].id
else: ## create
fuse_id = db.fused_file.insert(patient_id = id_patient,
config_id = id_config)
##check scheduled run
row3 = db( ( db.scheduler_task.args == '["' + id_sequence + '", "' + id_config + '", ' + str(data_id) + ', ' + str(fuse_id) + ']' )
& ( db.scheduler_task.status != "FAILED" )
& ( db.scheduler_task.status != "EXPIRED" )
& ( db.scheduler_task.status != "TIMEOUT" )
& ( db.scheduler_task.status != "COMPLETED" )
).select()
if len(row3) > 0 :
res = {"message": "run already registered"}
return res
##add task to scheduller
task = scheduler.queue_task('run', [id_sequence, id_config, data_id, fuse_id]
, repeats = 1, timeout = 6000)
db.data_file[data_id] = dict(scheduler_task_id = task.id)
(filename, str2) = db.sequence_file.data_file.retrieve(db.sequence_file[id_sequence].data_file)
config_name = db.config[id_config].name
patient_name = db.patient[id_patient].first_name + " " + db.patient[id_patient].last_name
res = {"redirect": "patient/info",
"args" : { "id" : id_patient,
"config_id" : id_config},
"message": "default/run_request : request added to run config " + config_name + " on " + filename + " for " + patient_name }
return res
def run_vidjil(id_file, id_config, id_data, id_fuse):
import time, datetime, sys, os.path
......@@ -30,7 +87,7 @@ def run_vidjil(id_file, id_config, id_data, id_fuse):
## execute la commande vidjil
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
p.wait()
output = p.stdout.read()
print p.stdout.read()
## récupération du fichier data.json généré
data_filepath = os.path.abspath(out_folder+"vidjil.data")
......@@ -77,7 +134,7 @@ def run_vidjil(id_file, id_config, id_data, id_fuse):
## l'output de Vidjil est stocké comme resultat pour l'ordonnanceur
## TODO parse result success/fail
return output
return "sucess"
from gluon.scheduler import Scheduler
......
{{extend 'db_layout.html'}}
Bientot vous trouverez içi un magnifique panneau d'administration, en attendant voila un lapin.</br>
<img src="http://upload.wikimedia.org/wikipedia/commons/3/3b/Rabbit_in_montana.jpg" style="width:200px; height:200px;">
</br>
<a class="button" onclick="db.call('admin/result');">liste des fichiers result (data)</a>
{{extend 'db_layout.html'}}
{{
query = db(
(db.data_file.sequence_file_id==db.sequence_file.id)
& (db.sequence_file.patient_id==db.patient.id)
& (db.data_file.config_id==db.config.id)
).select()
}}
<div>
<h3>Hi</h3>
<div id="db_table_container">
<table class="db_table" id="table">
<thead>
<tr>
<td class="column1">file_name</td>
<td class="column2">config</td>
<td> </td>
<td class="column1">patient</td>
<td class="column2">producer</td>
<td class="column2">last process</td>
<td class="column2">status</td>
</tr>
</thead>
{{for row in query :}}
{{if row.data_file.scheduler_task_id is None :}}
{{status = '' }}
{{else:}}
{{status = db.scheduler_task[row.data_file.scheduler_task_id ].status }}
{{pass}}
<tr>
<td> {{=row.sequence_file.filename}} </td>
<td> {{=row.config.name}} </td>
<td></td>
<td> {{=row.patient.last_name + " " + row.patient.first_name }} </td>
<td> {{=row.sequence_file.producer}} </td>
<td> {{=row.data_file.run_date}} </td>
<td> {{=status}} </td>
</tr>
{{pass}}
</table>
<table class="db_table" id="db_fixed_header"></table>
</div>
<div class="db_block">
<div class="db_block_right">
<a class="button" onclick="db.call('admin/run_all')" > run all </a>
</div>
</div>
</div>
......@@ -22,8 +22,8 @@ info = db.config[request.vars["id"]]
<td><label for="config_germline" id="config_germline__label"> germline: </label></td>
<td>
<select id="config_germline" name="config_germline">
<option value="TRG">TRG</option>
<option value="IGH">IGH</option>
<option value="TRG" {{if info.germline == "TRG":}}selected="selected"{{pass}}>TRG</option>
<option value="IGH" {{if info.germline == "IGH":}}selected="selected"{{pass}}>IGH</option>
</select>
</td>
<td></td>
......
......@@ -7,6 +7,7 @@
<a class="button" onclick="db.call('config/index');">configs</a>
<a class="button" onclick="db.call('group/index');">groups</a>
<a class="button" onclick="db.call('user/index');">users</a>
<a class="button" onclick="db.call('admin/index');">admin</a>
- - -
{{pass}}
</div>
......
......@@ -89,19 +89,14 @@ query = db(
<td class="column_sep"></td>
<td class="column2"> last processing </td>
<td class="column4"> </td>
<td class="column5"> </td>
<td class="column2"> </td>
</tr>
</thead>
<tbody>
{{for row in query :}}
{{if row.sequence_file.data_file is None :}}
{{filename = ''}}
{{else:}}
{{(filename, str) = db.sequence_file.data_file.retrieve(row.sequence_file.data_file)}}
{{pass}}
{{if row.data_file.scheduler_task_id is None :}}
{{status = '' }}
{{else:}}
......@@ -109,25 +104,36 @@ query = db(
{{pass}}
<tr>
<td id="sequence_file_{{=row.sequence_file.id}}"> {{=filename}}</td>
<td> {{if filename == 'plop':}}<a href="{{=URL('patient','download', scheme='https', args=row.sequence_file.data_file)}}" >dl</a>{{pass}}</td>
<td id="sequence_file_{{=row.sequence_file.id}}"> {{=row.sequence_file.filename}}</td>
<td> {{if row.sequence_file.filename == 'plop':}}<a href="{{=URL('patient','download', scheme='https', args=row.sequence_file.data_file)}}" >dl</a>{{pass}}</td>
<td> {{=row.sequence_file.sampling_date}} </td>
<td> {{=row.sequence_file.info}} </td>
{{if (auth.has_permission('admin', 'patient', request.vars["id"]) ):}}
<td onclick="db.call('file/edit', {'id' :'{{=row.sequence_file.id}}', 'patient_id' :'{{=request.vars['id']}}'} )" > e </td>
<td onclick="db.call('file/confirm', {'id' :'{{=row.sequence_file.id}}', 'patient_id' :'{{=request.vars['id']}}'} )" > X </td>
{{else:}}<td></td><td></td>{{pass}}
<td class="column_sep"></td>
<td> {{if row.data_file.run_date :}}{{=row.data_file.run_date }}{{pass}} </td>
{{if row.data_file.run_date :}}
<td class="button" onclick="db.call('patient/result_info', { 'data_file_id' : '{{=row.data_file.id}}' } )"> {{=row.data_file.run_date }}</td>
{{else:}}
<td></td>
{{pass}}
{{if (auth.has_permission('admin', 'patient', request.vars["id"]) ):}}
<td onclick="db.call('patient/result_confirm', {'data_file_id' :'{{=row.data_file.id}}'})" > X </td>
{{else:}}
<td></td>
{{pass}}
<td>
{{if filename != '' and config_id != -1:}}
{{if row.sequence_file.filename != '' and config_id != -1:}}
{{if row.data_file.id == None or ( status != "RUNNING" and status != "QUEUED" and status != "ASSIGNED"):}}
{{if auth.has_permission("run", "data_file") :}}
<span class="button" onclick="db.call('default/run_request', { 'sequence_file_id' : '{{=row.sequence_file.id}}', 'config_id' : {{=config_id}} } )"> run >> </span>
{{if auth.has_permission("run", "data_file") :}}
<span class="button" onclick="db.call('default/run_request', { 'sequence_file_id' : '{{=row.sequence_file.id}}', 'config_id' : {{=config_id}} } )"> run >> </span>
{{else:}}
<span class="button inactive" title="you don't have permission to schedule runs"> run >> </span>
<span class="button inactive" title="you don't have permission to schedule runs"> run >> </span>
{{pass}}
{{else:}}
{{=status}}
......@@ -136,6 +142,7 @@ query = db(
</td>
</tr>
{{pass}}
</tbody>
</table>
<table class="db_table" id="db_fixed_header"></table>
......@@ -157,7 +164,7 @@ query = db(
result :
{{for row in db(db.fused_file.patient_id == request.vars["id"]).select() :}}
{{filename = db.patient[request.vars["id"]].first_name + " " + db.patient[request.vars["id"]].last_name + " (" + db.config[row.config_id].name + ")"}}
<span class="button2" onclick="db.load_data( { 'patient_id' : '{{=request.vars["id"]}}' , 'config_id' : {{=row.config_id}} }, '{{=filename}}' )" >
{{if row.fused_file is not None :}}<span class="button2" onclick="db.load_data( { 'patient_id' : '{{=request.vars["id"]}}' , 'config_id' : {{=row.config_id}} }, '{{=filename}}' )" >{{pass}}
{{=db.config[row.config_id].name}} </span>
{{pass}}
</div>
......@@ -167,10 +174,12 @@ query = db(
{{if fused_count >0:}}
<div class="db_block">
<div class="db_block_right">
download {{=db.config[config_id].name}}
<a class="button" href={{=URL('default', 'download', scheme='https', args=fused_file[0].fused_file, vars=dict(filename=fused_filename))}} type="application/octet-stream" download> .data </a>
{{if analysis_count >0:}}
<a class="button" href={{=URL('default', 'download', scheme='https', args=analysis_file[0].analysis_file, vars=dict(filename=analysis_filename))}} type="application/octet-stream" download> .analysis </a>
{{if row.fused_file is not None :}}
download {{=db.config[config_id].name}}
<a class="button" href={{=URL('default', 'download', scheme='https', args=fused_file[0].fused_file, vars=dict(filename=fused_filename))}} type="application/octet-stream" download> .data </a>
{{if analysis_count >0:}}
<a class="button" href={{=URL('default', 'download', scheme='https', args=analysis_file[0].analysis_file, vars=dict(filename=analysis_filename))}} type="application/octet-stream" download> .analysis </a>
{{pass}}
{{pass}}
</div>
</div>
......
{{extend 'db_layout.html'}}
{{('message' in globals())}}
{{if 'message' in globals():}}
<div>
<h3>{{=message}}</h3>
Are you sure you want to delete this run</br>
<div class="center">
<button onclick="db.call('patient/result_delete', {'data_file_id' :'{{=request.vars["data_file_id"]}}'} )">delete</button>
<button onclick="db.call('patient/info', {'id' :'{{=db.sequence_file[db.data_file[request.vars["data_file_id"]].sequence_file_id].patient_id}}'} )">cancel</button>
</div>
</div>
{{elif 'content' in globals():}}
{{=content}}
{{else:}}
{{=BEAUTIFY(response._vars)}}
{{pass}}
{{extend 'db_layout.html'}}
{{('message' in globals())}}
{{if 'message' in globals():}}
{{
data_file_id = request.vars["data_file_id"]
data_file = db.data_file[data_file_id]
config_id = db.data_file[data_file_id].config_id
config = db.config[config_id]
sequence_file_id = db.data_file[data_file_id].sequence_file_id
sequence_file = db.sequence_file[sequence_file_id]
run = db.scheduler_run[data_file.scheduler_task_id]
}}
<div>
<h3>info run {{=sequence_file.filename}} ({{=config.name }}) ({{=data_file.run_date}}) </h3>
<div class="db_block">
<div class="db_block_left">
</div>
<div class="db_block_right">
</div>
</div>
</div>
<div id="db_table_container">
<table>
<tr>
<td>status :</td>
<td>{{=run.status}}</td>
</tr>
<tr>
<td>start :</td>
<td>{{=run.start_time}}</td>
</tr>
<tr>
<td>stop :</td>
<td>{{=run.stop_time}}</td>
</tr>
</table>
<table>
<tr><td>run result :</td></tr>
<tr><td><textarea class="text" cols="100" rows="15"> {{=run.run_result}} </textarea></td></tr>
<tr><td>run output :</td></tr>
<tr><td><textarea class="text" cols="100" rows="15"> {{=run.run_output}} </textarea></td></tr>
<tr><td>run traceback :</td></tr>
<tr><td><textarea class="text" cols="100" rows="15"> {{=run.traceback}} </textarea></td></tr>
</table>
</div>
<div class="db_block">
<div class="db_block_left">
</div>
<div class="db_block_right">
</div>
</div>
{{elif 'content' in globals():}}
{{=content}}
{{else:}}
{{=BEAUTIFY(response._vars)}}
{{pass}}
default_application='vidjil'
default_controller = "default"
default_function = "index"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment