about summary refs log tree commit diff
path: root/wqflask/utility
diff options
context:
space:
mode:
authorzsloan2020-04-21 16:54:41 -0500
committerGitHub2020-04-21 16:54:41 -0500
commit821465df32bfcbab73a654d1e2386f2a07f4695f (patch)
tree871c8502774cb7a8fce950f46285f62ba3d0b113 /wqflask/utility
parentd249d8fa90eabd47020926fdadbfe22ac2bba900 (diff)
parentcf8b4c21d81efaa01d347478dc126e6d9b53f7a9 (diff)
downloadgenenetwork2-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.py106
-rw-r--r--wqflask/utility/helper_functions.py6
-rw-r--r--wqflask/utility/hmac.py38
-rw-r--r--wqflask/utility/redis_tools.py80
-rw-r--r--wqflask/utility/tools.py12
-rw-r--r--wqflask/utility/webqtlUtil.py5
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']
 }
 
 #########################################