diff options
Diffstat (limited to 'wqflask')
-rw-r--r-- | wqflask/tests/base/test_trait.py | 4 | ||||
-rw-r--r-- | wqflask/utility/redis_tools.py | 118 | ||||
-rw-r--r-- | wqflask/wqflask/__init__.py | 21 | ||||
-rw-r--r-- | wqflask/wqflask/db_info.py | 127 | ||||
-rw-r--r-- | wqflask/wqflask/marker_regression/run_mapping.py | 12 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/css/marker_regression.css | 4 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/javascript/search_results.js | 22 | ||||
-rw-r--r-- | wqflask/wqflask/templates/base.html | 4 | ||||
-rw-r--r-- | wqflask/wqflask/templates/gsearch_gene.html | 16 | ||||
-rw-r--r-- | wqflask/wqflask/templates/gsearch_pheno.html | 17 | ||||
-rw-r--r-- | wqflask/wqflask/templates/info_page.html | 92 | ||||
-rw-r--r-- | wqflask/wqflask/templates/mapping_results.html | 139 | ||||
-rw-r--r-- | wqflask/wqflask/templates/search_result_page.html | 15 | ||||
-rw-r--r-- | wqflask/wqflask/templates/tutorials.html | 1 | ||||
-rw-r--r-- | wqflask/wqflask/user_login.py | 4 | ||||
-rw-r--r-- | wqflask/wqflask/views.py | 62 |
16 files changed, 460 insertions, 198 deletions
diff --git a/wqflask/tests/base/test_trait.py b/wqflask/tests/base/test_trait.py index d333458a..9c3154f3 100644 --- a/wqflask/tests/base/test_trait.py +++ b/wqflask/tests/base/test_trait.py @@ -93,6 +93,6 @@ class TestRetrieveTraitInfo(unittest.TestCase): test_trait = retrieve_trait_info(trait=mock_trait, dataset=mock_dataset) self.assertEqual(test_trait.abbreviation, - "ファイルを画面毎に見て行くには、次のコマンドを使います。") + "ファイルを画面毎に見て行くには、次のコマンドを使います。".decode('utf-8')) self.assertEqual(test_trait.authors, - "Jane Doe かいと") + "Jane Doe かいと".decode('utf-8')) diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 4aba2b70..d855a7fa 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -2,23 +2,21 @@ import uuid import simplejson as json import datetime -import redis # used for collections - -import logging - -from flask import (render_template, flash) - -from utility import hmac +import redis # used for collections +from utility.hmac import hmac_creation from utility.logger import getLogger logger = getLogger(__name__) + def get_redis_conn(): Redis = redis.StrictRedis(port=6379) return Redis + Redis = get_redis_conn() + def is_redis_available(): try: Redis.ping() @@ -26,6 +24,7 @@ def is_redis_available(): return False return True + def get_user_id(column_name, column_value): user_list = Redis.hgetall("users") key_list = [] @@ -36,6 +35,7 @@ def get_user_id(column_name, column_value): return None + def get_user_by_unique_column(column_name, column_value): item_details = None @@ -50,9 +50,11 @@ def get_user_by_unique_column(column_name, column_value): return item_details + def get_users_like_unique_column(column_name, column_value): - """ - Like previous function, but this only checks if the input is a subset of a field and can return multiple results + """Like previous function, but this only checks if the input is a + subset of a field and can return multiple results + """ matched_users = [] @@ -72,7 +74,6 @@ def get_users_like_unique_column(column_name, column_value): return matched_users -# def search_users_by_unique_column(column_name, column_value): def set_user_attribute(user_id, column_name, column_value): user_info = json.loads(Redis.hget("users", user_id)) @@ -80,6 +81,7 @@ def set_user_attribute(user_id, 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) @@ -89,22 +91,27 @@ def get_user_collections(user_id): 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) if email_address: - user_details = get_user_by_unique_column('email_address', email_address) + user_details = get_user_by_unique_column( + 'email_address', email_address) if user_details: return user_details else: @@ -112,10 +119,12 @@ def check_verification_code(code): else: return None + def get_user_groups(user_id): - #ZS: Get the groups where a user is an admin or a member and return lists corresponding to those two sets of groups - admin_group_ids = [] #ZS: Group IDs where user is an admin - user_group_ids = [] #ZS: Group IDs where user is a regular user + # ZS: Get the groups where a user is an admin or a member and + # return lists corresponding to those two sets of groups + admin_group_ids = [] # ZS: Group IDs where user is an admin + user_group_ids = [] # ZS: Group IDs where user is a regular user groups_list = Redis.hgetall("groups") for key in groups_list: try: @@ -140,6 +149,7 @@ def get_user_groups(user_id): return admin_groups, user_groups + def get_group_info(group_id): group_json = Redis.hget("groups", group_id) group_info = None @@ -148,6 +158,7 @@ def get_group_info(group_id): return group_info + def get_group_by_unique_column(column_name, column_value): """ Get group by column; not sure if there's a faster way to do this """ @@ -156,7 +167,8 @@ def get_group_by_unique_column(column_name, column_value): all_group_list = Redis.hgetall("groups") for key in all_group_list: group_info = json.loads(all_group_list[key]) - if column_name == "admins" or column_name == "members": #ZS: Since these fields are lists, search in the list + # ZS: Since these fields are lists, search in the list + if column_name == "admins" or column_name == "members": if column_value in group_info[column_name]: matched_groups.append(group_info) else: @@ -165,9 +177,11 @@ def get_group_by_unique_column(column_name, column_value): return matched_groups + def get_groups_like_unique_column(column_name, column_value): - """ - Like previous function, but this only checks if the input is a subset of a field and can return multiple results + """Like previous function, but this only checks if the input is a + subset of a field and can return multiple results + """ matched_groups = [] @@ -176,7 +190,8 @@ def get_groups_like_unique_column(column_name, column_value): if column_name != "group_id": for key in group_list: group_info = json.loads(group_list[key]) - if column_name == "admins" or column_name == "members": #ZS: Since these fields are lists, search in the list + # ZS: Since these fields are lists, search in the list + if column_name == "admins" or column_name == "members": if column_value in group_info[column_name]: matched_groups.append(group_info) else: @@ -188,13 +203,15 @@ def get_groups_like_unique_column(column_name, column_value): return matched_groups -def create_group(admin_user_ids, member_user_ids = [], group_name = "Default Group Name"): + +def create_group(admin_user_ids, member_user_ids=[], + group_name="Default Group Name"): group_id = str(uuid.uuid4()) new_group = { - "id" : group_id, + "id": group_id, "admins": admin_user_ids, - "members" : member_user_ids, - "name" : group_name, + "members": member_user_ids, + "name": group_name, "created_timestamp": datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p'), "changed_timestamp": datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') } @@ -203,8 +220,9 @@ def create_group(admin_user_ids, member_user_ids = [], group_name = "Default Gro return new_group + def delete_group(user_id, group_id): - #ZS: If user is an admin of a group, remove it from the groups hash + # ZS: If user is an admin of a group, remove it from the groups hash group_info = get_group_info(group_id) if user_id in group_info["admins"]: Redis.hdel("groups", group_id) @@ -212,9 +230,15 @@ def delete_group(user_id, group_id): else: None -def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS "admins" is just to indicate whether the users should be added to the groups admins or regular users set + +# ZS "admins" is just to indicate whether the users should be added to +# the groups admins or regular users set +def add_users_to_group(user_id, group_id, user_emails=[], admins=False): group_info = get_group_info(group_id) - if user_id in group_info["admins"]: #ZS: Just to make sure that the user is an admin for the group, even though they shouldn't be able to reach this point unless they are + # ZS: Just to make sure that the user is an admin for the group, + # even though they shouldn't be able to reach this point unless + # they are + if user_id in group_info["admins"]: if admins: group_users = set(group_info["admins"]) else: @@ -229,25 +253,36 @@ def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS else: group_info["members"] = list(group_users) - group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime( + '%b %d %Y %I:%M%p') Redis.hset("groups", group_id, json.dumps(group_info)) return group_info else: return None -def remove_users_from_group(user_id, users_to_remove_ids, group_id, user_type = "members"): #ZS: User type is because I assume admins can remove other admins + +# ZS: User type is because I assume admins can remove other admins +def remove_users_from_group(user_id, + users_to_remove_ids, + group_id, + user_type="members"): group_info = get_group_info(group_id) if user_id in group_info["admins"]: users_to_remove_set = set(users_to_remove_ids) - if user_type == "admins" and user_id in users_to_remove_set: #ZS: Make sure an admin can't remove themselves from a group, since I imagine we don't want groups to be able to become admin-less + # ZS: Make sure an admin can't remove themselves from a group, + # since I imagine we don't want groups to be able to become + # admin-less + if user_type == "admins" and user_id in users_to_remove_set: users_to_remove_set.remove(user_id) group_users = set(group_info[user_type]) group_users -= users_to_remove_set group_info[user_type] = list(group_users) - group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime( + '%b %d %Y %I:%M%p') Redis.hset("groups", group_id, json.dumps(group_info)) + def change_group_name(user_id, group_id, new_name): group_info = get_group_info(group_id) if user_id in group_info["admins"]: @@ -257,22 +292,28 @@ def change_group_name(user_id, group_id, new_name): else: return None + def get_resources(): resource_list = Redis.hgetall("resources") return resource_list + def get_resource_id(dataset, trait_id=None): resource_id = False if dataset.type == "Publish": if trait_id: - resource_id = hmac.hmac_creation("{}:{}:{}".format('dataset-publish', dataset.id, trait_id)) + resource_id = hmac_creation("{}:{}:{}".format( + 'dataset-publish', dataset.id, trait_id)) elif dataset.type == "ProbeSet": - resource_id = hmac.hmac_creation("{}:{}".format('dataset-probeset', dataset.id)) + resource_id = hmac_creation( + "{}:{}".format('dataset-probeset', dataset.id)) elif dataset.type == "Geno": - resource_id = hmac.hmac_creation("{}:{}".format('dataset-geno', dataset.id)) + resource_id = hmac_creation( + "{}:{}".format('dataset-geno', dataset.id)) return resource_id + def get_resource_info(resource_id): resource_info = Redis.hget("resources", resource_id) if resource_info: @@ -280,17 +321,23 @@ def get_resource_info(resource_id): else: return None + def add_resource(resource_info, update=True): if 'trait' in resource_info['data']: - resource_id = hmac.hmac_creation('{}:{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']), str(resource_info['data']['trait']))) + resource_id = hmac_creation('{}:{}:{}'.format( + str(resource_info['type']), str( + resource_info['data']['dataset']), + str(resource_info['data']['trait']))) else: - resource_id = hmac.hmac_creation('{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']))) + resource_id = hmac_creation('{}:{}'.format( + str(resource_info['type']), str(resource_info['data']['dataset']))) if update or not Redis.hexists("resources", resource_id): Redis.hset("resources", resource_id, json.dumps(resource_info)) return resource_info + def add_access_mask(resource_id, group_id, access_mask): the_resource = get_resource_info(resource_id) the_resource['group_masks'][group_id] = access_mask @@ -299,8 +346,9 @@ def add_access_mask(resource_id, group_id, access_mask): return the_resource + def change_resource_owner(resource_id, new_owner_id): - the_resource= get_resource_info(resource_id) + the_resource = get_resource_info(resource_id) the_resource['owner_id'] = new_owner_id Redis.delete("resource") diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index e73f833f..d484e525 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -10,13 +10,24 @@ logging.basicConfig(level=logging.INFO) app = Flask(__name__) -app.config.from_envvar('GN2_SETTINGS') # See http://flask.pocoo.org/docs/config/#configuring-from-files +# See http://flask.pocoo.org/docs/config/#configuring-from-files # Note no longer use the badly named WQFLASK_OVERRIDES (nyi) - +app.config.from_envvar('GN2_SETTINGS') app.jinja_env.globals.update( - undefined = jinja2.StrictUndefined, - numify = formatting.numify -) + undefined=jinja2.StrictUndefined, + numify=formatting.numify) from wqflask.api import router +from wqflask import group_manager +from wqflask import resource_manager +from wqflask import search_results +from wqflask import export_traits +from wqflask import gsearch +from wqflask import update_search_results +from wqflask import docs +from wqflask import news +from wqflask import db_info +from wqflask import user_login +from wqflask import user_session + import wqflask.views diff --git a/wqflask/wqflask/db_info.py b/wqflask/wqflask/db_info.py new file mode 100644 index 00000000..f04e38bf --- /dev/null +++ b/wqflask/wqflask/db_info.py @@ -0,0 +1,127 @@ +import httplib, urllib2
+import re
+
+from flask import Flask, g
+
+from utility.logger import getLogger
+logger = getLogger(__name__ )
+
+class InfoPage(object):
+ def __init__(self, start_vars):
+ self.info = None
+ self.gn_accession_id = None
+ if 'gn_accession_id' in start_vars:
+ self.gn_accession_id = start_vars['gn_accession_id']
+ self.info_page_name = start_vars['info_page_name']
+
+ self.get_info()
+ self.get_datasets_list()
+
+ def get_info(self, create=False):
+ query_base = ("SELECT InfoPageName, GN_AccesionId, Species.MenuName, Species.TaxonomyId, Tissue.Name, InbredSet.Name, " +
+ "GeneChip.GeneChipName, GeneChip.GeoPlatform, AvgMethod.Name, Datasets.DatasetName, Datasets.GeoSeries, " +
+ "Datasets.PublicationTitle, DatasetStatus.DatasetStatusName, Datasets.Summary, Datasets.AboutCases, " +
+ "Datasets.AboutTissue, Datasets.AboutDataProcessing, Datasets.Acknowledgment, Datasets.ExperimentDesign, " +
+ "Datasets.Contributors, Datasets.Citation, Datasets.Notes, Investigators.FirstName, Investigators.LastName, " +
+ "Investigators.Address, Investigators.City, Investigators.State, Investigators.ZipCode, Investigators.Country, " +
+ "Investigators.Phone, Investigators.Email, Investigators.Url, Organizations.OrganizationName, " +
+ "InvestigatorId, DatasetId, DatasetStatusId, Datasets.AboutPlatform, InfoFileTitle, Specifics " +
+ "FROM InfoFiles " +
+ "LEFT JOIN Species USING (SpeciesId) " +
+ "LEFT JOIN Tissue USING (TissueId) " +
+ "LEFT JOIN InbredSet USING (InbredSetId) " +
+ "LEFT JOIN GeneChip USING (GeneChipId) " +
+ "LEFT JOIN AvgMethod USING (AvgMethodId) " +
+ "LEFT JOIN Datasets USING (DatasetId) " +
+ "LEFT JOIN Investigators USING (InvestigatorId) " +
+ "LEFT JOIN Organizations USING (OrganizationId) " +
+ "LEFT JOIN DatasetStatus USING (DatasetStatusId) WHERE ")
+
+ if self.gn_accession_id:
+ final_query = query_base + "GN_AccesionId = {}".format(self.gn_accession_id)
+ results = g.db.execute(final_query).fetchone()
+ if self.info_page_name and not results:
+ final_query = query_base + "InfoPageName={}".format(self.info_page_name)
+ elif self.info_page_name:
+ final_query = query_base + "InfoPageName={}".format(self.info_page_name)
+ results = g.db.execute(final_query).fetchone()
+ else:
+ raise 'No correct parameter found'
+
+ if results:
+ self.info = process_query_results(results)
+
+ if (not results or len(results) < 1) and self.info_page_name and create:
+ insert_sql = "INSERT INTO InfoFiles SET InfoFiles.InfoPageName={}".format(self.info_page_name)
+ return self.get_info()
+
+ if not self.gn_accession_id and self.info:
+ self.gn_accession_id = self.info['accession_id']
+ if not self.info_page_name and self.info:
+ self.info_page_name = self.info['info_page_name']
+
+ def get_datasets_list(self):
+ self.filelist = []
+ try:
+ response = urllib2.urlopen("http://datafiles.genenetwork.org/download/GN%s" % self.gn_accession_id)
+ data = response.read()
+
+ matches = re.findall(r"<tr>.+?</tr>", data, re.DOTALL)
+ for i, match in enumerate(matches):
+ if i == 0:
+ continue
+ cells = re.findall(r"<td.+?>.+?</td>", match, re.DOTALL)
+ full_filename = re.search(r"<a href=\"(.+?)\"", cells[1], re.DOTALL).group(1).strip()
+ filename = full_filename.split("/")[-1]
+ filesize = re.search(r">(.+?)<", cells[2]).group(1).strip()
+ filedate = "N/A" #ZS: Since we can't get it for now
+
+ self.filelist.append([filename, filedate, filesize])
+ except Exception, e:
+ pass
+
+def process_query_results(results):
+ info_ob = {
+ 'info_page_name': results[0],
+ 'accession_id': results[1],
+ 'menu_name': results[2],
+ 'taxonomy_id': results[3],
+ 'tissue_name': results[4],
+ 'group_name': results[5],
+ 'gene_chip_name': results[6],
+ 'geo_platform': results[7],
+ 'avg_method_name': results[8],
+ 'dataset_name': results[9],
+ 'geo_series': results[10],
+ 'publication_title': results[11],
+ 'dataset_status_name': results[12],
+ 'dataset_summary': results[13],
+ 'about_cases': results[14],
+ 'about_tissue': results[15],
+ 'about_data_processing': results[16],
+ 'acknowledgement': results[17],
+ 'experiment_design': results[18],
+ 'contributors': results[19],
+ 'citation': results[20],
+ 'notes': results[21],
+ 'investigator_firstname': results[22],
+ 'investigator_lastname': results[23],
+ 'investigator_address': results[24],
+ 'investigator_city': results[25],
+ 'investigator_state': results[26],
+ 'investigator_zipcode': results[27],
+ 'investigator_country': results[28],
+ 'investigator_phone': results[29],
+ 'investigator_email': results[30],
+ 'investigator_url': results[31],
+ 'organization_name': results[32],
+ 'investigator_id': results[33],
+ 'dataset_id': results[34],
+ 'dataset_status_is': results[35],
+ 'about_platform': results[36],
+ 'info_file_title': results[37],
+ 'specifics': results[38]
+ }
+
+ return info_ob
+
\ No newline at end of file diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index c606cf53..f42d2315 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -399,9 +399,7 @@ class RunMapping(object): rs = marker['name'], pos = this_ps ) - #if 'p_value' in marker: - # logger.debug("P EXISTS:", marker['p_value']) - #else: + if 'lrs_value' in marker and marker['lrs_value'] > 0: browser_marker['p_wald'] = 10**-(marker['lrs_value']/4.61) elif 'lod_score' in marker and marker['lod_score'] > 0: @@ -414,7 +412,13 @@ class RunMapping(object): if marker['chr'] > 0 or marker['chr'] == "X" or marker['chr'] == "X/Y": if marker['chr'] > highest_chr or marker['chr'] == "X" or marker['chr'] == "X/Y": highest_chr = marker['chr'] - if ('lod_score' in list(marker.keys())) or ('lrs_value' in list(marker.keys())): + if ('lod_score' in marker.keys()) or ('lrs_value' in marker.keys()): + if 'Mb' in marker.keys(): + marker['display_pos'] = "Chr" + str(marker['chr']) + ": " + "{:.3f}".format(marker['Mb']) + elif 'cM' in marker.keys(): + marker['display_pos'] = "Chr" + str(marker['chr']) + ": " + "{:.3f}".format(marker['cM']) + else: + marker['display_pos'] = "N/A" self.qtl_results.append(marker) with Bench("Exporting Results"): diff --git a/wqflask/wqflask/static/new/css/marker_regression.css b/wqflask/wqflask/static/new/css/marker_regression.css index f1a26a83..e0a5ceea 100644 --- a/wqflask/wqflask/static/new/css/marker_regression.css +++ b/wqflask/wqflask/static/new/css/marker_regression.css @@ -62,6 +62,10 @@ table.dataTable tbody td { padding: 4px 20px 2px 10px; } +table.dataTable tbody tr.selected { + background-color: #ffee99; +} + table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td { border-top: 1px solid #ccc; border-right: 1px solid #ccc; diff --git a/wqflask/wqflask/static/new/javascript/search_results.js b/wqflask/wqflask/static/new/javascript/search_results.js index 4e87d67a..685d6291 100644 --- a/wqflask/wqflask/static/new/javascript/search_results.js +++ b/wqflask/wqflask/static/new/javascript/search_results.js @@ -259,14 +259,16 @@ $(function() { let naturalAsc = $.fn.dataTableExt.oSort["natural-ci-asc"] let naturalDesc = $.fn.dataTableExt.oSort["natural-ci-desc"] + let na_equivalent_vals = ["N/A", "--", ""]; //ZS: Since there are multiple values that should be treated the same as N/A + function sort_NAs(a, b, sort_function){ - if (a === "N/A" && b === "N/A") { + if ( na_equivalent_vals.includes(a) && na_equivalent_vals.includes(b)) { return 0; } - if (a === "N/A"){ + if (na_equivalent_vals.includes(a)){ return 1 } - if (b === "N/A") { + if (na_equivalent_vals.includes(b)) { return -1; } return sort_function(a, b) @@ -281,4 +283,18 @@ $(function() { } }); + $.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col ) + { + return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { + return $('input', td).prop('checked') ? '1' : '0'; + } ); + }; + + $.fn.dataTable.ext.order['dom-inner-text'] = function ( settings, col ) + { + return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { + return $(td).text(); + } ); + } + });
\ No newline at end of file diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 50562200..e6802cc4 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -4,7 +4,9 @@ <head> <meta charset="utf-8"> - <title>{% block title %}{% endblock %}</title> + + <title>{% block title %}{% endblock %} GeneNetwork 2</title> + <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png"> diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index 478d6f5f..d2c78d65 100644 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -59,20 +59,6 @@ </script> <script type="text/javascript" charset="utf-8"> - $.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $('input', td).prop('checked') ? '1' : '0'; - } ); - }; - - $.fn.dataTable.ext.order['dom-inner-text'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $(td).text(); - } ); - } - $(document).ready( function () { $('#trait_table tr').click(function(event) { @@ -252,7 +238,7 @@ 'sDom': "pitirp", 'autoWidth': true, 'iDisplayLength': 500, - 'deferRender': true, + 'deferRender': false, 'paging': true, 'orderClasses': true, 'processing': true, diff --git a/wqflask/wqflask/templates/gsearch_pheno.html b/wqflask/wqflask/templates/gsearch_pheno.html index eb998d15..c44231f3 100644 --- a/wqflask/wqflask/templates/gsearch_pheno.html +++ b/wqflask/wqflask/templates/gsearch_pheno.html @@ -59,20 +59,6 @@ </script> <script type="text/javascript" charset="utf-8"> - $.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $('input', td).prop('checked') ? '1' : '0'; - } ); - }; - - $.fn.dataTable.ext.order['dom-inner-text'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $(td).text(); - } ); - } - $(document).ready( function () { $('#trait_table tr').click(function(event) { @@ -172,6 +158,7 @@ 'title': "Record", 'type': "natural", 'data': null, + 'orderDataType': "dom-inner-text", 'render': function(data, type, row, meta) { return '<a target="_blank" href="/show_trait?trait_id=' + data.name + '&dataset=' + data.dataset + '">' + data.display_name + '</a>' } @@ -252,7 +239,7 @@ 'order': [[1, "asc" ]], 'sDom': "pitirp", 'autoWidth': false, - 'deferRender': true, + 'deferRender': false, 'iDisplayLength': 500, 'paging': true, 'orderClasses': true, diff --git a/wqflask/wqflask/templates/info_page.html b/wqflask/wqflask/templates/info_page.html new file mode 100644 index 00000000..d8b7d74c --- /dev/null +++ b/wqflask/wqflask/templates/info_page.html @@ -0,0 +1,92 @@ +{% extends "base.html" %}
+{% block title %}Policies{% endblock %}
+{% block content %}
+
+<h1 id="parent-fieldname-title">Data Set Group: {{ info.dataset_name }}
+<!--<a href="/infoshare/manager/member-studies-edit.html?DatasetId=%s"><img src="/images/modify.gif" alt="modify this page" border="0" valign="middle"></a>-->
+<span style="color:red;">{{ info.info_page_name }}</span>
+</h1>
+<table border="0" width="100%">
+<tr>
+<td valign="top" width="50%">
+<table name="info_table" cellSpacing=0 cellPadding=5 width=100% border=0>
+ <tr><td><b>Data Set:</b> {{ info.info_file_title }} <!--<a href="/infoshare/manager/member-infofile-edit.html?GN_AccesionId=%s"><img src="/images/modify.gif" alt="modify this page" border="0" valign="middle"></a>--></td></tr>
+ <tr><td><b>GN Accession:</b> GN{{ gn_accession_id }}</td></tr>
+ <tr><td><b>GEO Series:</b> <a href="http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={{ info.geo_series }}" target="_blank">{{ info.geo_series }}</a></td></tr>
+ <tr><td><b>Title:</b> {{ info.publication_title }}</td></tr>
+ <tr><td><b>Organism:</b> <a href="http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id={{ info.taxonomy_id }}" target="_blank">{{ info.menu_name }}</a></td></tr>
+ <tr><td><b>Group:</b> {{ info.group_name }}</td></tr>
+ <tr><td><b>Tissue:</b> {{ info.tissue_name }}</td></tr>
+ <tr><td><b>Dataset Status:</b> {{ info.dataset_status_name }}</td></tr>
+ <tr><td><b>Platforms:</b> <a href="http://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={{ info.geo_platform }}" target="_blank">{{ info.gene_chip_name }}</a></td></tr>
+ <tr><td><b>Normalization:</b> {{ info.avg_method_name }}</td></tr>
+</table>
+</td>
+<td valign="top" width="50%">
+<table border="0" width="100%">
+ <tr>
+ <td><b>Contact Information</b></td>
+ </tr>
+ <tr>
+ <td>
+ {{ info.investigator_first_name }} {{ info.inveestigator_last_name }}<br>
+ {{ info.organization_name }} <br>
+ {{ info.investigator_address }}<br>
+ {{ info.investigator_city }}, {{ info.investigator_state }} {{ info.investigator_zipcode }} {{ info.investigator_country }}<br>
+ Tel. {{ info.investigator_phone }}<br>
+ {{ info.investigator_email }}<br>
+ <a href="{{ info.investigator_url }}" target="_blank">Website</a>
+ </td>
+ </tr>
+
+<tr>
+ <td><b>Download datasets and supplementary data files</b></td>
+</tr>
+<tr>
+ <td>
+ <ul style="line-height: 160%">
+ {% for file in filelist %}
+ <li><a href="http://datafiles.genenetwork.org/download/GN{{ gn_accession_id }}/{{ file[0] }}">{{ file[0] }} ({{ file[2] }})</a></li>
+ {% endfor %}
+ </ul>
+ </td>
+</tr>
+
+<tr><td>
+</td></tr>
+
+</table>
+</td>
+</tr>
+</table>
+<HR>
+<p>
+<table name="info_table" width="100%" border="0" cellpadding="5" cellspacing="0">
+<tr><td><span style="font-size:115%%;font-weight:bold;">Specifics of this Data Set:</span></td></tr>
+ <tr><td> {{ info.specifics|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%%;font-weight:bold;">Summary:</span></td></tr>
+ <tr><td> {{ info.dataset_summary|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About the cases used to generate this set of data:</span></td></tr>
+ <tr><td> {{ info.about_cases|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About the tissue used to generate this set of data:</span></td></tr>
+ <tr><td> {{ info.about_tissue|safe }}<br><br></td></tr>
+ <tr><td><span style="font-size:115%; font-weight:bold;">About the array platform:</span></td></tr>
+ <tr><td> {{ info.about_platform|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">About data values and data processing:</span></td></tr>
+ <tr><td> {{ info.about_data_processing|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Notes:</span></td></tr>
+ <tr><td> {{ info.notes|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Experiment Type:</span></td></tr>
+ <tr><td> {{ info.experiment_design|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Contributor:</span></td></tr>
+ <tr><td> {{ info.contributors|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Citation:</span></td></tr>
+ <tr><td> {{ info.citation|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Data source acknowledgment:</span></td></tr>
+ <tr><td> {{ info.acknowledgement|safe }}<br><br></td></tr>
+<tr><td><span style="font-size:115%; font-weight:bold;">Study Id:</span></td></tr>
+ <tr><td> {{ info.dataset_id }}<br><br></td></tr>
+</table>
+</p>
+
+{% endblock %}
\ No newline at end of file diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index 8edda548..41d760c0 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -228,71 +228,61 @@ <button class="btn btn-success" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button> <br /> <br /> - <div id="table_container" style="width:{% if 'additive' in trimmed_markers[0] %}500{% else %}470{% endif %}px;"> - <table id="trait_table" class="table-hover table-striped cell-border dataTable no-footer"> - <thead> - <tr> - <th></th> - <th>Row</th> - <th>Marker</th> - <th>{{ LRS_LOD }}</th> - <th>Chr</th> - {% if plotScale != "physic" %} - <th>cM</th> - {% else %} - <th align="right">Mb</th> - {% endif %} - {% if 'additive' in trimmed_markers[0] %} - <th>Add Eff</th> - {% endif %} - {% if 'dominance' in trimmed_markers[0] and dataset.group.genetic_type != "riset" %} - <th>Dom Eff</th> - {% endif %} - </tr> - </thead> - <tbody> - {% for marker in trimmed_markers %} - <tr> - <td align="center" style="padding: 1px 0px 1px 0px;"> - <input type="checkbox" name="selectCheck" - class="checkbox trait_checkbox" - value="{{ data_hmac('{}:{}Geno'.format(marker.name, dataset.group.name)) }}"> - </td> - <td align="right">{{ loop.index }}</td> - <td>{% if geno_db_exists == "True" %}<a href="/show_trait?trait_id={{ marker.name }}&dataset={{ dataset.group.name }}Geno">{{ marker.name }}</a>{% else %}{{ marker.name }}{% endif %}</td> - {% if LRS_LOD == "LOD" or LRS_LOD == "-log(p)" %} - {% if 'lod_score' in marker %} - <td align="right">{{ '%0.2f' | format(marker.lod_score|float) }}</td> - {% else %} - <td align="right">{{ '%0.2f' | format(marker.lrs_value|float / 4.61) }}</td> - {% endif %} - {% else %} - {% if 'lod_score' in marker %} - <td align="right">{{ '%0.2f' | format(marker.lod_score|float * 4.61) }}</td> - {% else %} - <td align="right">{{ '%0.2f' | format(marker.lrs_value|float) }}</td> - {% endif %} - {% endif %} - <td align="right">{{marker.chr}}</td> - {% if plotScale != "physic" %} - {% if 'cM' in marker %} - <td align="right">{{ '%0.3f' | format(marker.cM|float) }}</td> - {% else %} - <td align="right">{{ '%0.3f' | format(marker.Mb|float) }}</td> - {% endif %} - {% else %} - <td align="right">{{ '%0.6f' | format(marker.Mb|float) }}</td> - {% endif %} - {% if 'additive' in marker %} - <td align="right">{{ '%0.3f' | format(marker.additive|float) }}</td> - {% endif %} - {% if 'dominance' in marker and dataset.group.genetic_type != "riset" %} - <td align="right">{{ '%0.2f' | format(marker.dominance|float) }}</td> - {% endif %} - </tr> - {% endfor %} - </tbody> - </table> + <div id="table_container" style="width:{% if 'additive' in trimmed_markers[0] %}600{% else %}550{% endif %}px;"> + <table id="trait_table" class="table-hover table-striped cell-border dataTable no-footer"> + <thead> + <tr> + <th></th> + <th>Row</th> + <th>Marker</th> + {% if LRS_LOD == "-log(p)" %} + <th>–log(p)</th> + {% else %} + <th>{{ LRS_LOD }}</th> + {% endif %} + <th>Position ({% if plotScale == "physic" %}Mb{% else %}cM{% endif %})</th> + {% if 'additive' in trimmed_markers[0] %} + <th>Add Eff</th> + {% endif %} + {% if 'dominance' in trimmed_markers[0] and dataset.group.genetic_type != "riset" %} + <th>Dom Eff</th> + {% endif %} + </tr> + </thead> + <tbody> + {% for marker in trimmed_markers %} + <tr> + <td align="center" style="padding: 1px 0px 1px 0px;"> + <input type="checkbox" name="selectCheck" + class="checkbox trait_checkbox" + value="{{ data_hmac('{}:{}Geno'.format(marker.name, dataset.group.name)) }}"> + </td> + <td align="right">{{ loop.index }}</td> + <td>{% if geno_db_exists == "True" %}<a href="/show_trait?trait_id={{ marker.name }}&dataset={{ dataset.group.name }}Geno">{{ marker.name }}</a>{% else %}{{ marker.name }}{% endif %}</td> + {% if LRS_LOD == "LOD" or LRS_LOD == "-log(p)" %} + {% if 'lod_score' in marker %} + <td align="right">{{ '%0.2f' | format(marker.lod_score|float) }}</td> + {% else %} + <td align="right">{{ '%0.2f' | format(marker.lrs_value|float / 4.61) }}</td> + {% endif %} + {% else %} + {% if 'lod_score' in marker %} + <td align="right">{{ '%0.2f' | format(marker.lod_score|float * 4.61) }}</td> + {% else %} + <td align="right">{{ '%0.2f' | format(marker.lrs_value|float) }}</td> + {% endif %} + {% endif %} + <td align="right">{{ marker.display_pos }}</td> + {% if 'additive' in marker %} + <td align="right">{{ '%0.3f' | format(marker.additive|float) }}</td> + {% endif %} + {% if 'dominance' in marker and dataset.group.genetic_type != "riset" %} + <td align="right">{{ '%0.2f' | format(marker.dominance|float) }}</td> + {% endif %} + </tr> + {% endfor %} + </tbody> + </table> </div> </div> {% elif selectedChr != -1 and plotScale =="physic" and (dataset.group.species == 'mouse' or dataset.group.species == 'rat') %} @@ -362,8 +352,7 @@ "columns": [ { "type": "natural", "width": "5%" }, { "type": "natural", "width": "8%" }, - { "type": "natural", "width": "25%" }, - { "type": "natural" }, + { "type": "natural", "width": "20%" }, { "type": "natural" }, { "type": "natural" }{% if 'additive' in qtlresults[0] %}, { "type": "natural" }{% endif %}{% if 'dominance' in qtlresults[0] and dataset.group.genetic_type != "riset" %}, @@ -395,16 +384,16 @@ $('td', row).eq(9).attr("align", "right"); }, "columns": [ - { "bSortable": false}, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural" }, - { "type": "natural" }, + { "orderDataType": "dom-checkbox" }, + { "type": "natural"}, + { "type": "natural" , "orderDataType": "dom-inner-text" }, + { "type": "natural" , "orderDataType": "dom-inner-text" }, + { "type": "natural" , "orderDataType": "dom-inner-text" }, { "type": "natural" }, { "type": "natural" }, + { "type": "natural-minus-na" }, + { "type": "natural-minus-na" }, + { "type": "natural-minus-na" , "orderDataType": "dom-inner-text" }, { "type": "natural" } ], "columnDefs": [ { diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 53373b41..282e752d 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -174,21 +174,6 @@ </script> <script type="text/javascript" charset="utf-8"> - - $.fn.dataTable.ext.order['dom-checkbox'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $('input', td).prop('checked') ? '1' : '0'; - } ); - }; - - $.fn.dataTable.ext.order['dom-inner-text'] = function ( settings, col ) - { - return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) { - return $(td).text(); - } ); - } - $(document).ready( function () { $('#trait_table tr').click(function(event) { diff --git a/wqflask/wqflask/templates/tutorials.html b/wqflask/wqflask/templates/tutorials.html index 3e6ef01c..f9d12ba5 100644 --- a/wqflask/wqflask/templates/tutorials.html +++ b/wqflask/wqflask/templates/tutorials.html @@ -15,3 +15,4 @@ and initial mapping results for Rat GWAS P50 as implemented in GeneNetwork.org</ </TR></TABLE> {% endblock %} + diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index 28d58712..cb2edbc5 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -451,7 +451,9 @@ def register_user(params): user_details['confirmed'] = 1 user_details['registration_info'] = basic_info() - save_user(user_details, user_details['user_id']) + + if len(errors) == 0: + save_user(user_details, user_details['user_id']) return errors diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 7e0b1c40..7fdc62e5 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -27,14 +27,7 @@ import array import sqlalchemy from wqflask import app from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for, send_file -from wqflask import group_manager -from wqflask import resource_manager -from wqflask import search_results -from wqflask import export_traits -from wqflask import gsearch -from wqflask import update_search_results -from wqflask import docs -from wqflask import news + from wqflask.submit_bnw import get_bnw_input from base.data_set import create_dataset, DataSet # Used by YAML in marker_regression from wqflask.show_trait import show_trait @@ -51,6 +44,12 @@ from wqflask.correlation import corr_scatter_plot from wqflask.wgcna import wgcna_analysis from wqflask.ctl import ctl_analysis from wqflask.snp_browser import snp_browser +from wqflask.search_results import SearchResultPage +from wqflask.export_traits import export_search_results_csv +from wqflask.gsearch import GSearch +from wqflask.update_search_results import GSearch as UpdateGSearch +from wqflask.docs import Docs +from wqflask.db_info import InfoPage from utility import temp_data from utility.tools import SQL_URI, TEMPDIR, USE_REDIS, USE_GN_SERVER, GN_SERVER_URL, GN_VERSION, JS_TWITTER_POST_FETCHER_PATH, JS_GUIX_PATH, CSS_PATH @@ -64,9 +63,6 @@ from utility.benchmark import Bench from pprint import pformat as pf -from wqflask import user_login -from wqflask import user_session - from wqflask import collect from wqflask.database import db_session @@ -213,7 +209,7 @@ def search_page(): logger.info("Skipping Redis cache (USE_REDIS=False)") logger.info("request.args is", request.args) - the_search = search_results.SearchResultPage(request.args) + the_search = SearchResultPage(request.args) result = the_search.__dict__ valid_search = result['search_term_exists'] @@ -229,7 +225,7 @@ def search_page(): @app.route("/gsearch", methods=('GET',)) def gsearchact(): logger.info(request.url) - result = gsearch.GSearch(request.args).__dict__ + result = GSearch(request.args).__dict__ type = request.args['type'] if type == "gene": return render_template("gsearch_gene.html", **result) @@ -240,7 +236,7 @@ def gsearchact(): def gsearch_updating(): logger.info("REQUEST ARGS:", request.values) logger.info(request.url) - result = update_search_results.GSearch(request.args).__dict__ + result = UpdateGSearch(request.args).__dict__ return result['results'] # type = request.args['type'] # if type == "gene": @@ -253,7 +249,7 @@ def docedit(): logger.info(request.url) try: if g.user_session.record['user_email_address'] == "zachary.a.sloan@gmail.com" or g.user_session.record['user_email_address'] == "labwilliams@gmail.com": - doc = docs.Docs(request.args['entry'], request.args) + doc = Docs(request.args['entry'], request.args) return render_template("docedit.html", **doc.__dict__) else: return "You shouldn't be here!" @@ -269,7 +265,7 @@ def generated_file(filename): @app.route("/help") def help(): logger.info(request.url) - doc = docs.Docs("help", request.args) + doc = Docs("help", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/wgcna_setup", methods=('POST',)) @@ -304,54 +300,54 @@ def ctl_results(): @app.route("/news") def news(): - doc = docs.Docs("news", request.args) + doc = Docs("news", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/references") def references(): - doc = docs.Docs("references", request.args) + doc = Docs("references", request.args) return render_template("docs.html", **doc.__dict__) #return render_template("reference.html") @app.route("/intro") def intro(): - doc = docs.Docs("intro", request.args) + doc = Docs("intro", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/policies") def policies(): - doc = docs.Docs("policies", request.args) + doc = Docs("policies", request.args) #return render_template("policies.html") return render_template("docs.html", **doc.__dict__) @app.route("/links") def links(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("links.html") @app.route("/tutorials") def tutorials(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("tutorials.html") @app.route("/credits") def credits(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("credits.html") @app.route("/environments") def environments(): - doc = docs.Docs("environments", request.args) + doc = Docs("environments", request.args) return render_template("docs.html", **doc.__dict__) #return render_template("environments.html", **doc.__dict__) @app.route("/update_text", methods=('POST',)) def update_page(): docs.update_text(request.form) - doc = docs.Docs(request.form['entry_type'], request.form) + doc = Docs(request.form['entry_type'], request.form) return render_template("docs.html", **doc.__dict__) @app.route("/submit_trait") @@ -366,7 +362,7 @@ def create_temp_trait(): #template_vars = submit_trait.SubmitTrait(request.form) - doc = docs.Docs("links") + doc = Docs("links") return render_template("links.html", **doc.__dict__) #return render_template("show_trait.html", **template_vars.__dict__) @@ -421,7 +417,7 @@ def export_traits_csv(): logger.info("In export_traits_csv") logger.info("request.form:", request.form) logger.info(request.url) - file_list = export_traits.export_search_results_csv(request.form) + file_list = export_search_results_csv(request.form) if len(file_list) > 1: now = datetime.datetime.now() @@ -904,12 +900,24 @@ def snp_browser_page(): return render_template("snp_browser.html", **template_vars.__dict__) +@app.route("/db_info", methods=('GET',)) +def db_info_page(): + template_vars = InfoPage(request.args) + + return render_template("info_page.html", **template_vars.__dict__) + @app.route("/tutorial/WebQTLTour", methods=('GET',)) def tutorial_page(): #ZS: Currently just links to GN1 logger.info(request.url) return redirect("http://gn1.genenetwork.org/tutorial/WebQTLTour/") +@app.route("/tutorial/security", methods=('GET',)) +def security_tutorial_page(): + #ZS: Currently just links to GN1 + logger.info(request.url) + return render_template("admin/security_help.html") + @app.route("/submit_bnw", methods=('POST',)) def submit_bnw(): logger.info(request.url) |