Commit 3207ac9c authored by Marc Duez's avatar Marc Duez
parents 9d148849 ecb943b5
......@@ -14,7 +14,7 @@ import vidjil_utils
import gluon.contrib.simplejson, time, datetime
if request.env.http_origin:
response.headers['Access-Control-Allow-Origin'] = 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
......@@ -39,20 +39,20 @@ def help():
#########################################################################
## add a scheduller task to run vidjil on a specific sequence file
# need sequence_file_id, config_id
# need patient admin permission
# need patient admin permission
def run_request():
error = ""
##TODO check
##TODO check
if not "sequence_file_id" in request.vars :
error += "id sequence file needed, "
if not "config_id" in request.vars:
error += "id config needed, "
if not auth.has_permission("run", "results_file") :
error += "permission needed"
id_patient = db.sequence_file[request.vars["sequence_file_id"]].patient_id
if not auth.has_permission('admin', 'patient', id_patient) :
error += "you do not have permission to launch process for this patient ("+str(id_patient)+"), "
......@@ -65,17 +65,17 @@ def run_request():
"message" : "default/run_request : " + error}
log.error(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## return .data file
# need patient_id, config_id
# need patient admin or read permission
# need patient, config
# need patient admin or read permission
def get_data():
import time
from subprocess import Popen, PIPE, STDOUT
if not auth.user :
if not auth.user :
res = {"redirect" : URL('default', 'user', args='login', scheme=True, host=True,
vars=dict(_next=URL('default', 'get_data', scheme=True, host=True,
vars=dict(patient = request.vars["patient"],
......@@ -83,7 +83,7 @@ def get_data():
)
)}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
error = ""
if not "patient" in request.vars :
......@@ -93,7 +93,7 @@ def get_data():
if not auth.has_permission('admin', 'patient', request.vars["patient"]) and \
not auth.has_permission('read', 'patient', request.vars["patient"]):
error += "you do not have permission to consult this patient ("+request.vars["patient"]+")"
query = db( ( db.fused_file.patient_id == request.vars["patient"] )
& ( db.fused_file.config_id == request.vars["config"] )
).select()
......@@ -103,18 +103,19 @@ def get_data():
if not 'fused_file' in locals():
error += "file not found"
if error == "" :
f = open(fused_file, "r")
data = gluon.contrib.simplejson.loads(f.read())
f.close()
data["info"] = db.patient(request.vars["patient"]).info
data["samples"]["original_names"] = []
data["samples"]["timestamp"] = []
data["samples"]["info"] = []
## récupération des infos stockées sur la base de données
## récupération des infos stockées sur la base de données
if sequence_file_list is not None:
sequence_file_list = sequence_file_list.split("_")
for i in range(len(sequence_file_list)-1):
......@@ -127,20 +128,20 @@ def get_data():
data["samples"]["original_names"].append("unknow")
data["samples"]["timestamp"].append("")
data["samples"]["info"].append("")
else :
## old method
query = db( ( db.patient.id == db.sequence_file.patient_id )
& ( db.results_file.sequence_file_id == db.sequence_file.id )
& ( db.patient.id == request.vars["patient"] )
& ( db.results_file.config_id == request.vars["config"] )
).select( orderby=db.sequence_file.id|db.results_file.run_date, groupby=db.sequence_file.id )
).select( orderby=db.sequence_file.id|db.results_file.run_date, groupby=db.sequence_file.id )
for row in query :
filename = row.sequence_file.filename
data["samples"]["original_names"].append(filename)
data["samples"]["timestamp"].append(str(row.sequence_file.sampling_date))
data["samples"]["info"].append(row.sequence_file.info)
data["samples"]["info"].append(row.sequence_file.info)
log.debug("get_data: %s -> %s" % (request.vars["patient"], fused_file))
return gluon.contrib.simplejson.dumps(data, separators=(',',':'))
......@@ -150,11 +151,11 @@ def get_data():
"message" : "default/get_data : " + error}
log.error(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## return .analysis file
# need patient_id, config_id
# need patient admin or read permission
# need patient admin or read permission
def get_analysis():
error = ""
......@@ -165,7 +166,7 @@ def get_analysis():
if not auth.has_permission('admin', 'patient', request.vars["patient"]) and \
not auth.has_permission('read', 'patient', request.vars["patient"]):
error += "you do not have permission to consult this patient ("+request.vars["patient"]+")"
## empty analysis file
res = {"samples": {"number": 0,
"original_names": [],
......@@ -178,10 +179,10 @@ def get_analysis():
"tags": {},
"vidjil_json_version" : "2014.09"
}
if error == "" :
## récupération des infos se trouvant dans le fichier .analysis
analysis_query = db( (db.analysis_file.patient_id == request.vars["patient"])
& (db.analysis_file.config_id == request.vars["config"] ) )
......@@ -202,18 +203,18 @@ def get_analysis():
res["info_patient"] = db.patient[request.vars["patient"]].info
res["patient"] = vidjil_utils.anon(db.patient[request.vars["patient"]].id, auth.user_id) + " (" + db.config[request.vars["config"]].name + ")"
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
else :
res = {"success" : "false",
"message" : "default/get_analysis : " + error}
log.error(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## upload .analysis file and store it on the database
# need patient_id, config_id, fileToUpload
# need patient admin permission
# need patient admin permission
def save_analysis():
error = ""
......@@ -223,29 +224,29 @@ def save_analysis():
error += "id config needed, "
if not auth.has_permission('admin', 'patient', request.vars['patient']) :
error += "you do not have permission to save changes on this patient"
if error == "" :
analysis_query = db( (db.analysis_file.patient_id == request.vars['patient'])
& (db.analysis_file.config_id == request.vars['config'] ) )
f = request.vars['fileToUpload']
ts = time.time()
if not analysis_query.isempty() :
analysis_id = analysis_query.select().first().id
db.analysis_file[analysis_id] = dict(analysis_file = db.analysis_file.analysis_file.store(f.file, f.filename),
analyze_date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
)
else:
else:
analysis_id = db.analysis_file.insert(analysis_file = db.analysis_file.analysis_file.store(f.file, f.filename),
config_id = request.vars['config'],
patient_id = request.vars['patient'],
analyze_date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
)
patient_name = db.patient[request.vars['patient']].first_name + " " + db.patient[request.vars['patient']].last_name
res = {"success" : "true",
"message" : patient_name+": analysis saved"}
log.info(res)
......@@ -255,8 +256,8 @@ def save_analysis():
"message" : error}
log.error(res)
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## TODO make custom download for .data et .analysis
......@@ -268,9 +269,13 @@ def download():
"""
return response.download(request, db, download_filename=request.vars.filename)
def download_data():
file = "test"
return response.stream( file, chunk_size=4096, filename=request.vars.filename)
#########################################################################
##
##
def create_self_signed_cert(cert_dir):
"""
create a new self-signed cert and key and write them to disk
......@@ -280,17 +285,17 @@ def create_self_signed_cert(cert_dir):
from pprint import pprint
from time import gmtime, mktime
from os.path import exists, join
CERT_FILE = "ssl_certificate.crt"
CERT_FILE = "ssl_certificate.crt"
KEY_FILE = "ssl_self_signed.key"
ssl_created = False
if not exists(join(cert_dir, CERT_FILE)) \
or not exists(join(cert_dir, KEY_FILE)):
ssl_created = True
ssl_created = True
# create a key pair
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 4096)
# create a self-signed cert
cert = crypto.X509()
cert.get_subject().C = "AQ"
......@@ -305,14 +310,14 @@ def create_self_signed_cert(cert_dir):
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha1')
open(join(cert_dir, CERT_FILE), "wt").write(
crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
open(join(cert_dir, KEY_FILE), "wt").write(
crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
create_self_signed_cert('.')
return(ssl_created, cert_dir, CERT_FILE, KEY_FILE)
......@@ -322,16 +327,16 @@ def handle_error():
Custom error handler that returns correct status codes,
adapted from http://www.web2pyslices.com/slice/show/1529/custom-error-routing
"""
code = request.vars.code
request_url = request.vars.request_url
ticket = request.vars.ticket
log.error("[%s] %s" % (code, ticket))
if code is not None and request_url != request.url:# Make sure error url is not current url to avoid infinite loop.
response.status = int(code) # Assign the error status code to the current response. (Must be integer to work.)
if code == '403':
return "Not authorized"
elif code == '404':
......@@ -339,7 +344,7 @@ def handle_error():
elif code == '500':
# Get ticket URL:
ticket_url = "<a href='%(scheme)s://%(host)s/admin/default/ticket/%(ticket)s' target='_blank'>%(ticket)s</a>" % {'scheme':'https','host':request.env.http_host,'ticket':ticket}
# Email a notice, etc:
mail.send(to=['contact@vidjil.org'],
subject="[Vidjil] web2py error",
......@@ -390,12 +395,12 @@ def data():
## not used
@auth.requires_login()
@auth.requires_membership('admin')
def add_membership():
def add_membership():
response.title = ""
user_query = db(db.auth_user).select()
group_query = db(~(db.auth_group.role.like("user%"))).select()
form = SQLFORM.factory(
Field('user', requires=IS_IN_SET([r.id for r in user_query], labels=[r.first_name+" "+r.last_name for r in user_query])),
Field('group', requires=IS_IN_SET([r.id for r in group_query], labels=[r.role for r in group_query]))
......@@ -405,48 +410,48 @@ def add_membership():
db.auth_membership.insert(user_id=form.vars.user,
group_id=form.vars.group)
response.flash = "membership added"
return dict(form=form)
#########################################################################
## not used
def upload_file():
import shutil, os.path
try:
# Get the file from the form
f = request.vars['files[]']
p = request.vars['patient_id[]']
i = request.vars['info[]']
d = request.vars['date[]']
# Store file
id = db.sequence_file.insert(data_file = db.sequence_file.data_file.store(f.file, f.filename))
record = db.sequence_file[id]
path_list = []
path_list.append(request.folder)
path_list.append('uploads')
path_list.append(record['data_file'])
size = shutil.os.path.getsize(shutil.os.path.join(*path_list))
db.sequence_file[id] = dict(size_file=size ,
patient_id=p,
sampling_date=d,
info=i)
File = db(db.sequence_file.id==id).select()[0]
res = dict(files=[{"name": str(f.filename),
"size": size,
res = dict(files=[{"name": str(f.filename),
"size": size,
"url": URL(f='download', args=[File['data_file']])
}])
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
except:
res = dict(files=[{"name": "kuik", "size": 0, "error": "fail!!" }])
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
#########################################################################
## not used
def delete_file():
......@@ -459,13 +464,13 @@ def delete_file():
redirect( URL(f='patient', args=[patient_id]) )
except:
redirect( URL(f='patient', args=[patient_id]) )
#########################################################################
## not used
def upload():
return dict()
def user():
"""
exposes:
......@@ -481,9 +486,9 @@ def user():
@auth.requires_permission('read','table name',record_id)
to decorate functions that need access control
"""
if auth.user and request.args[0] == 'login' :
if auth.user and request.args[0] == 'login' :
res = {"redirect" : URL('patient', 'index', scheme=True, host=True)}
return gluon.contrib.simplejson.dumps(res, separators=(',',':'))
return dict(form=auth())
......@@ -8,11 +8,11 @@
<h3>{{=vidjil_utils.anon(request.vars['id'], auth.user.id)}}</h3>
<div class="db_block">
<div class="db_block_left">
<span class="button" onclick="db.call('patient/edit', { 'id' : '{{=request.vars["id"]}}' } )" > edit patient info </span>
</div>
<div class="db_block_right">
{{if auth.has_permission("run", "results_file") :}}
......@@ -55,7 +55,7 @@
</tr>
</thead>
<tbody>
{{for row in query :}}
{{if row.results_file.scheduler_task_id is None :}}
{{status = '' }}
......@@ -70,22 +70,22 @@
<td> {{=row.sequence_file.sampling_date}} </td>
<td> {{=row.sequence_file.info}} </td>
<td> {{=row.sequence_file.pcr}} </td>
<td {{if row.sequence_file.data_file == None :}} {{=XML("class='inactive' title='file is missing' ")}} {{pass}} >
<td {{if row.sequence_file.data_file == None :}} {{=XML("class='inactive' title='file is missing' ")}} {{pass}} >
{{=vidjil_utils.format_size(row.sequence_file.size_file)}} </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>
<td> <a {{if row.sequence_file.data_file == None :}} {{=XML("class='inactive' title='file is missing' ")}}
<td> <a {{if row.sequence_file.data_file == None :}} {{=XML("class='inactive' title='file is missing' ")}}
{{else:}} href="{{=URL('patient','download', scheme='https', args=row.sequence_file.data_file)}}" {{pass}} >dl</a></td>
{{else:}}<td></td><td></td><td></td>{{pass}}
<td class="column_sep"></td>
{{if row.results_file.run_date :}}
<td class="button" onclick="db.call('results_file/info', { 'results_file_id' : '{{=row.results_file.id}}' } )"> {{=row.results_file.run_date }}</td>
{{else:}}<td></td>{{pass}}
{{else:}}<td></td>{{pass}}
<td class="button" onclick="db.call('results_file/info', { 'results_file_id' : '{{=row.results_file.id}}' } )"> {{=status}} </td>
<td onclick="db.call('results_file/confirm', {'results_file_id' :'{{=row.results_file.id}}'})" > X </td>
<td>
......@@ -97,7 +97,7 @@
</td>
</tr>
{{pass}}
</tbody>
</table>
<table class="db_table" id="db_fixed_header"></table>
......@@ -112,8 +112,8 @@
{{if not auth.has_permission("run", "results_file") :}}
<br /> Once your data are uploaded, please
<a href="mailto:contact@vidjil.org?Subject=%5Bvidjil%5D%20New%20sequences&Body=%0AHi%2C%0A%0AI%20uploaded%20some%20sequences%20on%20the%20rbx.vidjil.org%20server.%0ACould%20you%20run%20Vidjil%20on%20these%20data%20%3F%0A%0A">request an analysis</a>.
<br /> Once your data are uploaded, please
<a href="mailto:contact@vidjil.org?Subject=%5Bvidjil%5D%20New%20sequences&Body=%0AHi%2C%0A%0AI%20uploaded%20some%20sequences%20on%20the%20rbx.vidjil.org%20server.%0ACould%20you%20run%20Vidjil%20on%20these%20data%20%3F%0A%0A">request an analysis</a>.
{{pass}}
{{pass}}
......@@ -142,6 +142,9 @@
<div class="db_block_right">
{{if row.fused_file is not None :}}
download {{=db.config[config_id].name}}
<!--
<a class="button" href={{=URL('default', 'download_data', scheme='https', vars=dict(patient=request.vars["id"] ,config=request.vars["config_id"], filename=fused_filename ) )}} type="application/octet-stream" download> .data </a>
-->
<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>
......
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