diff options
author | zsloan | 2020-04-21 16:54:41 -0500 |
---|---|---|
committer | GitHub | 2020-04-21 16:54:41 -0500 |
commit | 821465df32bfcbab73a654d1e2386f2a07f4695f (patch) | |
tree | 871c8502774cb7a8fce950f46285f62ba3d0b113 /wqflask/utility | |
parent | d249d8fa90eabd47020926fdadbfe22ac2bba900 (diff) | |
parent | cf8b4c21d81efaa01d347478dc126e6d9b53f7a9 (diff) | |
download | genenetwork2-821465df32bfcbab73a654d1e2386f2a07f4695f.tar.gz |
Merge pull request #2 from genenetwork/testing
Pulling changes from main branch
Diffstat (limited to 'wqflask/utility')
-rw-r--r-- | wqflask/utility/gen_geno_ob.py | 106 | ||||
-rw-r--r-- | wqflask/utility/helper_functions.py | 6 | ||||
-rw-r--r-- | wqflask/utility/hmac.py | 38 | ||||
-rw-r--r-- | wqflask/utility/redis_tools.py | 80 | ||||
-rw-r--r-- | wqflask/utility/tools.py | 12 | ||||
-rw-r--r-- | wqflask/utility/webqtlUtil.py | 5 |
6 files changed, 208 insertions, 39 deletions
diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py index 5172369f..23b0b650 100644 --- a/wqflask/utility/gen_geno_ob.py +++ b/wqflask/utility/gen_geno_ob.py @@ -1,5 +1,8 @@ from __future__ import absolute_import, division, print_function +import utility.logger +logger = utility.logger.getLogger(__name__ ) + class genotype(object): """ Replacement for reaper.Dataset so we can remove qtlreaper use while still generating mapping output figure @@ -34,8 +37,36 @@ class genotype(object): def __len__(self): return len(self.chromosomes) - def read_file(self, filename): + def read_rdata_output(self, qtl_results): + #ZS: This is necessary because R/qtl requires centimorgan marker positions, which it normally gets from the .geno file, but that doesn't exist for HET3-ITP (which only has RData), so it needs to read in the marker cM positions from the results + self.chromosomes = [] #ZS: Overwriting since the .geno file's contents are just placeholders + + this_chr = "" #ZS: This is so it can track when the chromosome changes as it iterates through markers + chr_ob = None + for marker in qtl_results: + locus = Locus(self) + if (str(marker['chr']) != this_chr) and this_chr != "X": #ZS: This is really awkward but works as a temporary fix + if this_chr != "": + self.chromosomes.append(chr_ob) + this_chr = str(marker['chr']) + if this_chr == "20": + this_chr = "X" + chr_ob = Chr(this_chr, self) + if 'chr' in marker: + locus.chr = str(marker['chr']) + if 'name' in marker: + locus.name = marker['name'] + if 'Mb' in marker: + locus.Mb = marker['Mb'] + if 'cM' in marker: + locus.cM = marker['cM'] + chr_ob.loci.append(locus) + + self.chromosomes.append(chr_ob) + + return self + def read_file(self, filename): with open(filename, 'r') as geno_file: lines = geno_file.readlines() @@ -47,20 +78,20 @@ class genotype(object): elif line[0] == "@": label = line.split(":")[0][1:] if label == "name": - self.group = line.split(":")[1] + self.group = line.split(":")[1].strip() elif label == "filler": - if line.split(":")[1] == "yes": + if line.split(":")[1].strip() == "yes": self.filler = True elif label == "type": - self.type = line.split(":")[1] + self.type = line.split(":")[1].strip() elif label == "mat": - self.mat = line.split(":")[1] + self.mat = line.split(":")[1].strip() elif label == "pat": - self.pat = line.split(":")[1] + self.pat = line.split(":")[1].strip() elif label == "het": - self.het = line.split(":")[1] + self.het = line.split(":")[1].strip() elif label == "unk": - self.unk = line.split(":")[1] + self.unk = line.split(":")[1].strip() else: continue elif line[:3] == "Chr": @@ -109,29 +140,42 @@ class Chr(object): return len(self.loci) def add_marker(self, marker_row): - self.loci.append(Locus(marker_row, self.geno_ob)) + self.loci.append(Locus(self.geno_ob, marker_row)) class Locus(object): - def __init__(self, marker_row, geno_ob): - self.chr = marker_row[0] - self.name = marker_row[1] - self.cM = float(marker_row[geno_ob.cm_column]) - self.Mb = float(marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else None - - geno_table = { - geno_ob.mat: -1, - geno_ob.pat: 1, - geno_ob.het: 0, - geno_ob.unk: "U" - } - + def __init__(self, geno_ob, marker_row = None): + self.chr = None + self.name = None + self.cM = None + self.Mb = None self.genotype = [] - if geno_ob.mb_exists: - start_pos = 4 - else: - start_pos = 3 - for allele in marker_row[start_pos:]: - if allele in geno_table.keys(): - self.genotype.append(geno_table[allele]) - else: #ZS: Some genotype appears that isn't specified in the metadata, make it unknown - self.genotype.append("U")
\ No newline at end of file + if marker_row: + self.chr = marker_row[0] + self.name = marker_row[1] + try: + self.cM = float(marker_row[geno_ob.cm_column]) + except: + self.cM = float(marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else 0 + try: + self.Mb = float(marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else None + except: + self.Mb = self.cM + + geno_table = { + geno_ob.mat: -1, + geno_ob.pat: 1, + geno_ob.het: 0, + geno_ob.unk: "U" + } + + self.genotype = [] + if geno_ob.mb_exists: + start_pos = 4 + else: + start_pos = 3 + + for allele in marker_row[start_pos:]: + if allele in geno_table.keys(): + self.genotype.append(geno_table[allele]) + else: #ZS: Some genotype appears that isn't specified in the metadata, make it unknown + self.genotype.append("U")
\ No newline at end of file diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py index 6980af4e..e7c04fef 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -4,7 +4,7 @@ from base.trait import GeneralTrait from base import data_set from base.species import TheSpecies -from wqflask import user_manager +from utility import hmac from flask import Flask, g @@ -41,9 +41,9 @@ def get_trait_db_obs(self, trait_db_list): self.trait_list = [] for trait in trait_db_list: - data, _separator, hmac = trait.rpartition(':') + data, _separator, hmac_string = trait.rpartition(':') data = data.strip() - assert hmac==user_manager.actual_hmac_creation(data), "Data tampering?" + assert hmac_string==hmac.hmac_creation(data), "Data tampering?" trait_name, dataset_name = data.split(":") if dataset_name == "Temp": dataset_ob = data_set.create_dataset(dataset_name=dataset_name, dataset_type="Temp", group_name=trait_name.split("_")[2]) diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py new file mode 100644 index 00000000..d8a0eace --- /dev/null +++ b/wqflask/utility/hmac.py @@ -0,0 +1,38 @@ +from __future__ import print_function, division, absolute_import + +import hmac +import hashlib + +from wqflask import app + +def hmac_creation(stringy): + """Helper function to create the actual hmac""" + + secret = app.config['SECRET_HMAC_CODE'] + + hmaced = hmac.new(secret, stringy, hashlib.sha1) + hm = hmaced.hexdigest() + # ZS: Leaving the below comment here to ask Pjotr about + # "Conventional wisdom is that you don't lose much in terms of security if you throw away up to half of the output." + # http://www.w3.org/QA/2009/07/hmac_truncation_in_xml_signatu.html + hm = hm[:20] + return hm + +def data_hmac(stringy): + """Takes arbitray data string and appends :hmac so we know data hasn't been tampered with""" + return stringy + ":" + hmac_creation(stringy) + +def url_for_hmac(endpoint, **values): + """Like url_for but adds an hmac at the end to insure the url hasn't been tampered with""" + + url = url_for(endpoint, **values) + + hm = hmac_creation(url) + if '?' in url: + combiner = "&" + else: + combiner = "?" + return url + combiner + "hm=" + hm + +app.jinja_env.globals.update(url_for_hmac=url_for_hmac, + data_hmac=data_hmac)
\ No newline at end of file diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py new file mode 100644 index 00000000..0754e16f --- /dev/null +++ b/wqflask/utility/redis_tools.py @@ -0,0 +1,80 @@ +from __future__ import print_function, division, absolute_import + +import simplejson as json + +import redis # used for collections +Redis = redis.StrictRedis() + +import logging + +from flask import (render_template, flash) + +from utility.logger import getLogger +logger = getLogger(__name__) + +def is_redis_available(): + try: + Redis.ping() + except: + return False + return True + +def get_user_id(column_name, column_value): + user_list = Redis.hgetall("users") + for key in user_list: + user_ob = json.loads(user_list[key]) + if column_name in user_ob and user_ob[column_name] == column_value: + return key + + return None + +def get_user_by_unique_column(column_name, column_value): + item_details = None + + user_list = Redis.hgetall("users") + if column_name != "user_id": + for key in user_list: + user_ob = json.loads(user_list[key]) + if column_name in user_ob and user_ob[column_name] == column_value: + item_details = user_ob + else: + item_details = json.loads(user_list[column_value]) + + return item_details + +def set_user_attribute(user_id, column_name, column_value): + user_info = json.loads(Redis.hget("users", user_id)) + user_info[column_name] = column_value + + Redis.hset("users", user_id, json.dumps(user_info)) + +def get_user_collections(user_id): + collections = None + collections = Redis.hget("collections", user_id) + + if collections: + return json.loads(collections) + else: + return [] + +def save_user(user, user_id): + Redis.hset("users", user_id, json.dumps(user)) + +def save_collections(user_id, collections_ob): + Redis.hset("collections", user_id, collections_ob) + +def save_verification_code(user_email, code): + Redis.hset("verification_codes", code, user_email) + +def check_verification_code(code): + email_address = None + user_details = None + email_address = Redis.hget("verification_codes", code) + return email_address + + if email_address: + user_details = get_user_by_unique_column('email_address', email_address) + return user_details + else: + return None + flash("Invalid code: Password reset code does not exist or might have expired!", "error") diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 8b2260f5..75bddb24 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -107,6 +107,9 @@ def js_path(module=None): return try_guix raise "No JS path found for "+module+" (if not in Guix check JS_GN_PATH)" +def reaper_command(guess=None): + return get_setting("REAPER_COMMAND",guess) + def gemma_command(guess=None): return assert_bin(get_setting("GEMMA_COMMAND",guess)) @@ -251,7 +254,6 @@ JS_GN_PATH = get_setting('JS_GN_PATH') GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') -GITHUB_AUTH_URL = None if GITHUB_CLIENT_ID != 'UNKNOWN' and GITHUB_CLIENT_SECRET: GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id=" + \ GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET @@ -261,7 +263,7 @@ ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = None if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: - ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \ + ORCID_AUTH_URL = "https://orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \ ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') @@ -274,6 +276,7 @@ SMTP_CONNECT = get_setting('SMTP_CONNECT') SMTP_USERNAME = get_setting('SMTP_USERNAME') SMTP_PASSWORD = get_setting('SMTP_PASSWORD') +REAPER_COMMAND = app_set("REAPER_COMMAND",reaper_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) assert(GEMMA_COMMAND is not None) PLINK_COMMAND = app_set("PLINK_COMMAND",plink_command()) @@ -285,11 +288,14 @@ assert_dir(TEMPDIR) JS_GUIX_PATH = get_setting("JS_GUIX_PATH") assert_dir(JS_GUIX_PATH) assert_dir(JS_GUIX_PATH+'/cytoscape-panzoom') + CSS_PATH = "UNKNOWN" # assert_dir(JS_PATH) -JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("Twitter-Post-Fetcher")) + +JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("javascript-twitter-post-fetcher")) assert_dir(JS_TWITTER_POST_FETCHER_PATH) assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js") + JS_CYTOSCAPE_PATH = get_setting("JS_CYTOSCAPE_PATH",js_path("cytoscape")) assert_dir(JS_CYTOSCAPE_PATH) assert_file(JS_CYTOSCAPE_PATH+'/cytoscape.min.js') diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py index 67a476e3..53661ae4 100644 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -52,11 +52,12 @@ ParInfo ={ 'AXB':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'], 'BXA':['BAF1', 'ABF1', 'C57BL/6J', 'A/J'], 'LXS':['LSF1', 'SLF1', 'ISS', 'ILS'], -'HXBBXH':['HSRBNF1', 'BNHSRF1', 'BN', 'HSR'], +'HXBBXH':['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv'], 'BayXSha':['BayXShaF1', 'ShaXBayF1', 'Bay-0','Shahdara'], 'ColXBur':['ColXBurF1', 'BurXColF1', 'Col-0','Bur-0'], 'ColXCvi':['ColXCviF1', 'CviXColF1', 'Col-0','Cvi'], -'SXM':['SMF1', 'MSF1', 'Steptoe','Morex'] +'SXM':['SMF1', 'MSF1', 'Steptoe','Morex'], +'HRDP':['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv'] } ######################################### |