Commit 2c070552 authored by Tatiana Rocher's avatar Tatiana Rocher
Browse files
parents 47f92b7c ec03a357
......@@ -22,6 +22,8 @@ test:
test_browser: unit_browser functional_browser
test_server: unit_server
test_tools:
make -C tools/tests
......@@ -83,6 +85,9 @@ functional_browser:
headless_browser:
make -C browser/test headless
unit_server:
make -C server/ unit
### Code coverage
coverage: unit_coverage should_coverage
......@@ -127,6 +132,7 @@ cleanall: clean
make -C data $^
make -C germline $^
make -C $(VIDJIL_ALGO_SRC) cleanall
make -C server cleanall
.PHONY: all test should clean cleanall distrib data germline unit_coverage should_coverage coverage
......
This diff is collapsed.
'''
Sort and split a fontello config.json file according to 'src'
python fontello.py config.json
'''
import json
import copy
import sys
def dump(j, out):
print " ==> %-50s %3d glyphs" % (out, len(j['glyphs']))
json.dump(j, open(out, 'w'), indent=2)
name = sys.argv[1]
basename = name.replace('.json', '')
j = json.load(open(name))
glyphs = j['glyphs']
srcs = set(icon['src'] for icon in glyphs)
family_code = [ 0xE900, 0xEA00, 0xEB00, 0xEC00 ]
family = 0
for src in srcs:
code = family_code[family]
family += 1
jj = copy.deepcopy(j)
jj['glyphs'] = []
for icon in glyphs:
if not icon['src'] == src:
continue
code += 1
icon['code'] = code
jj['glyphs'].append(icon)
dump(jj, '%s-%s.json' % (basename, src))
dump(j, '%s-sorted.json' % basename)
doc: conf.json
jsdoc -c conf.json ../model.js ../list.js ../model_loader.js ../view.js ../germline_builder.js ../com.js ../germline.js ../shortcut.js
\ No newline at end of file
jsdoc -c conf.json ../*.js
This diff is collapsed.
......@@ -34,8 +34,14 @@
CGI_ADDRESS = ""
/* segment constructor
*
/** segment
* Segment is a view object to see the sequences of the selected clones in the model <br>
* some function are provided to allow alignement / highlight / imgt request / ...
* @constructor
* @param {string} id - dom id of the html div who will contain the segmenter
* @param {Model} model
* @augments View
* @this View
* */
function Segment(id, model) {
......@@ -71,13 +77,17 @@ function Segment(id, model) {
Segment.prototype = {
/*
*
/**
* init the view before use
* */
init: function () {
this.build()
},
/**
* build needed html elements (button / highlight menu)
*
* */
build: function () {
var self = this
......@@ -305,13 +315,9 @@ Segment.prototype = {
});
},
/*
*
* */
resize: function () {},
/*
*
/**
* update(size/style/position) a list of selected clones <br>
* @param {integer[]} list - array of clone index
* */
updateElem: function (list) {
......@@ -338,6 +344,10 @@ Segment.prototype = {
}
},
/**
* update(style only) a list of selected clones
* @param {integer[]} list - array of clone index
* */
updateElemStyle: function (list) {
for (var i = 0; i < list.length; i++) {
......@@ -361,8 +371,9 @@ Segment.prototype = {
},
/* Fonction permettant de recharger le bouton 'align'
*/
/**
* enable/disable align button if their is currently enough sequences selected
* */
updateAlignmentButton: function() {
var self = this;
var align = document.getElementById("align");
......@@ -380,9 +391,10 @@ Segment.prototype = {
},
/* genere le code HTML des infos d'un clone
* @div_elem : element HTML a remplir
* @cloneID : identifiant du clone a décrire
/**
* complete a div with a clone information/sequence
* @param {dom} div_elem - the dom element to complete
* @param {intger} cloneID - clone index
* */
div_elem: function (div_elem, cloneID) {
var self = this;
......@@ -433,6 +445,11 @@ Segment.prototype = {
div_elem.appendChild(seq_size);
},
/**
* add a clone in the segmenter<br>
* build a div with clone information and sequence
* @param {intger} cloneID - clone index
* */
addToSegmenter: function (cloneID) {
var self = this;
......@@ -470,6 +487,11 @@ Segment.prototype = {
},
/**
* build a request with currently selected clones to send to IMGT or igblast <br>
* (see crossDomain.js)
* @param {string} address - 'IMGT' or 'igBlast'
* */
sendTo: function (address) {
var list = this.m.getSelected()
......@@ -494,7 +516,10 @@ Segment.prototype = {
if (address == 'igBlast') igBlastPost(request, system);
},
/**
* move the horizontal slider to focus the most interesting parts of the sequences
* */
show: function () {
var li = document.getElementById("listSeq")
.getElementsByTagName("li");
......@@ -508,6 +533,9 @@ Segment.prototype = {
}
},
/**
* enable/disable alignment
* */
toggleAlign: function () {
if (this.aligned)
this.resetAlign() ;
......@@ -515,6 +543,9 @@ Segment.prototype = {
this.align() ;
},
/**
* align currently selected clone's sequences using a server side cgi script
* */
align: function () {
var self = this
var list = this.m.getSelected()
......@@ -551,23 +582,10 @@ Segment.prototype = {
})
},
clipBoard: function () {
var div = document.getElementById('clipBoard');
div.innerHTML = "";
div.appendChild(document.createTextNode(""));
/*
if (document.createRange && window.getSelection) {
var range = document.createRange();
range.selectNode(div);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
}
*/
},
/**
* transform currently selected sequences in fasta format
* @return {string} fasta
* */
toFasta: function () {
var selected = this.m.getSelected();
var result = "";
......@@ -579,6 +597,9 @@ Segment.prototype = {
return result
},
/**
* remove alignement
* */
resetAlign: function() {
var selected = this.m.getSelected();
......@@ -590,6 +611,11 @@ Segment.prototype = {
}
},
/**
* callback function for align()
* @param {file} file - align file done by the cgi script
* */
displayAjaxResult: function(file) {
var json = JSON.parse(file)
......@@ -609,6 +635,10 @@ Segment.prototype = {
}
},
/**
* build and display statistics about selected clones
* */
updateStats: function (){
var list = this.m.getSelected()
var sumPercentage = 0;
......@@ -639,6 +669,10 @@ Segment.prototype = {
$(".stats_content").text(t)
},
/**
* find and return the list of clone fields who contain potential information who can be highlighted on sequences
* @return {string[]} - field list
* */
findPotentialField : function () {
// Guess fields for the highlight menu
result = [""];
......@@ -671,6 +705,11 @@ Segment.prototype = {
return result;
},
/**
* determine if a string is a DNA sequence or not
* @param {string}
* @return {bool}
* */
isDNA : function (string) {
if (string == null) {
return false;
......@@ -684,6 +723,11 @@ Segment.prototype = {
}
},
/**
* check if the object can be used to find a position on a sequence
* @param {object}
* @return {bool}
* */
isPos : function (obj) {
if (obj == null) {
return false;
......@@ -693,7 +737,12 @@ Segment.prototype = {
return false;
}
},
/**
* determine if a string is an amino acid sequence or not
* @param {string}
* @return {bool}
* */
isAA : function (string) {
if (string == null) {
return false;
......@@ -719,7 +768,12 @@ Segment.prototype = $.extend(Object.create(View.prototype), Segment.prototype);
/**
* Sequence object contain a dna sequence and various functions to manipulate them
* @param {integer} id - clone index
* @param {Model} model
* @constructor
* */
function Sequence(id, model) {
this.id = id; //clone ID
this.m = model; //Model utilisé
......@@ -730,7 +784,11 @@ function Sequence(id, model) {
Sequence.prototype = {
//load sequence from model or use given argument
/**
* load the clone sequence <br>
* retrieve the one in the model or use the one given in parameter <br>
* @param {string} str
* */
load: function (str) {
if (typeof str !== 'undefined') this.use_marge = false
str = typeof str !== 'undefined' ? str : this.m.clone(this.id).sequence;
......@@ -747,7 +805,9 @@ Sequence.prototype = {
return this;
},
//store position of each nucleotide
/**
* save the position of each nucleotide in an array <br>
* */
computePos: function () {
this.pos = [];
var j = 0
......@@ -759,7 +819,10 @@ Sequence.prototype = {
this.pos.push(this.seq.length)
return this;
},
/**
* use the cdr3 (if available) to compute the amino acid sequence <br>
* */
computeAAseq : function () {
var start = -1;
var stop = -1;
......@@ -805,17 +868,24 @@ Sequence.prototype = {
}
},
//compare sequence with another string and surround change
/**
* compare sequence with another string and surround change
* @param {char} self
* @param {char} other
* @return {string}
* */
spanify_mutation: function (self, other) {
if (segment.aligned && self != other) {
return "<span class='substitution' other='" + other + '-' + segment.first_clone + "'>" + self + "</span>"
}
else {
}else {
return self
}
}
},
//return sequence completed with html tag
/**
* return sequence completed with html tag <br>
* @return {string}
* */
toString: function () {
var clone = this.m.clone(this.id)
var result = ""
......@@ -907,6 +977,13 @@ Sequence.prototype = {
return marge + result
},
/**
* build a highlight descriptor (start/stop/color/...)
* @param {string} field - clone field name who contain the information to highlight
* @param {string} color
* @return {object}
* */
get_positionned_highlight : function (field, color) {
var clone = this.m.clone(this.id);
var h = {'start' : -1, 'stop' : -1, 'seq': '', 'color' : color};
......@@ -964,6 +1041,8 @@ Sequence.prototype = {
}
}
tableAA = {
'TTT' : 'F',
'TTC' : 'F',
......
......@@ -71,4 +71,12 @@ View.prototype = {
updateElemStyle : function () {
},
/**
* resize view to match his div size
* @abstract
* */
resize : function () {
},
}
\ No newline at end of file
......@@ -3,6 +3,8 @@
cd $(dirname $0)
wget -O - http://www.imgt.org/download/GENE-DB/IMGTGENEDB-ReferenceSequences.fasta-nt-WithoutGaps-F+ORF+inframeP | python split-from-imgt.py
wget -O - IMGT_RELEASE http://www.imgt.org/download/GENE-DB/RELEASE
wget -N http://rbx.vidjil.org/browser/germline/IGK-INTRON.fa
wget -N http://rbx.vidjil.org/browser/germline/IGK-KDE.fa
......
data:
sh nginx_install.sh
install_web2py:
wget http://web2py.com/examples/static/web2py_src.zip
unzip web2py_src.zip
mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py
rm web2py_src.zip
cp -i web2py/applications/vidjil/modules/defs.py.sample web2py/applications/vidjil/modules/defs.py
install_unit_tests:
pip install unittest2
pip install unittest-xml-reporting
unit: clean_unit_tests
cd web2py; python web2py.py -S vidjil -M -R testRunner.py
clean_unit_tests:
rm -f web2py/test-reports/*.xml
cleanall: clean_unit_tests
......@@ -219,11 +219,7 @@ exec uwsgi --master --die-on-term --emperor /etc/uwsgi --logto /var/log/uwsgi/uw
# Install Web2py
cd $CWD
wget http://web2py.com/examples/static/web2py_src.zip
unzip web2py_src.zip
mv web2py/handlers/wsgihandler.py web2py/wsgihandler.py
rm web2py_src.zip
cp web2py/applications/vidjil/modules/defs.py.sample web2py/applications/vidjil/modules/defs.py
make install_web2py
chown -R www-data:www-data web2py
cd $CWD/web2py
sudo -u www-data python -c "from gluon.main import save_password; save_password('$PW',443)"
......
......@@ -14,7 +14,7 @@ if request.env.http_origin:
## return admin_panel
def index():
if auth.has_membership("admin"):
if auth.is_admin():
p = subprocess.Popen(["uptime"], stdout=subprocess.PIPE)
uptime, err = p.communicate()
......@@ -50,7 +50,7 @@ def monitor():
def showlog():
if auth.has_membership("admin"):
if auth.is_admin():
lines = []
......@@ -83,7 +83,7 @@ def showlog():
line["date"] = tmp[1]
line["date2"] = tmp[2].split(',')[0]
line["type"] = tmp[3]
line["file"] = tmp[5]
line["file"] = vidjil_utils.log_links(tmp[5])
if tmp[6] != "Creating":
if len(tmp) < 9:
......@@ -115,7 +115,7 @@ def showlog():
## to use after change in the upload folder
def repair_missing_files():
if auth.has_membership("admin"):
if auth.is_admin():
flist = ""
for row in db(db.sequence_file.id>0 and db.sequence_file.data_file != None).select() :
......@@ -134,7 +134,7 @@ def repair_missing_files():
def make_backup():
if auth.has_membership("admin"):
if auth.is_admin():
db.export_to_csv_file(open(defs.DB_BACKUP_FILE, 'wb'))
......@@ -144,7 +144,7 @@ def make_backup():
def repair():
if auth.has_membership("admin"):
if auth.is_admin():
flist = "fix creator "
for row in db(db.patient.creator == None).select() :
......
......@@ -5,6 +5,9 @@ if request.env.http_origin:
response.headers['Access-Control-Allow-Credentials'] = 'true'
response.headers['Access-Control-Max-Age'] = 86400
ACCESS_DENIED = "access denied"
def index():
if not auth.user :
res = {"redirect" : "default/user/login"}
......@@ -15,7 +18,7 @@ def index():
return dict(message=T('Configs'),
query=query,
isAdmin = auth.has_membership("admin"))
isAdmin = auth.is_admin())
def add():
......@@ -104,7 +107,7 @@ def delete():
def permission():
if (auth.has_permission('admin', 'patient', request.vars["id"]) ):
if (auth.can_modify_patient(request.vars["id"]) ):
query = db( (db.auth_group.role != 'admin') ).select()
......@@ -148,7 +151,7 @@ def permission():
#TODO refactor with patient/change_permission
def change_permission():
if (auth.has_permission('admin', 'config', request.vars["config_id"]) ):
if (auth.can_modify_config(request.vars["config_id"]) ):
error = ""
if request.vars["group_id"] == "" :
error += "missing group_id, "
......
......@@ -42,8 +42,11 @@ def logger():
lvl = logging.INFO
log.log(lvl, res)
def init_db():
if db(db.auth_user.id > 0).count() == 0:
def init_db(force=False):
if (db(db.auth_user.id > 0).count() == 0) or (force) :
for table in db :
table.truncate()
id_first_user=""
## création du premier user
......@@ -119,16 +122,16 @@ def run_request():
id_config = None
else:
id_config = request.vars["config_id"]
if not auth.has_permission("run", "results_file") and not auth.has_membership("admin") :
if not auth.can_process_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) :
if not auth.can_modify_patient(id_patient) :
error += "you do not have permission to launch process for this patient ("+str(id_patient)+"), "
if id_config:
if not auth.has_permission('read', 'config', id_config) :
if not auth.can_use_config(id_config) :
error += "you do not have permission to launch process for this config ("+str(id_config)+"), "
if error == "" :
......@@ -165,9 +168,8 @@ def get_data():
error += "id patient file needed, "
if not "config" in request.vars:
error += "id config needed, "
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"]+")"
if not auth.can_view_patient(request.vars["patient"]):
error += "you do not have permission to consult this patient ("+str(request.vars["patient"])+")"
query = db( ( db.fused_file.patient_id == request.vars["patient"] )
& (