From ff94904574c51eeb7aecb327d6f2679fa4a60fb4 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 28 May 2020 20:24:01 -0500 Subject: Added lines calling proxy for publish datasets + added some resource redis queries and a missing import for the hmac functions --- wqflask/utility/hmac.py | 2 ++ wqflask/utility/redis_tools.py | 54 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 5 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index d8a0eace..b08be97e 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -3,6 +3,8 @@ from __future__ import print_function, division, absolute_import import hmac import hashlib +from flask import url_for + from wqflask import app def hmac_creation(stringy): diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index ca42f7b7..15841032 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -1,17 +1,25 @@ from __future__ import print_function, division, absolute_import +import uuid import simplejson as json import redis # used for collections -Redis = redis.StrictRedis() import logging from flask import (render_template, flash) +from utility import hmac + from utility.logger import getLogger logger = getLogger(__name__) +def get_redis_conn(): + Redis = redis.StrictRedis(port=6380) + return Redis + +Redis = get_redis_conn() + def is_redis_available(): try: Redis.ping() @@ -70,14 +78,15 @@ 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 + if user_details: + return user_details + else: + return None else: return None - flash("Invalid code: Password reset code does not exist or might have expired!", "error") 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 @@ -167,4 +176,39 @@ def change_group_name(user_id, group_id, new_name): group_info["name"] = new_name return group_info else: - return None \ No newline at end of file + return None + +def get_resources(): + resource_list = Redis.hgetall("resources") + return resource_list + +def get_resource_id(dataset_type, dataset_id, trait_id = None, all_resources = None): + if not all_resources: + all_resources = get_resources() + + resource_list = [[key, json.loads(value)] for key, value in all_resources.items()] + + if not trait_id: + matched_resources = [resource[0] for resource in resource_list if resource[1]['data']['dataset'] == dataset_id] + else: + matched_resources = [resource[0] for resource in resource_list if resource[1]['data']['dataset'] == dataset_id and resource[1]['data']['trait'] == trait_id] + + if len(matched_resources): + return matched_resources[0] + else: + return False + +def get_resource_info(resource_id): + resource_info = Redis.hget("resources", resource_id) + return json.loads(resource_info) + +def add_resource(resource_info): + + if 'trait' in resource_info['data']: + resource_id = hmac.data_hmac('{}:{}'.format(str(resource_info['data']['dataset']), str(resource_info['data']['trait']))) + else: + resource_id = hmac.data_hmac('{}'.format(str(resource_info['data']['dataset']))) + + Redis.hset("resources", resource_id, json.dumps(resource_info)) + + return resource_info -- cgit v1.2.3 From 1a663f987bf3a640d21c2c89402318d5433efd9e Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 4 Jun 2020 14:23:30 -0500 Subject: Really should have split this into many more commits: - Now use proxy to pull trait data and hide traits/results that the user doesn't have view permission for - Created a factory method for creating trait ob so it can return None when user doesn't have view permissions (this is why such a large number of files are changed) - Added metadata to permutation export - Added current group management code - Added fixed password verification e-mail code --- wqflask/base/trait.py | 177 ++++---- wqflask/utility/helper_functions.py | 11 +- wqflask/utility/redis_tools.py | 58 +-- wqflask/wqflask/api/correlation.py | 472 ++++++++++----------- wqflask/wqflask/api/gen_menu.py | 11 +- wqflask/wqflask/api/mapping.py | 4 +- wqflask/wqflask/collect.py | 15 +- .../comparison_bar_chart/comparison_bar_chart.py | 4 +- wqflask/wqflask/correlation/corr_scatter_plot.py | 8 +- wqflask/wqflask/correlation/show_corr_results.py | 8 +- .../wqflask/correlation_matrix/show_corr_matrix.py | 22 +- wqflask/wqflask/ctl/ctl_analysis.py | 10 +- wqflask/wqflask/do_search.py | 11 +- wqflask/wqflask/gsearch.py | 13 +- .../marker_regression/display_mapping_results.py | 6 + wqflask/wqflask/marker_regression/gemma_mapping.py | 4 +- wqflask/wqflask/marker_regression/rqtl_mapping.py | 64 ++- wqflask/wqflask/marker_regression/run_mapping.py | 3 +- wqflask/wqflask/network_graph/network_graph.py | 4 +- wqflask/wqflask/search_results.py | 106 ++--- wqflask/wqflask/show_trait/export_trait_data.py | 4 +- wqflask/wqflask/show_trait/show_trait.py | 21 +- wqflask/wqflask/templates/admin/group_manager.html | 45 +- wqflask/wqflask/templates/correlation_page.html | 1 + wqflask/wqflask/templates/email/verification.txt | 7 - wqflask/wqflask/templates/gsearch_pheno.html | 2 +- wqflask/wqflask/templates/mapping_results.html | 31 +- wqflask/wqflask/user_login.py | 43 +- wqflask/wqflask/user_session.py | 18 +- wqflask/wqflask/views.py | 71 +++- 30 files changed, 637 insertions(+), 617 deletions(-) delete mode 100644 wqflask/wqflask/templates/email/verification.txt (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 1b7cb23c..b133bf21 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -11,6 +11,7 @@ from base.data_set import create_dataset from db import webqtlDatabaseFunction from utility import webqtlUtil from utility import hmac +from utility.authentication_tools import check_resource_availability from utility.tools import GN2_BASE_URL from utility.redis_tools import get_redis_conn Redis = get_redis_conn() @@ -21,11 +22,33 @@ import simplejson as json from MySQLdb import escape_string as escape from pprint import pformat as pf -from flask import Flask, g, request, url_for +from flask import Flask, g, request, url_for, redirect from utility.logger import getLogger logger = getLogger(__name__ ) +def create_trait(**kw): + assert bool(kw.get('dataset')) != bool(kw.get('dataset_name')), "Needs dataset ob. or name"; + + permitted = True + if kw.get('name'): + if kw.get('dataset_name'): + if kw.get('dataset_name') != "Temp": + dataset = create_dataset(kw.get('dataset_name')) + else: + dataset = kw.get('dataset') + + if kw.get('dataset_name') != "Temp": + if dataset.type == 'Publish': + permitted = check_resource_availability(dataset, kw.get('name')) + else: + permitted = check_resource_availability(dataset) + + if permitted: + return GeneralTrait(**kw) + else: + return None + class GeneralTrait(object): """ Trait class defines a trait in webqtl, can be either Microarray, @@ -50,6 +73,7 @@ class GeneralTrait(object): self.haveinfo = kw.get('haveinfo', False) self.sequence = kw.get('sequence') # Blat sequence, available for ProbeSet self.data = kw.get('data', {}) + self.view = True # Sets defaults self.locus = None @@ -77,6 +101,7 @@ class GeneralTrait(object): # So we could add a simple if statement to short-circuit this if necessary if self.dataset.type != "Temp": self = retrieve_trait_info(self, self.dataset, get_qtl_info=get_qtl_info) + if get_sample_info != False: self = retrieve_sample_data(self, self.dataset) @@ -212,26 +237,28 @@ def get_sample_data(): trait = params['trait'] dataset = params['dataset'] - trait_ob = GeneralTrait(name=trait, dataset_name=dataset) - - trait_dict = {} - trait_dict['name'] = trait - trait_dict['db'] = dataset - trait_dict['type'] = trait_ob.dataset.type - trait_dict['group'] = trait_ob.dataset.group.name - trait_dict['tissue'] = trait_ob.dataset.tissue - trait_dict['species'] = trait_ob.dataset.group.species - trait_dict['url'] = url_for('show_trait_page', trait_id = trait, dataset = dataset) - trait_dict['description'] = trait_ob.description_display - if trait_ob.dataset.type == "ProbeSet": - trait_dict['symbol'] = trait_ob.symbol - trait_dict['location'] = trait_ob.location_repr - elif trait_ob.dataset.type == "Publish": - if trait_ob.pubmed_id: - trait_dict['pubmed_link'] = trait_ob.pubmed_link - trait_dict['pubmed_text'] = trait_ob.pubmed_text - - return json.dumps([trait_dict, {key: value.value for key, value in trait_ob.data.iteritems() }]) + trait_ob = create_trait(name=trait, dataset_name=dataset) + if trait_ob: + trait_dict = {} + trait_dict['name'] = trait + trait_dict['db'] = dataset + trait_dict['type'] = trait_ob.dataset.type + trait_dict['group'] = trait_ob.dataset.group.name + trait_dict['tissue'] = trait_ob.dataset.tissue + trait_dict['species'] = trait_ob.dataset.group.species + trait_dict['url'] = url_for('show_trait_page', trait_id = trait, dataset = dataset) + trait_dict['description'] = trait_ob.description_display + if trait_ob.dataset.type == "ProbeSet": + trait_dict['symbol'] = trait_ob.symbol + trait_dict['location'] = trait_ob.location_repr + elif trait_ob.dataset.type == "Publish": + if trait_ob.pubmed_id: + trait_dict['pubmed_link'] = trait_ob.pubmed_link + trait_dict['pubmed_text'] = trait_ob.pubmed_text + + return json.dumps([trait_dict, {key: value.value for key, value in trait_ob.data.iteritems() }]) + else: + return None def jsonable(trait): """Return a dict suitable for using as json @@ -350,91 +377,36 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): assert dataset, "Dataset doesn't exist" if dataset.type == 'Publish': - resource_id = hmac.data_hmac("{}:{}".format(dataset.id, trait.name)) - - the_url = "http://localhost:8080/run_action/?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) - trait_data = json.loads(requests.get("http://localhost:8080/run_action/?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id))) - - query = """ - SELECT - PublishXRef.Id, InbredSet.InbredSetCode, Publication.PubMed_ID, - Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, - Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, PublishXRef.mean, - Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, - Publication.Authors, Publication.Title, Publication.Abstract, - Publication.Journal, Publication.Volume, Publication.Pages, - Publication.Month, Publication.Year, PublishXRef.Sequence, - Phenotype.Units, PublishXRef.comments - FROM - PublishXRef, Publication, Phenotype, PublishFreeze, InbredSet - WHERE - PublishXRef.Id = %s AND - Phenotype.Id = PublishXRef.PhenotypeId AND - Publication.Id = PublishXRef.PublicationId AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishXRef.InbredSetId = InbredSet.Id AND - PublishFreeze.Id = %s - """ % (trait.name, dataset.id) - - logger.sql(query) - trait_info = g.db.execute(query).fetchone() - - - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name - #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + resource_id = hmac.hmac_creation("{}:{}:{}".format('dataset-publish', dataset.id, trait.name)) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) elif dataset.type == 'ProbeSet': - display_fields_string = ', ProbeSet.'.join(dataset.display_fields) - display_fields_string = 'ProbeSet.' + display_fields_string - query = """ - SELECT %s - FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' - """ % (escape(display_fields_string), - escape(dataset.name), - escape(str(trait.name))) - logger.sql(query) - trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name - # to avoid the problem of same marker name from different species. - elif dataset.type == 'Geno': - display_fields_string = string.join(dataset.display_fields,',Geno.') - display_fields_string = 'Geno.' + display_fields_string - query = """ - SELECT %s - FROM Geno, GenoFreeze, GenoXRef - WHERE - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoXRef.GenoId = Geno.Id AND - GenoFreeze.Name = '%s' AND - Geno.Name = '%s' - """ % (escape(display_fields_string), - escape(dataset.name), - escape(trait.name)) - logger.sql(query) - trait_info = g.db.execute(query).fetchone() - else: #Temp type - query = """SELECT %s FROM %s WHERE Name = %s""" - logger.sql(query) - trait_info = g.db.execute(query, - (string.join(dataset.display_fields,','), - dataset.type, trait.name)).fetchone() + resource_id = hmac.hmac_creation("{}:{}".format('dataset-probeset', dataset.id)) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + else: + resource_id = hmac.hmac_creation("{}:{}".format('dataset-geno', dataset.id)) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + + try: + response = requests.get(the_url).content + if response.strip() == "no-access": + trait.view = False + return trait + except: + resource_info = get_resource_info(resource_id) + default_permissions = resource_info['default_mask']['data'] + if 'view' not in default_persmissions: + trait.view = False + return trait + + trait_info = json.loads(response) if trait_info: trait.haveinfo = True - #XZ: assign SQL query result to trait attributes. for i, field in enumerate(dataset.display_fields): holder = trait_info[i] - # if isinstance(trait_info[i], basestring): - # logger.debug("HOLDER:", holder) - # logger.debug("HOLDER2:", holder.decode(encoding='latin1')) - # holder = unicode(trait_info[i], "utf-8", "ignore") - if isinstance(trait_info[i], basestring): - holder = holder.encode('latin1') + #if isinstance(trait_info[i], basestring): + # holder = holder.encode('latin1') setattr(trait, field, holder) if dataset.type == 'Publish': @@ -453,13 +425,6 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if trait.confidential: trait.abbreviation = trait.pre_publication_abbreviation trait.description_display = trait.pre_publication_description - - #if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait( - # privilege=self.dataset.privilege, - # userName=self.dataset.userName, - # authorized_users=self.authorized_users): - # - # description = self.pre_publication_description else: trait.abbreviation = trait.post_publication_abbreviation if description: diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py index e7c04fef..9ce809b6 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -1,7 +1,7 @@ from __future__ import absolute_import, print_function, division -from base.trait import GeneralTrait from base import data_set +from base.trait import create_trait from base.species import TheSpecies from utility import hmac @@ -11,7 +11,6 @@ from flask import Flask, g import logging logger = logging.getLogger(__name__ ) - def get_species_dataset_trait(self, start_vars): #assert type(read_genotype) == type(bool()), "Expecting boolean value for read_genotype" if "temp_trait" in start_vars.keys(): @@ -24,7 +23,7 @@ def get_species_dataset_trait(self, start_vars): logger.debug("After creating dataset") self.species = TheSpecies(dataset=self.dataset) logger.debug("After creating species") - self.this_trait = GeneralTrait(dataset=self.dataset, + self.this_trait = create_trait(dataset=self.dataset, name=start_vars['trait_id'], cellid=None, get_qtl_info=True) @@ -34,7 +33,6 @@ def get_species_dataset_trait(self, start_vars): #self.dataset.group.read_genotype_file() #self.genotype = self.dataset.group.genotype - def get_trait_db_obs(self, trait_db_list): if isinstance(trait_db_list, basestring): trait_db_list = trait_db_list.split(",") @@ -49,10 +47,11 @@ def get_trait_db_obs(self, trait_db_list): dataset_ob = data_set.create_dataset(dataset_name=dataset_name, dataset_type="Temp", group_name=trait_name.split("_")[2]) else: dataset_ob = data_set.create_dataset(dataset_name) - trait_ob = GeneralTrait(dataset=dataset_ob, + trait_ob = create_trait(dataset=dataset_ob, name=trait_name, cellid=None) - self.trait_list.append((trait_ob, dataset_ob)) + if trait_ob: + self.trait_list.append((trait_ob, dataset_ob)) def get_species_groups(): diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 15841032..0ad96879 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -2,6 +2,7 @@ from __future__ import print_function, division, absolute_import import uuid import simplejson as json +import datetime import redis # used for collections @@ -96,15 +97,22 @@ def get_user_groups(user_id): for key in groups_list: group_ob = json.loads(groups_list[key]) group_admins = set(group_ob['admins']) - group_users = set(group_ob['users']) + group_members = set(group_ob['members']) if user_id in group_admins: admin_group_ids.append(group_ob['id']) - elif user_id in group_users: + elif user_id in group_members: user_group_ids.append(group_ob['id']) else: continue - return admin_group_ids, user_group_ids + admin_groups = [] + user_groups = [] + for the_id in admin_group_ids: + admin_groups.append(get_group_info(the_id)) + for the_id in user_group_ids: + user_groups.append(get_group_info(the_id)) + + return admin_groups, user_groups def get_group_info(group_id): group_json = Redis.hget("groups", group_id) @@ -114,18 +122,18 @@ def get_group_info(group_id): return group_info -def create_group(admin_member_ids, user_member_ids = [], 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, - "admins": admin_member_ids, - "users" : user_member_ids, + "admins": admin_user_ids, + "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') } - Redis.hset("groups", group_id, new_group) + Redis.hset("groups", group_id, json.dumps(new_group)) return new_group @@ -144,7 +152,7 @@ def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS if admins: group_users = set(group_info["admins"]) else: - group_users = set(group_info["users"]) + group_users = set(group_info["members"]) for email in user_emails: user_id = get_user_id("email_address", email) @@ -153,7 +161,7 @@ def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS if admins: group_info["admins"] = list(group_users) else: - group_info["users"] = list(group_users) + group_info["members"] = list(group_users) group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') Redis.hset("groups", group_id, json.dumps(group_info)) @@ -161,7 +169,7 @@ def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS else: return None -def remove_users_from_group(user_id, users_to_remove_ids, group_id, user_type = "users"): #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"): #ZS: User type is because I assume admins can remove other admins group_info = get_group_info(group_id) if user_id in group_info["admins"]: group_users = set(group_info[user_type]) @@ -174,6 +182,7 @@ def change_group_name(user_id, group_id, new_name): group_info = get_group_info(group_id) if user_id in group_info["admins"]: group_info["name"] = new_name + Redis.hset("groups", group_id, json.dumps(group_info)) return group_info else: return None @@ -182,22 +191,21 @@ def get_resources(): resource_list = Redis.hgetall("resources") return resource_list -def get_resource_id(dataset_type, dataset_id, trait_id = None, all_resources = None): - if not all_resources: - all_resources = get_resources() - - resource_list = [[key, json.loads(value)] for key, value in all_resources.items()] - - if not trait_id: - matched_resources = [resource[0] for resource in resource_list if resource[1]['data']['dataset'] == dataset_id] - else: - matched_resources = [resource[0] for resource in resource_list if resource[1]['data']['dataset'] == dataset_id and resource[1]['data']['trait'] == trait_id] - - if len(matched_resources): - return matched_resources[0] +def get_resource_id(dataset, trait_id=None): + if dataset.type == "Publish": + if trait_id: + resource_id = hmac.hmac_creation("{}:{}:{}".format('dataset-publish', dataset.id, trait_id)) + else: + return False + elif dataset.type == "ProbeSet": + resource_id = hmac.hmac_creation("{}:{}".format('dataset-probeset', dataset.id)) + elif dataset.type == "Geno": + resource_id = hmac.hmac_creation("{}:{}".format('dataset-geno', dataset.id)) else: return False + return resource_id + def get_resource_info(resource_id): resource_info = Redis.hget("resources", resource_id) return json.loads(resource_info) @@ -205,9 +213,9 @@ def get_resource_info(resource_id): def add_resource(resource_info): if 'trait' in resource_info['data']: - resource_id = hmac.data_hmac('{}:{}'.format(str(resource_info['data']['dataset']), str(resource_info['data']['trait']))) + resource_id = hmac.hmac_creation('{}:{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']), str(resource_info['data']['trait']))) else: - resource_id = hmac.data_hmac('{}'.format(str(resource_info['data']['dataset']))) + resource_id = hmac.hmac_creation('{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']))) Redis.hset("resources", resource_id, json.dumps(resource_info)) diff --git a/wqflask/wqflask/api/correlation.py b/wqflask/wqflask/api/correlation.py index 66eb94ac..7f5312c1 100644 --- a/wqflask/wqflask/api/correlation.py +++ b/wqflask/wqflask/api/correlation.py @@ -1,237 +1,237 @@ -from __future__ import absolute_import, division, print_function - -import collections - -import scipy - -from MySQLdb import escape_string as escape - -from flask import g - -from base import data_set -from base.trait import GeneralTrait, retrieve_sample_data - -from wqflask.correlation.show_corr_results import generate_corr_json -from wqflask.correlation import correlation_functions - -from utility import webqtlUtil, helper_functions, corr_result_helpers -from utility.benchmark import Bench - -import utility.logger -logger = utility.logger.getLogger(__name__ ) - -def do_correlation(start_vars): - assert('db' in start_vars) - assert('target_db' in start_vars) - assert('trait_id' in start_vars) - - this_dataset = data_set.create_dataset(dataset_name = start_vars['db']) - target_dataset = data_set.create_dataset(dataset_name = start_vars['target_db']) - this_trait = GeneralTrait(dataset = this_dataset, name = start_vars['trait_id']) - this_trait = retrieve_sample_data(this_trait, this_dataset) - - corr_params = init_corr_params(start_vars) - - corr_results = calculate_results(this_trait, this_dataset, target_dataset, corr_params) - #corr_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) - - final_results = [] - for _trait_counter, trait in enumerate(corr_results.keys()[:corr_params['return_count']]): - if corr_params['type'] == "tissue": - [sample_r, num_overlap, sample_p, symbol] = corr_results[trait] - result_dict = { - "trait" : trait, - "sample_r" : sample_r, - "#_strains" : num_overlap, - "p_value" : sample_p, - "symbol" : symbol - } - elif corr_params['type'] == "literature" or corr_params['type'] == "lit": - [gene_id, sample_r] = corr_results[trait] - result_dict = { - "trait" : trait, - "sample_r" : sample_r, - "gene_id" : gene_id - } - else: - [sample_r, sample_p, num_overlap] = corr_results[trait] - result_dict = { - "trait" : trait, - "sample_r" : sample_r, - "#_strains" : num_overlap, - "p_value" : sample_p - } - - final_results.append(result_dict) - - # json_corr_results = generate_corr_json(final_corr_results, this_trait, this_dataset, target_dataset, for_api = True) - - return final_results - -def calculate_results(this_trait, this_dataset, target_dataset, corr_params): - corr_results = {} - - target_dataset.get_trait_data() - - if corr_params['type'] == "tissue": - trait_symbol_dict = this_dataset.retrieve_genes("Symbol") - corr_results = do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_params) - sorted_results = collections.OrderedDict(sorted(corr_results.items(), - key=lambda t: -abs(t[1][1]))) - elif corr_params['type'] == "literature" or corr_params['type'] == "lit": #ZS: Just so a user can use either "lit" or "literature" - trait_geneid_dict = this_dataset.retrieve_genes("GeneId") - corr_results = do_literature_correlation_for_all_traits(this_trait, this_dataset, trait_geneid_dict, corr_params) - sorted_results = collections.OrderedDict(sorted(corr_results.items(), - key=lambda t: -abs(t[1][1]))) - else: - for target_trait, target_vals in target_dataset.trait_data.iteritems(): - result = get_sample_r_and_p_values(this_trait, this_dataset, target_vals, target_dataset, corr_params['type']) - if result is not None: - corr_results[target_trait] = result - - sorted_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) - - return sorted_results - -def do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_params, tissue_dataset_id=1): - #Gets tissue expression values for the primary trait - primary_trait_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list = [this_trait.symbol]) - - if this_trait.symbol.lower() in primary_trait_tissue_vals_dict: - primary_trait_tissue_values = primary_trait_tissue_vals_dict[this_trait.symbol.lower()] - - corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list=trait_symbol_dict.values()) - - tissue_corr_data = {} - for trait, symbol in trait_symbol_dict.iteritems(): - if symbol and symbol.lower() in corr_result_tissue_vals_dict: - this_trait_tissue_values = corr_result_tissue_vals_dict[symbol.lower()] - - result = correlation_functions.cal_zero_order_corr_for_tiss(primary_trait_tissue_values, - this_trait_tissue_values, - corr_params['method']) - - tissue_corr_data[trait] = [result[0], result[1], result[2], symbol] - - return tissue_corr_data - -def do_literature_correlation_for_all_traits(this_trait, target_dataset, trait_geneid_dict, corr_params): - input_trait_mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), this_trait.geneid) - - lit_corr_data = {} - for trait, gene_id in trait_geneid_dict.iteritems(): - mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), gene_id) - - if mouse_gene_id and str(mouse_gene_id).find(";") == -1: - result = g.db.execute( - """SELECT value - FROM LCorrRamin3 - WHERE GeneId1='%s' and - GeneId2='%s' - """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id)) - ).fetchone() - if not result: - result = g.db.execute("""SELECT value - FROM LCorrRamin3 - WHERE GeneId2='%s' and - GeneId1='%s' - """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id)) - ).fetchone() - if result: - lit_corr = result.value - lit_corr_data[trait] = [gene_id, lit_corr] - else: - lit_corr_data[trait] = [gene_id, 0] - else: - lit_corr_data[trait] = [gene_id, 0] - - return lit_corr_data - -def get_sample_r_and_p_values(this_trait, this_dataset, target_vals, target_dataset, type): - """ - Calculates the sample r (or rho) and p-value - - Given a primary trait and a target trait's sample values, - calculates either the pearson r or spearman rho and the p-value - using the corresponding scipy functions. - """ - - this_trait_vals = [] - shared_target_vals = [] - for i, sample in enumerate(target_dataset.group.samplelist): - if sample in this_trait.data: - this_sample_value = this_trait.data[sample].value - target_sample_value = target_vals[i] - this_trait_vals.append(this_sample_value) - shared_target_vals.append(target_sample_value) - - this_trait_vals, shared_target_vals, num_overlap = corr_result_helpers.normalize_values(this_trait_vals, shared_target_vals) - - if type == 'pearson': - sample_r, sample_p = scipy.stats.pearsonr(this_trait_vals, shared_target_vals) - else: - sample_r, sample_p = scipy.stats.spearmanr(this_trait_vals, shared_target_vals) - - if num_overlap > 5: - if scipy.isnan(sample_r): - return None - else: - return [sample_r, sample_p, num_overlap] - -def convert_to_mouse_gene_id(species=None, gene_id=None): - """If the species is rat or human, translate the gene_id to the mouse geneid - - If there is no input gene_id or there's no corresponding mouse gene_id, return None - - """ - if not gene_id: - return None - - mouse_gene_id = None - - if species == 'mouse': - mouse_gene_id = gene_id - - elif species == 'rat': - - query = """SELECT mouse - FROM GeneIDXRef - WHERE rat='%s'""" % escape(gene_id) - - result = g.db.execute(query).fetchone() - if result != None: - mouse_gene_id = result.mouse - - elif species == 'human': - - query = """SELECT mouse - FROM GeneIDXRef - WHERE human='%s'""" % escape(gene_id) - - result = g.db.execute(query).fetchone() - if result != None: - mouse_gene_id = result.mouse - - return mouse_gene_id - -def init_corr_params(start_vars): - method = "pearson" - if 'method' in start_vars: - method = start_vars['method'] - - type = "sample" - if 'type' in start_vars: - type = start_vars['type'] - - return_count = 500 - if 'return_count' in start_vars: - assert(start_vars['return_count'].isdigit()) - return_count = int(start_vars['return_count']) - - corr_params = { - 'method' : method, - 'type' : type, - 'return_count' : return_count - } - +from __future__ import absolute_import, division, print_function + +import collections + +import scipy + +from MySQLdb import escape_string as escape + +from flask import g + +from base import data_set +from base.trait import create_trait, retrieve_sample_data + +from wqflask.correlation.show_corr_results import generate_corr_json +from wqflask.correlation import correlation_functions + +from utility import webqtlUtil, helper_functions, corr_result_helpers +from utility.benchmark import Bench + +import utility.logger +logger = utility.logger.getLogger(__name__ ) + +def do_correlation(start_vars): + assert('db' in start_vars) + assert('target_db' in start_vars) + assert('trait_id' in start_vars) + + this_dataset = data_set.create_dataset(dataset_name = start_vars['db']) + target_dataset = data_set.create_dataset(dataset_name = start_vars['target_db']) + this_trait = create_trait(dataset = this_dataset, name = start_vars['trait_id']) + this_trait = retrieve_sample_data(this_trait, this_dataset) + + corr_params = init_corr_params(start_vars) + + corr_results = calculate_results(this_trait, this_dataset, target_dataset, corr_params) + #corr_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) + + final_results = [] + for _trait_counter, trait in enumerate(corr_results.keys()[:corr_params['return_count']]): + if corr_params['type'] == "tissue": + [sample_r, num_overlap, sample_p, symbol] = corr_results[trait] + result_dict = { + "trait" : trait, + "sample_r" : sample_r, + "#_strains" : num_overlap, + "p_value" : sample_p, + "symbol" : symbol + } + elif corr_params['type'] == "literature" or corr_params['type'] == "lit": + [gene_id, sample_r] = corr_results[trait] + result_dict = { + "trait" : trait, + "sample_r" : sample_r, + "gene_id" : gene_id + } + else: + [sample_r, sample_p, num_overlap] = corr_results[trait] + result_dict = { + "trait" : trait, + "sample_r" : sample_r, + "#_strains" : num_overlap, + "p_value" : sample_p + } + + final_results.append(result_dict) + + # json_corr_results = generate_corr_json(final_corr_results, this_trait, this_dataset, target_dataset, for_api = True) + + return final_results + +def calculate_results(this_trait, this_dataset, target_dataset, corr_params): + corr_results = {} + + target_dataset.get_trait_data() + + if corr_params['type'] == "tissue": + trait_symbol_dict = this_dataset.retrieve_genes("Symbol") + corr_results = do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_params) + sorted_results = collections.OrderedDict(sorted(corr_results.items(), + key=lambda t: -abs(t[1][1]))) + elif corr_params['type'] == "literature" or corr_params['type'] == "lit": #ZS: Just so a user can use either "lit" or "literature" + trait_geneid_dict = this_dataset.retrieve_genes("GeneId") + corr_results = do_literature_correlation_for_all_traits(this_trait, this_dataset, trait_geneid_dict, corr_params) + sorted_results = collections.OrderedDict(sorted(corr_results.items(), + key=lambda t: -abs(t[1][1]))) + else: + for target_trait, target_vals in target_dataset.trait_data.iteritems(): + result = get_sample_r_and_p_values(this_trait, this_dataset, target_vals, target_dataset, corr_params['type']) + if result is not None: + corr_results[target_trait] = result + + sorted_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) + + return sorted_results + +def do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_params, tissue_dataset_id=1): + #Gets tissue expression values for the primary trait + primary_trait_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list = [this_trait.symbol]) + + if this_trait.symbol.lower() in primary_trait_tissue_vals_dict: + primary_trait_tissue_values = primary_trait_tissue_vals_dict[this_trait.symbol.lower()] + + corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list=trait_symbol_dict.values()) + + tissue_corr_data = {} + for trait, symbol in trait_symbol_dict.iteritems(): + if symbol and symbol.lower() in corr_result_tissue_vals_dict: + this_trait_tissue_values = corr_result_tissue_vals_dict[symbol.lower()] + + result = correlation_functions.cal_zero_order_corr_for_tiss(primary_trait_tissue_values, + this_trait_tissue_values, + corr_params['method']) + + tissue_corr_data[trait] = [result[0], result[1], result[2], symbol] + + return tissue_corr_data + +def do_literature_correlation_for_all_traits(this_trait, target_dataset, trait_geneid_dict, corr_params): + input_trait_mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), this_trait.geneid) + + lit_corr_data = {} + for trait, gene_id in trait_geneid_dict.iteritems(): + mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), gene_id) + + if mouse_gene_id and str(mouse_gene_id).find(";") == -1: + result = g.db.execute( + """SELECT value + FROM LCorrRamin3 + WHERE GeneId1='%s' and + GeneId2='%s' + """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id)) + ).fetchone() + if not result: + result = g.db.execute("""SELECT value + FROM LCorrRamin3 + WHERE GeneId2='%s' and + GeneId1='%s' + """ % (escape(mouse_gene_id), escape(input_trait_mouse_gene_id)) + ).fetchone() + if result: + lit_corr = result.value + lit_corr_data[trait] = [gene_id, lit_corr] + else: + lit_corr_data[trait] = [gene_id, 0] + else: + lit_corr_data[trait] = [gene_id, 0] + + return lit_corr_data + +def get_sample_r_and_p_values(this_trait, this_dataset, target_vals, target_dataset, type): + """ + Calculates the sample r (or rho) and p-value + + Given a primary trait and a target trait's sample values, + calculates either the pearson r or spearman rho and the p-value + using the corresponding scipy functions. + """ + + this_trait_vals = [] + shared_target_vals = [] + for i, sample in enumerate(target_dataset.group.samplelist): + if sample in this_trait.data: + this_sample_value = this_trait.data[sample].value + target_sample_value = target_vals[i] + this_trait_vals.append(this_sample_value) + shared_target_vals.append(target_sample_value) + + this_trait_vals, shared_target_vals, num_overlap = corr_result_helpers.normalize_values(this_trait_vals, shared_target_vals) + + if type == 'pearson': + sample_r, sample_p = scipy.stats.pearsonr(this_trait_vals, shared_target_vals) + else: + sample_r, sample_p = scipy.stats.spearmanr(this_trait_vals, shared_target_vals) + + if num_overlap > 5: + if scipy.isnan(sample_r): + return None + else: + return [sample_r, sample_p, num_overlap] + +def convert_to_mouse_gene_id(species=None, gene_id=None): + """If the species is rat or human, translate the gene_id to the mouse geneid + + If there is no input gene_id or there's no corresponding mouse gene_id, return None + + """ + if not gene_id: + return None + + mouse_gene_id = None + + if species == 'mouse': + mouse_gene_id = gene_id + + elif species == 'rat': + + query = """SELECT mouse + FROM GeneIDXRef + WHERE rat='%s'""" % escape(gene_id) + + result = g.db.execute(query).fetchone() + if result != None: + mouse_gene_id = result.mouse + + elif species == 'human': + + query = """SELECT mouse + FROM GeneIDXRef + WHERE human='%s'""" % escape(gene_id) + + result = g.db.execute(query).fetchone() + if result != None: + mouse_gene_id = result.mouse + + return mouse_gene_id + +def init_corr_params(start_vars): + method = "pearson" + if 'method' in start_vars: + method = start_vars['method'] + + type = "sample" + if 'type' in start_vars: + type = start_vars['type'] + + return_count = 500 + if 'return_count' in start_vars: + assert(start_vars['return_count'].isdigit()) + return_count = int(start_vars['return_count']) + + corr_params = { + 'method' : method, + 'type' : type, + 'return_count' : return_count + } + return corr_params \ No newline at end of file diff --git a/wqflask/wqflask/api/gen_menu.py b/wqflask/wqflask/api/gen_menu.py index c7bcb65d..bdcc3bf7 100644 --- a/wqflask/wqflask/api/gen_menu.py +++ b/wqflask/wqflask/api/gen_menu.py @@ -126,9 +126,7 @@ def build_types(species, group): InbredSet.Name = '{1}' AND ProbeFreeze.TissueId = Tissue.Id AND ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.public > 0 AND - ProbeSetFreeze.confidentiality < 1 + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id ORDER BY Tissue.Name""".format(species, group) results = [] @@ -194,9 +192,7 @@ def build_datasets(species, group, type_name): FROM InfoFiles, GenoFreeze, InbredSet WHERE InbredSet.Name = '{}' AND GenoFreeze.InbredSetId = InbredSet.Id AND - InfoFiles.InfoPageName = GenoFreeze.ShortName AND - GenoFreeze.public > 0 AND - GenoFreeze.confidentiality < 1 + InfoFiles.InfoPageName = GenoFreeze.ShortName ORDER BY GenoFreeze.CreateTime DESC""".format(group)).fetchone() if results != None: @@ -214,8 +210,7 @@ def build_datasets(species, group, type_name): Species.Id = InbredSet.SpeciesId AND InbredSet.Name = '{1}' AND ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and Tissue.Name = '{2}' AND - ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeSetFreeze.confidentiality < 1 and ProbeSetFreeze.public > 0 + ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id ORDER BY ProbeSetFreeze.CreateTime DESC""".format(species, group, type_name)).fetchall() datasets = [] diff --git a/wqflask/wqflask/api/mapping.py b/wqflask/wqflask/api/mapping.py index d830cefc..92c27c9b 100644 --- a/wqflask/wqflask/api/mapping.py +++ b/wqflask/wqflask/api/mapping.py @@ -4,7 +4,7 @@ import string from base import data_set from base import webqtlConfig -from base.trait import GeneralTrait, retrieve_sample_data +from base.trait import create_trait, retrieve_sample_data from utility import helper_functions from wqflask.marker_regression import gemma_mapping, rqtl_mapping, qtlreaper_mapping, plink_mapping @@ -18,7 +18,7 @@ def do_mapping_for_api(start_vars): dataset = data_set.create_dataset(dataset_name = start_vars['db']) dataset.group.get_markers() - this_trait = GeneralTrait(dataset = dataset, name = start_vars['trait_id']) + this_trait = create_trait(dataset = dataset, name = start_vars['trait_id']) this_trait = retrieve_sample_data(this_trait, dataset) samples = [] diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index b22e0004..4fb8e69b 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -14,9 +14,6 @@ import urlparse import simplejson as json -import redis -Redis = redis.StrictRedis() - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash, jsonify) @@ -30,8 +27,10 @@ from wqflask import model from utility import Bunch, Struct, hmac from utility.formatting import numify +from utility.redis_tools import get_redis_conn +Redis = get_redis_conn() -from base import trait +from base.trait import create_trait, retrieve_trait_info, jsonable from base.data_set import create_dataset import logging @@ -208,14 +207,14 @@ def view_collection(): if dataset_name == "Temp": group = name.split("_")[2] dataset = create_dataset(dataset_name, dataset_type = "Temp", group_name = group) - trait_ob = trait.GeneralTrait(name=name, dataset=dataset) + trait_ob = create_trait(name=name, dataset=dataset) else: dataset = create_dataset(dataset_name) - trait_ob = trait.GeneralTrait(name=name, dataset=dataset) - trait_ob = trait.retrieve_trait_info(trait_ob, dataset, get_qtl_info=True) + trait_ob = create_trait(name=name, dataset=dataset) + trait_ob = retrieve_trait_info(trait_ob, dataset, get_qtl_info=True) trait_obs.append(trait_ob) - json_version.append(trait.jsonable(trait_ob)) + json_version.append(jsonable(trait_ob)) collection_info = dict(trait_obs=trait_obs, uc = uc) diff --git a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py index 21eb1493..5d74dc9d 100644 --- a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py +++ b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py @@ -37,7 +37,7 @@ from pprint import pformat as pf import reaper -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set from utility import webqtlUtil, helper_functions, corr_result_helpers from db import webqtlDatabaseFunction @@ -108,7 +108,7 @@ class ComparisonBarChart(object): trait_name, dataset_name = trait_db.split(":") #print("dataset_name:", dataset_name) dataset_ob = data_set.create_dataset(dataset_name) - trait_ob = GeneralTrait(dataset=dataset_ob, + trait_ob = create_trait(dataset=dataset_ob, name=trait_name, cellid=None) self.trait_list.append((trait_ob, dataset_ob)) diff --git a/wqflask/wqflask/correlation/corr_scatter_plot.py b/wqflask/wqflask/correlation/corr_scatter_plot.py index dfb81c54..04ec427d 100644 --- a/wqflask/wqflask/correlation/corr_scatter_plot.py +++ b/wqflask/wqflask/correlation/corr_scatter_plot.py @@ -4,7 +4,7 @@ import math from flask import g -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set from utility import corr_result_helpers from scipy import stats @@ -20,9 +20,9 @@ class CorrScatterPlot(object): self.data_set_1 = data_set.create_dataset(params['dataset_1']) self.data_set_2 = data_set.create_dataset(params['dataset_2']) #self.data_set_3 = data_set.create_dataset(params['dataset_3']) - self.trait_1 = GeneralTrait(name=params['trait_1'], dataset=self.data_set_1) - self.trait_2 = GeneralTrait(name=params['trait_2'], dataset=self.data_set_2) - #self.trait_3 = GeneralTrait(name=params['trait_3'], dataset=self.data_set_3) + self.trait_1 = create_trait(name=params['trait_1'], dataset=self.data_set_1) + self.trait_2 = create_trait(name=params['trait_2'], dataset=self.data_set_2) + #self.trait_3 = create_trait(name=params['trait_3'], dataset=self.data_set_3) samples_1, samples_2, num_overlap = corr_result_helpers.normalize_values_with_samples(self.trait_1.data, self.trait_2.data) diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index b099b83d..7eab7184 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -47,7 +47,7 @@ import reaper from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set from utility import webqtlUtil, helper_functions, corr_result_helpers, hmac from db import webqtlDatabaseFunction @@ -97,7 +97,7 @@ class CorrelationResults(object): if start_vars['dataset'] == "Temp": self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = start_vars['group']) self.trait_id = start_vars['trait_id'] - self.this_trait = GeneralTrait(dataset=self.dataset, + self.this_trait = create_trait(dataset=self.dataset, name=self.trait_id, cellid=None) else: @@ -199,7 +199,9 @@ class CorrelationResults(object): range_chr_as_int = order_id for _trait_counter, trait in enumerate(self.correlation_data.keys()[:self.return_number]): - trait_object = GeneralTrait(dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False) + trait_object = create_trait(dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False) + if not trait_object: + continue if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": #ZS: Convert trait chromosome to an int for the location range option diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index b5c45d05..2b9467d1 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -43,14 +43,16 @@ from pprint import pformat as pf import reaper -import redis -Redis = redis.StrictRedis() +from utility.redis_tools import get_redis_conn +Redis = get_redis_conn() +THIRTY_DAYS = 60 * 60 * 24 * 30 from utility.THCell import THCell from utility.TDCell import TDCell from base.trait import GeneralTrait from base import data_set from utility import webqtlUtil, helper_functions, corr_result_helpers + from db import webqtlDatabaseFunction import utility.webqtlUtil #this is for parallel computing only. from wqflask.correlation import correlation_functions @@ -204,20 +206,6 @@ class CorrelationMatrix(object): samples = self.all_sample_list, sample_data = self.sample_data,) # corr_results = [result[1] for result in result_row for result_row in self.corr_results]) - - def get_trait_db_obs(self, trait_db_list): - - self.trait_list = [] - for i, trait_db in enumerate(trait_db_list): - if i == (len(trait_db_list) - 1): - break - trait_name, dataset_name = trait_db.split(":") - #print("dataset_name:", dataset_name) - dataset_ob = data_set.create_dataset(dataset_name) - trait_ob = GeneralTrait(dataset=dataset_ob, - name=trait_name, - cellid=None) - self.trait_list.append((trait_ob, dataset_ob)) def calculate_pca(self, cols, corr_eigen_value, corr_eigen_vectors): base = importr('base') @@ -257,7 +245,7 @@ class CorrelationMatrix(object): this_vals_string += "x " this_vals_string = this_vals_string[:-1] - Redis.set(trait_id, this_vals_string) + Redis.set(trait_id, this_vals_string, ex=THIRTY_DAYS) self.pca_trait_ids.append(trait_id) return pca diff --git a/wqflask/wqflask/ctl/ctl_analysis.py b/wqflask/wqflask/ctl/ctl_analysis.py index 4415b86a..35067036 100644 --- a/wqflask/wqflask/ctl/ctl_analysis.py +++ b/wqflask/wqflask/ctl/ctl_analysis.py @@ -17,7 +17,7 @@ import csv import itertools from base import data_set -from base import trait as TRAIT +from base.trait import create_trait, retrieve_sample_data from utility import helper_functions from utility.tools import locate, GN2_BRANCH_URL @@ -122,8 +122,8 @@ class CTL(object): logger.debug("retrieving data for", trait) if trait != "": ts = trait.split(':') - gt = TRAIT.GeneralTrait(name = ts[0], dataset_name = ts[1]) - gt = TRAIT.retrieve_sample_data(gt, dataset, individuals) + gt = create_trait(name = ts[0], dataset_name = ts[1]) + gt = retrieve_sample_data(gt, dataset, individuals) for ind in individuals: if ind in gt.data.keys(): traits.append(gt.data[ind].value) @@ -180,8 +180,8 @@ class CTL(object): logger.debug(significant[0][x], significant[1][x], significant[2][x]) # Debug to console tsS = significant[0][x].split(':') # Source tsT = significant[2][x].split(':') # Target - gtS = TRAIT.GeneralTrait(name = tsS[0], dataset_name = tsS[1]) # Retrieve Source info from the DB - gtT = TRAIT.GeneralTrait(name = tsT[0], dataset_name = tsT[1]) # Retrieve Target info from the DB + gtS = create_trait(name = tsS[0], dataset_name = tsS[1]) # Retrieve Source info from the DB + gtT = create_trait(name = tsT[0], dataset_name = tsT[1]) # Retrieve Target info from the DB self.addNode(gtS) self.addNode(gtT) self.addEdge(gtS, gtT, significant, x) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index b0ca5ced..1e15d28f 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -34,10 +34,7 @@ class DoSearch(object): self.search_type = search_type if self.dataset: - logger.debug("self.dataset is boo: ", type(self.dataset), pf(self.dataset)) - logger.debug("self.dataset.group is: ", pf(self.dataset.group)) #Get group information for dataset and the species id - self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group.name) def execute(self, query): @@ -54,10 +51,6 @@ class DoSearch(object): return keyword - #def escape(self, stringy): - # """Shorter name than self.db_conn.escape_string""" - # return escape(str(stringy)) - def mescape(self, *items): """Multiple escape""" escaped = [escape(str(item)) for item in items] @@ -71,8 +64,6 @@ class DoSearch(object): @classmethod def get_search(cls, search_type): - logger.debug("search_types are:", pf(cls.search_types)) - search_type_string = search_type['dataset_type'] if 'key' in search_type and search_type['key'] != None: search_type_string += '_' + search_type['key'] @@ -648,7 +639,7 @@ class CisTransLrsSearch(DoSearch): escape(self.dataset.type), chromosome) else: - location_clause = "(ABS(%s.Mb-Geno.Mb) %s %s and %s.Chr = Geno.Chr) or (%s.Chr != Geno.Chr)" % (escape(self.dataset.type), the_operator, escape(str(self.mb_buffer)), escape(self.dataset.type)) + location_clause = "(ABS(%s.Mb-Geno.Mb) %s %s and %s.Chr = Geno.Chr) or (%s.Chr != Geno.Chr)" % (escape(self.dataset.type), the_operator, escape(str(self.mb_buffer)), escape(self.dataset.type), escape(self.dataset.type)) where_clause = sub_clause + """ %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py index 04e3d578..c65a1415 100644 --- a/wqflask/wqflask/gsearch.py +++ b/wqflask/wqflask/gsearch.py @@ -4,7 +4,7 @@ import json from flask import Flask, g from base.data_set import create_dataset -from base.trait import GeneralTrait +from base.trait import create_trait from db import webqtlDatabaseFunction from base import webqtlConfig @@ -96,7 +96,9 @@ class GSearch(object): #dataset = create_dataset(line[3], "ProbeSet", get_samplelist=False) #trait_id = line[4] #with Bench("Building trait object"): - trait_ob = GeneralTrait(dataset_name=this_trait['dataset'], name=this_trait['name'], get_qtl_info=True, get_sample_info=False) + trait_ob = create_trait(dataset_name=this_trait['dataset'], name=this_trait['name'], get_qtl_info=True, get_sample_info=False) + if not trait_ob: + continue max_lrs_text = "N/A" if trait_ob.locus_chr != "" and trait_ob.locus_mb != "": max_lrs_text = "Chr" + str(trait_ob.locus_chr) + ": " + str(trait_ob.locus_mb) @@ -210,13 +212,12 @@ class GSearch(object): if line[11] != "" and line[11] != None: this_trait['additive'] = '%.3f' % line[11] - #dataset = create_dataset(line[2], "Publish") - #trait_id = line[3] - #this_trait = GeneralTrait(dataset=dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) this_trait['max_lrs_text'] = "N/A" + trait_ob = create_trait(dataset_name=this_trait['dataset'], name=this_trait['name'], get_qtl_info=True, get_sample_info=False) + if not trait_ob: + continue if this_trait['dataset'] == this_trait['group'] + "Publish": try: - trait_ob = GeneralTrait(dataset_name=this_trait['dataset'], name=this_trait['name'], get_qtl_info=True, get_sample_info=False) if trait_ob.locus_chr != "" and trait_ob.locus_mb != "": this_trait['max_lrs_text'] = "Chr" + str(trait_ob.locus_chr) + ": " + str(trait_ob.locus_mb) except: diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index a648667b..74fa4329 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -246,6 +246,12 @@ class DisplayMappingResults(object): if 'output_files' in start_vars: self.output_files = ",".join(start_vars['output_files']) + self.categorical_vars = "" + self.perm_strata = "" + if 'perm_strata' in start_vars.keys() and 'categorical_vars' in start_vars.keys(): + self.categorical_vars = start_vars['categorical_vars'] + self.perm_strata = start_vars['perm_strata'] + self.selectedChr = int(start_vars['selected_chr']) self.strainlist = start_vars['samples'] diff --git a/wqflask/wqflask/marker_regression/gemma_mapping.py b/wqflask/wqflask/marker_regression/gemma_mapping.py index e2b15c26..88d27517 100644 --- a/wqflask/wqflask/marker_regression/gemma_mapping.py +++ b/wqflask/wqflask/marker_regression/gemma_mapping.py @@ -1,7 +1,7 @@ import os, math, string, random, json from base import webqtlConfig -from base.trait import GeneralTrait +from base.trait import create_trait from base.data_set import create_dataset from utility.tools import flat_files, GEMMA_COMMAND, GEMMA_WRAPPER_COMMAND, TEMPDIR, WEBSERVER_MODE @@ -129,7 +129,7 @@ def gen_covariates_file(this_dataset, covariates, samples): this_covariate_data = [] trait_name = covariate.split(":")[0] dataset_ob = create_dataset(covariate.split(":")[1]) - trait_ob = GeneralTrait(dataset=dataset_ob, + trait_ob = create_trait(dataset=dataset_ob, name=trait_name, cellid=None) diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py index e4a4d127..c5590a85 100644 --- a/wqflask/wqflask/marker_regression/rqtl_mapping.py +++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py @@ -6,7 +6,7 @@ import json from flask import g from base.webqtlConfig import TMPDIR -from base.trait import GeneralTrait +from base.trait import create_trait from base.data_set import create_dataset from utility import webqtlUtil from utility.tools import locate, TEMPDIR @@ -86,7 +86,6 @@ def run_rqtl_geno(vals, samples, dataset, mapping_scale, method, model, permChec cross_object = add_phenotype(cross_object, pheno_string, "the_pheno") # Add the phenotype cross_object = add_names(cross_object, names_string, "the_names") # Add the phenotype logger.info("Added pheno and names"); - # Scan for QTLs marker_covars = create_marker_covariates(control_marker, cross_object) # Create the additive covariate markers logger.info("Marker covars done"); if cofactors != "": @@ -115,6 +114,7 @@ def run_rqtl_geno(vals, samples, dataset, mapping_scale, method, model, permChec else: if do_control == "true" or cofactors != "": logger.info("Using covariate"); result_data_frame = scanone(cross_object, pheno = "the_pheno", addcovar = covars, model=model, method=method) + ro.r('save.image(file = "/home/zas1024/gn2-zach/itp_cofactor_test.RData")') else: logger.info("No covariates"); result_data_frame = scanone(cross_object, pheno = "the_pheno", model=model, method=method) @@ -295,7 +295,7 @@ def add_cofactors(cross, this_dataset, covariates, samples): covar_as_string = "c(" trait_name = covariate.split(":")[0] dataset_ob = create_dataset(covariate.split(":")[1]) - trait_ob = GeneralTrait(dataset=dataset_ob, + trait_ob = create_trait(dataset=dataset_ob, name=trait_name, cellid=None) @@ -321,27 +321,27 @@ def add_cofactors(cross, this_dataset, covariates, samples): datatype = get_trait_data_type(covariate) logger.info("Covariate: " + covariate + " is of type: " + datatype); if(datatype == "categorical"): # Cat variable - logger.info("call of add_categorical_covar"); - cross, col_names = add_categorical_covar(cross, covar_as_string, i) # Expand and add it to the cross - logger.info("add_categorical_covar returned"); - for z, col_name in enumerate(col_names): # Go through the additional covar names + logger.info("call of add_categorical_covar"); + cross, col_names = add_categorical_covar(cross, covar_as_string, i) # Expand and add it to the cross + logger.info("add_categorical_covar returned"); + for z, col_name in enumerate(col_names): # Go through the additional covar names + if i < (len(covariate_list) - 1): + covar_name_string += '"' + col_name + '", ' + else: + if(z < (len(col_names) -1)): + covar_name_string += '"' + col_name + '", ' + else: + covar_name_string += '"' + col_name + '"' + + logger.info("covar_name_string:" + covar_name_string) + else: + col_name = "covar_" + str(i) + cross = add_phenotype(cross, covar_as_string, col_name) if i < (len(covariate_list) - 1): - covar_name_string += '"' + col_name + '", ' - else: - if(z < (len(col_names) -1)): covar_name_string += '"' + col_name + '", ' - else: + else: covar_name_string += '"' + col_name + '"' - logger.info("covar_name_string:" + covar_name_string); - else: - col_name = "covar_" + str(i) - cross = add_phenotype(cross, covar_as_string, col_name) - if i < (len(covariate_list) - 1): - covar_name_string += '"' + col_name + '", ' - else: - covar_name_string += '"' + col_name + '"' - covar_name_string += ")" logger.info("covar_name_string:" + covar_name_string); covars_ob = pull_var("trait_covars", cross, covar_name_string) @@ -350,9 +350,13 @@ def add_cofactors(cross, this_dataset, covariates, samples): def create_marker_covariates(control_marker, cross): ro.globalenv["the_cross"] = cross ro.r('genotypes <- pull.geno(the_cross)') # Get the genotype matrix - userinputS = control_marker.replace(" ", "").split(",") # TODO: sanitize user input, Never Ever trust a user - covariate_names = ', '.join('"{0}"'.format(w) for w in userinputS) - ro.r('covnames <- c(' + covariate_names + ')') + userinput_sanitized = control_marker.replace(" ", "").split(",") # TODO: sanitize user input, Never Ever trust a user + logger.debug(userinput_sanitized) + if len(userinput_sanitized) > 0: + covariate_names = ', '.join('"{0}"'.format(w) for w in userinput_sanitized) + ro.r('covnames <- c(' + covariate_names + ')') + else: + ro.r('covnames <- c()') ro.r('covInGeno <- which(covnames %in% colnames(genotypes))') ro.r('covnames <- covnames[covInGeno]') ro.r("cat('covnames (purged): ', covnames,'\n')") @@ -404,16 +408,4 @@ def process_rqtl_results(result, species_name): # TODO: how to make this marker['lod_score'] = output[i][2] qtl_results.append(marker) - return qtl_results - -def get_trait_data_type(trait_db_string): - # Get a trait's type (numeric, categorical, etc) from the DB - the_query = "SELECT value FROM TraitMetadata WHERE type='trait_data_type'" - results_json = g.db.execute(the_query).fetchone() - - results_ob = json.loads(results_json[0]) - - if trait_db_string in results_ob: - return results_ob[trait_db_string] - else: - return "numeric" + return qtl_results \ 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 5f7710ab..0711b852 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -161,7 +161,7 @@ class RunMapping(object): self.num_perm = 0 self.perm_output = [] self.bootstrap_results = [] - self.covariates = start_vars['covariates'] if "covariates" in start_vars else None + self.covariates = start_vars['covariates'] if "covariates" in start_vars else "" #ZS: This is passed to GN1 code for single chr mapping self.selected_chr = -1 @@ -467,6 +467,7 @@ class RunMapping(object): #mapping_scale = self.mapping_scale, #chromosomes = chromosome_mb_lengths, #qtl_results = self.qtl_results, + categorical_vars = self.categorical_vars, chr_lengths = chr_lengths, num_perm = self.num_perm, perm_results = self.perm_output, diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index 152e4168..f41f3017 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -44,7 +44,7 @@ import reaper from utility.THCell import THCell from utility.TDCell import TDCell -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set from utility import webqtlUtil, helper_functions, corr_result_helpers from utility.tools import GN2_BRANCH_URL @@ -217,7 +217,7 @@ class NetworkGraph(object): break trait_name, dataset_name = trait_db.split(":") dataset_ob = data_set.create_dataset(dataset_name) - trait_ob = GeneralTrait(dataset=dataset_ob, + trait_ob = create_trait(dataset=dataset_ob, name=trait_name, cellid=None) self.trait_list.append((trait_ob, dataset_ob)) \ No newline at end of file diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 8f702d58..de4b01eb 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -1,15 +1,9 @@ -# from __future__ import absolute_import, print_function, division +from __future__ import absolute_import, print_function, division - -import os -import cPickle import re import uuid from math import * import time -import math -import datetime -import collections import re import requests @@ -18,18 +12,16 @@ from pprint import pformat as pf import json from base.data_set import create_dataset -from base import trait +from base.trait import create_trait from wqflask import parser from wqflask import do_search -from utility import webqtlUtil,tools from db import webqtlDatabaseFunction -from flask import render_template, Flask, g +from flask import Flask, g -from utility import formatting -from utility import hmac +from utility import hmac, helper_functions from utility.tools import GN2_BASE_URL -from utility.type_checking import is_float, is_int, is_str, get_float, get_int, get_string +from utility.type_checking import is_str from utility.logger import getLogger logger = getLogger(__name__ ) @@ -86,7 +78,7 @@ views.py). try: self.search() except: - self.search_term_exists = False + self.search_term_exists = False if self.search_term_exists: self.gen_search_result() @@ -113,50 +105,49 @@ views.py). trait_dict = {} trait_id = result[0] - trait_dict['index'] = index + 1 - this_trait = trait.GeneralTrait(dataset=self.dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) - trait_dict['name'] = this_trait.name - if this_trait.dataset.type == "Publish": - trait_dict['display_name'] = this_trait.display_name - else: - trait_dict['display_name'] = this_trait.name - trait_dict['dataset'] = this_trait.dataset.name - trait_dict['hmac'] = hmac.data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) - if this_trait.dataset.type == "ProbeSet": - trait_dict['symbol'] = this_trait.symbol - trait_dict['description'] = this_trait.description_display.decode('utf-8', 'replace') - trait_dict['location'] = this_trait.location_repr - trait_dict['mean'] = "N/A" - trait_dict['additive'] = "N/A" - if this_trait.mean != "" and this_trait.mean != None: - trait_dict['mean'] = '%.3f' % this_trait.mean - trait_dict['lrs_score'] = this_trait.LRS_score_repr - trait_dict['lrs_location'] = this_trait.LRS_location_repr - if this_trait.additive != "": - trait_dict['additive'] = '%.3f' % this_trait.additive - elif this_trait.dataset.type == "Geno": - trait_dict['location'] = this_trait.location_repr - elif this_trait.dataset.type == "Publish": - trait_dict['description'] = this_trait.description_display - trait_dict['authors'] = this_trait.authors - trait_dict['pubmed_id'] = "N/A" - if this_trait.pubmed_id: - trait_dict['pubmed_id'] = this_trait.pubmed_id - trait_dict['pubmed_link'] = this_trait.pubmed_link - trait_dict['pubmed_text'] = this_trait.pubmed_text - trait_dict['mean'] = "N/A" - if this_trait.mean != "" and this_trait.mean != None: - trait_dict['mean'] = '%.3f' % this_trait.mean - trait_dict['lrs_score'] = this_trait.LRS_score_repr - trait_dict['lrs_location'] = this_trait.LRS_location_repr - trait_dict['additive'] = "N/A" - if this_trait.additive != "": - trait_dict['additive'] = '%.3f' % this_trait.additive - trait_list.append(trait_dict) - #json_trait_list.append(trait.jsonable_table_row(this_trait, self.dataset.name, index + 1)) + this_trait = create_trait(dataset=self.dataset, name=trait_id, get_qtl_info=True, get_sample_info=False) + if this_trait: + trait_dict['index'] = index + 1 + trait_dict['name'] = this_trait.name + if this_trait.dataset.type == "Publish": + trait_dict['display_name'] = this_trait.display_name + else: + trait_dict['display_name'] = this_trait.name + trait_dict['dataset'] = this_trait.dataset.name + trait_dict['hmac'] = hmac.data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) + if this_trait.dataset.type == "ProbeSet": + trait_dict['symbol'] = this_trait.symbol + trait_dict['description'] = this_trait.description_display.decode('utf-8', 'replace') + trait_dict['location'] = this_trait.location_repr + trait_dict['mean'] = "N/A" + trait_dict['additive'] = "N/A" + if this_trait.mean != "" and this_trait.mean != None: + trait_dict['mean'] = '%.3f' % this_trait.mean + trait_dict['lrs_score'] = this_trait.LRS_score_repr + trait_dict['lrs_location'] = this_trait.LRS_location_repr + if this_trait.additive != "": + trait_dict['additive'] = '%.3f' % this_trait.additive + elif this_trait.dataset.type == "Geno": + trait_dict['location'] = this_trait.location_repr + elif this_trait.dataset.type == "Publish": + trait_dict['description'] = this_trait.description_display + trait_dict['authors'] = this_trait.authors + trait_dict['pubmed_id'] = "N/A" + if this_trait.pubmed_id: + trait_dict['pubmed_id'] = this_trait.pubmed_id + trait_dict['pubmed_link'] = this_trait.pubmed_link + trait_dict['pubmed_text'] = this_trait.pubmed_text + trait_dict['mean'] = "N/A" + if this_trait.mean != "" and this_trait.mean != None: + trait_dict['mean'] = '%.3f' % this_trait.mean + trait_dict['lrs_score'] = this_trait.LRS_score_repr + trait_dict['lrs_location'] = this_trait.LRS_location_repr + trait_dict['additive'] = "N/A" + if this_trait.additive != "": + trait_dict['additive'] = '%.3f' % this_trait.additive + trait_list.append(trait_dict) self.trait_list = json.dumps(trait_list) - #self.json_trait_list = json.dumps(json_trait_list) def search(self): """ @@ -234,7 +225,6 @@ views.py). self.header_fields = the_search.header_fields def get_search_ob(self, a_search): - logger.debug("[kodak] item is:", pf(a_search)) search_term = a_search['search_term'] search_operator = a_search['separator'] search_type = {} @@ -243,12 +233,10 @@ views.py). search_type['key'] = a_search['key'].upper() else: search_type['key'] = None - logger.debug("search_type is:", pf(search_type)) search_ob = do_search.DoSearch.get_search(search_type) if search_ob: search_class = getattr(do_search, search_ob) - logger.debug("search_class is: ", pf(search_class)) the_search = search_class(search_term, search_operator, self.dataset, diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index 107f87c6..253c887b 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -4,7 +4,7 @@ import simplejson as json from pprint import pformat as pf -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set def export_sample_table(targs): @@ -26,7 +26,7 @@ def export_sample_table(targs): def get_export_metadata(trait_id, dataset_name): dataset = data_set.create_dataset(dataset_name) - this_trait = GeneralTrait(dataset=dataset, + this_trait = create_trait(dataset=dataset, name=trait_id, cellid=None, get_qtl_info=False) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 29b2f77e..c77e247f 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -10,9 +10,6 @@ import json as json from collections import OrderedDict -import redis -Redis = redis.StrictRedis() - import numpy as np import scipy.stats as ss @@ -21,11 +18,15 @@ from flask import Flask, g from base import webqtlConfig from base import webqtlCaseData from wqflask.show_trait.SampleList import SampleList -from utility import webqtlUtil, Plot, Bunch, helper_functions -from utility.tools import locate_ignore_error -from base.trait import GeneralTrait +from base.trait import create_trait from base import data_set from db import webqtlDatabaseFunction +from utility import webqtlUtil, Plot, Bunch, helper_functions +from utility.authentication_tools import check_owner +from utility.tools import locate_ignore_error +from utility.redis_tools import get_redis_conn, get_resource_id +Redis = get_redis_conn() +ONE_YEAR = 60 * 60 * 24 * 365 from pprint import pformat as pf @@ -55,9 +56,9 @@ class ShowTrait(object): self.temp_group = kw['group'] self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = self.temp_group) # Put values in Redis so they can be looked up later if added to a collection - Redis.set(self.trait_id, kw['trait_paste']) + Redis.set(self.trait_id, kw['trait_paste'], ex=ONE_YEAR) self.trait_vals = kw['trait_paste'].split() - self.this_trait = GeneralTrait(dataset=self.dataset, + self.this_trait = create_trait(dataset=self.dataset, name=self.trait_id, cellid=None) else: @@ -66,11 +67,13 @@ class ShowTrait(object): self.temp_species = self.trait_id.split("_")[1] self.temp_group = self.trait_id.split("_")[2] self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = self.temp_group) - self.this_trait = GeneralTrait(dataset=self.dataset, + self.this_trait = create_trait(dataset=self.dataset, name=self.trait_id, cellid=None) self.trait_vals = Redis.get(self.trait_id).split() + self.resource_id = check_owner(self.dataset, self.trait_id) + #ZS: Get verify/rna-seq link URLs try: blatsequence = self.this_trait.sequence diff --git a/wqflask/wqflask/templates/admin/group_manager.html b/wqflask/wqflask/templates/admin/group_manager.html index ac5c1350..b7df1aad 100644 --- a/wqflask/wqflask/templates/admin/group_manager.html +++ b/wqflask/wqflask/templates/admin/group_manager.html @@ -2,17 +2,25 @@ {% block title %}Group Manager{% endblock %} {% block content %} - {{ header("List of groups", "" )}} -
-
+ +
+ {% if admin_groups|length == 0 and user_groups|length == 0 %} +

You currently aren't a member or admin of any groups.

+
+ + {% else %}

Admin Groups


- + {% if admin_groups|length == 0 %} +

You currently aren't the administrator of any groups.

+ {% else %} +
@@ -26,7 +34,7 @@ {% for group in admin_groups %} - + @@ -36,12 +44,16 @@ {% endfor %}
{{ loop.index }} {{ group.name }} {{ group.admins|length + group.users|length }}
+ {% endif %}

User Groups


- + {% if user_groups|length == 0 %} +

You currently aren't a member of any groups.

+ {% else %} +
@@ -65,12 +77,12 @@ {% endfor %}
+ {% endif %} + {% endif %}
- - {% endblock %} @@ -79,7 +91,6 @@ - {% endblock %} diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index 1c84239c..71705390 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% block title %}Correlation Results{% endblock %} {% block css %} diff --git a/wqflask/wqflask/templates/email/verification.txt b/wqflask/wqflask/templates/email/verification.txt deleted file mode 100644 index 76149a3a..00000000 --- a/wqflask/wqflask/templates/email/verification.txt +++ /dev/null @@ -1,7 +0,0 @@ -Thank you for signing up for GeneNetwork. - -We need to verify your email address. - -To do that please click the following link, or cut and paste it into your browser window: - -{{ url_for_hmac("verify_email", code = verification_code, _external=True )}} diff --git a/wqflask/wqflask/templates/gsearch_pheno.html b/wqflask/wqflask/templates/gsearch_pheno.html index 05b2f988..04b45659 100644 --- a/wqflask/wqflask/templates/gsearch_pheno.html +++ b/wqflask/wqflask/templates/gsearch_pheno.html @@ -31,7 +31,7 @@

-
+
diff --git a/wqflask/wqflask/templates/mapping_results.html b/wqflask/wqflask/templates/mapping_results.html index b4429b46..c5d49168 100644 --- a/wqflask/wqflask/templates/mapping_results.html +++ b/wqflask/wqflask/templates/mapping_results.html @@ -41,7 +41,8 @@ - + + @@ -464,13 +465,27 @@ {% if mapping_method != "gemma" and mapping_method != "plink" %} $('#download_perm').click(function(){ - var num_perm, perm_data; - num_perm = js_data.num_perm - perm_data = js_data.perm_results - json_perm_data = JSON.stringify(perm_data); - $('input[name=perm_results]').val(json_perm_data); - $('#marker_regression_form').attr('action', '/export_perm_data'); - return $('#marker_regression_form').submit(); + perm_info_dict = { + perm_data: js_data.perm_results, + num_perm: "{{ nperm }}", + trait_name: "{{ this_trait.display_name }}", + trait_description: "{{ this_trait.description_display }}", + cofactors: "{{ covariates }}", + n_samples: {{ n_samples }}, + n_genotypes: {{ qtl_results|length }}, + {% if genofile_string is defined %} + genofile: "{{ genofile_string }}", + {% else %} + genofile: "", + {% endif %} + units_linkage: "{{ LRS_LOD }}", + strat_cofactors: js_data.categorical_vars + } + json_perm_data = JSON.stringify(perm_info_dict); + + $('input[name=perm_info]').val(json_perm_data); + $('#marker_regression_form').attr('action', '/export_perm_data'); + return $('#marker_regression_form').submit(); }); modebar_options = { diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index edd272c2..cfee0079 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -12,9 +12,6 @@ import requests import simplejson as json -import redis # used for collections -Redis = redis.StrictRedis() - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash, abort) @@ -23,7 +20,8 @@ from wqflask import pbkdf2 from wqflask.user_session import UserSession from utility import hmac -from utility.redis_tools import is_redis_available, get_user_id, get_user_by_unique_column, set_user_attribute, save_user, save_verification_code, check_verification_code, get_user_collections, save_collections +from utility.redis_tools import is_redis_available, get_redis_conn, get_user_id, get_user_by_unique_column, set_user_attribute, save_user, save_verification_code, check_verification_code, get_user_collections, save_collections +Redis = get_redis_conn() from utility.logger import getLogger logger = getLogger(__name__) @@ -127,7 +125,7 @@ def send_email(toaddr, msg, fromaddr="no-reply@genenetwork.org"): server.quit() logger.info("Successfully sent email to "+toaddr) -def send_verification_email(user_details, template_name = "email/verification.txt", key_prefix = "verification_code", subject = "GeneNetwork email verification"): +def send_verification_email(user_details, template_name = "email/user_verification.txt", key_prefix = "verification_code", subject = "GeneNetwork e-mail verification"): verification_code = str(uuid.uuid4()) key = key_prefix + ":" + verification_code @@ -141,6 +139,21 @@ def send_verification_email(user_details, template_name = "email/verification.tx send_email(recipient, subject, body) return {"recipient": recipient, "subject": subject, "body": body} +@app.route("/manage/verify_email") +def verify_email(): + if 'code' in request.args: + user_details = check_verification_code(request.args['code']) + if user_details: + # As long as they have access to the email account + # We might as well log them in + session_id_signed = get_signed_session_id(user_details) + flash("Thank you for logging in {}.".format(user_details['full_name']), "alert-success") + response = make_response(redirect(url_for('index_page', import_collections = import_col, anon_id = anon_id))) + response.set_cookie(UserSession.user_cookie_name, session_id_signed, max_age=None) + return response + else: + flash("Invalid code: Password reset code does not exist or might have expired!", "error") + @app.route("/n/login", methods=('GET', 'POST')) def login(): params = request.form if request.form else request.args @@ -204,7 +217,7 @@ def login(): response.set_cookie(UserSession.user_cookie_name, session_id_signed, max_age=None) return response else: - email_ob = send_verification_email(user_details) + email_ob = send_verification_email(user_details, template_name = "email/user_verification.txt") return render_template("newsecurity/verification_still_needed.html", subject=email_ob['subject']) else: # Incorrect password #ZS: It previously seemed to store that there was an incorrect log-in attempt here, but it did so in the MySQL DB so this might need to be reproduced with Redis @@ -374,16 +387,13 @@ def password_reset(): hmac = request.args.get('hm') if verification_code: - user_email = check_verification_code(verification_code) - if user_email: - user_details = get_user_by_unique_column('email_address', user_email) - if user_details: - return render_template( - "new_security/password_reset.html", user_encode=user_details["email_address"]) - else: - flash("Invalid code: User no longer exists!", "error") + user_details = check_verification_code(verification_code) + if user_details: + return render_template( + "new_security/password_reset.html", user_encode=user_details["email_address"]) else: flash("Invalid code: Password reset code does not exist or might have expired!", "error") + return redirect(url_for("login")) else: return redirect(url_for("login")) @@ -394,6 +404,7 @@ def password_reset_step2(): errors = [] user_email = request.form['user_encode'] + user_id = get_user_id("email_address", user_email) password = request.form['password'] encoded_password = set_password(password) @@ -401,9 +412,7 @@ def password_reset_step2(): set_user_attribute(user_id, "password", encoded_password) flash("Password changed successfully. You can now sign in.", "alert-info") - response = make_response(redirect(url_for('login'))) - - return response + return redirect(url_for('login')) def register_user(params): thank_you_mode = False diff --git a/wqflask/wqflask/user_session.py b/wqflask/wqflask/user_session.py index 50419146..ec6d4ae3 100644 --- a/wqflask/wqflask/user_session.py +++ b/wqflask/wqflask/user_session.py @@ -6,10 +6,6 @@ import uuid import simplejson as json -import redis # used for collections -Redis = redis.StrictRedis() - - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash, abort) @@ -17,7 +13,8 @@ from wqflask import app from utility import hmac #from utility.elasticsearch_tools import get_elasticsearch_connection -from utility.redis_tools import get_user_id, get_user_by_unique_column, get_user_collections, save_collections +from utility.redis_tools import get_redis_conn, get_user_id, get_user_collections, save_collections +Redis = get_redis_conn() from utility.logger import getLogger logger = getLogger(__name__) @@ -29,6 +26,11 @@ THIRTY_DAYS = 60 * 60 * 24 * 30 def get_user_session(): logger.info("@app.before_request get_session") g.user_session = UserSession() + #ZS: I think this should solve the issue of deleting the cookie and redirecting to the home page when a user's session has expired + if not g.user_session: + response = make_response(redirect(url_for('login'))) + response.set_cookie('session_id_v2', '', expires=0) + return response @app.after_request def set_user_session(response): @@ -37,7 +39,6 @@ def set_user_session(response): response.set_cookie(g.user_session.cookie_name, g.user_session.cookie) return response - def verify_cookie(cookie): the_uuid, separator, the_signature = cookie.partition(':') assert len(the_uuid) == 36, "Is session_id a uuid?" @@ -88,14 +89,11 @@ class UserSession(object): user_id = str(uuid.uuid4())) Redis.hmset(self.redis_key, self.record) Redis.expire(self.redis_key, THIRTY_DAYS) - response = make_response(redirect(url_for('login'))) - response.set_cookie(self.user_cookie_name, '', expires=0) ########### Grrr...this won't work because of the way flask handles cookies # Delete the cookie flash("Due to inactivity your session has expired. If you'd like please login again.") - return response - #return + return None else: self.record = dict(login_time = time.time(), user_type = "anon", diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 938570f3..24a4dcee 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -23,16 +23,13 @@ import uuid import simplejson as json import yaml -#Switching from Redis to StrictRedis; might cause some issues -import redis -Redis = redis.StrictRedis() - import flask import base64 import array import sqlalchemy from wqflask import app -from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect +from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for +from wqflask import group_manager from wqflask import search_results from wqflask import export_traits from wqflask import gsearch @@ -55,11 +52,13 @@ 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.trait_submission import submit_trait 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 from utility.helper_functions import get_species_groups +from utility.authentication_tools import check_resource_availability +from utility.redis_tools import get_redis_conn +Redis = get_redis_conn() from base.webqtlConfig import GENERATED_IMAGE_DIR from utility.benchmark import Bench @@ -87,6 +86,24 @@ def connect_db(): g.db = g._database = sqlalchemy.create_engine(SQL_URI, encoding="latin1") logger.debug(g.db) +@app.before_request +def check_access_permissions(): + logger.debug("@app.before_request check_access_permissions") + if "temp_trait" in request.args: + if request.args['temp_trait'] == "True": + pass + else: + if 'dataset' in request.args: + dataset = create_dataset(request.args['dataset']) + logger.debug("USER:", Redis.hget("users")) + if 'trait_id' in request.args: + available = check_resource_availability(dataset, request.args['trait_id']) + else: + available = check_resource_availability(dataset) + + if not available: + return redirect(url_for("no_access_page")) + @app.teardown_appcontext def shutdown_session(exception=None): db = getattr(g, '_database', None) @@ -120,6 +137,10 @@ def handle_bad_request(e): resp.set_cookie(err_msg[:32],animation) return resp +@app.route("/authentication_needed") +def no_access_page(): + return render_template("new_security/not_authenticated.html") + @app.route("/") def index_page(): logger.info("Sending index_page") @@ -401,25 +422,43 @@ def export_traits_csv(): def export_perm_data(): """CSV file consisting of the permutation data for the mapping results""" logger.info(request.url) - num_perm = float(request.form['num_perm']) - perm_data = json.loads(request.form['perm_results']) + perm_info = json.loads(request.form['perm_info']) + + now = datetime.datetime.now() + time_str = now.strftime('%H:%M_%d%B%Y') + + file_name = "Permutation_" + perm_info['num_perm'] + "_" + perm_info['trait_name'] + "_" + time_str + + the_rows = [ + ["#Permutation Test"], + ["#File_name: " + file_name], + ["#Metadata: From GeneNetwork.org"], + ["#Trait_ID: " + perm_info['trait_name']], + ["#Trait_description: " + perm_info['trait_description']], + ["#N_permutations: " + str(perm_info['num_perm'])], + ["#Cofactors: " + perm_info['cofactors']], + ["#N_cases: " + str(perm_info['n_samples'])], + ["#N_genotypes: " + str(perm_info['n_genotypes'])], + ["#Genotype_file: " + perm_info['genofile']], + ["#Units_linkage: " + perm_info['units_linkage']], + ["#Permutation_stratified_by: " + ", ".join([ str(cofactor) for cofactor in perm_info['strat_cofactors']])], + ["#RESULTS_1: Suggestive LRS(p=0.63) = " + str(np.percentile(np.array(perm_info['perm_data']), 67))], + ["#RESULTS_2: Significant LRS(p=0.05) = " + str(np.percentile(np.array(perm_info['perm_data']), 95))], + ["#RESULTS_3: Highly Significant LRS(p=0.01) = " + str(np.percentile(np.array(perm_info['perm_data']), 99))], + ["#Comment: Results sorted from low to high peak linkage"] + ] buff = StringIO.StringIO() writer = csv.writer(buff) - writer.writerow(["Suggestive LRS (p=0.63) = " + str(np.percentile(np.array(perm_data), 67))]) - writer.writerow(["Significant LRS (p=0.05) = " + str(np.percentile(np.array(perm_data), 95))]) - writer.writerow(["Highly Significant LRS (p=0.01) = " + str(np.percentile(np.array(perm_data), 99))]) - writer.writerow("") - writer.writerow([str(num_perm) + " Permutations"]) - writer.writerow("") - for item in perm_data: + writer.writerows(the_rows) + for item in perm_info['perm_data']: writer.writerow([item]) csv_data = buff.getvalue() buff.close() return Response(csv_data, mimetype='text/csv', - headers={"Content-Disposition":"attachment;filename=perm_data.csv"}) + headers={"Content-Disposition":"attachment;filename=" + file_name + ".csv"}) @app.route("/show_temp_trait", methods=('POST',)) def show_temp_trait_page(): -- cgit v1.2.3 From a302a2b0ac0e7c0f26a0d063c3f2b057f61d47f1 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 5 Jun 2020 16:52:56 -0500 Subject: Commiting other current group/resource management code, plus the new files --- wqflask/base/trait.py | 2 + wqflask/maintenance/set_resource_defaults.py | 155 +++++++++++++++++++++ wqflask/utility/authentication_tools.py | 46 ++++++ wqflask/utility/redis_tools.py | 37 +++-- wqflask/wqflask/group_manager.py | 77 ++++++++++ wqflask/wqflask/resource_manager.py | 72 ++++++++++ .../wqflask/static/new/javascript/group_manager.js | 38 +++++ wqflask/wqflask/templates/admin/create_group.html | 89 ++++++++++++ wqflask/wqflask/templates/admin/group_manager.html | 68 ++++----- .../wqflask/templates/admin/manage_resource.html | 92 ++++++++++++ .../wqflask/templates/admin/search_for_groups.html | 64 +++++++++ .../templates/admin/select_group_to_add.html | 54 +++++++ .../templates/new_security/not_authenticated.html | 11 ++ wqflask/wqflask/templates/show_trait_details.html | 5 + wqflask/wqflask/views.py | 3 +- 15 files changed, 764 insertions(+), 49 deletions(-) create mode 100644 wqflask/maintenance/set_resource_defaults.py create mode 100644 wqflask/utility/authentication_tools.py create mode 100644 wqflask/wqflask/group_manager.py create mode 100644 wqflask/wqflask/resource_manager.py create mode 100644 wqflask/wqflask/static/new/javascript/group_manager.js create mode 100644 wqflask/wqflask/templates/admin/create_group.html create mode 100644 wqflask/wqflask/templates/admin/manage_resource.html create mode 100644 wqflask/wqflask/templates/admin/search_for_groups.html create mode 100644 wqflask/wqflask/templates/admin/select_group_to_add.html create mode 100644 wqflask/wqflask/templates/new_security/not_authenticated.html (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 405c4ebf..2a945588 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -391,6 +391,8 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if response.strip() == "no-access": trait.view = False return trait + else: + trait_info = json.loads(response) except: resource_info = get_resource_info(resource_id) default_permissions = resource_info['default_mask']['data'] diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py new file mode 100644 index 00000000..ba102d9c --- /dev/null +++ b/wqflask/maintenance/set_resource_defaults.py @@ -0,0 +1,155 @@ +""" + +Script that sets default resource access masks for use with the DB proxy + +Defaults will be: +Owner - omni_gn +Mask - Public/non-confidential: { data: "view", + metadata: "view", + admin: "not-admin" } + Private/confidentia: { data: "no-access", + metadata: "no-access", + admin: "not-admin" } + +To run: +./bin/genenetwork2 ~/my_settings.py -c ./wqflask/maintenance/gen_select_dataset.py + +""" + +from __future__ import print_function, division + +import sys +import json + +# NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead +sys.path.insert(0,'./') + +# NEW: import app to avoid a circular dependency on utility.tools +from wqflask import app + +from utility.tools import SQL_URI +from utility.redis_tools import get_redis_conn, get_user_id, add_resource, get_resources +Redis = get_redis_conn() + +import MySQLdb + +import urlparse + +from utility.logger import getLogger +logger = getLogger(__name__) + +def parse_db_uri(): + """Converts a database URI to the db name, host name, user name, and password""" + + parsed_uri = urlparse.urlparse(SQL_URI) + + db_conn_info = dict( + db = parsed_uri.path[1:], + host = parsed_uri.hostname, + user = parsed_uri.username, + passwd = parsed_uri.password) + + print(db_conn_info) + return db_conn_info + +def insert_probeset_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.confidentiality, ProbeSetFreeze.public + FROM + ProbeSetFreeze""") + + resource_results = Cursor.fetchall() + for i, resource in enumerate(resource_results): + if i % 20 == 0: + print(i) + resource_ob = {} + resource_ob['name'] = resource[1] + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[0])} + resource_ob['type'] = "dataset-probeset" + if resource[2] < 1 and resource[3] > 0: + resource_ob['default_mask'] = { "data": ["no-access", "view"] } + else: + resource_ob['default_mask'] = { "data": ["no-access"] } + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + +def insert_publish_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + PublishXRef.Id, PublishFreeze.Id, InbredSet.InbredSetCode + FROM + PublishXRef, PublishFreeze, InbredSet, Publication + WHERE + PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND + InbredSet.Id = PublishXRef.InbredSetId AND + Publication.Id = PublishXRef.PublicationId""") + + resource_results = Cursor.fetchall() + for resource in resource_results: + if resource[2]: + resource_ob = {} + if resource[2]: + resource_ob['name'] = resource[2] + "_" + str(resource[0]) + else: + resource_ob['name'] = str(resource[0]) + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[1]) , + "trait" : str(resource[0])} + resource_ob['type'] = "dataset-publish" + resource_ob['default_mask'] = { "data": "view" } + + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + else: + continue + +def insert_geno_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + GenoFreeze.Id, GenoFreeze.ShortName, GenoFreeze.confidentiality + FROM + GenoFreeze""") + + resource_results = Cursor.fetchall() + for i, resource in enumerate(resource_results): + if i % 20 == 0: + print(i) + resource_ob = {} + resource_ob['name'] = resource[1] + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[0]) } + resource_ob['type'] = "dataset-geno" + if resource[2] < 1: + resource_ob['default_mask'] = { "data": "view" } + else: + resource_ob['default_mask'] = { "data": "no-access" } + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + +def insert_resources(default_owner_id): + current_resources = get_resources() + print("START") + insert_publish_resources(default_owner_id) + print("AFTER PUBLISH") + insert_geno_resources(default_owner_id) + print("AFTER GENO") + insert_probeset_resources(default_owner_id) + print("AFTER PROBESET") + +def main(): + """Generates and outputs (as json file) the data for the main dropdown menus on the home page""" + + Redis.delete("resources") + + owner_id = get_user_id("email_address", "zachary.a.sloan@gmail.com") + insert_resources(owner_id) + +if __name__ == '__main__': + Conn = MySQLdb.Connect(**parse_db_uri()) + Cursor = Conn.cursor() + main() \ No newline at end of file diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py new file mode 100644 index 00000000..537881a5 --- /dev/null +++ b/wqflask/utility/authentication_tools.py @@ -0,0 +1,46 @@ +from __future__ import absolute_import, print_function, division + +import json +import requests + +from base import data_set + +from utility import hmac +from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id + +from flask import Flask, g, redirect, url_for + +import logging +logger = logging.getLogger(__name__ ) + +def check_resource_availability(dataset, trait_id=None): + resource_id = get_resource_id(dataset, trait_id) + + if resource_id: + the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + try: + response = json.loads(requests.get(the_url).content)['data'] + except: + resource_info = get_resource_info(resource_id) + response = resource_info['default_mask']['data'] + + if 'view' in response: + return True + else: + return redirect(url_for("no_access_page")) + + return True + +def check_owner(dataset=None, trait_id=None, resource_id=None): + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return resource_id + else: + resource_id = get_resource_id(dataset, trait_id) + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return resource_id + + return False \ No newline at end of file diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 0ad96879..bc30a0af 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -95,14 +95,17 @@ def get_user_groups(user_id): user_group_ids = [] #ZS: Group IDs where user is a regular user groups_list = Redis.hgetall("groups") for key in groups_list: - group_ob = json.loads(groups_list[key]) - group_admins = set(group_ob['admins']) - group_members = set(group_ob['members']) - if user_id in group_admins: - admin_group_ids.append(group_ob['id']) - elif user_id in group_members: - user_group_ids.append(group_ob['id']) - else: + try: + group_ob = json.loads(groups_list[key]) + group_admins = set(group_ob['admins']) + group_members = set(group_ob['members']) + if user_id in group_admins: + admin_group_ids.append(group_ob['id']) + elif user_id in group_members: + user_group_ids.append(group_ob['id']) + else: + continue + except: continue admin_groups = [] @@ -122,6 +125,24 @@ 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 """ + + matched_groups = [] + + 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 + if column_value in group_info[column_name]: + matched_groups.append(group_info) + else: + if group_info[column_name] == column_value: + matched_groups.append(group_info) + + return matched_groups + + def create_group(admin_user_ids, member_user_ids = [], group_name = "Default Group Name"): group_id = str(uuid.uuid4()) new_group = { diff --git a/wqflask/wqflask/group_manager.py b/wqflask/wqflask/group_manager.py new file mode 100644 index 00000000..f41ae56d --- /dev/null +++ b/wqflask/wqflask/group_manager.py @@ -0,0 +1,77 @@ + +from __future__ import print_function, division, absolute_import + +from flask import (Flask, g, render_template, url_for, request, make_response, + redirect, flash) + +from wqflask import app +from wqflask.user_login import send_verification_email + +from utility.redis_tools import get_user_groups, get_group_info, create_group, delete_group, add_users_to_group, remove_users_from_group, \ + change_group_name, save_verification_code, check_verification_code, get_user_by_unique_column + +from utility.logger import getLogger +logger = getLogger(__name__) + +@app.route("/groups/manage", methods=('GET', 'POST')) +def manage_groups(): + params = request.form if request.form else request.args + if "add_new_group" in params: + return redirect(url_for('add_group')) + else: + admin_groups, user_groups = get_user_groups(g.user_session.user_id) + return render_template("admin/group_manager.html", admin_groups=admin_groups, user_groups=user_groups) + +@app.route("/groups/remove", methods=('POST',)) +def remove_groups(): + group_ids_to_remove = request.form['selected_group_ids'] + for group_id in group_ids_to_remove.split(":"): + delete_group(g.user_session.user_id, group_id) + + return redirect(url_for('manage_groups')) + +@app.route("/groups/create", methods=('GET', 'POST')) +def add_group(): + params = request.form if request.form else request.args + if "group_name" in params: + member_user_ids = set() + admin_user_ids = set() + admin_user_ids.add(g.user_session.user_id) #ZS: Always add the user creating the group as an admin + if "admin_emails" in params: + admin_emails = params['admin_emails_to_add'].split(",") + for email in admin_emails: + user_details = get_user_by_unique_column("email_address", email) + if user_details: + admin_user_ids.add(user_details['user_id']) + #send_group_invites(params['group_id'], user_email_list = admin_emails, user_type="admins") + if "user_emails" in params: + member_emails = params['member_emails_to_add'].split(",") + for email in member_emails: + user_details = get_user_by_unique_column("email_address", email) + if user_details: + member_user_ids.add(user_details['user_id']) + #send_group_invites(params['group_id'], user_email_list = user_emails, user_type="members") + + create_group(list(admin_user_ids), list(member_user_ids), params['group_name']) + return redirect(url_for('manage_groups')) + else: + return render_template("admin/create_group.html") + +#ZS: Will integrate this later, for now just letting users be added directly +def send_group_invites(group_id, user_email_list = [], user_type="members"): + for user_email in user_email_list: + user_details = get_user_by_unique_column("email_address", user_email) + if user_details: + group_info = get_group_info(group_id) + #ZS: Probably not necessary since the group should normally always exist if group_id is being passed here, + # but it's technically possible to hit it if Redis is cleared out before submitting the new users or something + if group_info: + #ZS: Don't add user if they're already an admin or if they're being added a regular user and are already a regular user, + # but do add them if they're a regular user and are added as an admin + if (user_details['user_id'] in group_info['admins']) or \ + ((user_type == "members") and (user_details['user_id'] in group_info['members'])): + continue + else: + send_verification_email(user_details, template_name = "email/group_verification.txt", key_prefix = "verification_code", subject = "You've been invited to join a GeneNetwork user group") + +#@app.route() \ No newline at end of file diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py new file mode 100644 index 00000000..7d88b8ed --- /dev/null +++ b/wqflask/wqflask/resource_manager.py @@ -0,0 +1,72 @@ +from __future__ import print_function, division, absolute_import + +from flask import (Flask, g, render_template, url_for, request, make_response, + redirect, flash) + +from wqflask import app + +from utility.authentication_tools import check_owner +from utility.redis_tools import get_resource_info, get_group_info, get_group_by_unique_column, get_user_id + +from utility.logger import getLogger +logger = getLogger(__name__) + +@app.route("/resources/manage", methods=('GET', 'POST')) +def view_resource(): + params = request.form if request.form else request.args + if 'resource_id' in request.args: + resource_id = request.args['resource_id'] + if check_owner(resource_id=resource_id): + resource_info = get_resource_info(resource_id) + group_masks = resource_info['group_masks'] + group_masks_with_names = get_group_names(group_masks) + default_mask = resource_info['default_mask']['data'] + return render_template("admin/manage_resource.html", resource_id = resource_id, resource_info=resource_info, default_mask=default_mask, group_masks=group_masks_with_names) + else: + return redirect(url_for("no_access_page")) + +@app.route("/resources/add_group", methods=('POST',)) +def add_group_to_resource(): + resource_id = request.form['resource_id'] + if check_owner(resource_id=resource_id): + if all(key in request.form for key in ('group_id', 'group_name', 'user_name', 'user_email')): + group_list = [] + if request.form['group_id'] != "": + the_group = get_group_info(request.form['group_id']) + if the_group: + group_list.append(the_group) + if request.form['group_name'] != "": + matched_groups = get_group_by_unique_column("name", request.form['group_name']) + for group in matched_groups: + group_list.append(group) + if request.form['user_name'] != "": + user_id = get_user_id("user_name", request.form['user_name']) + if user_id: + matched_groups = get_group_by_unique_column("admins", user_id) + matched_groups += get_group_by_unique_column("members", user_id) + for group in matched_groups: + group_list.append(group) + if request.form['user_email'] != "": + user_id = get_user_id("email_address", request.form['user_email']) + if user_id: + matched_groups = get_group_by_unique_column("admins", user_id) + matched_groups += get_group_by_unique_column("members", user_id) + for group in matched_groups: + group_list.append(group) + return render_template("admin/select_group_to_add.html", group_list=group_list, resource_id = resource_id) + elif 'selected_group' in request.form: + group_id = request.form['selected_group'] + return render_template("admin/set_group_privileges.html", resource_id = resource_id, group_id = group_id) + else: + return render_template("admin/search_for_groups.html", resource_id = resource_id) + else: + return redirect(url_for("no_access_page")) + +def get_group_names(group_masks): + group_masks_with_names = {} + for group_id, group_mask in group_masks.iteritems(): + this_mask = group_mask + group_name = get_group_info(group_id)['name'] + this_mask['name'] = group_name + + return group_masks_with_names \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/group_manager.js b/wqflask/wqflask/static/new/javascript/group_manager.js new file mode 100644 index 00000000..5e82d104 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/group_manager.js @@ -0,0 +1,38 @@ +$('#add_to_admins').click(function() { + add_emails('admin') +}) + +$('#add_to_members').click(function() { + add_emails('member') +}) + +$('#clear_admins').click(function(){ + clear_emails('admin') +}) + +$('#clear_members').click(function(){ + clear_emails('member') +}) + + +function add_emails(user_type){ + var email_address = $('input[name=user_email]').val(); + var email_list_string = $('input[name=' + user_type + '_emails_to_add]').val() + console.log(email_list_string) + if (email_list_string == ""){ + var email_set = new Set(); + } else { + var email_set = new Set(email_list_string.split(",")) + } + email_set.add(email_address) + + $('input[name=' + user_type + '_emails_to_add]').val(Array.from(email_set).join(',')) + + var emails_display_string = Array.from(email_set).join('\n') + $('.added_' + user_type + 's').val(emails_display_string) +} + +function clear_emails(user_type){ + $('input[name=' + user_type + '_emails_to_add]').val("") + $('.added_' + user_type + 's').val("") +} \ No newline at end of file diff --git a/wqflask/wqflask/templates/admin/create_group.html b/wqflask/wqflask/templates/admin/create_group.html new file mode 100644 index 00000000..55c3fa0b --- /dev/null +++ b/wqflask/wqflask/templates/admin/create_group.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} +{% block title %}Group Manager{% endblock %} +{% block content %} + +
+ +
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+ + + + + +{% endblock %} + +{% block js %} + + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/group_manager.html b/wqflask/wqflask/templates/admin/group_manager.html index b7df1aad..23d8205a 100644 --- a/wqflask/wqflask/templates/admin/group_manager.html +++ b/wqflask/wqflask/templates/admin/group_manager.html @@ -1,15 +1,23 @@ {% extends "base.html" %} {% block title %}Group Manager{% endblock %} +{% block css %} + + + +{% endblock %} {% block content %}
-
+
{% if admin_groups|length == 0 and user_groups|length == 0 %}

You currently aren't a member or admin of any groups.


@@ -20,7 +28,7 @@ {% if admin_groups|length == 0 %}

You currently aren't the administrator of any groups.

{% else %} -

Loading...
+
@@ -29,17 +37,19 @@ + {% for group in admin_groups %} - + - + + {% endfor %} @@ -47,13 +57,13 @@ {% endif %}
-
+

User Groups


{% if user_groups|length == 0 %}

You currently aren't a member of any groups.

{% else %} -
# Members Created Last ChangedGroup ID
{{ loop.index }}{{ loop.index }} {{ group.name }}{{ group.admins|length + group.users|length }}{{ group.admins|length + group.users|length }} {{ group.created_timestamp }} {{ group.changed_timestamp }}{{ group.id }}
+
@@ -88,48 +98,26 @@ {% endblock %} {% block js %} - - - + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/search_for_groups.html b/wqflask/wqflask/templates/admin/search_for_groups.html new file mode 100644 index 00000000..89eb11dd --- /dev/null +++ b/wqflask/wqflask/templates/admin/search_for_groups.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} +{% block title %}Resource Manager{% endblock %} +{% block content %} + +
+ + + +
+
+
+
+

Search by:

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ + + +{% endblock %} + +{% block js %} + + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/select_group_to_add.html b/wqflask/wqflask/templates/admin/select_group_to_add.html new file mode 100644 index 00000000..df70fb2f --- /dev/null +++ b/wqflask/wqflask/templates/admin/select_group_to_add.html @@ -0,0 +1,54 @@ +{% extends "base.html" %} +{% block title %}Matched Groups{% endblock %} +{% block css %} + + + +{% endblock %} +{% block content %} + +
+

The following groups were found:

+
+
+ +
+ {% if group_list|length > 0 %} + +
+ + + + + + + + + + {% for group in group_list %} + + + + + + + {% endfor %} + +
NameCreatedLast Changed
{% if 'name' in group %}{{ group.name }}{% else %}N/A{% endif %}{% if 'created_timestamp' in group %}{{ group.created_timestamp }}{% else %}N/A{% endif %}{% if 'changed_timestamp' in group %}{{ group.changed_timestamp }}{% else %}N/A{% endif %}
+ {% else %} +

No matching groups were found.

+ {% endif %} +
+ +
+ + + +{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/wqflask/wqflask/templates/new_security/not_authenticated.html b/wqflask/wqflask/templates/new_security/not_authenticated.html new file mode 100644 index 00000000..7d0d3060 --- /dev/null +++ b/wqflask/wqflask/templates/new_security/not_authenticated.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} +{% block title %}Authentication Needed{% endblock %} +{% block content %} +
+ +

Please contact the data's owner or GN administrators if you believe you should have access to this data.

+
+ +{% endblock %} \ No newline at end of file diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 878b6ced..5c315878 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -248,6 +248,11 @@ + {% if resource_id %} + + + + {% endif %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 24a4dcee..ee827ba3 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -30,6 +30,7 @@ import sqlalchemy from wqflask import app from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for from wqflask import group_manager +from wqflask import resource_manager from wqflask import search_results from wqflask import export_traits from wqflask import gsearch @@ -89,13 +90,13 @@ def connect_db(): @app.before_request def check_access_permissions(): logger.debug("@app.before_request check_access_permissions") + available = True if "temp_trait" in request.args: if request.args['temp_trait'] == "True": pass else: if 'dataset' in request.args: dataset = create_dataset(request.args['dataset']) - logger.debug("USER:", Redis.hget("users")) if 'trait_id' in request.args: available = check_resource_availability(dataset, request.args['trait_id']) else: -- cgit v1.2.3 From ea47eb228b1224ea83e3f50a056bf715b3bf5ec6 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 17 Jun 2020 14:49:40 -0500 Subject: Adding all the authentication stuff --- wqflask/base/data_set.py | 36 +-- wqflask/base/trait.py | 5 +- wqflask/maintenance/set_resource_defaults.py | 307 ++++++++++----------- wqflask/utility/authentication_tools.py | 132 ++++++--- wqflask/utility/redis_tools.py | 67 ++++- wqflask/wqflask/docs.py | 4 +- wqflask/wqflask/group_manager.py | 220 ++++++++++----- wqflask/wqflask/resource_manager.py | 204 +++++++++----- .../wqflask/static/new/javascript/group_manager.js | 74 ++--- .../static/new/javascript/search_results.js | 1 - .../templates/admin/change_resource_owner.html | 116 ++++++++ wqflask/wqflask/templates/admin/create_group.html | 178 ++++++------ wqflask/wqflask/templates/admin/group_manager.html | 18 +- .../wqflask/templates/admin/manage_resource.html | 200 ++++++++------ .../wqflask/templates/admin/search_for_groups.html | 198 ++++++++----- .../templates/admin/select_group_to_add.html | 54 ---- .../templates/admin/set_group_privileges.html | 102 +++++++ wqflask/wqflask/templates/admin/view_group.html | 238 ++++++++++++++++ wqflask/wqflask/templates/base.html | 5 + .../wqflask/templates/set_group_privileges.html | 77 ++++++ wqflask/wqflask/templates/show_trait_details.html | 4 +- wqflask/wqflask/views.py | 2 +- 22 files changed, 1516 insertions(+), 726 deletions(-) create mode 100644 wqflask/wqflask/templates/admin/change_resource_owner.html delete mode 100644 wqflask/wqflask/templates/admin/select_group_to_add.html create mode 100644 wqflask/wqflask/templates/admin/set_group_privileges.html create mode 100644 wqflask/wqflask/templates/admin/view_group.html create mode 100644 wqflask/wqflask/templates/set_group_privileges.html (limited to 'wqflask/utility') diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 1457ba8d..92dc8615 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -486,25 +486,18 @@ class DatasetGroup(object): def datasets(group_name, this_group = None): key = "group_dataset_menu:v2:" + group_name - logger.debug("key is2:", key) dataset_menu = [] - logger.debug("[tape4] webqtlConfig.PUBLICTHRESH:", webqtlConfig.PUBLICTHRESH) - logger.debug("[tape4] type webqtlConfig.PUBLICTHRESH:", type(webqtlConfig.PUBLICTHRESH)) the_results = fetchall(''' (SELECT '#PublishFreeze',PublishFreeze.FullName,PublishFreeze.Name FROM PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = '%s' - and PublishFreeze.public > %s - and PublishFreeze.confidentiality < 1 ORDER BY PublishFreeze.Id ASC) UNION (SELECT '#GenoFreeze',GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze, InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id - and InbredSet.Name = '%s' - and GenoFreeze.public > %s - and GenoFreeze.confidentiality < 1) + and InbredSet.Name = '%s') UNION (SELECT Tissue.Name, ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue @@ -512,12 +505,10 @@ def datasets(group_name, this_group = None): and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like %s - and ProbeSetFreeze.public > %s - and ProbeSetFreeze.confidentiality < 1 ORDER BY Tissue.Name, ProbeSetFreeze.OrderList DESC) - ''' % (group_name, webqtlConfig.PUBLICTHRESH, - group_name, webqtlConfig.PUBLICTHRESH, - "'" + group_name + "'", webqtlConfig.PUBLICTHRESH)) + ''' % (group_name, + group_name, + "'" + group_name + "'")) sorted_results = sorted(the_results, key=lambda kv: kv[0]) @@ -637,29 +628,25 @@ class DataSet(object): """ - try: if self.type == "ProbeSet": query_args = tuple(escape(x) for x in ( - str(webqtlConfig.PUBLICTHRESH), self.name, self.name, self.name)) self.id, self.name, self.fullname, self.shortname, self.data_scale, self.tissue = fetch1(""" -SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.FullName, ProbeSetFreeze.ShortName, ProbeSetFreeze.DataScale, Tissue.Name -FROM ProbeSetFreeze, ProbeFreeze, Tissue -WHERE ProbeSetFreeze.public > %s -AND ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id -AND ProbeFreeze.TissueId = Tissue.Id -AND (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFreeze.ShortName = '%s') + SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.FullName, ProbeSetFreeze.ShortName, ProbeSetFreeze.DataScale, Tissue.Name + FROM ProbeSetFreeze, ProbeFreeze, Tissue + WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id + AND ProbeFreeze.TissueId = Tissue.Id + AND (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFreeze.ShortName = '%s') """ % (query_args),"/dataset/"+self.name+".json", lambda r: (r["id"],r["name"],r["full_name"],r["short_name"],r["data_scale"],r["tissue"]) ) else: query_args = tuple(escape(x) for x in ( (self.type + "Freeze"), - str(webqtlConfig.PUBLICTHRESH), self.name, self.name, self.name)) @@ -668,9 +655,8 @@ AND (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFre self.id, self.name, self.fullname, self.shortname = fetchone(""" SELECT Id, Name, FullName, ShortName FROM %s - WHERE public > %s AND - (Name = '%s' OR FullName = '%s' OR ShortName = '%s') - """ % (query_args)) + WHERE (Name = '%s' OR FullName = '%s' OR ShortName = '%s') + """ % (query_args)) except TypeError: logger.debug("Dataset {} is not yet available in GeneNetwork.".format(self.name)) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 2a945588..7700ecd5 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -46,9 +46,10 @@ def create_trait(**kw): else: permitted = check_resource_availability(dataset) - if permitted: + if permitted != "no-access": the_trait = GeneralTrait(**kw) if the_trait.dataset.type != "Temp": + the_trait = retrieve_trait_info(the_trait, the_trait.dataset, get_qtl_info=kw.get('get_qtl_info')) return the_trait else: @@ -383,7 +384,6 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if dataset.type == 'Publish': the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) else: - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) try: @@ -424,7 +424,6 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): logger.sql(query) trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif dataset.type == 'ProbeSet': diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index ba102d9c..344e6a23 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -1,155 +1,154 @@ -""" - -Script that sets default resource access masks for use with the DB proxy - -Defaults will be: -Owner - omni_gn -Mask - Public/non-confidential: { data: "view", - metadata: "view", - admin: "not-admin" } - Private/confidentia: { data: "no-access", - metadata: "no-access", - admin: "not-admin" } - -To run: -./bin/genenetwork2 ~/my_settings.py -c ./wqflask/maintenance/gen_select_dataset.py - -""" - -from __future__ import print_function, division - -import sys -import json - -# NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead -sys.path.insert(0,'./') - -# NEW: import app to avoid a circular dependency on utility.tools -from wqflask import app - -from utility.tools import SQL_URI -from utility.redis_tools import get_redis_conn, get_user_id, add_resource, get_resources -Redis = get_redis_conn() - -import MySQLdb - -import urlparse - -from utility.logger import getLogger -logger = getLogger(__name__) - -def parse_db_uri(): - """Converts a database URI to the db name, host name, user name, and password""" - - parsed_uri = urlparse.urlparse(SQL_URI) - - db_conn_info = dict( - db = parsed_uri.path[1:], - host = parsed_uri.hostname, - user = parsed_uri.username, - passwd = parsed_uri.password) - - print(db_conn_info) - return db_conn_info - -def insert_probeset_resources(default_owner_id): - current_resources = Redis.hgetall("resources") - Cursor.execute(""" SELECT - ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.confidentiality, ProbeSetFreeze.public - FROM - ProbeSetFreeze""") - - resource_results = Cursor.fetchall() - for i, resource in enumerate(resource_results): - if i % 20 == 0: - print(i) - resource_ob = {} - resource_ob['name'] = resource[1] - resource_ob['owner_id'] = default_owner_id - resource_ob['data'] = { "dataset" : str(resource[0])} - resource_ob['type'] = "dataset-probeset" - if resource[2] < 1 and resource[3] > 0: - resource_ob['default_mask'] = { "data": ["no-access", "view"] } - else: - resource_ob['default_mask'] = { "data": ["no-access"] } - resource_ob['group_masks'] = {} - - add_resource(resource_ob) - -def insert_publish_resources(default_owner_id): - current_resources = Redis.hgetall("resources") - Cursor.execute(""" SELECT - PublishXRef.Id, PublishFreeze.Id, InbredSet.InbredSetCode - FROM - PublishXRef, PublishFreeze, InbredSet, Publication - WHERE - PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND - InbredSet.Id = PublishXRef.InbredSetId AND - Publication.Id = PublishXRef.PublicationId""") - - resource_results = Cursor.fetchall() - for resource in resource_results: - if resource[2]: - resource_ob = {} - if resource[2]: - resource_ob['name'] = resource[2] + "_" + str(resource[0]) - else: - resource_ob['name'] = str(resource[0]) - resource_ob['owner_id'] = default_owner_id - resource_ob['data'] = { "dataset" : str(resource[1]) , - "trait" : str(resource[0])} - resource_ob['type'] = "dataset-publish" - resource_ob['default_mask'] = { "data": "view" } - - resource_ob['group_masks'] = {} - - add_resource(resource_ob) - else: - continue - -def insert_geno_resources(default_owner_id): - current_resources = Redis.hgetall("resources") - Cursor.execute(""" SELECT - GenoFreeze.Id, GenoFreeze.ShortName, GenoFreeze.confidentiality - FROM - GenoFreeze""") - - resource_results = Cursor.fetchall() - for i, resource in enumerate(resource_results): - if i % 20 == 0: - print(i) - resource_ob = {} - resource_ob['name'] = resource[1] - resource_ob['owner_id'] = default_owner_id - resource_ob['data'] = { "dataset" : str(resource[0]) } - resource_ob['type'] = "dataset-geno" - if resource[2] < 1: - resource_ob['default_mask'] = { "data": "view" } - else: - resource_ob['default_mask'] = { "data": "no-access" } - resource_ob['group_masks'] = {} - - add_resource(resource_ob) - -def insert_resources(default_owner_id): - current_resources = get_resources() - print("START") - insert_publish_resources(default_owner_id) - print("AFTER PUBLISH") - insert_geno_resources(default_owner_id) - print("AFTER GENO") - insert_probeset_resources(default_owner_id) - print("AFTER PROBESET") - -def main(): - """Generates and outputs (as json file) the data for the main dropdown menus on the home page""" - - Redis.delete("resources") - - owner_id = get_user_id("email_address", "zachary.a.sloan@gmail.com") - insert_resources(owner_id) - -if __name__ == '__main__': - Conn = MySQLdb.Connect(**parse_db_uri()) - Cursor = Conn.cursor() +""" + +Script that sets default resource access masks for use with the DB proxy + +Defaults will be: +Owner - omni_gn +Mask - Public/non-confidential: { data: "view", + metadata: "view", + admin: "not-admin" } + Private/confidentia: { data: "no-access", + metadata: "no-access", + admin: "not-admin" } + +To run: +./bin/genenetwork2 ~/my_settings.py -c ./wqflask/maintenance/gen_select_dataset.py + +""" + +from __future__ import print_function, division + +import sys +import json + +# NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead +sys.path.insert(0,'./') + +# NEW: import app to avoid a circular dependency on utility.tools +from wqflask import app + +from utility.tools import SQL_URI +from utility.redis_tools import get_redis_conn, get_user_id, add_resource, get_resources +Redis = get_redis_conn() + +import MySQLdb + +import urlparse + +from utility.logger import getLogger +logger = getLogger(__name__) + +def parse_db_uri(): + """Converts a database URI to the db name, host name, user name, and password""" + + parsed_uri = urlparse.urlparse(SQL_URI) + + db_conn_info = dict( + db = parsed_uri.path[1:], + host = parsed_uri.hostname, + user = parsed_uri.username, + passwd = parsed_uri.password) + + print(db_conn_info) + return db_conn_info + +def insert_probeset_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.confidentiality, ProbeSetFreeze.public + FROM + ProbeSetFreeze""") + + resource_results = Cursor.fetchall() + for i, resource in enumerate(resource_results): + resource_ob = {} + resource_ob['name'] = resource[1] + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[0])} + resource_ob['type'] = "dataset-probeset" + if resource[2] < 1 and resource[3] > 0: + resource_ob['default_mask'] = { "data": "view" } + else: + resource_ob['default_mask'] = { "data": "no-access" } + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + +def insert_publish_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + PublishXRef.Id, PublishFreeze.Id, InbredSet.InbredSetCode + FROM + PublishXRef, PublishFreeze, InbredSet, Publication + WHERE + PublishFreeze.InbredSetId = PublishXRef.InbredSetId AND + InbredSet.Id = PublishXRef.InbredSetId AND + Publication.Id = PublishXRef.PublicationId""") + + resource_results = Cursor.fetchall() + for resource in resource_results: + if resource[2]: + resource_ob = {} + if resource[2]: + resource_ob['name'] = resource[2] + "_" + str(resource[0]) + else: + resource_ob['name'] = str(resource[0]) + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[1]) , + "trait" : str(resource[0])} + resource_ob['type'] = "dataset-publish" + resource_ob['default_mask'] = { "data": "view" } + + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + else: + continue + +def insert_geno_resources(default_owner_id): + current_resources = Redis.hgetall("resources") + Cursor.execute(""" SELECT + GenoFreeze.Id, GenoFreeze.ShortName, GenoFreeze.confidentiality + FROM + GenoFreeze""") + + resource_results = Cursor.fetchall() + for i, resource in enumerate(resource_results): + resource_ob = {} + resource_ob['name'] = resource[1] + if resource[1] == "HET3-ITPGeno": + resource_ob['owner_id'] = "73a3f093-ca13-4ae0-a179-9a446f709f6e" + else: + resource_ob['owner_id'] = default_owner_id + resource_ob['data'] = { "dataset" : str(resource[0]) } + resource_ob['type'] = "dataset-geno" + if resource[2] < 1: + resource_ob['default_mask'] = { "data": "view" } + else: + resource_ob['default_mask'] = { "data": "no-access" } + resource_ob['group_masks'] = {} + + add_resource(resource_ob) + +def insert_resources(default_owner_id): + current_resources = get_resources() + print("START") + insert_publish_resources(default_owner_id) + print("AFTER PUBLISH") + insert_geno_resources(default_owner_id) + print("AFTER GENO") + insert_probeset_resources(default_owner_id) + print("AFTER PROBESET") + +def main(): + """Generates and outputs (as json file) the data for the main dropdown menus on the home page""" + + Redis.delete("resources") + + owner_id = get_user_id("email_address", "zachary.a.sloan@gmail.com") + insert_resources(owner_id) + +if __name__ == '__main__': + Conn = MySQLdb.Connect(**parse_db_uri()) + Cursor = Conn.cursor() main() \ No newline at end of file diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 537881a5..07ceacc0 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -1,46 +1,86 @@ -from __future__ import absolute_import, print_function, division - -import json -import requests - -from base import data_set - -from utility import hmac -from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id - -from flask import Flask, g, redirect, url_for - -import logging -logger = logging.getLogger(__name__ ) - -def check_resource_availability(dataset, trait_id=None): - resource_id = get_resource_id(dataset, trait_id) - - if resource_id: - the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) - try: - response = json.loads(requests.get(the_url).content)['data'] - except: - resource_info = get_resource_info(resource_id) - response = resource_info['default_mask']['data'] - - if 'view' in response: - return True - else: - return redirect(url_for("no_access_page")) - - return True - -def check_owner(dataset=None, trait_id=None, resource_id=None): - if resource_id: - resource_info = get_resource_info(resource_id) - if g.user_session.user_id == resource_info['owner_id']: - return resource_id - else: - resource_id = get_resource_id(dataset, trait_id) - if resource_id: - resource_info = get_resource_info(resource_id) - if g.user_session.user_id == resource_info['owner_id']: - return resource_id - - return False \ No newline at end of file +from __future__ import absolute_import, print_function, division + +import json +import requests + +from base import data_set + +from utility import hmac +from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id + +from flask import Flask, g, redirect, url_for + +import logging +logger = logging.getLogger(__name__ ) + +def check_resource_availability(dataset, trait_id=None): + resource_id = get_resource_id(dataset, trait_id) + + response = None + if resource_id: + resource_info = get_resource_info(resource_id) + + the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + try: + response = json.loads(requests.get(the_url).content)['data'] + except: + response = resource_info['default_mask']['data'] + + if 'edit' in response: + return "edit" + elif 'view' in response: + return "view" + else: + return "no-access" + + return False + +def check_admin(resource_id=None): + + return "not-admin" + + # ZS: commented out until proxy can return this + # the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + # try: + # response = json.loads(requests.get(the_url).content) + # except: + # response = resource_info['default_mask']['admin'] + + # if 'edit-admins' in response: + # return "edit-admins" + # elif 'edit-access' in response: + # return "edit-access" + # else: + # return "not-admin" + +def check_owner(dataset=None, trait_id=None, resource_id=None): + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return resource_id + else: + resource_id = get_resource_id(dataset, trait_id) + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return resource_id + + return False + +def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return [resource_id, "owner"] + else: + return [resource_id, check_admin(resource_id)] + else: + resource_id = get_resource_id(dataset, trait_id) + if resource_id: + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return [resource_id, "owner"] + else: + return [resource_id, check_admin(resource_id)] + + return [resource_id, "not-admin"] \ No newline at end of file diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index bc30a0af..c6d221ff 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -16,7 +16,7 @@ from utility.logger import getLogger logger = getLogger(__name__) def get_redis_conn(): - Redis = redis.StrictRedis(port=6380) + Redis = redis.StrictRedis(port=6379) return Redis Redis = get_redis_conn() @@ -51,6 +51,27 @@ 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 + """ + matched_users = [] + + if column_value != "": + 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: + if column_value in user_ob[column_name]: + matched_users.append(user_ob) + else: + matched_users.append(json.loads(user_list[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)) user_info[column_name] = column_value @@ -142,6 +163,28 @@ 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 + """ + matched_groups = [] + + if column_value != "": + group_list = Redis.hgetall("groups") + 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 + if column_value in group_info[column_name]: + matched_groups.append(group_info) + else: + if column_name in group_info: + if column_value in group_info[column_name]: + matched_groups.append(group_info) + else: + matched_groups.append(json.loads(group_list[column_value])) + + return matched_groups def create_group(admin_user_ids, member_user_ids = [], group_name = "Default Group Name"): group_id = str(uuid.uuid4()) @@ -192,9 +235,13 @@ def add_users_to_group(user_id, group_id, user_emails = [], admins = False): #ZS 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 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 + users_to_remove_set.remove(user_id) group_users = set(group_info[user_type]) - group_users -= set(users_to_remove_ids) + 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') Redis.hset("groups", group_id, json.dumps(group_info)) @@ -232,7 +279,6 @@ def get_resource_info(resource_id): return json.loads(resource_info) def add_resource(resource_info): - 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']))) else: @@ -241,3 +287,18 @@ def add_resource(resource_info): 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 + + Redis.hset("resources", resource_id, json.dumps(the_resource)) + + return the_resource + +def change_resource_owner(resource_id, new_owner_id): + the_resource= get_resource_info(resource_id) + the_resource['owner_id'] = new_owner_id + + Redis.delete("resource") + Redis.hset("resources", resource_id, json.dumps(the_resource)) \ No newline at end of file diff --git a/wqflask/wqflask/docs.py b/wqflask/wqflask/docs.py index 0187f32e..78407e22 100644 --- a/wqflask/wqflask/docs.py +++ b/wqflask/wqflask/docs.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, print_function, division +import codecs + from flask import g from utility.logger import getLogger @@ -20,7 +22,7 @@ class Docs(object): self.content = "" else: self.title = result[0] - self.content = result[1] + self.content = result[1].encode("latin1") self.editable = "false" # ZS: Removing option to edit to see if text still gets vandalized diff --git a/wqflask/wqflask/group_manager.py b/wqflask/wqflask/group_manager.py index f41ae56d..9afc016b 100644 --- a/wqflask/wqflask/group_manager.py +++ b/wqflask/wqflask/group_manager.py @@ -1,77 +1,145 @@ - -from __future__ import print_function, division, absolute_import - -from flask import (Flask, g, render_template, url_for, request, make_response, - redirect, flash) - -from wqflask import app -from wqflask.user_login import send_verification_email - -from utility.redis_tools import get_user_groups, get_group_info, create_group, delete_group, add_users_to_group, remove_users_from_group, \ - change_group_name, save_verification_code, check_verification_code, get_user_by_unique_column - -from utility.logger import getLogger -logger = getLogger(__name__) - -@app.route("/groups/manage", methods=('GET', 'POST')) -def manage_groups(): - params = request.form if request.form else request.args - if "add_new_group" in params: - return redirect(url_for('add_group')) - else: - admin_groups, user_groups = get_user_groups(g.user_session.user_id) - return render_template("admin/group_manager.html", admin_groups=admin_groups, user_groups=user_groups) - -@app.route("/groups/remove", methods=('POST',)) -def remove_groups(): - group_ids_to_remove = request.form['selected_group_ids'] - for group_id in group_ids_to_remove.split(":"): - delete_group(g.user_session.user_id, group_id) - - return redirect(url_for('manage_groups')) - -@app.route("/groups/create", methods=('GET', 'POST')) -def add_group(): - params = request.form if request.form else request.args - if "group_name" in params: - member_user_ids = set() - admin_user_ids = set() - admin_user_ids.add(g.user_session.user_id) #ZS: Always add the user creating the group as an admin - if "admin_emails" in params: - admin_emails = params['admin_emails_to_add'].split(",") - for email in admin_emails: - user_details = get_user_by_unique_column("email_address", email) - if user_details: - admin_user_ids.add(user_details['user_id']) - #send_group_invites(params['group_id'], user_email_list = admin_emails, user_type="admins") - if "user_emails" in params: - member_emails = params['member_emails_to_add'].split(",") - for email in member_emails: - user_details = get_user_by_unique_column("email_address", email) - if user_details: - member_user_ids.add(user_details['user_id']) - #send_group_invites(params['group_id'], user_email_list = user_emails, user_type="members") - - create_group(list(admin_user_ids), list(member_user_ids), params['group_name']) - return redirect(url_for('manage_groups')) - else: - return render_template("admin/create_group.html") - -#ZS: Will integrate this later, for now just letting users be added directly -def send_group_invites(group_id, user_email_list = [], user_type="members"): - for user_email in user_email_list: - user_details = get_user_by_unique_column("email_address", user_email) - if user_details: - group_info = get_group_info(group_id) - #ZS: Probably not necessary since the group should normally always exist if group_id is being passed here, - # but it's technically possible to hit it if Redis is cleared out before submitting the new users or something - if group_info: - #ZS: Don't add user if they're already an admin or if they're being added a regular user and are already a regular user, - # but do add them if they're a regular user and are added as an admin - if (user_details['user_id'] in group_info['admins']) or \ - ((user_type == "members") and (user_details['user_id'] in group_info['members'])): - continue - else: - send_verification_email(user_details, template_name = "email/group_verification.txt", key_prefix = "verification_code", subject = "You've been invited to join a GeneNetwork user group") - + +from __future__ import print_function, division, absolute_import + +from flask import (Flask, g, render_template, url_for, request, make_response, + redirect, flash) + +from wqflask import app +from wqflask.user_login import send_verification_email + +from utility.redis_tools import get_user_groups, get_group_info, create_group, delete_group, add_users_to_group, remove_users_from_group, \ + change_group_name, save_verification_code, check_verification_code, get_user_by_unique_column, get_resources, get_resource_info + +from utility.logger import getLogger +logger = getLogger(__name__) + +@app.route("/groups/manage", methods=('GET', 'POST')) +def manage_groups(): + params = request.form if request.form else request.args + if "add_new_group" in params: + return redirect(url_for('add_group')) + else: + admin_groups, user_groups = get_user_groups(g.user_session.user_id) + return render_template("admin/group_manager.html", admin_groups=admin_groups, user_groups=user_groups) + +@app.route("/groups/view", methods=('GET', 'POST')) +def view_group(): + params = request.form if request.form else request.args + group_id = params['id'] + group_info = get_group_info(group_id) + admins_info = [] + user_is_admin = False + if g.user_session.user_id in group_info['admins']: + user_is_admin = True + for user_id in group_info['admins']: + if user_id: + user_info = get_user_by_unique_column("user_id", user_id) + admins_info.append(user_info) + members_info = [] + for user_id in group_info['members']: + if user_id: + user_info = get_user_by_unique_column("user_id", user_id) + members_info.append(user_info) + + #ZS: This whole part might not scale well with many resources + resources_info = [] + all_resources = get_resources() + for resource_id in all_resources: + resource_info = get_resource_info(resource_id) + group_masks = resource_info['group_masks'] + if group_id in group_masks: + this_resource = {} + privileges = group_masks[group_id] + this_resource['id'] = resource_id + this_resource['name'] = resource_info['name'] + this_resource['data'] = privileges['data'] + this_resource['metadata'] = privileges['metadata'] + this_resource['admin'] = privileges['admin'] + resources_info.append(this_resource) + + return render_template("admin/view_group.html", group_info=group_info, admins=admins_info, members=members_info, user_is_admin=user_is_admin, resources=resources_info) + +@app.route("/groups/remove", methods=('POST',)) +def remove_groups(): + group_ids_to_remove = request.form['selected_group_ids'] + for group_id in group_ids_to_remove.split(":"): + delete_group(g.user_session.user_id, group_id) + + return redirect(url_for('manage_groups')) + +@app.route("/groups/remove_users", methods=('POST',)) +def remove_users(): + group_id = request.form['group_id'] + admin_ids_to_remove = request.form['selected_admin_ids'] + member_ids_to_remove = request.form['selected_member_ids'] + + remove_users_from_group(g.user_session.user_id, admin_ids_to_remove.split(":"), group_id, user_type="admins") + remove_users_from_group(g.user_session.user_id, member_ids_to_remove.split(":"), group_id, user_type="members") + + return redirect(url_for('view_group', id=group_id)) + +@app.route("/groups/add_", methods=('POST',)) +def add_users(user_type='members'): + group_id = request.form['group_id'] + if user_type == "admins": + user_emails = request.form['admin_emails_to_add'].split(",") + add_users_to_group(g.user_session.user_id, group_id, user_emails, admins = True) + elif user_type == "members": + user_emails = request.form['member_emails_to_add'].split(",") + add_users_to_group(g.user_session.user_id, group_id, user_emails, admins = False) + + return redirect(url_for('view_group', id=group_id)) + +@app.route("/groups/change_name", methods=('POST',)) +def change_name(): + group_id = request.form['group_id'] + new_name = request.form['new_name'] + group_info = change_group_name(g.user_session.user_id, group_id, new_name) + + return new_name + +@app.route("/groups/create", methods=('GET', 'POST')) +def add_or_edit_group(): + params = request.form if request.form else request.args + if "group_name" in params: + member_user_ids = set() + admin_user_ids = set() + admin_user_ids.add(g.user_session.user_id) #ZS: Always add the user creating the group as an admin + if "admin_emails_to_add" in params: + admin_emails = params['admin_emails_to_add'].split(",") + for email in admin_emails: + user_details = get_user_by_unique_column("email_address", email) + if user_details: + admin_user_ids.add(user_details['user_id']) + #send_group_invites(params['group_id'], user_email_list = admin_emails, user_type="admins") + if "member_emails_to_add" in params: + member_emails = params['member_emails_to_add'].split(",") + for email in member_emails: + user_details = get_user_by_unique_column("email_address", email) + if user_details: + member_user_ids.add(user_details['user_id']) + #send_group_invites(params['group_id'], user_email_list = user_emails, user_type="members") + + create_group(list(admin_user_ids), list(member_user_ids), params['group_name']) + return redirect(url_for('manage_groups')) + else: + return render_template("admin/create_group.html") + +#ZS: Will integrate this later, for now just letting users be added directly +def send_group_invites(group_id, user_email_list = [], user_type="members"): + for user_email in user_email_list: + user_details = get_user_by_unique_column("email_address", user_email) + if user_details: + group_info = get_group_info(group_id) + #ZS: Probably not necessary since the group should normally always exist if group_id is being passed here, + # but it's technically possible to hit it if Redis is cleared out before submitting the new users or something + if group_info: + #ZS: Don't add user if they're already an admin or if they're being added a regular user and are already a regular user, + # but do add them if they're a regular user and are added as an admin + if (user_details['user_id'] in group_info['admins']) or \ + ((user_type == "members") and (user_details['user_id'] in group_info['members'])): + continue + else: + send_verification_email(user_details, template_name = "email/group_verification.txt", key_prefix = "verification_code", subject = "You've been invited to join a GeneNetwork user group") + #@app.route() \ No newline at end of file diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py index 7d88b8ed..0f9f5c9d 100644 --- a/wqflask/wqflask/resource_manager.py +++ b/wqflask/wqflask/resource_manager.py @@ -1,72 +1,134 @@ -from __future__ import print_function, division, absolute_import - -from flask import (Flask, g, render_template, url_for, request, make_response, - redirect, flash) - -from wqflask import app - -from utility.authentication_tools import check_owner -from utility.redis_tools import get_resource_info, get_group_info, get_group_by_unique_column, get_user_id - -from utility.logger import getLogger -logger = getLogger(__name__) - -@app.route("/resources/manage", methods=('GET', 'POST')) -def view_resource(): - params = request.form if request.form else request.args - if 'resource_id' in request.args: - resource_id = request.args['resource_id'] - if check_owner(resource_id=resource_id): - resource_info = get_resource_info(resource_id) - group_masks = resource_info['group_masks'] - group_masks_with_names = get_group_names(group_masks) - default_mask = resource_info['default_mask']['data'] - return render_template("admin/manage_resource.html", resource_id = resource_id, resource_info=resource_info, default_mask=default_mask, group_masks=group_masks_with_names) - else: - return redirect(url_for("no_access_page")) - -@app.route("/resources/add_group", methods=('POST',)) -def add_group_to_resource(): - resource_id = request.form['resource_id'] - if check_owner(resource_id=resource_id): - if all(key in request.form for key in ('group_id', 'group_name', 'user_name', 'user_email')): - group_list = [] - if request.form['group_id'] != "": - the_group = get_group_info(request.form['group_id']) - if the_group: - group_list.append(the_group) - if request.form['group_name'] != "": - matched_groups = get_group_by_unique_column("name", request.form['group_name']) - for group in matched_groups: - group_list.append(group) - if request.form['user_name'] != "": - user_id = get_user_id("user_name", request.form['user_name']) - if user_id: - matched_groups = get_group_by_unique_column("admins", user_id) - matched_groups += get_group_by_unique_column("members", user_id) - for group in matched_groups: - group_list.append(group) - if request.form['user_email'] != "": - user_id = get_user_id("email_address", request.form['user_email']) - if user_id: - matched_groups = get_group_by_unique_column("admins", user_id) - matched_groups += get_group_by_unique_column("members", user_id) - for group in matched_groups: - group_list.append(group) - return render_template("admin/select_group_to_add.html", group_list=group_list, resource_id = resource_id) - elif 'selected_group' in request.form: - group_id = request.form['selected_group'] - return render_template("admin/set_group_privileges.html", resource_id = resource_id, group_id = group_id) - else: - return render_template("admin/search_for_groups.html", resource_id = resource_id) - else: - return redirect(url_for("no_access_page")) - -def get_group_names(group_masks): - group_masks_with_names = {} - for group_id, group_mask in group_masks.iteritems(): - this_mask = group_mask - group_name = get_group_info(group_id)['name'] - this_mask['name'] = group_name - +from __future__ import print_function, division, absolute_import + +import json + +from flask import (Flask, g, render_template, url_for, request, make_response, + redirect, flash) + +from wqflask import app + +from utility.authentication_tools import check_owner_or_admin +from utility.redis_tools import get_resource_info, get_group_info, get_groups_like_unique_column, get_user_id, get_user_by_unique_column, get_users_like_unique_column, add_access_mask, add_resource, change_resource_owner + +from utility.logger import getLogger +logger = getLogger(__name__) + +@app.route("/resources/manage", methods=('GET', 'POST')) +def manage_resource(): + params = request.form if request.form else request.args + if 'resource_id' in request.args: + resource_id = request.args['resource_id'] + admin_status = check_owner_or_admin(resource_id=resource_id)[1] + + resource_info = get_resource_info(resource_id) + group_masks = resource_info['group_masks'] + group_masks_with_names = get_group_names(group_masks) + default_mask = resource_info['default_mask']['data'] + owner_id = resource_info['owner_id'] + owner_info = get_user_by_unique_column("user_id", owner_id) + + if 'name' in owner_info: + owner_display_name = owner_info['full_name'] + elif 'user_name' in owner_info: + owner_display_name = owner_info['user_name'] + elif 'email_address' in owner_info: + owner_display_name = owner_info['email_address'] + else: + owner_display_name = None + + return render_template("admin/manage_resource.html", owner_name = owner_display_name, resource_id = resource_id, resource_info=resource_info, default_mask=default_mask, group_masks=group_masks_with_names, admin_status=admin_status) + +@app.route("/search_for_users", methods=('POST',)) +def search_for_user(): + params = request.form + user_list = [] + user_list += get_users_like_unique_column("full_name", params['user_name']) + user_list += get_users_like_unique_column("email_address", params['user_email']) + + return json.dumps(user_list) + +@app.route("/search_for_groups", methods=('POST',)) +def search_for_groups(): + params = request.form + group_list = [] + group_list += get_groups_like_unique_column("id", params['group_id']) + group_list += get_groups_like_unique_column("name", params['group_name']) + + user_list = [] + user_list += get_users_like_unique_column("full_name", params['user_name']) + user_list += get_users_like_unique_column("email_address", params['user_email']) + for user in user_list: + group_list += get_groups_like_unique_column("admins", user['user_id']) + group_list += get_groups_like_unique_column("members", user['user_id']) + + return json.dumps(group_list) + +@app.route("/resources/change_owner", methods=('POST',)) +def change_owner(): + resource_id = request.form['resource_id'] + if 'new_owner' in request.form: + admin_status = check_owner_or_admin(resource_id=resource_id)[1] + if admin_status == "owner": + new_owner_id = request.form['new_owner'] + change_resource_owner(resource_id, new_owner_id) + flash("The resource's owner has beeen changed.", "alert-info") + return redirect(url_for("manage_resource", resource_id=resource_id)) + else: + flash("You lack the permissions to make this change.", "error") + return redirect(url_for("manage_resource", resource_id=resource_id)) + else: + return render_template("admin/change_resource_owner.html", resource_id = resource_id) + +@app.route("/resources/change_default_privileges", methods=('POST',)) +def change_default_privileges(): + resource_id = request.form['resource_id'] + admin_status = check_owner_or_admin(resource_id=resource_id) + if admin_status == "owner" or admin_status == "edit-admins": + resource_info = get_resource_info(resource_id) + default_mask = resource_info['default_mask'] + if request.form['open_to_public'] == "True": + default_mask['data'] = 'view' + else: + default_mask['data'] = 'no-access' + resource_info['default_mask'] = default_mask + add_resource(resource_info) + flash("Your changes have been saved.", "alert-info") + return redirect(url_for("manage_resource", resource_id=resource_id)) + else: + return redirect(url_for("no_access_page")) + +@app.route("/resources/add_group", methods=('POST',)) +def add_group_to_resource(): + resource_id = request.form['resource_id'] + admin_status = check_owner_or_admin(resource_id=resource_id)[1] + if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access": + if 'selected_group' in request.form: + group_id = request.form['selected_group'] + resource_info = get_resource_info(resource_id) + default_privileges = resource_info['default_mask'] + return render_template("admin/set_group_privileges.html", resource_id = resource_id, group_id = group_id, default_privileges = default_privileges) + elif all(key in request.form for key in ('data_privilege', 'metadata_privilege', 'admin_privilege')): + group_id = request.form['group_id'] + group_name = get_group_info(group_id)['name'] + access_mask = { + 'data': request.form['data_privilege'], + 'metadata': request.form['metadata_privilege'], + 'admin': request.form['admin_privilege'] + } + add_access_mask(resource_id, group_id, access_mask) + flash("Privileges have been added for group {}.".format(group_name), "alert-info") + return redirect(url_for("manage_resource", resource_id=resource_id)) + else: + return render_template("admin/search_for_groups.html", resource_id = resource_id) + else: + return redirect(url_for("no_access_page")) + +def get_group_names(group_masks): + group_masks_with_names = {} + for group_id, group_mask in group_masks.iteritems(): + this_mask = group_mask + group_name = get_group_info(group_id)['name'] + this_mask['name'] = group_name + group_masks_with_names[group_id] = this_mask + return group_masks_with_names \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/group_manager.js b/wqflask/wqflask/static/new/javascript/group_manager.js index 5e82d104..4c172cbf 100644 --- a/wqflask/wqflask/static/new/javascript/group_manager.js +++ b/wqflask/wqflask/static/new/javascript/group_manager.js @@ -1,38 +1,38 @@ -$('#add_to_admins').click(function() { - add_emails('admin') -}) - -$('#add_to_members').click(function() { - add_emails('member') -}) - -$('#clear_admins').click(function(){ - clear_emails('admin') -}) - -$('#clear_members').click(function(){ - clear_emails('member') -}) - - -function add_emails(user_type){ - var email_address = $('input[name=user_email]').val(); - var email_list_string = $('input[name=' + user_type + '_emails_to_add]').val() - console.log(email_list_string) - if (email_list_string == ""){ - var email_set = new Set(); - } else { - var email_set = new Set(email_list_string.split(",")) - } - email_set.add(email_address) - - $('input[name=' + user_type + '_emails_to_add]').val(Array.from(email_set).join(',')) - - var emails_display_string = Array.from(email_set).join('\n') - $('.added_' + user_type + 's').val(emails_display_string) -} - -function clear_emails(user_type){ - $('input[name=' + user_type + '_emails_to_add]').val("") - $('.added_' + user_type + 's').val("") +$('#add_to_admins').click(function() { + add_emails('admin') +}) + +$('#add_to_members').click(function() { + add_emails('member') +}) + +$('#clear_admins').click(function(){ + clear_emails('admin') +}) + +$('#clear_members').click(function(){ + clear_emails('member') +}) + + +function add_emails(user_type){ + var email_address = $('input[name=user_email]').val(); + var email_list_string = $('input[name=' + user_type + '_emails_to_add]').val().trim() + console.log(email_list_string) + if (email_list_string == ""){ + var email_set = new Set(); + } else { + var email_set = new Set(email_list_string.split(",")) + } + email_set.add(email_address) + + $('input[name=' + user_type + '_emails_to_add]').val(Array.from(email_set).join(',')) + + var emails_display_string = Array.from(email_set).join('\n') + $('.added_' + user_type + 's').val(emails_display_string) +} + +function clear_emails(user_type){ + $('input[name=' + user_type + '_emails_to_add]').val("") + $('.added_' + user_type + 's').val("") } \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/search_results.js b/wqflask/wqflask/static/new/javascript/search_results.js index 8fa698b4..115dac13 100644 --- a/wqflask/wqflask/static/new/javascript/search_results.js +++ b/wqflask/wqflask/static/new/javascript/search_results.js @@ -296,7 +296,6 @@ $(function() { $("#deselect_all").click(deselect_all); $("#invert").click(invert); $("#add").click(add); - $("#remove").click(remove); $("#submit_bnw").click(submit_bnw); $("#export_traits").click(export_traits); $('.trait_checkbox, .btn').click(change_buttons); diff --git a/wqflask/wqflask/templates/admin/change_resource_owner.html b/wqflask/wqflask/templates/admin/change_resource_owner.html new file mode 100644 index 00000000..ae9409b0 --- /dev/null +++ b/wqflask/wqflask/templates/admin/change_resource_owner.html @@ -0,0 +1,116 @@ +{% extends "base.html" %} +{% block title %}Resource Manager{% endblock %} +{% block css %} + + +{% endblock %} +{% block content %} + +
+ +
+ +
+
+
+
+

Search for user by either name or e-mail:

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+ + + +{% endblock %} + +{% block js %} + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/create_group.html b/wqflask/wqflask/templates/admin/create_group.html index 55c3fa0b..5a6929fb 100644 --- a/wqflask/wqflask/templates/admin/create_group.html +++ b/wqflask/wqflask/templates/admin/create_group.html @@ -1,89 +1,89 @@ -{% extends "base.html" %} -{% block title %}Group Manager{% endblock %} -{% block content %} - -
- -
- - -
-
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
-
-
-
-
-
- - - - - -{% endblock %} - -{% block js %} - - - - - -{% endblock %} +{% extends "base.html" %} +{% block title %}Group Manager{% endblock %} +{% block content %} + +
+ +
+ + +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+ + + + + +{% endblock %} + +{% block js %} + + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/group_manager.html b/wqflask/wqflask/templates/admin/group_manager.html index 23d8205a..70d55684 100644 --- a/wqflask/wqflask/templates/admin/group_manager.html +++ b/wqflask/wqflask/templates/admin/group_manager.html @@ -23,7 +23,7 @@
{% else %} -

Admin Groups

+

Admin Groups


{% if admin_groups|length == 0 %}

You currently aren't the administrator of any groups.

@@ -45,8 +45,8 @@ {{ loop.index }} - {{ group.name }} - {{ group.admins|length + group.users|length }} + {{ group.name }} + {{ group.admins|length + group.members|length }} {{ group.created_timestamp }} {{ group.changed_timestamp }} {{ group.id }} @@ -58,7 +58,7 @@
-

User Groups

+

User Groups


{% if user_groups|length == 0 %}

You currently aren't a member of any groups.

@@ -80,7 +80,7 @@ {{ loop.index }} {{ group.name }} - {{ group.admins|length + group.users|length }} + {{ group.admins|length + group.members|length }} {{ group.created_timestamp }} {{ group.changed_timestamp }} @@ -103,10 +103,14 @@ - - - - -{% endblock %} +{% extends "base.html" %} +{% block title %}Resource Manager{% endblock %} +{% block css %} + + +{% endblock %} +{% block content %} + +
+ {{ flash_me() }} + +
+ +
+
+
+
+ +
+ {{ resource_info.name }} +
+
+ {% if admin_status == "owner" %} +
+ +
+ + +
+
+
+ +
+ +
+
+ {% endif %} +
+
+
+ {% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %} +
+
+ +
+ {% if group_masks|length > 0 %} +

Current Group Permissions

+
+ + + + + + + + + + + {% for key, value in group_masks.iteritems() %} + + + + + + + {% endfor %} + +
NameDataMetadataAdmin
{{ value.name }}{{ value.data }}{{ value.metadata }}{{ value.admin }}
+ {% else %} +

No groups are currently added to this resource.

+ {% endif %} +
+ {% endif %} +
+
+ + + + + +{% endblock %} + +{% block js %} + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/search_for_groups.html b/wqflask/wqflask/templates/admin/search_for_groups.html index 89eb11dd..f304a172 100644 --- a/wqflask/wqflask/templates/admin/search_for_groups.html +++ b/wqflask/wqflask/templates/admin/search_for_groups.html @@ -1,64 +1,134 @@ -{% extends "base.html" %} -{% block title %}Resource Manager{% endblock %} -{% block content %} - -
- -
- -
-
-
-
-

Search by:

-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
-
-
- - - -{% endblock %} - -{% block js %} - - - - - -{% endblock %} +{% extends "base.html" %} +{% block title %}Resource Manager{% endblock %} +{% block css %} + + +{% endblock %} +{% block content %} + +
+ +
+ +
+
+
+
+

Search by:

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
+ + + +{% endblock %} + +{% block js %} + + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/select_group_to_add.html b/wqflask/wqflask/templates/admin/select_group_to_add.html deleted file mode 100644 index df70fb2f..00000000 --- a/wqflask/wqflask/templates/admin/select_group_to_add.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends "base.html" %} -{% block title %}Matched Groups{% endblock %} -{% block css %} - - - -{% endblock %} -{% block content %} - -
-

The following groups were found:

-
-
- -
- {% if group_list|length > 0 %} - - - - - - - - - - - - {% for group in group_list %} - - - - - - - {% endfor %} - -
NameCreatedLast Changed
{% if 'name' in group %}{{ group.name }}{% else %}N/A{% endif %}{% if 'created_timestamp' in group %}{{ group.created_timestamp }}{% else %}N/A{% endif %}{% if 'changed_timestamp' in group %}{{ group.changed_timestamp }}{% else %}N/A{% endif %}
- {% else %} -

No matching groups were found.

- {% endif %} -
-
-
- - - -{% endblock %} - -{% block js %} - - -{% endblock %} diff --git a/wqflask/wqflask/templates/admin/set_group_privileges.html b/wqflask/wqflask/templates/admin/set_group_privileges.html new file mode 100644 index 00000000..bc52788f --- /dev/null +++ b/wqflask/wqflask/templates/admin/set_group_privileges.html @@ -0,0 +1,102 @@ +{% extends "base.html" %} +{% block title %}Set Group Privileges{% endblock %} +{% block css %} + + + +{% endblock %} +{% block content %} + +
+

Group Privileges

+
+
+ + +
+ +
+

Data and Metadata Privileges

+ + + + + + + + + + + + + {% if 'data' in default_privileges %} + + + + {% else %} + + + + {% endif %} + + + + {% if 'metadata' in default_privileges %} + + + + {% else %} + + + + {% endif %} + + +
No-AccessViewEdit
Data:
Metadata:
+
+

Admin Privileges

+ + + + + + + + + + + + + {% if 'admin' in default_privileges %} + + + + {% else %} + + + + {% endif %} + + +
Not AdminEdit AccessEdit Admins
Admin:
+
+
+
+ + + +{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/wqflask/wqflask/templates/admin/view_group.html b/wqflask/wqflask/templates/admin/view_group.html new file mode 100644 index 00000000..b797cd70 --- /dev/null +++ b/wqflask/wqflask/templates/admin/view_group.html @@ -0,0 +1,238 @@ +{% extends "base.html" %} +{% block title %}View and Edit Group{% endblock %} +{% block css %} + + + +{% endblock %} +{% block content %} + +
+ +
+ + + +
+
+
+

Admins

+
+ + + + + + + + + + + + {% for admin in admins %} + + + + + + + + {% endfor %} + +
IndexNameEmail AddressOrganization
{{ loop.index }}{% if 'full_name' in admin %}{{ admin.full_name }}{% else %}N/A{% endif %}{% if 'email_address' in admin %}{{ admin.email_address }}{% else %}N/A{% endif %}{% if 'organization' in admin %}{{ admin.organization }}{% else %}N/A{% endif %}
+ {% if user_is_admin == true %} +
+ E-mail of user to add to admins (multiple e-mails can be added separated by commas): + +
+
+ +
+ {% endif %} +
+
+
+ {% if members|length > 0 %} +

Members

+
+ + + + + + + + + + + + {% for member in members %} + + + + + + + + {% endfor %} + +
IndexNameEmail AddressOrganization
{{ loop.index }}{% if 'full_name' in member %}{{ member.full_name }}{% else %}N/A{% endif %}{% if 'email_address' in member %}{{ member.email_address }}{% else %}N/A{% endif %}{% if 'organization' in member %}{{ member.organization }}{% else %}N/A{% endif %}
+ {% if user_is_admin == true %} +
+ E-mail of user to add to members (multiple e-mails can be added separated by commas): + +
+
+ +
+ {% endif %} + {% else %} + There are currently no members in this group. + {% endif %} +
+
+
+

Resources

+
+ {% if resources|length > 0 %} + + + + + + + + + + + + {% for resource in resources %} + + + + + + + + {% endfor %} + +
IndexNameDataMetadataAdmin
{{ loop.index }}{% if 'name' in resource %}{{ resource.name }}{% else %}N/A{% endif %}{% if 'data' in resource %}{{ resource.data }}{% else %}N/A{% endif %}{% if 'metadata' in resource %}{{ resource.metadata }}{% else %}N/A{% endif %}{% if 'admin' in resource %}{{ resource.admin }}{% else %}N/A{% endif %}
+ {% else %} + There are currently no resources associated with this group. + {% endif %} +
+
+
+
+ + + +{% endblock %} + +{% block js %} + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 07c1b48e..262d9ee5 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -94,6 +94,11 @@ Sign in {% endif %} + {% if g.user_session.logged_in %} +
  • + Manage Groups +
  • + {% endif %} {% endif %} +
    +

    Group Privileges

    +
    +
    + +
    + +
    +

    Data and Metadata Privileges

    + + + + + + + + + + + + + + + + + + + + + + + +
    No-AccessViewEdit
    Data:
    Metadata:
    +
    +

    Admin Privileges

    + + + + + + + + + + + + + + + + + +
    Not AdminEdit AccessEdit Admins
    Admin:
    +
    +
    +
    + + + +{% endblock %} + +{% block js %} + + +{% endblock %} diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 5c315878..5e0bae79 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -248,8 +248,8 @@ - {% if resource_id %} - + {% if admin_status[1] == "owner" or admin_status[1] == "edit-admins" or admin_status[1] == "edit-access" %} + {% endif %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index ee827ba3..dc431aa9 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -102,7 +102,7 @@ def check_access_permissions(): else: available = check_resource_availability(dataset) - if not available: + if available == "no-access": return redirect(url_for("no_access_page")) @app.teardown_appcontext -- cgit v1.2.3 From fcb3cb1105cf2a1d97c1a08fa636b118ed231ffa Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 17 Jun 2020 16:28:15 -0500 Subject: A user's id is now set as a parameter if it doesn't already exist --- wqflask/maintenance/set_resource_defaults.py | 8 +++--- wqflask/utility/authentication_tools.py | 30 ++++++++++++---------- wqflask/utility/redis_tools.py | 4 +++ wqflask/wqflask/group_manager.py | 4 +-- wqflask/wqflask/templates/admin/group_manager.html | 16 +++++++----- 5 files changed, 36 insertions(+), 26 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index 344e6a23..0c221bbf 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -27,8 +27,9 @@ sys.path.insert(0,'./') # NEW: import app to avoid a circular dependency on utility.tools from wqflask import app +from utility import hmac from utility.tools import SQL_URI -from utility.redis_tools import get_redis_conn, get_user_id, add_resource, get_resources +from utility.redis_tools import get_redis_conn, get_user_id, add_resource, get_resources, get_resource_info Redis = get_redis_conn() import MySQLdb @@ -117,7 +118,7 @@ def insert_geno_resources(default_owner_id): resource_ob = {} resource_ob['name'] = resource[1] if resource[1] == "HET3-ITPGeno": - resource_ob['owner_id'] = "73a3f093-ca13-4ae0-a179-9a446f709f6e" + resource_ob['owner_id'] = "c5ce8c56-78a6-474f-bcaf-7129d97f56ae" else: resource_ob['owner_id'] = default_owner_id resource_ob['data'] = { "dataset" : str(resource[0]) } @@ -145,7 +146,8 @@ def main(): Redis.delete("resources") - owner_id = get_user_id("email_address", "zachary.a.sloan@gmail.com") + owner_id = "c5ce8c56-78a6-474f-bcaf-7129d97f56ae" + insert_resources(owner_id) if __name__ == '__main__': diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 07ceacc0..dfa0e2d9 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -7,6 +7,7 @@ from base import data_set from utility import hmac from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id +Redis = get_redis_conn() from flask import Flask, g, redirect, url_for @@ -14,8 +15,12 @@ import logging logger = logging.getLogger(__name__ ) def check_resource_availability(dataset, trait_id=None): - resource_id = get_resource_id(dataset, trait_id) + #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy + if g.user_session.user_id in Redis.smembers("super_users"): + return "edit" + + resource_id = get_resource_id(dataset, trait_id) response = None if resource_id: resource_info = get_resource_info(resource_id) @@ -68,19 +73,16 @@ def check_owner(dataset=None, trait_id=None, resource_id=None): return False def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): - if resource_id: - resource_info = get_resource_info(resource_id) - if g.user_session.user_id == resource_info['owner_id']: - return [resource_id, "owner"] - else: - return [resource_id, check_admin(resource_id)] - else: + if not resource_id: resource_id = get_resource_id(dataset, trait_id) - if resource_id: - resource_info = get_resource_info(resource_id) - if g.user_session.user_id == resource_info['owner_id']: - return [resource_id, "owner"] - else: - return [resource_id, check_admin(resource_id)] + + if g.user_session.user_id in Redis.smembers("super_users"): + return [resource_id, "owner"] + + resource_info = get_resource_info(resource_id) + if g.user_session.user_id == resource_info['owner_id']: + return [resource_id, "owner"] + else: + return [resource_id, check_admin(resource_id)] return [resource_id, "not-admin"] \ No newline at end of file diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index c6d221ff..9d09a66b 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -30,6 +30,7 @@ def is_redis_available(): def get_user_id(column_name, column_value): user_list = Redis.hgetall("users") + key_list = [] 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: @@ -62,6 +63,9 @@ def get_users_like_unique_column(column_name, column_value): if column_name != "user_id": for key in user_list: user_ob = json.loads(user_list[key]) + if "user_id" not in user_ob: + set_user_attribute(key, "user_id", key) + user_ob["user_id"] = key if column_name in user_ob: if column_value in user_ob[column_name]: matched_users.append(user_ob) diff --git a/wqflask/wqflask/group_manager.py b/wqflask/wqflask/group_manager.py index 9afc016b..24848ed8 100644 --- a/wqflask/wqflask/group_manager.py +++ b/wqflask/wqflask/group_manager.py @@ -19,8 +19,8 @@ def manage_groups(): if "add_new_group" in params: return redirect(url_for('add_group')) else: - admin_groups, user_groups = get_user_groups(g.user_session.user_id) - return render_template("admin/group_manager.html", admin_groups=admin_groups, user_groups=user_groups) + admin_groups, member_groups = get_user_groups(g.user_session.user_id) + return render_template("admin/group_manager.html", admin_groups=admin_groups, member_groups=member_groups) @app.route("/groups/view", methods=('GET', 'POST')) def view_group(): diff --git a/wqflask/wqflask/templates/admin/group_manager.html b/wqflask/wqflask/templates/admin/group_manager.html index 70d55684..c8ed6851 100644 --- a/wqflask/wqflask/templates/admin/group_manager.html +++ b/wqflask/wqflask/templates/admin/group_manager.html @@ -10,18 +10,20 @@
    - {% if admin_groups|length == 0 and user_groups|length == 0 %} + {% if admin_groups|length == 0 and member_groups|length == 0 %}

    You currently aren't a member or admin of any groups.


    - + {% else %}

    Admin Groups


    @@ -60,10 +62,10 @@

    User Groups


    - {% if user_groups|length == 0 %} + {% if member_groups|length == 0 %}

    You currently aren't a member of any groups.

    {% else %} - +
    @@ -75,7 +77,7 @@ - {% for group in user_groups %} + {% for group in member_groups %} @@ -107,8 +109,8 @@ 'sDom': 'tr' }); {% endif %} - {% if user_groups|length != 0 %} - $('#user_groups').dataTable({ + {% if member_groups|length != 0 %} + $('#member_groups').dataTable({ 'sDom': 'tr' }); {% endif %} -- cgit v1.2.3 From 75802ed1f9e5d955987bf5f5eb78a9cb120116ec Mon Sep 17 00:00:00 2001 From: zsloan Date: Sat, 20 Jun 2020 17:33:22 -0500 Subject: Added some admin functionality and fixed issue with temp traits --- wqflask/base/trait.py | 17 ++++-- wqflask/base/webqtlConfig.py | 4 ++ wqflask/maintenance/set_resource_defaults.py | 20 +++++-- wqflask/utility/authentication_tools.py | 79 +++++++++++++++------------- wqflask/wqflask/resource_manager.py | 6 +-- wqflask/wqflask/views.py | 20 ++++--- 6 files changed, 90 insertions(+), 56 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 7700ecd5..c2b8b910 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -42,11 +42,11 @@ def create_trait(**kw): if kw.get('dataset_name') != "Temp": if dataset.type == 'Publish': - permitted = check_resource_availability(dataset, kw.get('name')) + permissions = check_resource_availability(dataset, kw.get('name')) else: - permitted = check_resource_availability(dataset) + permissions = check_resource_availability(dataset) - if permitted != "no-access": + if "view" in permissions['data']: the_trait = GeneralTrait(**kw) if the_trait.dataset.type != "Temp": @@ -382,9 +382,16 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): resource_id = get_resource_id(dataset, trait.name) if dataset.type == 'Publish': - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8081/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) else: - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + the_url = "http://localhost:8081/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + + response = requests.get(the_url).content + if response.strip() == "no-access": + trait.view = False + return trait + else: + trait_info = json.loads(response) try: response = requests.get(the_url).content diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py index 55407123..3d86bc22 100644 --- a/wqflask/base/webqtlConfig.py +++ b/wqflask/base/webqtlConfig.py @@ -17,6 +17,10 @@ DEBUG = 1 #USER privilege USERDICT = {'guest':1,'user':2, 'admin':3, 'root':4} +#Set privileges +SUPER_PRIVILEGES = {'data': ['no-access', 'view', 'edit'], 'metadata': ['no-access', 'view', 'edit'], 'admin': ['not-admin', 'edit-access', 'edit-admins']} +DEFAULT_PRIVILEGES = {'data': ['no-access', 'view'], 'metadata': ['no-access', 'view'], 'admin': ['not-admin']} + #minimum number of informative strains KMININFORMATIVE = 5 diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index 0c221bbf..ddb3b17b 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -68,9 +68,13 @@ def insert_probeset_resources(default_owner_id): resource_ob['data'] = { "dataset" : str(resource[0])} resource_ob['type'] = "dataset-probeset" if resource[2] < 1 and resource[3] > 0: - resource_ob['default_mask'] = { "data": "view" } + resource_ob['default_mask'] = { "data": "view", + "metadata": "view", + "admin": "not-admin"} else: - resource_ob['default_mask'] = { "data": "no-access" } + resource_ob['default_mask'] = { "data": "no-access", + "metadata": "no-access", + "admin": "not-admin"} resource_ob['group_masks'] = {} add_resource(resource_ob) @@ -98,7 +102,9 @@ def insert_publish_resources(default_owner_id): resource_ob['data'] = { "dataset" : str(resource[1]) , "trait" : str(resource[0])} resource_ob['type'] = "dataset-publish" - resource_ob['default_mask'] = { "data": "view" } + resource_ob['default_mask'] = { "data": "view", + "metadata": "view", + "admin": "not-admin"} resource_ob['group_masks'] = {} @@ -124,9 +130,13 @@ def insert_geno_resources(default_owner_id): resource_ob['data'] = { "dataset" : str(resource[0]) } resource_ob['type'] = "dataset-geno" if resource[2] < 1: - resource_ob['default_mask'] = { "data": "view" } + resource_ob['default_mask'] = { "data": "view", + "metadata": "view", + "admin": "not-admin"} else: - resource_ob['default_mask'] = { "data": "no-access" } + resource_ob['default_mask'] = { "data": "no-access", + "metadata": "no-access", + "admin": "not-admin"} resource_ob['group_masks'] = {} add_resource(resource_ob) diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index dfa0e2d9..6c88949b 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -3,7 +3,7 @@ from __future__ import absolute_import, print_function, division import json import requests -from base import data_set +from base import data_set, webqtlConfig from utility import hmac from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id @@ -18,45 +18,47 @@ def check_resource_availability(dataset, trait_id=None): #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy if g.user_session.user_id in Redis.smembers("super_users"): - return "edit" + return webqtlConfig.SUPER_PRIVILEGES - resource_id = get_resource_id(dataset, trait_id) response = None - if resource_id: - resource_info = get_resource_info(resource_id) - - the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) - try: - response = json.loads(requests.get(the_url).content)['data'] - except: - response = resource_info['default_mask']['data'] - if 'edit' in response: - return "edit" - elif 'view' in response: - return "view" - else: - return "no-access" + #At least for now assume temporary entered traits are accessible#At least for now assume temporary entered traits are accessible + if type(dataset) == str: + return webqtlConfig.DEFAULT_PRIVILEGES + if dataset.type == "Temp": + return webqtlConfig.DEFAULT_PRIVILEGES - return False + resource_id = get_resource_id(dataset, trait_id) -def check_admin(resource_id=None): + if resource_id: + resource_info = get_resource_info(resource_id) + else: + return response #ZS: Need to substitute in something that creates the resource in Redis later - return "not-admin" + the_url = "http://localhost:8081/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + try: + response = json.loads(requests.get(the_url).content) + except: + response = resource_info['default_mask'] - # ZS: commented out until proxy can return this - # the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) - # try: - # response = json.loads(requests.get(the_url).content) - # except: - # response = resource_info['default_mask']['admin'] + if response: + return response + else: #ZS: No idea how this would happen, but just in case + return False - # if 'edit-admins' in response: - # return "edit-admins" - # elif 'edit-access' in response: - # return "edit-access" - # else: - # return "not-admin" +def check_admin(resource_id=None): + the_url = "http://localhost:8081/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + try: + response = json.loads(requests.get(the_url).content)['admin'] + except: + response = resource_info['default_mask']['admin'] + + if 'edit-admins' in response: + return "edit-admins" + elif 'edit-access' in response: + return "edit-access" + else: + return "not-admin" def check_owner(dataset=None, trait_id=None, resource_id=None): if resource_id: @@ -74,15 +76,18 @@ def check_owner(dataset=None, trait_id=None, resource_id=None): def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): if not resource_id: - resource_id = get_resource_id(dataset, trait_id) + if dataset.type == "Temp": + return "not-admin" + else: + resource_id = get_resource_id(dataset, trait_id) if g.user_session.user_id in Redis.smembers("super_users"): - return [resource_id, "owner"] + return "owner" resource_info = get_resource_info(resource_id) if g.user_session.user_id == resource_info['owner_id']: - return [resource_id, "owner"] + return "owner" else: - return [resource_id, check_admin(resource_id)] + return check_admin(resource_id) - return [resource_id, "not-admin"] \ No newline at end of file + return "not-admin" \ No newline at end of file diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py index 0f9f5c9d..39a07310 100644 --- a/wqflask/wqflask/resource_manager.py +++ b/wqflask/wqflask/resource_manager.py @@ -18,7 +18,7 @@ def manage_resource(): params = request.form if request.form else request.args if 'resource_id' in request.args: resource_id = request.args['resource_id'] - admin_status = check_owner_or_admin(resource_id=resource_id)[1] + admin_status = check_owner_or_admin(resource_id=resource_id) resource_info = get_resource_info(resource_id) group_masks = resource_info['group_masks'] @@ -67,7 +67,7 @@ def search_for_groups(): def change_owner(): resource_id = request.form['resource_id'] if 'new_owner' in request.form: - admin_status = check_owner_or_admin(resource_id=resource_id)[1] + admin_status = check_owner_or_admin(resource_id=resource_id) if admin_status == "owner": new_owner_id = request.form['new_owner'] change_resource_owner(resource_id, new_owner_id) @@ -100,7 +100,7 @@ def change_default_privileges(): @app.route("/resources/add_group", methods=('POST',)) def add_group_to_resource(): resource_id = request.form['resource_id'] - admin_status = check_owner_or_admin(resource_id=resource_id)[1] + admin_status = check_owner_or_admin(resource_id=resource_id) if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access": if 'selected_group' in request.form: group_id = request.form['selected_group'] diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index dc431aa9..bc01839b 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -96,13 +96,21 @@ def check_access_permissions(): pass else: if 'dataset' in request.args: - dataset = create_dataset(request.args['dataset']) - if 'trait_id' in request.args: - available = check_resource_availability(dataset, request.args['trait_id']) + if request.args['dataset'] == "Temp": + permissions = check_resource_availability("Temp") else: - available = check_resource_availability(dataset) - - if available == "no-access": + dataset = create_dataset(request.args['dataset']) + + if dataset.type == "Temp": + permissions = False + if 'trait_id' in request.args: + permissions = check_resource_availability(dataset, request.args['trait_id']) + elif dataset.type != "Publish": + permissions = check_resource_availability(dataset) + else: + return None + + if 'view' not in permissions['data']: return redirect(url_for("no_access_page")) @app.teardown_appcontext -- cgit v1.2.3 From 51417c06061246bc92be89db198b3e74e7126035 Mon Sep 17 00:00:00 2001 From: zsloan Date: Sat, 20 Jun 2020 17:47:38 -0500 Subject: Fixed ports for proxy (though I need to add the port to global variables) and also simplified the check_owner_or_admin function a little --- wqflask/base/trait.py | 4 ++-- wqflask/utility/authentication_tools.py | 4 ++-- wqflask/wqflask/show_trait/show_trait.py | 3 ++- wqflask/wqflask/templates/show_trait_details.html | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index c2b8b910..0e26ca2c 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -382,9 +382,9 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): resource_id = get_resource_id(dataset, trait.name) if dataset.type == 'Publish': - the_url = "http://localhost:8081/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) else: - the_url = "http://localhost:8081/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) response = requests.get(the_url).content if response.strip() == "no-access": diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 6c88949b..06b2854a 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -35,7 +35,7 @@ def check_resource_availability(dataset, trait_id=None): else: return response #ZS: Need to substitute in something that creates the resource in Redis later - the_url = "http://localhost:8081/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) try: response = json.loads(requests.get(the_url).content) except: @@ -47,7 +47,7 @@ def check_resource_availability(dataset, trait_id=None): return False def check_admin(resource_id=None): - the_url = "http://localhost:8081/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) try: response = json.loads(requests.get(the_url).content)['admin'] except: diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index ed4ff0ad..4698807a 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -72,7 +72,8 @@ class ShowTrait(object): cellid=None) self.trait_vals = Redis.get(self.trait_id).split() - self.admin_status = check_owner_or_admin(self.dataset, self.trait_id) + self.resource_id = get_resource_id(self.dataset, self.trait_id) + self.admin_status = check_owner_or_admin(resource_id=self.resource_id) #ZS: Get verify/rna-seq link URLs try: diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 5e0bae79..965c0340 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -248,8 +248,8 @@ - {% if admin_status[1] == "owner" or admin_status[1] == "edit-admins" or admin_status[1] == "edit-access" %} - + {% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %} + {% endif %} -- cgit v1.2.3 From 645c07b98aae9508e8a0aeedd8eaca815d5daf54 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 24 Jun 2020 17:13:45 -0500 Subject: Temporary partial fix to issue of resources without info; need to add something that automatically inserts resources with default privileges --- wqflask/base/trait.py | 12 ++++-------- wqflask/utility/authentication_tools.py | 11 +++++++---- wqflask/utility/redis_tools.py | 5 ++++- wqflask/wqflask/correlation/show_corr_results.py | 7 +++---- wqflask/wqflask/templates/correlation_page.html | 4 ++++ 5 files changed, 22 insertions(+), 17 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 0e26ca2c..7fc016f3 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -386,13 +386,6 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): else: the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) - response = requests.get(the_url).content - if response.strip() == "no-access": - trait.view = False - return trait - else: - trait_info = json.loads(response) - try: response = requests.get(the_url).content if response.strip() == "no-access": @@ -402,7 +395,10 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait_info = json.loads(response) except: resource_info = get_resource_info(resource_id) - default_permissions = resource_info['default_mask']['data'] + if resource_info: + default_permissions = resource_info['default_mask']['data'] + else: + default_permissions = webqtlConfig.DEFAULT_PRIVILEGES if 'view' not in default_permissions: trait.view = False return trait diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 06b2854a..f9028f32 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -32,6 +32,8 @@ def check_resource_availability(dataset, trait_id=None): if resource_id: resource_info = get_resource_info(resource_id) + if not resource_info: + return webqtlConfig.DEFAULT_PRIVILEGES else: return response #ZS: Need to substitute in something that creates the resource in Redis later @@ -85,9 +87,10 @@ def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): return "owner" resource_info = get_resource_info(resource_id) - if g.user_session.user_id == resource_info['owner_id']: - return "owner" - else: - return check_admin(resource_id) + if resource_info: + if g.user_session.user_id == resource_info['owner_id']: + return "owner" + else: + return check_admin(resource_id) return "not-admin" \ No newline at end of file diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 9d09a66b..8a5f95ee 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -280,7 +280,10 @@ def get_resource_id(dataset, trait_id=None): def get_resource_info(resource_id): resource_info = Redis.hget("resources", resource_id) - return json.loads(resource_info) + if resource_info: + return json.loads(resource_info) + else: + return None def add_resource(resource_info): if 'trait' in resource_info['data']: diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 7eab7184..bc2912f2 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -200,8 +200,6 @@ class CorrelationResults(object): for _trait_counter, trait in enumerate(self.correlation_data.keys()[:self.return_number]): trait_object = create_trait(dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False) - if not trait_object: - continue if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": #ZS: Convert trait chromosome to an int for the location range option @@ -237,9 +235,8 @@ class CorrelationResults(object): trait_object.tissue_pvalue = tissue_corr_data[trait][2] elif self.corr_type == "lit": trait_object.lit_corr = lit_corr_data[trait][1] - self.correlation_results.append(trait_object) - self.target_dataset.get_trait_info(self.correlation_results, self.target_dataset.group.species) + self.correlation_results.append(trait_object) if self.corr_type != "lit" and self.dataset.type == "ProbeSet" and self.target_dataset.type == "ProbeSet": self.do_lit_correlation_for_trait_list() @@ -498,6 +495,8 @@ def do_bicor(this_trait_vals, target_trait_vals): def generate_corr_json(corr_results, this_trait, dataset, target_dataset, for_api = False): results_list = [] for i, trait in enumerate(corr_results): + if trait.view == False: + continue results_dict = {} if not for_api: results_dict['checkbox'] = "" diff --git a/wqflask/wqflask/templates/correlation_page.html b/wqflask/wqflask/templates/correlation_page.html index f429948d..3d750bea 100644 --- a/wqflask/wqflask/templates/correlation_page.html +++ b/wqflask/wqflask/templates/correlation_page.html @@ -169,7 +169,11 @@ {% endif %} + {% if trait.authors %} + {% else %} + + {% endif %}
    {{ loop.index }}N/A{% if trait.description_display|length > 70 %}{{ trait.description_display[:70] }}...{% else %}{{ trait.description_display }}{% endif %}{% if trait.authors.split(',') > 6 %}{{ trait.authors.split(',')[:6]|join(', ') }}, et al.{% else %}{{ trait.authors }}{% endif %}N/A {{ trait.pubmed_text }} -- cgit v1.2.3 From 0a0d733af4b6c61c381a1c4ec9fa162182a057e9 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 6 Jul 2020 14:47:04 -0500 Subject: Fixed some of the logic with how traits are authenticated to avoid situation where a trait is authenticated twice --- wqflask/base/trait.py | 30 ++++++++-------------------- wqflask/maintenance/set_resource_defaults.py | 6 +++--- wqflask/utility/redis_tools.py | 5 +++-- 3 files changed, 14 insertions(+), 27 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 7fc016f3..4c3e790c 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -49,7 +49,6 @@ def create_trait(**kw): if "view" in permissions['data']: the_trait = GeneralTrait(**kw) if the_trait.dataset.type != "Temp": - the_trait = retrieve_trait_info(the_trait, the_trait.dataset, get_qtl_info=kw.get('get_qtl_info')) return the_trait else: @@ -144,6 +143,7 @@ class GeneralTrait(object): formatted = self.post_publication_description else: formatted = "Not available" + return formatted @property @@ -388,27 +388,14 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): try: response = requests.get(the_url).content - if response.strip() == "no-access": - trait.view = False - return trait - else: - trait_info = json.loads(response) - except: - resource_info = get_resource_info(resource_id) - if resource_info: - default_permissions = resource_info['default_mask']['data'] - else: - default_permissions = webqtlConfig.DEFAULT_PRIVILEGES - if 'view' not in default_permissions: - trait.view = False - return trait - + trait_info = json.loads(response) + except: #ZS: I'm assuming the trait is viewable if the try fails for some reason; it should never reach this point unless the user has privileges, since that's dealt with in create_trait if dataset.type == 'Publish': query = """ SELECT - PublishXRef.Id, Publication.PubMed_ID, + PublishXRef.Id, InbredSet.InbredSetCode, Publication.PubMed_ID, Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, - Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, + Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, PublishXRef.mean, Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, Publication.Authors, Publication.Title, Publication.Abstract, Publication.Journal, Publication.Volume, Publication.Pages, @@ -472,11 +459,10 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if trait_info: trait.haveinfo = True - for i, field in enumerate(dataset.display_fields): - holder = trait_info[i] - #if isinstance(trait_info[i], basestring): - # holder = holder.encode('latin1') + holder = trait_info[i] + # if isinstance(trait_info[i], basestring): + # holder = unicode(holder.strip(codecs.BOM_UTF8), 'utf-8', "ignore") setattr(trait, field, holder) if dataset.type == 'Publish': diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index ddb3b17b..54fd8e7e 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -77,7 +77,7 @@ def insert_probeset_resources(default_owner_id): "admin": "not-admin"} resource_ob['group_masks'] = {} - add_resource(resource_ob) + add_resource(resource_ob, update=False) def insert_publish_resources(default_owner_id): current_resources = Redis.hgetall("resources") @@ -108,7 +108,7 @@ def insert_publish_resources(default_owner_id): resource_ob['group_masks'] = {} - add_resource(resource_ob) + add_resource(resource_ob, update=False) else: continue @@ -139,7 +139,7 @@ def insert_geno_resources(default_owner_id): "admin": "not-admin"} resource_ob['group_masks'] = {} - add_resource(resource_ob) + add_resource(resource_ob, update=False) def insert_resources(default_owner_id): current_resources = get_resources() diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 8a5f95ee..6c912a23 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -285,13 +285,14 @@ def get_resource_info(resource_id): else: return None -def add_resource(resource_info): +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']))) else: resource_id = hmac.hmac_creation('{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']))) - Redis.hset("resources", resource_id, json.dumps(resource_info)) + if not Redis.hexists("resources", resource_id): + Redis.hset("resources", resource_id, json.dumps(resource_info)) return resource_info -- cgit v1.2.3 From ddc7dfa6afb2ae02d6a23e345d408ec1ec73b1aa Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 8 Jul 2020 13:00:30 -0500 Subject: Removed remaining unused references to the old qtlreaper --- wqflask/base/trait.py | 2 +- wqflask/utility/Plot.py | 2 -- wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py | 2 -- wqflask/wqflask/correlation/show_corr_results.py | 2 -- wqflask/wqflask/correlation_matrix/show_corr_matrix.py | 2 -- wqflask/wqflask/heatmap/heatmap.py | 2 -- wqflask/wqflask/network_graph/network_graph.py | 2 -- 7 files changed, 1 insertion(+), 13 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 8e11c11d..ecb9dcd9 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -403,7 +403,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): Publication.Month, Publication.Year, PublishXRef.Sequence, Phenotype.Units, PublishXRef.comments FROM - PublishXRef, Publication, Phenotype, PublishFreeze + PublishXRef, Publication, Phenotype, PublishFreeze, InbredSet WHERE PublishXRef.Id = %s AND Phenotype.Id = PublishXRef.PhenotypeId AND diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index cce8435d..9bc84d22 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -35,8 +35,6 @@ import sys, os from numarray import linear_algebra as la from numarray import ones, array, dot, swapaxes -import reaper - import webqtlUtil import corestats from base import webqtlConfig diff --git a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py index 5d74dc9d..09d6b9cc 100644 --- a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py +++ b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py @@ -35,8 +35,6 @@ import resource from pprint import pformat as pf -import reaper - from base.trait import create_trait from base import data_set from utility import webqtlUtil, helper_functions, corr_result_helpers diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index bc2912f2..de7a1c0c 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -42,8 +42,6 @@ utils = importr("utils") from pprint import pformat as pf -import reaper - from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 2b9467d1..0ac94139 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -41,8 +41,6 @@ import rpy2.robjects as robjects from pprint import pformat as pf -import reaper - from utility.redis_tools import get_redis_conn Redis = get_redis_conn() THIRTY_DAYS = 60 * 60 * 24 * 30 diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py index e82aa0ef..5098a184 100644 --- a/wqflask/wqflask/heatmap/heatmap.py +++ b/wqflask/wqflask/heatmap/heatmap.py @@ -19,8 +19,6 @@ import numpy as np from pprint import pformat as pf -import reaper - from base.trait import GeneralTrait from base import data_set from base import species diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index f41f3017..f61c40b4 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -40,8 +40,6 @@ import rpy2.robjects as robjects from pprint import pformat as pf -import reaper - from utility.THCell import THCell from utility.TDCell import TDCell from base.trait import create_trait -- cgit v1.2.3 From c9e5ea428684590ab11fa2cadbd2a60b72f98168 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 16 Jul 2020 16:20:27 +0300 Subject: Expose elastic-search variables for tests to pass --- wqflask/utility/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 89d88516..77db5d53 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -270,8 +270,8 @@ if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') -# ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') -# ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') +ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') +ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') # import utility.elasticsearch_tools as es # es.test_elasticsearch_connection() -- cgit v1.2.3 From 81c35e99a7ff808bf2fcf1f5e19631adf07d42e8 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 22 Jul 2020 17:46:37 -0500 Subject: It should add new resources to Redis automatically now --- wqflask/utility/authentication_tools.py | 61 +++++++++++++++++++++++++-------- wqflask/utility/redis_tools.py | 5 +-- 2 files changed, 47 insertions(+), 19 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index f9028f32..ed7462d1 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -6,7 +6,7 @@ import requests from base import data_set, webqtlConfig from utility import hmac -from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id +from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id, add_resource Redis = get_redis_conn() from flask import Flask, g, redirect, url_for @@ -16,13 +16,7 @@ logger = logging.getLogger(__name__ ) def check_resource_availability(dataset, trait_id=None): - #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy - if g.user_session.user_id in Redis.smembers("super_users"): - return webqtlConfig.SUPER_PRIVILEGES - - response = None - - #At least for now assume temporary entered traits are accessible#At least for now assume temporary entered traits are accessible + #At least for now assume temporary entered traits are accessible if type(dataset) == str: return webqtlConfig.DEFAULT_PRIVILEGES if dataset.type == "Temp": @@ -33,9 +27,13 @@ def check_resource_availability(dataset, trait_id=None): if resource_id: resource_info = get_resource_info(resource_id) if not resource_info: - return webqtlConfig.DEFAULT_PRIVILEGES - else: - return response #ZS: Need to substitute in something that creates the resource in Redis later + resource_info = add_new_resource(dataset, trait_id) + + #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy + if g.user_session.user_id in Redis.smembers("super_users"): + return webqtlConfig.SUPER_PRIVILEGES + + response = None the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) try: @@ -43,10 +41,43 @@ def check_resource_availability(dataset, trait_id=None): except: response = resource_info['default_mask'] - if response: - return response - else: #ZS: No idea how this would happen, but just in case - return False + return response + +def add_new_resource(dataset, trait_id=None): + resource_ob = { + 'owner_id' : webqtlConfig.DEFAULT_OWNER_ID, + 'default_mask': webqtlConfig.DEFAULT_PRIVILEGES, + 'group_masks' : {} + } + + if dataset.type == "Publish": + resource_ob['name'] = get_group_code(dataset) + "_" + str(trait_id) + resource_ob['data'] = { + 'dataset': dataset.id, + 'trait' : trait_id + } + resource_ob['type'] = 'dataset-publish' + elif dataset.type == "Geno": + resource_ob['name'] = dataset.name + resource_ob['data'] = { + 'dataset': dataset.id + } + resource_ob['type'] = 'dataset-geno' + else: + resource_ob['name'] = dataset.name + resource_ob['data'] = { + 'dataset': dataset.id + } + resource_ob['type'] = 'dataset-probeset' + + resource_info = add_resource(resource_ob, update=False) + + return resource_info + +def get_group_code(dataset): + results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format(dataset.group.name)).fetchone() + + return results[0] def check_admin(resource_id=None): the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 6c912a23..1377a564 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -264,17 +264,14 @@ def get_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)) - else: - return False elif dataset.type == "ProbeSet": resource_id = hmac.hmac_creation("{}:{}".format('dataset-probeset', dataset.id)) elif dataset.type == "Geno": resource_id = hmac.hmac_creation("{}:{}".format('dataset-geno', dataset.id)) - else: - return False return resource_id -- cgit v1.2.3 From f4e61929d0eb490dbf7e8ddc03a20d42d44b6f5c Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 21 Jul 2020 12:36:06 +0300 Subject: Add work-around for failed imports in unittest * wqflask/utility/tools.py: Unittests will use `from wqflask.wqflask import app` and the gn2 script will use `from wqflask import app` --- wqflask/utility/tools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 77db5d53..37f9d8fe 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -5,7 +5,10 @@ import os import sys import json -from wqflask import app +try: + from wqflask import app +except ImportError: + from wqflask.wqflask import app # Use the standard logger here to avoid a circular dependency import logging -- cgit v1.2.3 From 2cbda12fe9fa9fca4d27796b2a8eb719e659dc7f Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 21 Jul 2020 21:53:30 +0300 Subject: Revert "Add work-around for failed imports in unittest" This reverts commit d5e87fa6fe7546b46790f512d984a5501223082f. --- wqflask/utility/tools.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 37f9d8fe..77db5d53 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -5,10 +5,7 @@ import os import sys import json -try: - from wqflask import app -except ImportError: - from wqflask.wqflask import app +from wqflask import app # Use the standard logger here to avoid a circular dependency import logging -- cgit v1.2.3 From d26ca838b6e823303c4b903c286fcc452caed0ad Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 21 Jul 2020 23:37:21 +0300 Subject: Remove unused doc-tests * wqflask/utility/chunks.py: Remove test code from module --- wqflask/utility/chunks.py | 63 ----------------------------------------------- 1 file changed, 63 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/chunks.py b/wqflask/utility/chunks.py index b0e33c08..d91b9bf4 100644 --- a/wqflask/utility/chunks.py +++ b/wqflask/utility/chunks.py @@ -31,66 +31,3 @@ def divide_into_chunks(the_list, number_chunks): chunks.append(the_list[counter:counter+chunksize]) return chunks - -def _confirm_chunk(original, result): - all_chunked = [] - for chunk in result: - all_chunked.extend(chunk) - print("length of all chunked:", len(all_chunked)) - assert original == all_chunked, "You didn't chunk right" - - -def _chunk_test(divide_func): - import random - random.seed(7) - - number_exact = 0 - total_amount_off = 0 - - for test in range(1, 1001): - print("\n\ntest:", test) - number_chunks = random.randint(1, 20) - number_elements = random.randint(0, 100) - the_list = list(range(1, number_elements)) - result = divide_func(the_list, number_chunks) - - print("Dividing list of length {} into approximately {} chunks - got {} chunks".format( - len(the_list), number_chunks, len(result))) - print("result:", result) - - _confirm_chunk(the_list, result) - - amount_off = abs(number_chunks - len(result)) - if amount_off == 0: - number_exact += 1 - else: - total_amount_off += amount_off - - - print("\n{} exact out of {} [Total amount off: {}]".format(number_exact, - test, - total_amount_off)) - assert number_exact == 558 - assert total_amount_off == 1580 - return number_exact, total_amount_off - - -def _main(): - info = dict() - #funcs = (("sam", sam_divide_into_chunks), ("zach", zach_divide_into_chunks)) - funcs = (("only one", divide_into_chunks),) - for name, func in funcs: - start = time.time() - number_exact, total_amount_off = _chunk_test(func) - took = time.time() - start - info[name] = dict(number_exact=number_exact, - total_amount_off=total_amount_off, - took=took) - - print("info is:", info) - -if __name__ == '__main__': - _main() - print("\nConfirming doctests...") - import doctest - doctest.testmod() -- cgit v1.2.3 From b39ef1e464208cf8806dc73cfe9684183ce7c9a2 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 01:37:52 +0300 Subject: Simplify normalize_values * wqflask/utility/corr_result_helpers.py(normalize_values): Replace loop with zip form --- wqflask/utility/corr_result_helpers.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py index b543c589..69c6fe1b 100644 --- a/wqflask/utility/corr_result_helpers.py +++ b/wqflask/utility/corr_result_helpers.py @@ -14,15 +14,11 @@ def normalize_values(a_values, b_values): min_length = min(len(a_values), len(b_values)) a_new = [] b_new = [] - for counter in range(min_length): - if (a_values[counter] or a_values[counter] == 0) and (b_values[counter] or b_values[counter] == 0): - a_new.append(a_values[counter]) - b_new.append(b_values[counter]) - - num_overlap = len(a_new) - assert num_overlap == len(b_new), "Lengths should be the same" - - return a_new, b_new, num_overlap + for a, b in zip(a_values, b_values): + if not (a == None or b == None): + a_new.append(a) + b_new.append(b) + return a_new, b_new, len(a_new) def common_keys(a_samples, b_samples): -- cgit v1.2.3 From f99df1fa0f2163a93f7e194beeb65f0e1d542594 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 01:40:03 +0300 Subject: Remove unused doc-tests * wqflask/utility/corr_result_helpers.py: Delete doc-test --- wqflask/utility/corr_result_helpers.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py index 69c6fe1b..09017e4a 100644 --- a/wqflask/utility/corr_result_helpers.py +++ b/wqflask/utility/corr_result_helpers.py @@ -44,9 +44,3 @@ def normalize_values_with_samples(a_samples, b_samples): assert num_overlap == len(b_new), "Lengths should be the same" return a_new, b_new, num_overlap - - - -if __name__ == '__main__': - import doctest - doctest.testmod() \ No newline at end of file -- cgit v1.2.3 From 2b7d50f9ac6d0f4f6a032e60053b5923c292a0a1 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 01:41:14 +0300 Subject: Remove unused assert * wqflask/utility/corr_result_helpers.py(normalize_values): At no one point will that assert be hit --- wqflask/utility/corr_result_helpers.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py index 09017e4a..a43edbd4 100644 --- a/wqflask/utility/corr_result_helpers.py +++ b/wqflask/utility/corr_result_helpers.py @@ -33,14 +33,10 @@ def common_keys(a_samples, b_samples): def normalize_values_with_samples(a_samples, b_samples): common_samples = common_keys(a_samples, b_samples) - a_new = {} b_new = {} for sample in common_samples: a_new[sample] = a_samples[sample] b_new[sample] = b_samples[sample] - num_overlap = len(a_new) - assert num_overlap == len(b_new), "Lengths should be the same" - return a_new, b_new, num_overlap -- cgit v1.2.3 From 82ee315583281b93e1eff9640ce04e44bc70ac58 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 01:41:45 +0300 Subject: Remove redundant variable * wqflask/utility/corr_result_helpers.py(normalize_values_with_values): Remove `num_overlap` --- wqflask/utility/corr_result_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py index a43edbd4..ea3ababf 100644 --- a/wqflask/utility/corr_result_helpers.py +++ b/wqflask/utility/corr_result_helpers.py @@ -39,4 +39,4 @@ def normalize_values_with_samples(a_samples, b_samples): a_new[sample] = a_samples[sample] b_new[sample] = b_samples[sample] - return a_new, b_new, num_overlap + return a_new, b_new, len(a_new) -- cgit v1.2.3 From aed1b7f12f653694c22ab389a403120e143a0669 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 17:03:37 +0300 Subject: Add zero to num_repr dictionary * wqflask/utility/formatting.py(numify): Update `num_repr` to have a zero --- wqflask/utility/formatting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/formatting.py b/wqflask/utility/formatting.py index e53dda22..1c0269e9 100644 --- a/wqflask/utility/formatting.py +++ b/wqflask/utility/formatting.py @@ -28,7 +28,8 @@ def numify(number, singular=None, plural=None): '12,334 hippopotami' """ - num_repr = {1 : "one", + num_repr = {0 : "zero", + 1 : "one", 2 : "two", 3 : "three", 4 : "four", -- cgit v1.2.3 From 073e8c9813505fc00372b2ec21f3e4a87b5be9aa Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 22 Jul 2020 17:05:11 +0300 Subject: Apply autopep-8 * wqflask/utility/formatting.py: apply it --- wqflask/utility/formatting.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/formatting.py b/wqflask/utility/formatting.py index 1c0269e9..1da3e9b7 100644 --- a/wqflask/utility/formatting.py +++ b/wqflask/utility/formatting.py @@ -28,22 +28,20 @@ def numify(number, singular=None, plural=None): '12,334 hippopotami' """ - num_repr = {0 : "zero", - 1 : "one", - 2 : "two", - 3 : "three", - 4 : "four", - 5 : "five", - 6 : "six", - 7 : "seven", - 8 : "eight", - 9 : "nine", - 10 : "ten", - 11 : "eleven", - 12 : "twelve"} - - #Below line commented out cause doesn't work in Python 2.4 - #assert all((singular, plural)) or not any((singular, plural)), "Need to pass two words or none" + num_repr = {0: "zero", + 1: "one", + 2: "two", + 3: "three", + 4: "four", + 5: "five", + 6: "six", + 7: "seven", + 8: "eight", + 9: "nine", + 10: "ten", + 11: "eleven", + 12: "twelve"} + if number == 1: word = singular else: -- cgit v1.2.3 From b8e17aee9000943e0fd379b5ef006d76314733e4 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 21 Jul 2020 12:36:06 +0300 Subject: Add work-around for failed imports in unittest * wqflask/utility/tools.py: Unittests will use `from wqflask.wqflask import app` and the gn2 script will use `from wqflask import app` --- wqflask/utility/tools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 77db5d53..37f9d8fe 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -5,7 +5,10 @@ import os import sys import json -from wqflask import app +try: + from wqflask import app +except ImportError: + from wqflask.wqflask import app # Use the standard logger here to avoid a circular dependency import logging -- cgit v1.2.3 From 98035fccfd7960e6992e1e47afc32b56d54ff074 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 21 Jul 2020 21:53:30 +0300 Subject: Revert "Add work-around for failed imports in unittest" This reverts commit d5e87fa6fe7546b46790f512d984a5501223082f. --- wqflask/utility/tools.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 37f9d8fe..77db5d53 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -5,10 +5,7 @@ import os import sys import json -try: - from wqflask import app -except ImportError: - from wqflask.wqflask import app +from wqflask import app # Use the standard logger here to avoid a circular dependency import logging -- cgit v1.2.3 From 91e52482071ce90acf3607597de2ae79e298fd67 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Sat, 25 Jul 2020 16:25:14 +0100 Subject: The variable is never defined, so let's default to "none" --- wqflask/utility/authentication_tools.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index ed7462d1..9a2a5ccd 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -45,7 +45,7 @@ def check_resource_availability(dataset, trait_id=None): def add_new_resource(dataset, trait_id=None): resource_ob = { - 'owner_id' : webqtlConfig.DEFAULT_OWNER_ID, + 'owner_id' : "none", # webqtlConfig.DEFAULT_OWNER_ID, 'default_mask': webqtlConfig.DEFAULT_PRIVILEGES, 'group_masks' : {} } @@ -84,6 +84,7 @@ def check_admin(resource_id=None): try: response = json.loads(requests.get(the_url).content)['admin'] except: + logger.debug(resource_info) response = resource_info['default_mask']['admin'] if 'edit-admins' in response: @@ -124,4 +125,4 @@ def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): else: return check_admin(resource_id) - return "not-admin" \ No newline at end of file + return "not-admin" -- cgit v1.2.3 From 317d7a78930ecf4be8ec80bd688c14baa8852f04 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 29 Jul 2020 18:50:08 -0500 Subject: Fixed error that occured for new resources in check_admin * wqflask/utility/authentication_tools.py: the code forgot to get resource_info when a resource wasn't in Redis yet, causing an error when it was referenced, so I added a line getting the resource info (and also a couple comments for other lines related to authentication) --- wqflask/utility/authentication_tools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 9a2a5ccd..ece7022c 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -24,9 +24,9 @@ def check_resource_availability(dataset, trait_id=None): resource_id = get_resource_id(dataset, trait_id) - if resource_id: + if resource_id: #ZS: This should never be false, but it's technically possible if a non-Temp dataset somehow had a type other than Publish/ProbeSet/Geno resource_info = get_resource_info(resource_id) - if not resource_info: + if not resource_info: #ZS: If resource isn't already in redis, add it with default privileges resource_info = add_new_resource(dataset, trait_id) #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy @@ -84,7 +84,7 @@ def check_admin(resource_id=None): try: response = json.loads(requests.get(the_url).content)['admin'] except: - logger.debug(resource_info) + resource_info = get_resource_info(resource_id) response = resource_info['default_mask']['admin'] if 'edit-admins' in response: -- cgit v1.2.3 From 49dfdc0c986901683f3e00e65f922e2318e0f330 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 15 Feb 2019 08:41:28 +0300 Subject: Migrate code from Piddle to Pillow * wqflask/wqflask/marker_regression/display_mapping_results.py: Add font files (DisplayMappingResults): Update the code from the Piddle way of things to the Pillow way of things, for example, replace: - pid.drawRect(...) with im_drawer.rectangle(...) - pid.drawString(...) with im_drawer.text(...) - pid.drawPolygon(...) with im_drawer.polygon(...) etc. * wqflask/utility/Plot.py: Migrate code from the older, unsupported Piddle to the newer Pillow library. --- wqflask/utility/Plot.py | 87 ++- .../marker_regression/display_mapping_results.py | 757 ++++++++++++++++----- 2 files changed, 637 insertions(+), 207 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 9bc84d22..c557bcc6 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -26,7 +26,7 @@ from __future__ import print_function -import piddle as pid +from PIL import (Image, ImageColor, ImageDraw, ImageFont) from pprint import pformat as pf from math import * @@ -42,6 +42,17 @@ from base import webqtlConfig import utility.logger logger = utility.logger.getLogger(__name__ ) +# ---- Define common colours ---- # +BLUE = ImageColor.getrgb("blue") +BLACK = ImageColor.getrgb("black") +# ---- END: Define common colours ---- # + +# ---- FONT FILES ---- # +VERDANA_FILE = "fonts/ttf/verdana.ttf" +COUR_FILE = "fonts/ttf/courbd.ttf" +TAHOMA_FILE = "fonts/ttf/tahoma.ttf" +# ---- END: FONT FILES ---- # + def cformat(d, rank=0): 'custom string format' strD = "%2.6f" % d @@ -114,7 +125,8 @@ def find_outliers(vals): # parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py) # or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) -def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): +def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset @@ -161,43 +173,67 @@ def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid if count: xc = (dataXY[i]-xLow)*xScale+xLeftOffset yc =-(count-yLow)*yScale+yTopOffset+plotHeight - canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) + im_drawer.rectangle( + xy=((xc+2,yc),(xc+barWidth-2,yTopOffset+plotHeight)), + outline=barColor, fill=barColor) #draw drawing region - canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) + im_drawer.rectangle( + xy=((xLeftOffset, yTopOffset), (xLeftOffset+plotWidth, yTopOffset+plotHeight)) + ) #draw scale - scaleFont=pid.Font(ttf="cour",size=11,bold=1) + scaleFont=ImageFont.truetype(font=COUR_FILE,size=11) x=xLow for i in range(int(stepX)+1): xc=xLeftOffset+(x-xLow)*xScale - canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) + im_drawer.line( + xy=((xc,yTopOffset+plotHeight),(xc,yTopOffset+plotHeight+5)), + fill=axesColor) strX = cformat(d=x, rank=0) - canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) + im_drawer.text( + text=strX, + xy=(xc-im_drawer.textsize(strX,font=scaleFont)[0]/2, + yTopOffset+plotHeight+14),font=scaleFont) x+= (xTop - xLow)/stepX y=yLow for i in range(int(stepY)+1): yc=yTopOffset+plotHeight-(y-yLow)*yScale - canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) + im_drawer.line(xy=((xLeftOffset,yc),(xLeftOffset-5,yc)), fill=axesColor) strY = "%d" %y - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) + im_drawer.text( + text=strY, + xy=(xLeftOffset-im_drawer.textsize(strY,font=scaleFont)[0]-6,yc+5), + font=scaleFont) y+= (yTop - yLow)/stepY #draw label - labelFont=pid.Font(ttf="tahoma",size=17,bold=0) + labelFont=ImageFont.truetype(font=TAHOMA_FILE,size=17) if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, - yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) + im_drawer.text( + text=XLabel, + xy=(xLeftOffset+( + plotWidth-im_drawer.textsize(XLabel,font=labelFont)[0])/2.0, + yTopOffset+plotHeight+yBottomOffset-10), + font=labelFont,fill=labelColor) if YLabel: - canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, - font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=16,bold=0) + im_drawer.text( + text=YLabel, + xy=(19, + yTopOffset+plotHeight-(plotHeight-im_drawer.textsize( + YLabel,font=labelFont)[0])/2.0), + font=labelFont,fill=labelColor,angle=90) + + labelFont=ImageFont.truetype(font=VERDANA_FILE,size=16) if title: - canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, - 20,font=labelFont,color=labelColor) + im_drawer.text( + text=title, + xy=(xLeftOffset+(plotWidth-im_drawer.textsize( + title,font=labelFont)[0])/2.0, + 20), + font=labelFont,fill=labelColor) # This function determines the scale of the plot def detScaleOld(min,max): @@ -265,16 +301,21 @@ def greenfunc(x): def colorSpectrum(n=100): multiple = 10 if n == 1: - return [pid.Color(1,0,0)] + return [ImageColor.getrgb("rgb(100%,0%,0%)")] elif n == 2: - return [pid.Color(1,0,0),pid.Color(0,0,1)] + return [ImageColor.getrgb("100%,0%,0%)"), + ImageColor.getrgb("rgb(0%,0%,100%)")] elif n == 3: - return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] + return [ImageColor.getrgb("rgb(100%,0%,0%)"), + ImageColor.getrgb("rgb(0%,100%,0%)"), + ImageColor.getrgb("rgb(0%,0%,100%)")] N = n*multiple out = [None]*N; for i in range(N): x = float(i)/N - out[i] = pid.Color(redfunc(x), greenfunc(x), bluefunc(x)); + out[i] = ImageColor.getrgb("rgb({}%,{}%,{}%".format( + *[int(i*100) for i in ( + redfunc(x), greenfunc(x), bluefunc(x))])) out2 = [out[0]] step = N/float(n-1) j = 0 @@ -290,4 +331,4 @@ def _test(): if __name__=="__main__": - _test() \ No newline at end of file + _test() diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 25846099..39067fc5 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -27,7 +27,7 @@ import datetime import string from math import * -from PIL import (ImageColor) +from PIL import (Image,ImageDraw,ImageFont,ImageColor) import sys,os import cPickle import httplib @@ -70,6 +70,13 @@ DARKVIOLET = ImageColor.getrgb("darkviolet") MEDIUMPURPLE = ImageColor.getrgb("mediumpurple") # ---- END: Define common colours ---- # +# ---- FONT FILES ---- # +VERDANA_FILE = "fonts/ttf/verdana.ttf" +TREBUC_FILE = "fonts/ttf/trebucbd.ttf" +FNT_BS_FILE = "fonts/ttf/fnt_bs.ttf" +ARIAL_FILE = "fonts/ttf/arial.ttf" +# ---- END: FONT FILES ---- # + ######################################### # Inteval Mapping Plot Page ######################################### @@ -487,21 +494,28 @@ class DisplayMappingResults(object): # Plots goes here ################################################################ showLocusForm = "" - intCanvas = pid.PILCanvas(size=(self.graphWidth, self.graphHeight)) + intCanvas = Image.new("RGBA", size=(self.graphWidth, self.graphHeight)) with Bench("Drawing Plot"): gifmap = self.plotIntMapping(intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= showLocusForm) self.gifmap = gifmap.__str__() self.filename= webqtlUtil.genRandStr("Itvl_") - intCanvas.save(os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename), format='png') + intCanvas.save( + "{}.png".format( + os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename)), + format='png') intImg=HT.Image('/image/'+self.filename+'.png', border=0, usemap='#WebQTLImageMap') #Scales plot differently for high resolution if self.draw2X: - intCanvasX2 = pid.PILCanvas(size=(self.graphWidth*2,self.graphHeight*2)) + intCanvasX2 = Image.new("RGBA", size=(self.graphWidth*2,self.graphHeight*2)) gifmapX2 = self.plotIntMapping(intCanvasX2, startMb = self.startMb, endMb = self.endMb, showLocusForm= showLocusForm, zoom=2) - intCanvasX2.save(os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, self.filename+"X2"), format='png') + intCanvasX2.save( + "{}.png".format( + os.path.join(webqtlConfig.GENERATED_IMAGE_DIR, + self.filename+"X2")), + format='png') ################################################################ # Outputs goes here @@ -529,6 +543,7 @@ class DisplayMappingResults(object): btminfo.append(HT.BR(), 'Mapping using genotype data as a trait will result in infinity LRS at one locus. In order to display the result properly, all LRSs higher than 100 are capped at 100.') def plotIntMapping(self, canvas, offset= (80, 120, 20, 100), zoom = 1, startMb = None, endMb = None, showLocusForm = ""): + im_drawer = ImageDraw.Draw(canvas) #calculating margins xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset if self.multipleInterval: @@ -622,6 +637,7 @@ class DisplayMappingResults(object): return gifmap def drawBootStrapResult(self, canvas, nboot, drawAreaHeight, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -708,8 +724,10 @@ class DisplayMappingResults(object): if item[1] > xLeftOffset+plotWidth: item[1] = xLeftOffset+plotWidth if item[0] != item[1]: - canvas.drawRect(item[0], yZero, item[1], yZero - item[2]*bootHeightThresh/maxBootCount, - fillColor=self.BOOTSTRAP_BOX_COLOR) + im_drawer.rectangle( + xy=((item[0], yZero), + (item[1], yZero - item[2]*bootHeightThresh/maxBootCount)), + fill=self.BOOTSTRAP_BOX_COLOR) ###draw boot scale highestPercent = (maxBootCount*100.0)/nboot @@ -718,26 +736,43 @@ class DisplayMappingResults(object): bootScale = bootScale[:-1] + [highestPercent] bootOffset = 50*fontZoom - bootScaleFont=pid.Font(ttf="verdana",size=13*fontZoom,bold=0) - canvas.drawRect(canvas.size[0]-bootOffset,yZero-bootHeightThresh,canvas.size[0]-bootOffset-15*zoom,yZero,fillColor = YELLOW) - canvas.drawLine(canvas.size[0]-bootOffset+4, yZero, canvas.size[0]-bootOffset, yZero, color=BLACK) - canvas.drawString('0%' ,canvas.size[0]-bootOffset+10,yZero+5,font=bootScaleFont,color=BLACK) + bootScaleFont=ImageFont.truetype(font=VERDANA_FILE,size=13*fontZoom) + im_drawer.rectangle( + xy=((canvas.size[0]-bootOffset, yZero-bootHeightThresh), + (canvas.size[0]-bootOffset-15*zoom,yZero)), + fill = YELLOW) + im_drawer.line( + xy=((canvas.size[0]-bootOffset+4, yZero), + (canvas.size[0]-bootOffset, yZero)), + fill=BLACK) + im_drawer.text(xy=(canvas.size[0]-bootOffset+10,yZero+5), text='0%', + font=bootScaleFont, fill=BLACK) + for item in bootScale: if item == 0: continue bootY = yZero-bootHeightThresh*item/highestPercent - canvas.drawLine(canvas.size[0]-bootOffset+4,bootY,canvas.size[0]-bootOffset,bootY,color=BLACK) - canvas.drawString('%2.1f'%item ,canvas.size[0]-bootOffset+10,bootY+5,font=bootScaleFont,color=BLACK) + im_drawer.line( + xy=((canvas.size[0]-bootOffset+4,bootY), + (canvas.size[0]-bootOffset,bootY)), + fill=BLACK) + im_drawer.text(xy=(canvas.size[0]-bootOffset+10,bootY+5), + text='%2.1f'%item, font=bootScaleFont, color=BLACK) if self.legendChecked: startPosY = 30 nCol = 2 - smallLabelFont = pid.Font(ttf="trebuc", size=12*fontZoom, bold=1) + smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) leftOffset = xLeftOffset+(nCol-1)*200 - canvas.drawRect(leftOffset,startPosY-6, leftOffset+12,startPosY+6, fillColor=YELLOW) - canvas.drawString('Frequency of the Peak LRS',leftOffset+ 20, startPosY+5,font=smallLabelFont,color=BLACK) + im_drawer.rectangle( + xy=((leftOffset,startPosY-6), (leftOffset+12,startPosY+6)), + fill=YELLOW) + im_drawer.text(xy=(leftOffset+ 20, startPosY+5), + text='Frequency of the Peak LRS', + font=smallLabelFont, color=BLACK) def drawProbeSetPosition(self, canvas, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) if len(self.traitList) != 1: return @@ -805,12 +840,15 @@ class DisplayMappingResults(object): break if locPixel >= 0 and self.plotScale == 'physic': traitPixel = ((locPixel, yZero), (locPixel-7, yZero+14), (locPixel+7, yZero+14)) - canvas.drawPolygon(traitPixel, edgeColor=BLACK, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) + im_drawer.polygon( + xy=traitPixel, outline=BLACK, + fill=self.TRANSCRIPT_LOCATION_COLOR#, closed=1 + ) if self.legendChecked: startPosY = 15 nCol = 2 - smallLabelFont = pid.Font(ttf="trebuc", size=12*fontZoom, bold=1) + smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) if self.manhattan_plot: leftOffset = xLeftOffset else: @@ -819,6 +857,7 @@ class DisplayMappingResults(object): canvas.drawString("Sequence Site", (leftOffset+15), (startPosY+5), smallLabelFont, self.TOP_RIGHT_INFO_COLOR) def drawSNPTrackNew(self, canvas, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) if self.plotScale != 'physic' or self.selectedChr == -1 or not self.diffCol: return @@ -856,12 +895,15 @@ class DisplayMappingResults(object): if maxCount>0: for i in range(xLeftOffset, xLeftOffset + plotWidth): snpDensity = float(SNPCounts[i-xLeftOffset]*SNP_HEIGHT_MODIFIER/maxCount) - canvas.drawLine(i, drawSNPLocationY+(snpDensity)*zoom, i, drawSNPLocationY-(snpDensity)*zoom, color=self.SNP_COLOR, width=1) + im_drawer.line( + xy=((i, drawSNPLocationY+(snpDensity)*zoom), + (i, drawSNPLocationY-(snpDensity)*zoom)), + fill=self.SNP_COLOR, width=1) def drawMultiTraitName(self, fd, canvas, gifmap, showLocusForm, offset= (40, 120, 80, 10), zoom = 1): nameWidths = [] yPaddingTop = 10 - colorFont=pid.Font(ttf="trebuc",size=12,bold=1) + colorFont=ImageFont.truetype(font=TREBUC_FILE,size=12) if len(self.qtlresults) >20 and self.selectedChr > -1: rightShift = 20 rightShiftStep = 60 @@ -880,11 +922,16 @@ class DisplayMappingResults(object): rightShift += rightShiftStep name = thisTrait.displayName() - nameWidth = canvas.stringWidth(name,font=colorFont) + nameWidth, nameHeight = im_drawer.textsize(name,font=colorFont) nameWidths.append(nameWidth) - canvas.drawRect(rightShift,yPaddingTop+kstep*15, rectWidth+rightShift,yPaddingTop+10+kstep*15, fillColor=thisLRSColor) - canvas.drawString(name,rectWidth+2+rightShift,yPaddingTop+10+kstep*15,font=colorFont,color=BLACK) + im_drawer.rectangle( + xy=((rightShift,yPaddingTop+kstep*15), + (rectWidth+rightShift,yPaddingTop+10+kstep*15)), + fill=thisLRSColor) + im_drawer.text( + text=name,xy=(rectWidth+2+rightShift,yPaddingTop+10+kstep*15), + font=colorFont,fill=BLACK) if thisTrait.db: COORDS = "%d,%d,%d,%d" %(rectWidth+2+rightShift,yPaddingTop+kstep*15,rectWidth+2+rightShift+nameWidth,yPaddingTop+10+kstep*15,) HREF= "javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm, thisTrait.db.name, thisTrait.name) @@ -892,6 +939,7 @@ class DisplayMappingResults(object): gifmap.areas.append(Areas) def drawLegendPanel(self, canvas, offset= (40, 120, 80, 10), zoom = 1): + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -900,45 +948,80 @@ class DisplayMappingResults(object): if zoom == 2: fontZoom = 1.5 - labelFont=pid.Font(ttf="trebuc",size=12*fontZoom, bold=1) + labelFont=ImageFont.truetype(font=TREBUC_FILE,size=12*fontZoom) startPosY = 15 stepPosY = 12*fontZoom if self.manhattan_plot != True: - canvas.drawLine(xLeftOffset,startPosY,xLeftOffset+32,startPosY,color=self.LRS_COLOR, width=2) - canvas.drawString(self.LRS_LOD, xLeftOffset+40,startPosY+5,font=labelFont,color=BLACK) + im_drawer.line( + xy=((xLeftOffset,startPosY),(xLeftOffset+32,startPosY)), + fill=self.LRS_COLOR, width=2) + im_drawer.text( + text=self.LRS_LOD, xy=(xLeftOffset+40,startPosY+5), + font=labelFont,fill=BLACK) startPosY += stepPosY if self.additiveChecked: startPosX = xLeftOffset - canvas.drawLine(startPosX,startPosY,startPosX+17,startPosY,color=self.ADDITIVE_COLOR_POSITIVE, width=2) - canvas.drawLine(startPosX+18,startPosY,startPosX+32,startPosY,color=self.ADDITIVE_COLOR_NEGATIVE, width=2) - canvas.drawString('Additive Effect',startPosX+40,startPosY+5,font=labelFont,color=BLACK) + im_drawer.line( + xy=((startPosX,startPosY),(startPosX+17,startPosY)), + fill=self.ADDITIVE_COLOR_POSITIVE, width=2) + im_drawer.line( + xy=((startPosX+18,startPosY),(startPosX+32,startPosY)), + fill=self.ADDITIVE_COLOR_NEGATIVE, width=2) + im_drawer.text( + text='Additive Effect',xy=(startPosX+40,startPosY+5), + font=labelFont,fill=BLACK) if self.genotype.type == 'intercross' and self.dominanceChecked: startPosX = xLeftOffset startPosY += stepPosY - canvas.drawLine(startPosX,startPosY,startPosX+17,startPosY,color=self.DOMINANCE_COLOR_POSITIVE, width=4) - canvas.drawLine(startPosX+18,startPosY,startPosX+35,startPosY,color=self.DOMINANCE_COLOR_NEGATIVE, width=4) - canvas.drawString('Dominance Effect',startPosX+42,startPosY+5,font=labelFont,color=BLACK) + im_drawer.line( + xy=((startPosX,startPosY),(startPosX+17,startPosY)), + fill=self.DOMINANCE_COLOR_POSITIVE, width=4) + im_drawer.line( + xy=((startPosX+18,startPosY),(startPosX+35,startPosY)), + fill=self.DOMINANCE_COLOR_NEGATIVE, width=4) + im_drawer.text( + text='Dominance Effect', xy=(startPosX+42,startPosY+5), + font=labelFont,fill=BLACK) if self.haplotypeAnalystChecked: startPosY += stepPosY startPosX = xLeftOffset - canvas.drawLine(startPosX,startPosY,startPosX+17,startPosY,color=self.HAPLOTYPE_POSITIVE, width=4) - canvas.drawLine(startPosX+18,startPosY,startPosX+35,startPosY,color=self.HAPLOTYPE_NEGATIVE, width=4) - canvas.drawLine(startPosX+36,startPosY,startPosX+53,startPosY,color=self.HAPLOTYPE_HETEROZYGOUS, width=4) - canvas.drawLine(startPosX+54,startPosY,startPosX+67,startPosY,color=self.HAPLOTYPE_RECOMBINATION, width=4) - canvas.drawString('Haplotypes (Pat, Mat, Het, Unk)',startPosX+76,startPosY+5,font=labelFont,color=BLACK) + im_drawer.line( + xy=((startPosX,startPosY),(startPosX+17,startPosY)), + fill=self.HAPLOTYPE_POSITIVE, width=4) + im_drawer.line( + xy=((startPosX+18,startPosY),(startPosX+35,startPosY)), + fill=self.HAPLOTYPE_NEGATIVE, width=4) + im_drawer.line( + xy=((startPosX+36,startPosY),(startPosX+53,startPosY)), + fill=self.HAPLOTYPE_HETEROZYGOUS, width=4) + im_drawer.line( + xy=((startPosX+54,startPosY),(startPosX+67,startPosY)), + fill=self.HAPLOTYPE_RECOMBINATION, width=4) + im_drawer.text( + text='Haplotypes (Pat, Mat, Het, Unk)', + xy=(startPosX+76,startPosY+5),font=labelFont,fill=BLACK) if self.permChecked and self.nperm > 0: startPosY += stepPosY startPosX = xLeftOffset - canvas.drawLine(startPosX, startPosY, startPosX + 32, startPosY, color=self.SIGNIFICANT_COLOR, width=self.SIGNIFICANT_WIDTH) - canvas.drawLine(startPosX, startPosY + stepPosY, startPosX + 32, startPosY + stepPosY, color=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH) - canvas.drawString('Significant %s = %2.2f' % (self.LRS_LOD, self.significant),xLeftOffset+42,startPosY +5,font=labelFont,color=BLACK) - canvas.drawString('Suggestive %s = %2.2f' % (self.LRS_LOD, self.suggestive),xLeftOffset+42,startPosY + 5 +stepPosY,font=labelFont,color=BLACK) - - labelFont = pid.Font(ttf="verdana",size=12*fontZoom) + im_drawer.line( + xy=((startPosX, startPosY),( startPosX + 32, startPosY)), + fill=self.SIGNIFICANT_COLOR, width=self.SIGNIFICANT_WIDTH) + im_drawer.line( + xy=((startPosX, startPosY + stepPosY),( startPosX + 32, startPosY + stepPosY)), + fill=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH) + im_drawer.text( + text='Significant %s = %2.2f' % (self.LRS_LOD,self.significant), + xy=(xLeftOffset+42,startPosY +5),font=labelFont,fill=BLACK) + im_drawer.text( + text='Suggestive %s = %2.2f' % (self.LRS_LOD, self.suggestive), + xy=(xLeftOffset+42,startPosY + 5 +stepPosY),font=labelFont, + fill=BLACK) + + labelFont = ImageFont.truetype(font=VERDANA_FILE,size=12*fontZoom) labelColor = BLACK if self.dataset.type == "Publish" or self.dataset.type == "Geno": dataset_label = self.dataset.fullname @@ -1000,20 +1083,32 @@ class DisplayMappingResults(object): identification += "Trait: %s" % (self.this_trait.name) identification += " with %s samples" % (self.n_samples) - d = 4+ max(canvas.stringWidth(identification, font=labelFont), canvas.stringWidth(string1, font=labelFont), canvas.stringWidth(string2, font=labelFont)) - canvas.drawString(identification,canvas.size[0] - xRightOffset-d,20*fontZoom,font=labelFont,color=labelColor) - else: - d = 4+ max(canvas.stringWidth(string1, font=labelFont), canvas.stringWidth(string2, font=labelFont)) - canvas.drawString(string1,canvas.size[0] - xRightOffset-d,35*fontZoom,font=labelFont,color=labelColor) - canvas.drawString(string2,canvas.size[0] - xRightOffset-d,50*fontZoom,font=labelFont,color=labelColor) - canvas.drawString(string3,canvas.size[0] - xRightOffset-d,65*fontZoom,font=labelFont,color=labelColor) - if string4 != '': - canvas.drawString(string4,canvas.size[0] - xRightOffset-d,80*fontZoom,font=labelFont,color=labelColor) - canvas.drawString("Created at: " + str(datetime.datetime.now()).split('.')[0], canvas.size[0] - xRightOffset-d,95*fontZoom,font=labelFont,color=labelColor) + d = 4+ max( + im_drawer.textsize(identification, font=labelFont)[0], + im_drawer.textsize(string1, font=labelFont)[0], + im_drawer.textsize(string2, font=labelFont)[0]) + im_drawer.text( + text=identification, + xy=(canvas.size[0] - xRightOffset-d,20*fontZoom),font=labelFont, + fill=labelColor) else: - canvas.drawString("Created at: " + str(datetime.datetime.now()).split('.')[0], canvas.size[0] - xRightOffset-d,80*fontZoom,font=labelFont,color=labelColor) + d = 4+ max( + im_drawer.textsize(string1, font=labelFont)[0], + im_drawer.textsize(string2, font=labelFont)[0]) + im_drawer.text( + text=string1,xy=(canvas.size[0] - xRightOffset-d,35*fontZoom), + font=labelFont,fill=labelColor) + im_drawer.text( + text=string2,xy=(canvas.size[0] - xRightOffset-d,50*fontZoom), + font=labelFont,fill=labelColor) + if string3 != '': + im_drawer.text( + text=string3,xy=(canvas.size[0] - xRightOffset-d,65*fontZoom), + font=labelFont,fill=labelColor) + def drawGeneBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) if self.plotScale != 'physic' or self.selectedChr == -1 or not self.geneCol: return @@ -1126,11 +1221,15 @@ class DisplayMappingResults(object): #draw the detail view if self.endMb - self.startMb <= self.DRAW_DETAIL_MB and geneEndPix - geneStartPix > self.EACH_GENE_ARROW_SPACING * 3: - utrColor = pid.Color(0.66, 0.66, 0.66) - arrowColor = pid.Color(0.7, 0.7, 0.7) + utrColor = ImageColor.getrgb("rgb(66%, 66%, 66%)") + arrowColor = ImageColor.getrgb("rgb(70%, 70%, 70%)") #draw the line that runs the entire length of the gene - canvas.drawLine(geneStartPix, geneYLocation + self.EACH_GENE_HEIGHT/2*zoom, geneEndPix, geneYLocation + self.EACH_GENE_HEIGHT/2*zoom, color=outlineColor, width=1) + im_drawer.line( + xy=( + (geneStartPix, geneYLocation + self.EACH_GENE_HEIGHT/2*zoom), + ( geneEndPix, geneYLocation + self.EACH_GENE_HEIGHT/2*zoom)), + fill=outlineColor, width=1) #draw the arrows if geneEndPix - geneStartPix < 1: @@ -1141,11 +1240,30 @@ class DisplayMappingResults(object): if (xCoord % self.EACH_GENE_ARROW_SPACING == 0 and xCoord + self.EACH_GENE_ARROW_SPACING < geneEndPix-geneStartPix) or xCoord == 0: if strand == "+": - canvas.drawLine(geneStartPix + xCoord, geneYLocation, geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, geneYLocation +(self.EACH_GENE_HEIGHT / 2)*zoom, color=arrowColor, width=1) - canvas.drawLine(geneStartPix + xCoord, geneYLocation + self.EACH_GENE_HEIGHT*zoom, geneStartPix + xCoord+self.EACH_GENE_ARROW_WIDTH, geneYLocation + (self.EACH_GENE_HEIGHT / 2) * zoom, color=arrowColor, width=1) + im_drawer.line( + xy=((geneStartPix + xCoord, geneYLocation), + (geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, + geneYLocation +(self.EACH_GENE_HEIGHT / 2)*zoom)), + fill=arrowColor, width=1) + im_drawer.line( + xy=((geneStartPix + xCoord, + geneYLocation + self.EACH_GENE_HEIGHT*zoom), + (geneStartPix + xCoord+self.EACH_GENE_ARROW_WIDTH, + geneYLocation + (self.EACH_GENE_HEIGHT / 2) * zoom)), + fill=arrowColor, width=1) else: - canvas.drawLine(geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, geneYLocation, geneStartPix + xCoord, geneYLocation +(self.EACH_GENE_HEIGHT / 2)*zoom, color=arrowColor, width=1) - canvas.drawLine(geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, geneYLocation + self.EACH_GENE_HEIGHT*zoom, geneStartPix + xCoord, geneYLocation + (self.EACH_GENE_HEIGHT / 2)*zoom, color=arrowColor, width=1) + im_drawer.line( + xy=((geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, + geneYLocation), + ( geneStartPix + xCoord, + geneYLocation +(self.EACH_GENE_HEIGHT / 2)*zoom)), + fill=arrowColor, width=1) + im_drawer.line( + xy=((geneStartPix + xCoord + self.EACH_GENE_ARROW_WIDTH, + geneYLocation + self.EACH_GENE_HEIGHT*zoom), + ( geneStartPix + xCoord, + geneYLocation + (self.EACH_GENE_HEIGHT / 2)*zoom)), + fill=arrowColor, width=1) #draw the blocks for the exon regions for i in range(0, len(exonStarts)): @@ -1159,7 +1277,10 @@ class DisplayMappingResults(object): exonEndPix = xLeftOffset + plotWidth if (exonStartPix > xLeftOffset + plotWidth): exonStartPix = xLeftOffset + plotWidth - canvas.drawRect(exonStartPix, geneYLocation, exonEndPix, (geneYLocation + self.EACH_GENE_HEIGHT*zoom), edgeColor = outlineColor, fillColor = fillColor) + im_drawer.rectangle( + xy=((exonStartPix, geneYLocation), + (exonEndPix, (geneYLocation + self.EACH_GENE_HEIGHT*zoom))), + outline = outlineColor, fill = fillColor) #draw gray blocks for 3' and 5' UTR blocks if cdsStart and cdsEnd: @@ -1173,14 +1294,16 @@ class DisplayMappingResults(object): utrEndPix = xLeftOffset + plotWidth if (utrStartPix > xLeftOffset + plotWidth): utrStartPix = xLeftOffset + plotWidth - #canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) if self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: if strand == "-": labelText = "3'" else: labelText = "5'" - canvas.drawString(labelText, utrStartPix-9, geneYLocation+self.EACH_GENE_HEIGHT, pid.Font(face="helvetica", size=2)) + im_drawer.text( + text=labelText, + xy=(utrStartPix-9, geneYLocation+self.EACH_GENE_HEIGHT), + font=ImageFont.truetype(font=ARIAL_FILE, size=2)) #the second UTR region @@ -1194,18 +1317,23 @@ class DisplayMappingResults(object): utrEndPix = xLeftOffset + plotWidth if (utrStartPix > xLeftOffset + plotWidth): utrStartPix = xLeftOffset + plotWidth - #canvas.drawRect(utrStartPix, geneYLocation, utrEndPix, (geneYLocation+self.EACH_GENE_HEIGHT*zoom), edgeColor=utrColor, fillColor =utrColor) if self.endMb - self.startMb <= self.DRAW_UTR_LABELS_MB: if strand == "-": labelText = "5'" else: labelText = "3'" - canvas.drawString(labelText, utrEndPix+2, geneYLocation+self.EACH_GENE_HEIGHT, pid.Font(face="helvetica", size=2)) + im_drawer.text( + text=labelText, + xy=(utrEndPix+2,geneYLocation+self.EACH_GENE_HEIGHT), + font=ImageFont.truetype(font=ARIAL_FILE, size=2)) #draw the genes as rectangles else: - canvas.drawRect(geneStartPix, geneYLocation, geneEndPix, (geneYLocation + self.EACH_GENE_HEIGHT*zoom), edgeColor = outlineColor, fillColor = fillColor) + im_drawer.rectangle( + xy=((geneStartPix, geneYLocation), + (geneEndPix, (geneYLocation + self.EACH_GENE_HEIGHT*zoom))), + outline= outlineColor, fill = fillColor) COORDS = "%d, %d, %d, %d" %(geneStartPix, geneYLocation, geneEndPix, (geneYLocation + self.EACH_GENE_HEIGHT)) # NL: 06-02-2011 Rob required to display NCBI info in a new window @@ -1354,12 +1482,22 @@ class DisplayMappingResults(object): else: mylineColor = self.HAPLOTYPE_RECOMBINATION # XZ: Unknown - canvas.drawLine(drawStart, geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom, drawEnd, geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom, color = mylineColor, width=zoom*(self.EACH_GENE_HEIGHT+2)) + im_drawer.line( + xy=((drawStart, + geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom), + (drawEnd, + geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom)), + fill= mylineColor, width=zoom*(self.EACH_GENE_HEIGHT+2)) fillColor=BLACK outlineColor=BLACK if lastGene == 0: - canvas.drawRect(geneStartPix, geneYLocation+2*ind*self.EACH_GENE_HEIGHT*zoom, geneEndPix, geneYLocation+2*ind*self.EACH_GENE_HEIGHT+ 2*self.EACH_GENE_HEIGHT*zoom, edgeColor = outlineColor, fillColor = fillColor) + im_drawer.rectangle( + xy=((geneStartPix, + geneYLocation+2*ind*self.EACH_GENE_HEIGHT*zoom), + (geneEndPix, + geneYLocation+2*ind*self.EACH_GENE_HEIGHT+ 2*self.EACH_GENE_HEIGHT*zoom)), + outline=outlineColor, fill=fillColor) COORDS = "%d, %d, %d, %d" %(geneStartPix, geneYLocation+ind*self.EACH_GENE_HEIGHT, geneEndPix+1, (geneYLocation + ind*self.EACH_GENE_HEIGHT)) @@ -1372,11 +1510,21 @@ class DisplayMappingResults(object): if (plotRight < (xLeftOffset + plotWidth - 3)) and (lastGene == 0): drawEnd = xLeftOffset + plotWidth - 6 mylineColor = self.HAPLOTYPE_RECOMBINATION - canvas.drawLine(plotRight, geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom, drawEnd, geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom, color = mylineColor, width=zoom*(self.EACH_GENE_HEIGHT+2)) + im_drawer.line( + xy=((plotRight, + geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom), + (drawEnd, + geneYLocation+7+2*ind*self.EACH_GENE_HEIGHT*zoom)), + fill= mylineColor, width=zoom*(self.EACH_GENE_HEIGHT+2)) if lastGene == 0: - canvas.drawString("%s" % (_chr[j].name), geneStartPix , geneYLocation+17+2*maxind*self.EACH_GENE_HEIGHT*zoom, font=pid.Font(ttf="verdana", size=12, bold=0), color=BLACK, angle=-90) + im_drawer.text( + text="%s" % (_chr[j].name), + xy=(geneStartPix, + geneYLocation+17+2*maxind*self.EACH_GENE_HEIGHT*zoom), + font=ImageFont.truetype(font=VERDANA_FILE, size=12), + fill=BLACK, angle=-90) oldgeneEndPix = geneEndPix; oldgeno = _chr[j].genotype @@ -1405,12 +1553,23 @@ class DisplayMappingResults(object): expr = item.value # Place where font is hardcoded - canvas.drawString("%s" % (samplelist[j]), (xLeftOffset + plotWidth + 10) , geneYLocation+8+2*ind*self.EACH_GENE_HEIGHT*zoom, font=pid.Font(ttf="verdana", size=12, bold=0), color=BLACK) - canvas.drawString("%2.2f" % (expr), (xLeftOffset + plotWidth + 60) , geneYLocation+8+2*ind*self.EACH_GENE_HEIGHT*zoom, font=pid.Font(ttf="verdana", size=12, bold=0), color=BLACK) + im_drawer.text( + text="%s" % (samplelist[j]), + xy=((xLeftOffset + plotWidth + 10), + geneYLocation+8+2*ind*self.EACH_GENE_HEIGHT*zoom), + font=ImageFont.truetype(font=VERDANA_FILE, size=12), + fill=BLACK) + im_drawer.text( + text="%2.2f" % (expr), + xy=((xLeftOffset + plotWidth + 60), + geneYLocation+8+2*ind*self.EACH_GENE_HEIGHT*zoom), + font=ImageFont.truetype(font=VERDANA_FILE, size=12), + fill=BLACK) ## END HaplotypeAnalyst def drawClickBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) if self.plotScale != 'physic' or self.selectedChr == -1: return @@ -1426,7 +1585,7 @@ class DisplayMappingResults(object): # but it makes the HTML huge, and takes forever to render the page in the first place) # Draw the bands that you can click on to go to UCSC / Ensembl MAX_CLICKABLE_REGION_DIVISIONS = 100 - clickableRegionLabelFont=pid.Font(ttf="verdana", size=9, bold=0) + clickableRegionLabelFont=ImageFont.truetype(font=VERDANA_FILE, size=9) pixelStep = max(5, int(float(plotWidth)/MAX_CLICKABLE_REGION_DIVISIONS)) # pixelStep: every N pixels, we make a new clickable area for the user to go to that area of the genome. @@ -1463,8 +1622,14 @@ class DisplayMappingResults(object): WEBQTL_TITLE = "Click to view this section of the genome in WebQTL" gifmap.areas.append(HT.Area(shape='rect',coords=WEBQTL_COORDS,href=WEBQTL_HREF, title=WEBQTL_TITLE)) - canvas.drawRect(xBrowse1, paddingTop, xBrowse2, (paddingTop + self.BAND_HEIGHT), edgeColor=self.CLICKABLE_WEBQTL_REGION_COLOR, fillColor=self.CLICKABLE_WEBQTL_REGION_COLOR) - canvas.drawLine(xBrowse1, paddingTop, xBrowse1, (paddingTop + self.BAND_HEIGHT), color=self.CLICKABLE_WEBQTL_REGION_OUTLINE_COLOR) + im_drawer.rectangle( + xy=((xBrowse1, paddingTop), + (xBrowse2, (paddingTop + self.BAND_HEIGHT))), + outline=self.CLICKABLE_WEBQTL_REGION_COLOR, + fill=self.CLICKABLE_WEBQTL_REGION_COLOR) + im_drawer.line( + xy=((xBrowse1, paddingTop),( xBrowse1, (paddingTop + self.BAND_HEIGHT))), + fill=self.CLICKABLE_WEBQTL_REGION_OUTLINE_COLOR) if self.dataset.group.species == "mouse" or self.dataset.group.species == "rat": PHENOGEN_COORDS = "%d, %d, %d, %d" % (xBrowse1, phenogenPaddingTop, xBrowse2, (phenogenPaddingTop+self.BAND_HEIGHT)) @@ -1474,8 +1639,14 @@ class DisplayMappingResults(object): PHENOGEN_HREF = "https://phenogen.org/gene.jsp?speciesCB=Mm&auto=Y&geneTxt=chr%s:%d-%d&genomeVer=mm10" % (self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) PHENOGEN_TITLE = "Click to view this section of the genome in PhenoGen" gifmap.areas.append(HT.Area(shape='rect',coords=PHENOGEN_COORDS,href=PHENOGEN_HREF, title=PHENOGEN_TITLE)) - canvas.drawRect(xBrowse1, phenogenPaddingTop, xBrowse2, (phenogenPaddingTop+self.BAND_HEIGHT), edgeColor=self.CLICKABLE_PHENOGEN_REGION_COLOR, fillColor=self.CLICKABLE_PHENOGEN_REGION_COLOR) - canvas.drawLine(xBrowse1, phenogenPaddingTop, xBrowse1, (phenogenPaddingTop+self.BAND_HEIGHT), color=self.CLICKABLE_PHENOGEN_REGION_OUTLINE_COLOR) + im_drawer.rectangle( + xy=((xBrowse1, phenogenPaddingTop), + (xBrowse2, (phenogenPaddingTop+self.BAND_HEIGHT))), + outline=self.CLICKABLE_PHENOGEN_REGION_COLOR, + fill=self.CLICKABLE_PHENOGEN_REGION_COLOR) + im_drawer.line( + xy=((xBrowse1, phenogenPaddingTop),( xBrowse1, (phenogenPaddingTop+self.BAND_HEIGHT))), + fill=self.CLICKABLE_PHENOGEN_REGION_OUTLINE_COLOR) UCSC_COORDS = "%d, %d, %d, %d" %(xBrowse1, ucscPaddingTop, xBrowse2, (ucscPaddingTop+self.BAND_HEIGHT)) if self.dataset.group.species == "mouse": @@ -1484,8 +1655,15 @@ class DisplayMappingResults(object): UCSC_HREF = "http://genome.ucsc.edu/cgi-bin/hgTracks?db=%s&position=chr%s:%d-%d" % (self._ucscDb, self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) UCSC_TITLE = "Click to view this section of the genome in the UCSC Genome Browser" gifmap.areas.append(HT.Area(shape='rect',coords=UCSC_COORDS,href=UCSC_HREF, title=UCSC_TITLE)) - canvas.drawRect(xBrowse1, ucscPaddingTop, xBrowse2, (ucscPaddingTop+self.BAND_HEIGHT), edgeColor=self.CLICKABLE_UCSC_REGION_COLOR, fillColor=self.CLICKABLE_UCSC_REGION_COLOR) - canvas.drawLine(xBrowse1, ucscPaddingTop, xBrowse1, (ucscPaddingTop+self.BAND_HEIGHT), color=self.CLICKABLE_UCSC_REGION_OUTLINE_COLOR) + im_drawer.rectangle( + xy=((xBrowse1, ucscPaddingTop), + (xBrowse2, (ucscPaddingTop+self.BAND_HEIGHT))), + outline=self.CLICKABLE_UCSC_REGION_COLOR, + fill=self.CLICKABLE_UCSC_REGION_COLOR) + im_drawer.line( + xy=((xBrowse1, ucscPaddingTop), + (xBrowse1, (ucscPaddingTop+self.BAND_HEIGHT))), + fill=self.CLICKABLE_UCSC_REGION_OUTLINE_COLOR) ENSEMBL_COORDS = "%d, %d, %d, %d" %(xBrowse1, ensemblPaddingTop, xBrowse2, (ensemblPaddingTop+self.BAND_HEIGHT)) if self.dataset.group.species == "mouse": @@ -1494,32 +1672,59 @@ class DisplayMappingResults(object): ENSEMBL_HREF = "http://www.ensembl.org/Rattus_norvegicus/contigview?chr=%s&start=%d&end=%d" % (self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) ENSEMBL_TITLE = "Click to view this section of the genome in the Ensembl Genome Browser" gifmap.areas.append(HT.Area(shape='rect',coords=ENSEMBL_COORDS,href=ENSEMBL_HREF, title=ENSEMBL_TITLE)) - canvas.drawRect(xBrowse1, ensemblPaddingTop, xBrowse2, (ensemblPaddingTop+self.BAND_HEIGHT), edgeColor=self.CLICKABLE_ENSEMBL_REGION_COLOR, fillColor=self.CLICKABLE_ENSEMBL_REGION_COLOR) - canvas.drawLine(xBrowse1, ensemblPaddingTop, xBrowse1, (ensemblPaddingTop+self.BAND_HEIGHT), color=self.CLICKABLE_ENSEMBL_REGION_OUTLINE_COLOR) + im_drawer.rectangle( + xy=((xBrowse1, ensemblPaddingTop), + (xBrowse2, (ensemblPaddingTop+self.BAND_HEIGHT))), + outline=self.CLICKABLE_ENSEMBL_REGION_COLOR, + fill=self.CLICKABLE_ENSEMBL_REGION_COLOR) + im_drawer.line( + xy=((xBrowse1, ensemblPaddingTop), + (xBrowse1, (ensemblPaddingTop+self.BAND_HEIGHT))), + fill=self.CLICKABLE_ENSEMBL_REGION_OUTLINE_COLOR) # end for - canvas.drawString("Click to view the corresponding section of the genome in an 8x expanded WebQTL map", (xLeftOffset + 10), paddingTop + self.BAND_HEIGHT/2, font=clickableRegionLabelFont, color=self.CLICKABLE_WEBQTL_TEXT_COLOR) + im_drawer.text( + text="Click to view the corresponding section of the genome in an 8x expanded WebQTL map", + xy=((xLeftOffset + 10), paddingTop + self.BAND_HEIGHT/2), + font=clickableRegionLabelFont, + fill=self.CLICKABLE_WEBQTL_TEXT_COLOR) if self.dataset.group.species == "mouse" or self.dataset.group.species == "rat": - canvas.drawString("Click to view the corresponding section of the genome in PhenoGen", (xLeftOffset + 10), phenogenPaddingTop + self.BAND_HEIGHT/2, font=clickableRegionLabelFont, color=self.CLICKABLE_PHENOGEN_TEXT_COLOR) - canvas.drawString("Click to view the corresponding section of the genome in the UCSC Genome Browser", (xLeftOffset + 10), ucscPaddingTop + self.BAND_HEIGHT/2, font=clickableRegionLabelFont, color=self.CLICKABLE_UCSC_TEXT_COLOR) - canvas.drawString("Click to view the corresponding section of the genome in the Ensembl Genome Browser", (xLeftOffset+10), ensemblPaddingTop + self.BAND_HEIGHT/2, font=clickableRegionLabelFont, color=self.CLICKABLE_ENSEMBL_TEXT_COLOR) + im_drawer.text( + text="Click to view the corresponding section of the genome in PhenoGen", + xy=((xLeftOffset + 10), phenogenPaddingTop + self.BAND_HEIGHT/2), + font=clickableRegionLabelFont, fill=self.CLICKABLE_PHENOGEN_TEXT_COLOR) + im_drawer.text( + text="Click to view the corresponding section of the genome in the UCSC Genome Browser", + xy=((xLeftOffset + 10), ucscPaddingTop + self.BAND_HEIGHT/2), + font=clickableRegionLabelFont, fill=self.CLICKABLE_UCSC_TEXT_COLOR) + im_drawer.text( + text="Click to view the corresponding section of the genome in the Ensembl Genome Browser", + xy=((xLeftOffset+10), ensemblPaddingTop + self.BAND_HEIGHT/2), + font=clickableRegionLabelFont, fill=self.CLICKABLE_ENSEMBL_TEXT_COLOR) #draw the gray text - chrFont = pid.Font(ttf="verdana", size=26*zoom, bold=1) - traitFont = pid.Font(ttf="verdana", size=14, bold=0) - chrX = xLeftOffset + plotWidth - 2 - canvas.stringWidth("Chr %s" % self.ChrList[self.selectedChr][0], font=chrFont) - canvas.drawString("Chr %s" % self.ChrList[self.selectedChr][0], chrX, ensemblPaddingTop-5, font=chrFont, color=GRAY) + chrFont = ImageFont.truetype(font=VERDANA_FILE, size=26*zoom) + traitFont = ImageFont.truetype(font=VERDANA_FILE, size=14) + chrX = xLeftOffset + plotWidth - 2 - im_drawer.textsize( + "Chr %s" % self.ChrList[self.selectedChr][0], font=chrFont)[0] + im_drawer.text( + text="Chr %s" % self.ChrList[self.selectedChr][0], + xy=(chrX, ensemblPaddingTop-5), font=chrFont, fill=GRAY) # end of drawBrowserClickableRegions else: #draw the gray text - chrFont = pid.Font(ttf="verdana", size=26*zoom, bold=1) - traitFont = pid.Font(ttf="verdana", size=14, bold=0) - chrX = xLeftOffset + (plotWidth - canvas.stringWidth("Chr %s" % currentChromosome, font=chrFont))/2 - canvas.drawString("Chr %s" % currentChromosome, chrX, 32, font=chrFont, color=GRAY) + chrFont = ImageFont.truetype(font=VERDANA_FILE, size=26*zoom) + traitFont = ImageFont.truetype(font=VERDANA_FILE, size=14) + chrX = xLeftOffset + (plotWidth - im_drawer.textsize( + "Chr %s" % currentChromosome, font=chrFont)[0])/2 + im_drawer.text( + text="Chr %s" % currentChromosome, xy=(chrX, 32), font=chrFont, + fill=GRAY) # end of drawBrowserClickableRegions pass def drawXAxis(self, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -1535,7 +1740,7 @@ class DisplayMappingResults(object): X_AXIS_THICKNESS = 1*zoom # ======= Alex: Draw the X-axis labels (megabase location) - MBLabelFont = pid.Font(ttf="verdana", size=15*zoom, bold=0) + MBLabelFont = ImageFont.truetype(font=VERDANA_FILE, size=15*zoom) xMajorTickHeight = 10 * zoom # How high the tick extends below the axis xMinorTickHeight = 5*zoom xAxisTickMarkColor = BLACK @@ -1544,7 +1749,7 @@ class DisplayMappingResults(object): spacingFromLabelToAxis = 5 if self.plotScale == 'physic': - strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + strYLoc = yZero + spacingFromLabelToAxis + MBLabelFont.font.height ###Physical single chromosome view if self.selectedChr > -1: XScale = Plot.detScale(startMb, endMb) @@ -1565,13 +1770,21 @@ class DisplayMappingResults(object): continue Xc = xLeftOffset + plotXScale*(_Mb - startMb) if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark - canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark + im_drawer.line(xy=((Xc,yZero), + (Xc,yZero+xMajorTickHeight)), + fill=xAxisTickMarkColor, + width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark labelStr = str(formatStr % _Mb) # What Mbase location to put on the label - strWidth = canvas.stringWidth(labelStr, font=MBLabelFont) + strWidth, strHeight = im_drawer.textsize(labelStr, font=MBLabelFont) drawStringXc = (Xc - (strWidth / 2.0)) - canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0) + im_drawer.text(xy=(drawStringXc, strYLoc), + text=labelStr, font=MBLabelFont, + fill=xAxisLabelColor) else: - canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark + im_drawer.line(xy=((Xc,yZero), + (Xc,yZero+xMinorTickHeight)), + fill=xAxisTickMarkColor, + width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark ###Physical genome wide view else: @@ -1586,17 +1799,27 @@ class DisplayMappingResults(object): else: distScale = 5 for j, tickdists in enumerate(range(distScale, int(ceil(distLen)), distScale)): - canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=BLACK, width=1*zoom) + im_drawer.line( + xy=((startPosX+tickdists*plotXScale, yZero), + (startPosX+tickdists*plotXScale, yZero + 7)), + fill=BLACK, width=1*zoom) if j % 2 == 0: - canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=BLACK, font=MBLabelFont, angle=270) + im_drawer.text( + xy=(startPosX+tickdists*plotXScale, yZero+10*zoom), + text=str(tickdists), fill=BLACK, font=MBLabelFont, angle=270) startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale - megabaseLabelFont = pid.Font(ttf="verdana", size=18*zoom*1.5, bold=0) - canvas.drawString("Megabases", xLeftOffset + (plotWidth - canvas.stringWidth("Megabases", font=megabaseLabelFont))/2, - strYLoc + canvas.fontHeight(MBLabelFont)+ 10*(zoom%2) + 10, font=megabaseLabelFont, color=BLACK) + megabaseLabelFont = ImageFont.truetype(font=VERDANA_FILE, size=int(18*zoom*1.5)) + im_drawer.text( + text="Megabases", + xy=( + xLeftOffset+(plotWidth-im_drawer.textsize( + "Megabases",font=megabaseLabelFont)[0])/2, + strYLoc+MBLabelFont.font.height+10*(zoom%2)+ 10), + font=megabaseLabelFont, fill=BLACK) pass else: - strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + 8 + strYLoc = yZero + spacingFromLabelToAxis + MBLabelFont.font.height + 8 ChrAInfo = [] preLpos = -1 distinctCount = 0.0 @@ -1659,18 +1882,26 @@ class DisplayMappingResults(object): else: Zorder = 0 if differ: - canvas.drawLine(startPosX+Lpos,yZero,xLeftOffset+offsetA,\ - yZero+25, color=lineColor) - canvas.drawLine(xLeftOffset+offsetA,yZero+25,xLeftOffset+offsetA,\ - yZero+40+Zorder*(LRectWidth+3),color=lineColor) + im_drawer.line( + xy=((startPosX+Lpos,yZero),(xLeftOffset+offsetA,\ + yZero+25)), + fill=lineColor) + im_drawer.line( + xy=((xLeftOffset+offsetA,yZero+25),(xLeftOffset+offsetA,\ + yZero+40+Zorder*(LRectWidth+3))), + fill=lineColor) rectColor = ORANGE else: - canvas.drawLine(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3,\ - xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),color=lineColor) + im_drawer.line( + xy=((xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3),(\ + xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3))), + fill=lineColor) rectColor = DEEPPINK - canvas.drawRect(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),\ - xLeftOffset+offsetA-LRectHeight,yZero+40+Zorder*(LRectWidth+3)+LRectWidth,\ - edgeColor=rectColor,fillColor=rectColor,edgeWidth = 0) + im_drawer.rectangle( + xy=((xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)), + (xLeftOffset+offsetA-LRectHeight, + yZero+40+Zorder*(LRectWidth+3)+LRectWidth)), + outline=rectColor,fill=rectColor,width = 0) COORDS="%d,%d,%d,%d"%(xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3),\ xLeftOffset+offsetA,yZero+40+Zorder*(LRectWidth+3)+LRectWidth) HREF="/show_trait?trait_id=%s&dataset=%s" % (Lname, self.dataset.group.name+"Geno") @@ -1679,17 +1910,25 @@ class DisplayMappingResults(object): gifmap.areas.append(Areas) ##piddle bug if j == 0: - canvas.drawLine(startPosX,yZero,startPosX,yZero+40, color=lineColor) + im_drawer.line( + xy=((startPosX,yZero),(startPosX,yZero+40)), + fill=lineColor) startPosX += (self.ChrLengthDistList[j]+self.GraphInterval)*plotXScale - centimorganLabelFont = pid.Font(ttf="verdana", size=18*zoom*1.5, bold=0) - canvas.drawString("Centimorgans", xLeftOffset + (plotWidth - canvas.stringWidth("Megabases", font=centimorganLabelFont))/2, - strYLoc + canvas.fontHeight(MBLabelFont)+ 10*(zoom%2) + 10, font=centimorganLabelFont, color=BLACK) + centimorganLabelFont = ImageFont.truetype(font=VERDANA_FILE, size=18*zoom*1.5) + im_drawer.text( + text="Centimorgans", + xy=(xLeftOffset+(plotWidth-im_drawer.textsize( + "Megabases", font=centimorganLabelFont)[0])/2, + strYLoc + MBLabelFont.font.height+ 10*(zoom%2) + 10), + font=centimorganLabelFont, fill=BLACK) - canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=BLACK, width=X_AXIS_THICKNESS) # Draw the X axis itself + im_drawer.line(xy=((xLeftOffset,yZero), (xLeftOffset+plotWidth,yZero)), + fill=BLACK, width=X_AXIS_THICKNESS) # Draw the X axis itself def drawQTL(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -1787,29 +2026,40 @@ class DisplayMappingResults(object): else: all_int = False break - - if all_int: - max_lrs_width = canvas.stringWidth("%d" % LRS_LOD_Max, font=LRSScaleFont) + 40 - else: - max_lrs_width = canvas.stringWidth("%2.1f" % LRS_LOD_Max, font=LRSScaleFont) + 30 + # TODO(PIL): Convert from PIL + # if all_int: + # max_lrs_width = canvas.stringWidth("%d" % LRS_LOD_Max, font=LRSScaleFont) + 40 + # else: + # max_lrs_width = canvas.stringWidth("%2.1f" % LRS_LOD_Max, font=LRSScaleFont) + 30 #draw the "LRS" or "LOD" string to the left of the axis - canvas.drawString(self.LRS_LOD, xLeftOffset - max_lrs_width - 15*(zoom-1), \ - yZero - 150 - 300*(zoom - 1), font=LRSLODFont, color=BLACK, angle=90) + LRSScaleFont=ImageFont.truetype(font=VERDANA_FILE, size=16*zoom) + LRSLODFont=ImageFont.truetype(font=VERDANA_FILE, size=int(18*zoom*1.5)) + yZero = yTopOffset + plotHeight + + im_drawer.text( + text=self.LRS_LOD, + xy=(xLeftOffset - im_drawer.textsize("999.99", font=LRSScaleFont)[0] - 15*(zoom-1), + yZero - 150 - 300*(zoom - 1)), + font=LRSLODFont, fill=BLACK, angle=90) for item in LRSAxisList: if LRS_LOD_Max == 0.0: LRS_LOD_Max = 0.000001 yTopOffset + 30*(zoom - 1) yLRS = yZero - (item/LRS_LOD_Max) * LRSHeightThresh - #yLRS = yZero - (item/LRSAxisList[-1]) * LRSHeightThresh - canvas.drawLine(xLeftOffset, yLRS, xLeftOffset - 4, yLRS, color=self.LRS_COLOR, width=1*zoom) + im_drawer.line(xy=((xLeftOffset,yLRS), (xLeftOffset-4,yLRS)), + fill=self.LRS_COLOR, width=1*zoom) if all_int: scaleStr = "%d" % item else: scaleStr = "%2.1f" % item #Draw the LRS/LOD Y axis label - canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=LRSScaleFont)-5, yLRS+3, font=LRSScaleFont, color=self.LRS_COLOR) + im_drawer.text( + text=scaleStr, + xy=(xLeftOffset-4-im_drawer.textsize(scaleStr, font=LRSScaleFont)[0]-5, + yLRS+3), + font=LRSScaleFont, fill=self.LRS_COLOR) if self.permChecked and self.nperm > 0 and not self.multipleInterval: significantY = yZero - self.significant*LRSHeightThresh/LRS_LOD_Max @@ -1824,10 +2074,19 @@ class DisplayMappingResults(object): #ZS: I don't know if what I did here with this inner function is clever or overly complicated, but it's the only way I could think of to avoid duplicating the code inside this function def add_suggestive_significant_lines_and_legend(start_pos_x, chr_length_dist): rightEdge = int(start_pos_x + chr_length_dist*plotXScale - self.SUGGESTIVE_WIDTH/1.5) - canvas.drawLine(start_pos_x+self.SUGGESTIVE_WIDTH/1.5, suggestiveY, rightEdge, suggestiveY, color=self.SUGGESTIVE_COLOR, - width=self.SUGGESTIVE_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) - canvas.drawLine(start_pos_x+self.SUGGESTIVE_WIDTH/1.5, significantY, rightEdge, significantY, color=self.SIGNIFICANT_COLOR, - width=self.SIGNIFICANT_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) + im_drawer.line( + xy=((start_pos_x+self.SUGGESTIVE_WIDTH/1.5, suggestiveY), + (rightEdge, suggestiveY)), + fill=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH*zoom + #,clipX=(xLeftOffset, xLeftOffset + plotWidth-2) + ) + im_drawer.line( + xy=((start_pos_x+self.SUGGESTIVE_WIDTH/1.5, significantY), + (rightEdge, significantY)), + fill=self.SIGNIFICANT_COLOR, + width=self.SIGNIFICANT_WIDTH*zoom + #, clipX=(xLeftOffset, xLeftOffset + plotWidth-2) + ) sugg_coords = "%d, %d, %d, %d" % (start_pos_x, suggestiveY-2, rightEdge + 2*zoom, suggestiveY+2) sig_coords = "%d, %d, %d, %d" % (start_pos_x, significantY-2, rightEdge + 2*zoom, significantY+2) if self.LRS_LOD == 'LRS': @@ -1868,7 +2127,7 @@ class DisplayMappingResults(object): AdditiveCoordXY = [] DominanceCoordXY = [] - symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0) #ZS: For Manhattan Plot + symbolFont = ImageFont.truetype(font=FNT_BS_FILE, size=5) #ZS: For Manhattan Plot previous_chr = 1 previous_chr_as_int = 0 @@ -1880,7 +2139,12 @@ class DisplayMappingResults(object): thisLRSColor = self.colorCollection[0] if qtlresult['chr'] != previous_chr and self.selectedChr == -1: if self.manhattan_plot != True: - canvas.drawPolygon(LRSCoordXY,edgeColor=thisLRSColor,closed=0, edgeWidth=lrsEdgeWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.polygon( + xy=LRSCoordXY, + outline=thisLRSColor + # , closed=0, edgeWidth=lrsEdgeWidth, + # clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) if not self.multipleInterval and self.additiveChecked: plusColor = self.ADDITIVE_COLOR_POSITIVE @@ -1895,22 +2159,58 @@ class DisplayMappingResults(object): else: Xcm = (yZero-Yc0)/((Yc-Yc0)/(Xc-Xc0)) +Xc0 if Yc0 < yZero: - canvas.drawLine(Xc0, Yc0, Xcm, yZero, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, yZero-(Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xcm, yZero)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, yZero-(Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xcm, yZero, color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero-(Yc0-yZero)), + (Xcm, yZero)), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) elif (Yc0-yZero)*(Yc-yZero) > 0: if Yc < yZero: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), + fill=plusColor, + width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xc, yZero - (Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: minYc = min(Yc-yZero, Yc0-yZero) if minYc < 0: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xc, yZero - (Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) LRSCoordXY = [] AdditiveCoordXY = [] @@ -1979,15 +2279,12 @@ class DisplayMappingResults(object): point_color = RED else: point_color = BLUE - - final_x_pos = Xc-canvas.stringWidth("5",font=symbolFont)/2+1 - if final_x_pos > (xLeftOffset + plotWidth): - continue - #break ZS: This is temporary until issue with sorting for GEMMA is fixed - elif final_x_pos < xLeftOffset: - continue - else: - canvas.drawString("5", final_x_pos,Yc+2,color=point_color, font=symbolFont) + im_drawer.text( + text="5", + xy=( + Xc-im_drawer.textsize("5",font=symbolFont)[0]/2+1, + Yc+2), + fill=point_color, font=symbolFont) else: LRSCoordXY.append((Xc, Yc)) @@ -2000,7 +2297,11 @@ class DisplayMappingResults(object): m += 1 if self.manhattan_plot != True: - canvas.drawPolygon(LRSCoordXY,edgeColor=thisLRSColor,closed=0, edgeWidth=lrsEdgeWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.polygon( + xy=LRSCoordXY, + outline=thisLRSColor + #, closed=0, edgeWidth=lrsEdgeWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) if not self.multipleInterval and self.additiveChecked: plusColor = self.ADDITIVE_COLOR_POSITIVE @@ -2015,22 +2316,57 @@ class DisplayMappingResults(object): else: Xcm = (yZero-Yc0)/((Yc-Yc0)/(Xc-Xc0)) +Xc0 if Yc0 < yZero: - canvas.drawLine(Xc0, Yc0, Xcm, yZero, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, yZero-(Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xcm, yZero)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, yZero-(Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xcm, yZero, color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xcm, yZero)), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) elif (Yc0-yZero)*(Yc-yZero) > 0: if Yc < yZero: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), fill=plusColor, + width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0,yZero-(Yc0-yZero)), + (Xc,yZero-(Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: minYc = min(Yc-yZero, Yc0-yZero) if minYc < 0: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xc, yZero - (Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) if not self.multipleInterval and INTERCROSS and self.dominanceChecked: plusColor = self.DOMINANCE_COLOR_POSITIVE @@ -2045,27 +2381,61 @@ class DisplayMappingResults(object): else: Xcm = (yZero-Yc0)/((Yc-Yc0)/(Xc-Xc0)) +Xc0 if Yc0 < yZero: - canvas.drawLine(Xc0, Yc0, Xcm, yZero, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, yZero-(Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xcm, yZero)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, yZero-(Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xcm, yZero, color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) - canvas.drawLine(Xcm, yZero, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), (Xcm, yZero)), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) + im_drawer.line( + xy=((Xcm, yZero), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) elif (Yc0-yZero)*(Yc-yZero) > 0: if Yc < yZero: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xc, yZero - (Yc-yZero))), + fill=minusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: minYc = min(Yc-yZero, Yc0-yZero) if minYc < 0: - canvas.drawLine(Xc0, Yc0, Xc, Yc, color=plusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, Yc0), (Xc, Yc)), + fill=plusColor, width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) else: - canvas.drawLine(Xc0, yZero - (Yc0-yZero), Xc, yZero - (Yc-yZero), color=minusColor, width=lineWidth, clipX=(xLeftOffset, xLeftOffset + plotWidth)) + im_drawer.line( + xy=((Xc0, yZero - (Yc0-yZero)), + (Xc, yZero - (Yc-yZero))), fill=minusColor, + width=lineWidth + #, clipX=(xLeftOffset, xLeftOffset + plotWidth) + ) ###draw additive scale if not self.multipleInterval and self.additiveChecked: - additiveScaleFont=pid.Font(ttf="verdana",size=16*zoom,bold=0) + additiveScaleFont=ImageFont.truetype(font=VERDANA_FILE,size=16*zoom) additiveScale = Plot.detScaleOld(0,additiveMax) additiveStep = (additiveScale[1]-additiveScale[0])/additiveScale[2] additiveAxisList = Plot.frange(0, additiveScale[1], additiveStep) @@ -2074,13 +2444,24 @@ class DisplayMappingResults(object): additiveAxisList.append(additiveScale[1]) for item in additiveAxisList: additiveY = yZero - item*addPlotScale - canvas.drawLine(xLeftOffset + plotWidth,additiveY,xLeftOffset+4+ plotWidth,additiveY,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + im_drawer.line( + xy=((xLeftOffset + plotWidth,additiveY), + (xLeftOffset+4+ plotWidth,additiveY)), + fill=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) scaleStr = "%2.3f" % item - canvas.drawString(scaleStr,xLeftOffset + plotWidth +6,additiveY+5,font=additiveScaleFont,color=self.ADDITIVE_COLOR_POSITIVE) + im_drawer.text( + text=scaleStr, + xy=(xLeftOffset + plotWidth +6,additiveY+5), + font=additiveScaleFont,fill=self.ADDITIVE_COLOR_POSITIVE) - canvas.drawLine(xLeftOffset+plotWidth,additiveY,xLeftOffset+plotWidth,yZero,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + im_drawer.line( + xy=((xLeftOffset+plotWidth,additiveY), + (xLeftOffset+plotWidth,yZero)), + fill=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) - canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset + 30*(zoom - 1), color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis + im_drawer.line( + xy=((xLeftOffset, yZero), (xLeftOffset, yTopOffset + 30*(zoom - 1))), + fill=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis def drawGraphBackground(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None): @@ -2088,6 +2469,7 @@ class DisplayMappingResults(object): ##multiple Chromosome view ##single Chromosome Physical ##single Chromosome Genetic + im_drawer = ImageDraw.Draw(canvas) xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -2114,8 +2496,10 @@ class DisplayMappingResults(object): else: theBackColor = self.GRAPH_BACK_LIGHT_COLOR i += 1 - canvas.drawRect(startPix, yTopOffset, min(startPix+spacingAmt, xLeftOffset+plotWidth), \ - yBottom, edgeColor=theBackColor, fillColor=theBackColor) + im_drawer.rectangle( + [(startPix, yTopOffset), + (min(startPix+spacingAmt, xLeftOffset+plotWidth), yBottom)], + outline=theBackColor, fill=theBackColor) drawRegionDistance = self.ChrLengthDistList[self.ChrList[self.selectedChr][1]] self.ChrLengthDistList = [drawRegionDistance] @@ -2132,7 +2516,7 @@ class DisplayMappingResults(object): chrFontZoom = 2 else: chrFontZoom = 1 - chrLabelFont=pid.Font(ttf="verdana",size=24*chrFontZoom,bold=0) + chrLabelFont=ImageFont.truetype(font=VERDANA_FILE,size=24*chrFontZoom) for i, _chr in enumerate(self.genotype): if (i % 2 == 0): @@ -2141,14 +2525,18 @@ class DisplayMappingResults(object): theBackColor = self.GRAPH_BACK_LIGHT_COLOR #draw the shaded boxes and the sig/sug thick lines - canvas.drawRect(startPosX, yTopOffset, startPosX + self.ChrLengthDistList[i]*plotXScale, \ - yBottom, edgeColor=GAINSBORO,fillColor=theBackColor) + im_drawer.rectangle( + ((startPosX, yTopOffset), + (startPosX + self.ChrLengthDistList[i]*plotXScale, yBottom)), + outline=GAINSBORO, + fill=theBackColor) - chrNameWidth = canvas.stringWidth(_chr.name, font=chrLabelFont) + chrNameWidth, chrNameHeight = im_drawer.textsize(_chr.name, font=chrLabelFont) chrStartPix = startPosX + (self.ChrLengthDistList[i]*plotXScale -chrNameWidth)/2 chrEndPix = startPosX + (self.ChrLengthDistList[i]*plotXScale +chrNameWidth)/2 - canvas.drawString(_chr.name, chrStartPix, yTopOffset + 20 ,font = chrLabelFont,color=BLACK) + im_drawer.text(xy=(chrStartPix, yTopOffset + 20), + text=_chr.name, font=chrLabelFont, fill=BLACK) COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) #add by NL 09-03-2010 @@ -2164,7 +2552,7 @@ class DisplayMappingResults(object): ######################################### # Permutation Graph ######################################### - myCanvas = pid.PILCanvas(size=(500,300)) + myCanvas = Image.new("RGBA", size=(500, 300)) if 'lod_score' in self.qtlresults[0] and self.LRS_LOD == "LRS": perm_output = [value*4.61 for value in self.perm_output] elif 'lod_score' not in self.qtlresults[0] and self.LRS_LOD == "LOD": @@ -2174,7 +2562,8 @@ class DisplayMappingResults(object): filename= webqtlUtil.genRandStr("Reg_") Plot.plotBar(myCanvas, perm_output, XLabel=self.LRS_LOD, YLabel='Frequency', title=' Histogram of Permutation Test') - myCanvas.save(GENERATED_IMAGE_DIR+filename, format='gif') + myCanvas.save("{}.gif".format(GENERATED_IMAGE_DIR+filename), + format='gif') return filename -- cgit v1.2.3 From 95dbb4a18a205b475ca8eb72210d7d2193062295 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sat, 23 Feb 2019 07:32:29 +0300 Subject: Fix font paths * wqflask/utility/Plot.py: Update font paths. * wqflask/fonts/ttf: Update font files. --- wqflask/fonts/ttf/arial.ttf | Bin 151232 -> 0 bytes wqflask/fonts/ttf/courbd.ttf | Bin 181388 -> 0 bytes wqflask/fonts/ttf/fnt_bs.ttf | Bin 20988 -> 0 bytes wqflask/fonts/ttf/tahoma.ttf | Bin 249012 -> 0 bytes wqflask/fonts/ttf/trebucbd.ttf | Bin 123828 -> 0 bytes wqflask/fonts/ttf/verdana.ttf | Bin 139640 -> 0 bytes wqflask/utility/Plot.py | 6 +++--- wqflask/wqflask/static/fonts/courbd.ttf | Bin 0 -> 181388 bytes wqflask/wqflask/static/fonts/tahoma.ttf | Bin 0 -> 249012 bytes 9 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 wqflask/fonts/ttf/arial.ttf delete mode 100644 wqflask/fonts/ttf/courbd.ttf delete mode 100644 wqflask/fonts/ttf/fnt_bs.ttf delete mode 100644 wqflask/fonts/ttf/tahoma.ttf delete mode 100644 wqflask/fonts/ttf/trebucbd.ttf delete mode 100644 wqflask/fonts/ttf/verdana.ttf create mode 100644 wqflask/wqflask/static/fonts/courbd.ttf create mode 100644 wqflask/wqflask/static/fonts/tahoma.ttf (limited to 'wqflask/utility') diff --git a/wqflask/fonts/ttf/arial.ttf b/wqflask/fonts/ttf/arial.ttf deleted file mode 100644 index bf0d4a95..00000000 Binary files a/wqflask/fonts/ttf/arial.ttf and /dev/null differ diff --git a/wqflask/fonts/ttf/courbd.ttf b/wqflask/fonts/ttf/courbd.ttf deleted file mode 100644 index c8081467..00000000 Binary files a/wqflask/fonts/ttf/courbd.ttf and /dev/null differ diff --git a/wqflask/fonts/ttf/fnt_bs.ttf b/wqflask/fonts/ttf/fnt_bs.ttf deleted file mode 100644 index 712c38cf..00000000 Binary files a/wqflask/fonts/ttf/fnt_bs.ttf and /dev/null differ diff --git a/wqflask/fonts/ttf/tahoma.ttf b/wqflask/fonts/ttf/tahoma.ttf deleted file mode 100644 index bb314be3..00000000 Binary files a/wqflask/fonts/ttf/tahoma.ttf and /dev/null differ diff --git a/wqflask/fonts/ttf/trebucbd.ttf b/wqflask/fonts/ttf/trebucbd.ttf deleted file mode 100644 index 1ab1ae0a..00000000 Binary files a/wqflask/fonts/ttf/trebucbd.ttf and /dev/null differ diff --git a/wqflask/fonts/ttf/verdana.ttf b/wqflask/fonts/ttf/verdana.ttf deleted file mode 100644 index 754a9b7b..00000000 Binary files a/wqflask/fonts/ttf/verdana.ttf and /dev/null differ diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index c557bcc6..e7115036 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -48,9 +48,9 @@ BLACK = ImageColor.getrgb("black") # ---- END: Define common colours ---- # # ---- FONT FILES ---- # -VERDANA_FILE = "fonts/ttf/verdana.ttf" -COUR_FILE = "fonts/ttf/courbd.ttf" -TAHOMA_FILE = "fonts/ttf/tahoma.ttf" +VERDANA_FILE = "./wqflask/static/fonts/verdana.ttf" +COUR_FILE = "./wqflask/static/fonts/courbd.ttf" +TAHOMA_FILE = "./wqflask/static/fonts/tahoma.ttf" # ---- END: FONT FILES ---- # def cformat(d, rank=0): diff --git a/wqflask/wqflask/static/fonts/courbd.ttf b/wqflask/wqflask/static/fonts/courbd.ttf new file mode 100644 index 00000000..c8081467 Binary files /dev/null and b/wqflask/wqflask/static/fonts/courbd.ttf differ diff --git a/wqflask/wqflask/static/fonts/tahoma.ttf b/wqflask/wqflask/static/fonts/tahoma.ttf new file mode 100644 index 00000000..bb314be3 Binary files /dev/null and b/wqflask/wqflask/static/fonts/tahoma.ttf differ -- cgit v1.2.3 From dcd053e0249b14c938d94eb749a8b4095c80be29 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 8 Mar 2019 10:39:53 +0300 Subject: Create new utility module for drawing * wqflask/utility/pillow_utils.py: Create a module to hold some utility functions for drawing with Pillow. Initialise the module with a function to draw rotated text. --- wqflask/utility/pillow_utils.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 wqflask/utility/pillow_utils.py (limited to 'wqflask/utility') diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py new file mode 100644 index 00000000..4a666e4b --- /dev/null +++ b/wqflask/utility/pillow_utils.py @@ -0,0 +1,16 @@ +from PIL import Image, ImageColor, ImageDraw, ImageFont + +import utility.logger +logger = utility.logger.getLogger(__name__ ) + +BLACK = ImageColor.getrgb("black") +# def draw_rotated_text(canvas: Image, text: str, font: ImageFont, xy: tuple, fill: ImageColor=BLACK, angle: int=-90): +def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90): + # type: (Image, str, ImageFont, tuple, ImageColor, int) + """Utility function draw rotated text""" + tmp_img = Image.new("RGBA", font.getsize(text), color=(0,0,0,0)) + draw_text = ImageDraw.Draw(tmp_img) + draw_text.text(text=text, xy=(0,0), font=font, fill=fill) + tmp_img2 = tmp_img.rotate(angle, expand=1) + tmp_img2.save("/tmp/{}.png".format(text), format="png") + canvas.paste(im=tmp_img2, box=tuple([int(i) for i in xy])) -- cgit v1.2.3 From 6e1102e36737a3f48a74cf431819c269c54f2601 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 8 Mar 2019 10:41:40 +0300 Subject: Use draw_rotated_text() Use the new draw_rotated_text() function to draw the text rotated as was formerly done. * wqflask/utility/Plot.py (plotBar): Use draw_rotated_text(). * wqflask/wqflask/marker_regression/display_mapping_results.py: (DisplayMappingResults) Use draw_rotated_text(). --- wqflask/utility/Plot.py | 14 ++++++------- .../marker_regression/display_mapping_results.py | 24 +++++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index e7115036..d4373412 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -38,7 +38,7 @@ from numarray import ones, array, dot, swapaxes import webqtlUtil import corestats from base import webqtlConfig - +from utility.pillow_utils import draw_rotated_text import utility.logger logger = utility.logger.getLogger(__name__ ) @@ -219,12 +219,12 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab font=labelFont,fill=labelColor) if YLabel: - im_drawer.text( - text=YLabel, - xy=(19, - yTopOffset+plotHeight-(plotHeight-im_drawer.textsize( - YLabel,font=labelFont)[0])/2.0), - font=labelFont,fill=labelColor,angle=90) + draw_rotated_text(canvas, text=YLabel, + xy=(19, + yTopOffset+plotHeight-( + plotHeight-im_drawer.textsize( + YLabel,font=labelFont)[0])/2.0), + font=labelFont, fill=labelColor, angle=90) labelFont=ImageFont.truetype(font=VERDANA_FILE,size=16) if title: diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 39067fc5..b03902a5 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -45,6 +45,7 @@ from utility import Plot from utility.benchmark import Bench from wqflask.interval_analyst import GeneUtil from base.webqtlConfig import TMPDIR, GENERATED_TEXT_DIR, GENERATED_IMAGE_DIR +from utility.pillow_utils import draw_rotated_text import utility.logger logger = utility.logger.getLogger(__name__ ) @@ -1519,11 +1520,12 @@ class DisplayMappingResults(object): if lastGene == 0: - im_drawer.text( - text="%s" % (_chr[j].name), + draw_rotated_text( + canvas, text="%s" % (_chr[j].name), + font=ImageFont.truetype(font=VERDANA_FILE, + size=12), xy=(geneStartPix, geneYLocation+17+2*maxind*self.EACH_GENE_HEIGHT*zoom), - font=ImageFont.truetype(font=VERDANA_FILE, size=12), fill=BLACK, angle=-90) oldgeneEndPix = geneEndPix; @@ -1804,9 +1806,10 @@ class DisplayMappingResults(object): (startPosX+tickdists*plotXScale, yZero + 7)), fill=BLACK, width=1*zoom) if j % 2 == 0: - im_drawer.text( - xy=(startPosX+tickdists*plotXScale, yZero+10*zoom), - text=str(tickdists), fill=BLACK, font=MBLabelFont, angle=270) + draw_rotated_text( + canvas, text=str(tickdists), font=MBLabelFont, + xy=(startPosX+tickdists*plotXScale, + yZero+10*zoom), fill=BLACK, angle=270) startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale megabaseLabelFont = ImageFont.truetype(font=VERDANA_FILE, size=int(18*zoom*1.5)) @@ -2037,11 +2040,12 @@ class DisplayMappingResults(object): LRSLODFont=ImageFont.truetype(font=VERDANA_FILE, size=int(18*zoom*1.5)) yZero = yTopOffset + plotHeight - im_drawer.text( - text=self.LRS_LOD, - xy=(xLeftOffset - im_drawer.textsize("999.99", font=LRSScaleFont)[0] - 15*(zoom-1), + draw_rotated_text( + canvas, text=self.LRS_LOD, font=LRSLODFont, + xy=(xLeftOffset - im_drawer.textsize( + "999.99", font=LRSScaleFont)[0] - 15*(zoom-1), yZero - 150 - 300*(zoom - 1)), - font=LRSLODFont, fill=BLACK, angle=90) + fill=BLACK, angle=90) for item in LRSAxisList: if LRS_LOD_Max == 0.0: -- cgit v1.2.3 From e3c0745fdc3bf33cb10256643f3b1469ee6614c4 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sat, 9 Mar 2019 08:33:19 +0300 Subject: Add draw_open_polygon() utility * wqflask/utility/pillow_utils.py: New method. --- wqflask/utility/pillow_utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py index 4a666e4b..dfbf3e19 100644 --- a/wqflask/utility/pillow_utils.py +++ b/wqflask/utility/pillow_utils.py @@ -4,6 +4,8 @@ import utility.logger logger = utility.logger.getLogger(__name__ ) BLACK = ImageColor.getrgb("black") +WHITE = ImageColor.getrgb("white") + # def draw_rotated_text(canvas: Image, text: str, font: ImageFont, xy: tuple, fill: ImageColor=BLACK, angle: int=-90): def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90): # type: (Image, str, ImageFont, tuple, ImageColor, int) @@ -14,3 +16,10 @@ def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90): tmp_img2 = tmp_img.rotate(angle, expand=1) tmp_img2.save("/tmp/{}.png".format(text), format="png") canvas.paste(im=tmp_img2, box=tuple([int(i) for i in xy])) + +# def draw_open_polygon(canvas: Image, xy: tuple, fill: ImageColor=WHITE, outline: ImageColor=BLACK): +def draw_open_polygon(canvas, xy, fill=None, outline=BLACK, width=0): + # type: (Image, tuple, ImageColor, ImageColor) + draw_ctx = ImageDraw.Draw(canvas) + draw_ctx.polygon(xy, fill=fill) + draw_ctx.line(xy, fill=outline, width=width) -- cgit v1.2.3 From e49ef0954e111ace2044cced0a83b4d9dc00bc72 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 17 Aug 2020 20:45:08 +0300 Subject: Fix malformed docstring * wqflask/utility/Plot.py: Update docstring. --- wqflask/utility/Plot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index d4373412..82bf6070 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -97,7 +97,7 @@ def find_outliers(vals): >>> find_outliers([3.504, 5.234, 6.123, 7.234, 3.542, 5.341, 7.852, 4.555, 12.537]) (11.252500000000001, 0.5364999999999993) - >>> >>> find_outliers([9,12,15,17,31,50,7,5,6,8]) + >>> find_outliers([9,12,15,17,31,50,7,5,6,8]) (32.0, -8.0) If there are no vals, returns None for the upper and lower bounds, -- cgit v1.2.3 From af330a2aa7b36fd0cf8505eb20fa06d2ed58b86b Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 17 Aug 2020 17:41:58 +0300 Subject: Wrap print statements in parentheses --- scripts/maintenance/QTL_Reaper_v6.py | 6 ++-- .../Update_Case_Attributes_MySQL_tab.py | 2 +- scripts/maintenance/delete_genotypes.py | 14 ++++---- scripts/maintenance/delete_phenotypes.py | 14 ++++---- scripts/maintenance/load_genotypes.py | 16 ++++----- scripts/maintenance/load_phenotypes.py | 30 ++++++++-------- scripts/maintenance/readProbeSetMean_v7.py | 40 +++++++++++----------- scripts/maintenance/readProbeSetSE_v7.py | 22 ++++++------ wqflask/run_gunicorn.py | 2 +- wqflask/utility/startup_config.py | 4 +-- wqflask/utility/svg.py | 10 +++--- wqflask/utility/tools.py | 8 ++--- wqflask/wqflask/marker_regression/rqtl_mapping.py | 2 +- wqflask/wqflask/pbkdf2.py | 16 ++++----- wqflask/wqflask/views.py | 4 +-- wqflask/wqflask/wgcna/wgcna_analysis.py | 12 +++---- 16 files changed, 101 insertions(+), 101 deletions(-) (limited to 'wqflask/utility') diff --git a/scripts/maintenance/QTL_Reaper_v6.py b/scripts/maintenance/QTL_Reaper_v6.py index e50dbd40..7fb56eca 100755 --- a/scripts/maintenance/QTL_Reaper_v6.py +++ b/scripts/maintenance/QTL_Reaper_v6.py @@ -53,7 +53,7 @@ for ProbeSetFreezeId in ProbeSetFreezeIds: #if InbredSetId==12: # InbredSetId=2 - print ProbeSetFreezeId, InbredSets[InbredSetId] + print((ProbeSetFreezeId, InbredSets[InbredSetId])) genotype_1.read(InbredSets[InbredSetId]) locuses = [] @@ -102,7 +102,7 @@ for ProbeSetFreezeId in ProbeSetFreezeIds: kj += 1 if kj%1000==0: - print ProbeSetFreezeId, InbredSets[InbredSetId],kj + print((ProbeSetFreezeId, InbredSets[InbredSetId],kj)) - print ProbeSetFreezeIds + print(ProbeSetFreezeIds) diff --git a/scripts/maintenance/Update_Case_Attributes_MySQL_tab.py b/scripts/maintenance/Update_Case_Attributes_MySQL_tab.py index 0f8602c9..bf796df4 100644 --- a/scripts/maintenance/Update_Case_Attributes_MySQL_tab.py +++ b/scripts/maintenance/Update_Case_Attributes_MySQL_tab.py @@ -24,4 +24,4 @@ for row in csv_data: #close the connection to the database. mydb.commit() cursor.close() -print "Done" \ No newline at end of file +print("Done") \ No newline at end of file diff --git a/scripts/maintenance/delete_genotypes.py b/scripts/maintenance/delete_genotypes.py index fa693f0f..060640e1 100755 --- a/scripts/maintenance/delete_genotypes.py +++ b/scripts/maintenance/delete_genotypes.py @@ -8,13 +8,13 @@ import genotypes def main(argv): # config config = utilities.get_config(argv[1]) - print "config:" + print("config:") for item in config.items('config'): - print "\t%s" % (str(item)) + print(("\t%s" % (str(item)))) # var - print "variable:" + print("variable:") inbredsetid = config.get('config', 'inbredsetid') - print "\tinbredsetid: %s" % inbredsetid + print(("\tinbredsetid: %s" % inbredsetid)) # datafile datafile = open(config.get('config', 'datafile'), 'r') datafile = csv.reader(datafile, delimiter='\t', quotechar='"') @@ -25,9 +25,9 @@ def main(argv): continue genoname = row[0] delrowcount += genotypes.delete(genoname, inbredsetid) - print "deleted %d genotypes" % (delrowcount) + print(("deleted %d genotypes" % (delrowcount))) if __name__ == "__main__": - print "command line arguments:\n\t%s" % sys.argv + print(("command line arguments:\n\t%s" % sys.argv)) main(sys.argv) - print "exit successfully" + print("exit successfully") diff --git a/scripts/maintenance/delete_phenotypes.py b/scripts/maintenance/delete_phenotypes.py index 326c466e..60dbec61 100755 --- a/scripts/maintenance/delete_phenotypes.py +++ b/scripts/maintenance/delete_phenotypes.py @@ -8,13 +8,13 @@ import phenotypes def main(argv): # config config = utilities.get_config(argv[1]) - print "config:" + print("config:") for item in config.items('config'): - print "\t%s" % (str(item)) + print(("\t%s" % (str(item)))) # var - print "variable:" + print("variable:") inbredsetid = config.get('config', 'inbredsetid') - print "\tinbredsetid: %s" % inbredsetid + print(("\tinbredsetid: %s" % inbredsetid)) # datafile datafile = open(config.get('config', 'datafile'), 'r') datafile = csv.reader(datafile, delimiter='\t', quotechar='"') @@ -27,9 +27,9 @@ def main(argv): except: continue delrowcount += phenotypes.delete(publishxrefid=publishxrefid, inbredsetid=inbredsetid) - print "deleted %d phenotypes" % (delrowcount) + print(("deleted %d phenotypes" % (delrowcount))) if __name__ == "__main__": - print "command line arguments:\n\t%s" % sys.argv + print(("command line arguments:\n\t%s" % sys.argv)) main(sys.argv) - print "exit successfully" + print("exit successfully") diff --git a/scripts/maintenance/load_genotypes.py b/scripts/maintenance/load_genotypes.py index 338483f4..c235a31f 100755 --- a/scripts/maintenance/load_genotypes.py +++ b/scripts/maintenance/load_genotypes.py @@ -8,7 +8,7 @@ def main(argv): config = utilities.get_config(argv[1]) print("config file:") for item in config.items('config'): - print("\t%s" % str(item)) + print(("\t%s" % str(item))) parse_genofile(config, fetch_parameters(config)) def fetch_parameters(config): @@ -20,7 +20,7 @@ def fetch_parameters(config): config_dic['genofile'] = config.get('config', 'genofile') print("config dictionary:") for k, v in config_dic.items(): - print("\t%s: %s" % (k, v)) + print(("\t%s: %s" % (k, v))) return config_dic def parse_genofile(config, config_dic): @@ -43,9 +43,9 @@ def parse_genofile(config, config_dic): # print("geno file meta dictionary:") for k, v in meta_dic.items(): - print("\t%s: %s" % (k, v)) + print(("\t%s: %s" % (k, v))) # - print("geno file head:\n\t%s" % line) + print(("geno file head:\n\t%s" % line)) strainnames = line.split()[4:] config_dic['strains'] = datastructure.get_strains_bynames(inbredsetid=config_dic['inbredsetid'], strainnames=strainnames, updatestrainxref="yes") continue @@ -81,7 +81,7 @@ def check_or_insert_geno(config_dic, marker_dic): result = cursor.fetchone() if result: genoid = result[0] - print("get geno record: %d" % genoid) + print(("get geno record: %d" % genoid)) else: sql = """ INSERT INTO Geno @@ -95,7 +95,7 @@ def check_or_insert_geno(config_dic, marker_dic): cursor.execute(sql, (config_dic['speciesid'], marker_dic['locus'], marker_dic['locus'], marker_dic['chromosome'], marker_dic['mb'])) rowcount = cursor.rowcount genoid = con.insert_id() - print("INSERT INTO Geno: %d record: %d" % (rowcount, genoid)) + print(("INSERT INTO Geno: %d record: %d" % (rowcount, genoid))) return genoid def check_genoxref(config_dic, marker_dic): @@ -146,9 +146,9 @@ def insert_genoxref(config_dic, marker_dic): """ cursor.execute(sql, (config_dic['genofreezeid'], marker_dic['genoid'], config_dic['dataid'], marker_dic['cm'], 'N')) rowcount = cursor.rowcount - print("INSERT INTO GenoXRef: %d record" % (rowcount)) + print(("INSERT INTO GenoXRef: %d record" % (rowcount))) if __name__ == "__main__": - print("command line arguments:\n\t%s" % sys.argv) + print(("command line arguments:\n\t%s" % sys.argv)) main(sys.argv) print("exit successfully") diff --git a/scripts/maintenance/load_phenotypes.py b/scripts/maintenance/load_phenotypes.py index c3c6570b..61d527d4 100755 --- a/scripts/maintenance/load_phenotypes.py +++ b/scripts/maintenance/load_phenotypes.py @@ -7,31 +7,31 @@ import datastructure def main(argv): # config config = utilities.get_config(argv[1]) - print "config:" + print("config:") for item in config.items('config'): - print "\t%s" % (str(item)) + print(("\t%s" % (str(item)))) # var inbredsetid = config.get('config', 'inbredsetid') - print "inbredsetid: %s" % inbredsetid + print(("inbredsetid: %s" % inbredsetid)) species = datastructure.get_species(inbredsetid) speciesid = species[0] - print "speciesid: %s" % speciesid + print(("speciesid: %s" % speciesid)) dataid = datastructure.get_nextdataid_phenotype() - print "next data id: %s" % dataid + print(("next data id: %s" % dataid)) cursor, con = utilities.get_cursor() # datafile datafile = open(config.get('config', 'datafile'), 'r') phenotypedata = csv.reader(datafile, delimiter='\t', quotechar='"') phenotypedata_head = phenotypedata.next() - print "phenotypedata head:\n\t%s" % phenotypedata_head + print(("phenotypedata head:\n\t%s" % phenotypedata_head)) strainnames = phenotypedata_head[1:] strains = datastructure.get_strains_bynames(inbredsetid=inbredsetid, strainnames=strainnames, updatestrainxref="yes") # metafile metafile = open(config.get('config', 'metafile'), 'r') phenotypemeta = csv.reader(metafile, delimiter='\t', quotechar='"') phenotypemeta_head = phenotypemeta.next() - print "phenotypemeta head:\n\t%s" % phenotypemeta_head - print + print(("phenotypemeta head:\n\t%s" % phenotypemeta_head)) + print() # load for metarow in phenotypemeta: # @@ -67,7 +67,7 @@ def main(argv): )) rowcount = cursor.rowcount phenotypeid = con.insert_id() - print "INSERT INTO Phenotype: %d record: %d" % (rowcount, phenotypeid) + print(("INSERT INTO Phenotype: %d record: %d" % (rowcount, phenotypeid))) # Publication publicationid = None # reset pubmed_id = utilities.to_db_string(metarow[0], None) @@ -81,7 +81,7 @@ def main(argv): re = cursor.fetchone() if re: publicationid = re[0] - print "get Publication record: %d" % publicationid + print(("get Publication record: %d" % publicationid)) if not publicationid: sql = """ INSERT INTO Publication @@ -109,7 +109,7 @@ def main(argv): )) rowcount = cursor.rowcount publicationid = con.insert_id() - print "INSERT INTO Publication: %d record: %d" % (rowcount, publicationid) + print(("INSERT INTO Publication: %d record: %d" % (rowcount, publicationid))) # data for index, strain in enumerate(strains): # @@ -158,14 +158,14 @@ def main(argv): cursor.execute(sql, (inbredsetid, phenotypeid, publicationid, dataid, "")) rowcount = cursor.rowcount publishxrefid = con.insert_id() - print "INSERT INTO PublishXRef: %d record: %d" % (rowcount, publishxrefid) + print(("INSERT INTO PublishXRef: %d record: %d" % (rowcount, publishxrefid))) # for loop next dataid += 1 - print + print() # release con.close() if __name__ == "__main__": - print "command line arguments:\n\t%s" % sys.argv + print(("command line arguments:\n\t%s" % sys.argv)) main(sys.argv) - print "exit successfully" + print("exit successfully") diff --git a/scripts/maintenance/readProbeSetMean_v7.py b/scripts/maintenance/readProbeSetMean_v7.py index e9c8f25c..e7a4c826 100755 --- a/scripts/maintenance/readProbeSetMean_v7.py +++ b/scripts/maintenance/readProbeSetMean_v7.py @@ -42,9 +42,9 @@ try: con = MySQLdb.Connect(db='db_webqtl',host='localhost', user='username',passwd=passwd) db = con.cursor() - print "You have successfully connected to mysql.\n" + print("You have successfully connected to mysql.\n") except: - print "You entered incorrect password.\n" + print("You entered incorrect password.\n") sys.exit(0) time0 = time.time() @@ -55,7 +55,7 @@ time0 = time.time() # generate the gene list of expression data here # ######################################################################### -print 'Checking if each line have same number of members' +print('Checking if each line have same number of members') GeneList = [] isCont = 1 @@ -70,7 +70,7 @@ while line: line2 = string.split(string.strip(line),'\t') line2 = map(string.strip, line2) if len(line2) != nfield: - print "Error : " + line + print(("Error : " + line)) isCont = 0 GeneList.append(line2[0]) @@ -78,7 +78,7 @@ while line: kj+=1 if kj%100000 == 0: - print 'checked ',kj,' lines' + print(('checked ',kj,' lines')) GeneList = map(string.lower, GeneList) GeneList.sort() @@ -87,14 +87,14 @@ if isCont==0: sys.exit(0) -print 'used ',time.time()-time0,' seconds' +print(('used ',time.time()-time0,' seconds')) ######################################################################### # # Check if each strain exist in database # generate the string id list of expression data here # ######################################################################### -print 'Checking if each strain exist in database' +print('Checking if each strain exist in database') isCont = 1 fp.seek(0) @@ -109,20 +109,20 @@ for item in header: db.execute('select Id from Strain where Name = "%s"' % item) Ids.append(db.fetchall()[0][0]) except: - print item,'does not exist, check the if the strain name is correct' + print((item,'does not exist, check the if the strain name is correct')) isCont=0 if isCont==0: sys.exit(0) -print 'used ',time.time()-time0,' seconds' +print(('used ',time.time()-time0,' seconds')) ######################################################################## # # Check if each ProbeSet exist in database # ######################################################################## -print 'Check if each ProbeSet exist in database' +print('Check if each ProbeSet exist in database') ##---- find PID is name or target ----## line = fp.readline() @@ -146,7 +146,7 @@ Names = [] for item in results: Names.append(item[0]) -print Names +print(Names) Names = map(string.lower, Names) @@ -170,7 +170,7 @@ while x 0: DataValues = ','.join(DataValues) diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py index adffdca3..58108e03 100644 --- a/wqflask/run_gunicorn.py +++ b/wqflask/run_gunicorn.py @@ -7,7 +7,7 @@ # from flask import Flask # application = Flask(__name__) -print "===> Starting up Gunicorn process" +print("===> Starting up Gunicorn process") from wqflask import app from utility.startup_config import app_config diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py index 817284dd..42ead709 100644 --- a/wqflask/utility/startup_config.py +++ b/wqflask/utility/startup_config.py @@ -27,7 +27,7 @@ def app_config(): port = get_setting_int("SERVER_PORT") if get_setting_bool("USE_GN_SERVER"): - print("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]") + print(("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]")) import requests page = requests.get(get_setting("GN_SERVER_URL")) if page.status_code != 200: @@ -36,4 +36,4 @@ def app_config(): # import utility.elasticsearch_tools as es # es.test_elasticsearch_connection() - print("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL"))) + print(("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL")))) diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index db13b9d1..6285ea63 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -102,7 +102,7 @@ if use_dom_implementation<>0: from xml.dom import implementation from xml.dom.ext import PrettyPrint except: - raise exceptions.ImportError, "PyXML is required for using the dom implementation" + raise exceptions.ImportError("PyXML is required for using the dom implementation") #The implementation is used for the creating the XML document. #The prettyprint module is used for converting the xml document object to a xml file @@ -1018,12 +1018,12 @@ class drawing: PrettyPrint(root,f) f.close() except: - print "Cannot write SVG file: " + filename + print(("Cannot write SVG file: " + filename)) def validate(self): try: import xml.parsers.xmlproc.xmlval except: - raise exceptions.ImportError,'PyXml is required for validating SVG' + raise exceptions.ImportError('PyXml is required for validating SVG') svg=self.toXml() xv=xml.parsers.xmlproc.xmlval.XMLValidator() try: @@ -1031,7 +1031,7 @@ class drawing: except: raise Exception("SVG is not well formed, see messages above") else: - print "SVG well formed" + print("SVG well formed") if __name__=='__main__': @@ -1065,4 +1065,4 @@ if __name__=='__main__': s.addElement(c) d.setSVG(s) - print d.toXml() + print((d.toXml())) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 77db5d53..f790d424 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -214,20 +214,20 @@ ENDC = '\033[0m' def show_settings(): from utility.tools import LOG_LEVEL - print("Set global log level to "+BLUE+LOG_LEVEL+ENDC) + print(("Set global log level to "+BLUE+LOG_LEVEL+ENDC)) log_level = getattr(logging, LOG_LEVEL.upper()) logging.basicConfig(level=log_level) logger.info(OVERRIDES) logger.info(BLUE+"Mr. Mojo Risin 2"+ENDC) - print "runserver.py: ****** Webserver configuration - k,v pairs from app.config ******" keylist = app.config.keys() + print("runserver.py: ****** Webserver configuration - k,v pairs from app.config ******") keylist.sort() for k in keylist: try: - print("%s: %s%s%s%s" % (k,BLUE,BOLD,get_setting(k),ENDC)) + print(("%s: %s%s%s%s" % (k,BLUE,BOLD,get_setting(k),ENDC))) except: - print("%s: %s%s%s%s" % (k,GREEN,BOLD,app.config[k],ENDC)) + print(("%s: %s%s%s%s" % (k,GREEN,BOLD,app.config[k],ENDC))) # Cached values diff --git a/wqflask/wqflask/marker_regression/rqtl_mapping.py b/wqflask/wqflask/marker_regression/rqtl_mapping.py index c5590a85..0a5758af 100644 --- a/wqflask/wqflask/marker_regression/rqtl_mapping.py +++ b/wqflask/wqflask/marker_regression/rqtl_mapping.py @@ -42,7 +42,7 @@ def run_rqtl_geno(vals, samples, dataset, mapping_scale, method, model, permChec png = ro.r["png"] # Map the png function dev_off = ro.r["dev.off"] # Map the device off function - print(r_library("qtl")) # Load R/qtl + print((r_library("qtl"))) # Load R/qtl logger.info("QTL library loaded"); diff --git a/wqflask/wqflask/pbkdf2.py b/wqflask/wqflask/pbkdf2.py index f7f61a09..811c83b0 100644 --- a/wqflask/wqflask/pbkdf2.py +++ b/wqflask/wqflask/pbkdf2.py @@ -92,14 +92,14 @@ def test(): def check(data, salt, iterations, keylen, expected): rv = pbkdf2_hex(data, salt, iterations, keylen) if rv != expected: - print 'Test failed:' - print ' Expected: %s' % expected - print ' Got: %s' % rv - print ' Parameters:' - print ' data=%s' % data - print ' salt=%s' % salt - print ' iterations=%d' % iterations - print + print('Test failed:') + print((' Expected: %s' % expected)) + print((' Got: %s' % rv)) + print(' Parameters:') + print((' data=%s' % data)) + print((' salt=%s' % salt)) + print((' iterations=%d' % iterations)) + print() failed.append(1) # From RFC 6070 diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index dde22bf7..d67f1a2e 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -943,5 +943,5 @@ def json_default_handler(obj): # logger.info("Not going to serialize Dataset") # return None else: - raise TypeError, 'Object of type %s with value of %s is not JSON serializable' % ( - type(obj), repr(obj)) + raise TypeError('Object of type %s with value of %s is not JSON serializable' % ( + type(obj), repr(obj))) diff --git a/wqflask/wqflask/wgcna/wgcna_analysis.py b/wqflask/wqflask/wgcna/wgcna_analysis.py index 880a1cb2..d79ad6df 100644 --- a/wqflask/wqflask/wgcna/wgcna_analysis.py +++ b/wqflask/wqflask/wgcna/wgcna_analysis.py @@ -60,7 +60,7 @@ class WGCNA(object): print("Starting WGCNA analysis on dataset") self.r_enableWGCNAThreads() # Enable multi threading self.trait_db_list = [trait.strip() for trait in requestform['trait_list'].split(',')] - print("Retrieved phenotype data from database", requestform['trait_list']) + print(("Retrieved phenotype data from database", requestform['trait_list'])) helper_functions.get_trait_db_obs(self, self.trait_db_list) self.input = {} # self.input contains the phenotype values we need to send to R @@ -101,13 +101,13 @@ class WGCNA(object): if requestform.get('SoftThresholds') is not None: powers = [int(threshold.strip()) for threshold in requestform['SoftThresholds'].rstrip().split(",")] rpow = r_unlist(r_c(powers)) - print "SoftThresholds: {} == {}".format(powers, rpow) + print(("SoftThresholds: {} == {}".format(powers, rpow))) self.sft = self.r_pickSoftThreshold(rM, powerVector = rpow, verbose = 5) - print "PowerEstimate: {}".format(self.sft[0]) + print(("PowerEstimate: {}".format(self.sft[0]))) self.results['PowerEstimate'] = self.sft[0] if self.sft[0][0] is ri.NA_Integer: - print "No power is suitable for the analysis, just use 1" + print("No power is suitable for the analysis, just use 1") self.results['Power'] = 1 # No power could be estimated else: self.results['Power'] = self.sft[0][0] # Use the estimated power @@ -122,7 +122,7 @@ class WGCNA(object): self.results['network'] = network # How many modules and how many gene per module ? - print "WGCNA found {} modules".format(r_table(network[1])) + print(("WGCNA found {} modules".format(r_table(network[1])))) self.results['nmod'] = r_length(r_table(network[1]))[0] # The iconic WCGNA plot of the modules in the hanging tree @@ -135,7 +135,7 @@ class WGCNA(object): sys.stdout.flush() def render_image(self, results): - print("pre-loading imgage results:", self.results['imgloc']) + print(("pre-loading imgage results:", self.results['imgloc'])) imgfile = open(self.results['imgloc'], 'rb') imgdata = imgfile.read() imgB64 = imgdata.encode("base64") -- cgit v1.2.3 From acdc611247c8eaccbba3dec00ad640e10a4c99b1 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 17 Aug 2020 21:45:04 +0300 Subject: Replace "<>" with "!=" * wqflask/utility/svg.py: Use "!=". The operator, "<>" is removed in Python3 --- wqflask/utility/svg.py | 196 ++++++++++++++++++++++++------------------------- 1 file changed, 98 insertions(+), 98 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index 6285ea63..f737d2f2 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -97,7 +97,7 @@ use_dom_implementation=0 import exceptions -if use_dom_implementation<>0: +if use_dom_implementation!=0: try: from xml.dom import implementation from xml.dom.ext import PrettyPrint @@ -398,22 +398,22 @@ class rect(SVGelement): """ def __init__(self,x=None,y=None,width=None,height=None,fill=None,stroke=None,stroke_width=None,**args): if width==None or height==None: - if width<>None: raise ValueError, 'height is required' - if height<>None: raise ValueError, 'width is required' + if width!=None: + if height!=None: else: raise ValueError, 'both height and width are required' SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) - if x<>None: + if x!=None: self.attributes['x']=x - if y<>None: + if y!=None: self.attributes['y']=y - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width class ellipse(SVGelement): @@ -423,22 +423,22 @@ class ellipse(SVGelement): """ def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args): if rx==None or ry== None: - if rx<>None: raise ValueError, 'rx is required' - if ry<>None: raise ValueError, 'ry is required' + if rx!=None: + if ry!=None: else: raise ValueError, 'both rx and ry are required' SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) - if cx<>None: + if cx!=None: self.attributes['cx']=cx - if cy<>None: + if cy!=None: self.attributes['cy']=cy - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width @@ -451,15 +451,15 @@ class circle(SVGelement): if r==None: raise ValueError, 'r is required' SVGelement.__init__(self,'circle',{'r':r},**args) - if cx<>None: + if cx!=None: self.attributes['cx']=cx - if cy<>None: + if cy!=None: self.attributes['cy']=cy - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width class point(circle): @@ -478,17 +478,17 @@ class line(SVGelement): """ def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args): SVGelement.__init__(self,'line',**args) - if x1<>None: + if x1!=None: self.attributes['x1']=x1 - if y1<>None: + if y1!=None: self.attributes['y1']=y1 - if x2<>None: + if x2!=None: self.attributes['x2']=x2 - if y2<>None: + if y2!=None: self.attributes['y2']=y2 - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke class polyline(SVGelement): @@ -498,11 +498,11 @@ class polyline(SVGelement): """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): SVGelement.__init__(self,'polyline',{'points':_xypointlist(points)},**args) - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke class polygon(SVGelement): @@ -512,11 +512,11 @@ class polygon(SVGelement): """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): SVGelement.__init__(self,'polygon',{'points':_xypointlist(points)},**args) - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke class path(SVGelement): @@ -526,13 +526,13 @@ class path(SVGelement): """ def __init__(self,pathdata,fill=None,stroke=None,stroke_width=None,id=None,**args): SVGelement.__init__(self,'path',{'d':str(pathdata)},**args) - if stroke<>None: + if stroke!=None: self.attributes['stroke']=stroke - if fill<>None: + if fill!=None: self.attributes['fill']=fill - if stroke_width<>None: + if stroke_width!=None: self.attributes['stroke-width']=stroke_width - if id<>None: + if id!=None: self.attributes['id']=id @@ -543,17 +543,17 @@ class text(SVGelement): """ def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args): SVGelement.__init__(self,'text',**args) - if x<>None: + if x!=None: self.attributes['x']=x - if y<>None: + if y!=None: self.attributes['y']=y - if font_size<>None: + if font_size!=None: self.attributes['font-size']=font_size - if font_family<>None: + if font_family!=None: self.attributes['font-family']=font_family - if text<>None: + if text!=None: self.text=text - if text_anchor<>None: + if text_anchor!=None: self.attributes['text-anchor']=text_anchor @@ -564,7 +564,7 @@ class textpath(SVGelement): """ def __init__(self,link,text=None,**args): SVGelement.__init__(self,'textPath',{'xlink:href':link},**args) - if text<>None: + if text!=None: self.text=text class pattern(SVGelement): @@ -576,15 +576,15 @@ class pattern(SVGelement): """ def __init__(self,x=None,y=None,width=None,height=None,patternUnits=None,**args): SVGelement.__init__(self,'pattern',**args) - if x<>None: + if x!=None: self.attributes['x']=x - if y<>None: + if y!=None: self.attributes['y']=y - if width<>None: + if width!=None: self.attributes['width']=width - if height<>None: + if height!=None: self.attributes['height']=height - if patternUnits<>None: + if patternUnits!=None: self.attributes['patternUnits']=patternUnits class title(SVGelement): @@ -595,7 +595,7 @@ class title(SVGelement): """ def __init__(self,text=None,**args): SVGelement.__init__(self,'title',**args) - if text<>None: + if text!=None: self.text=text class description(SVGelement): @@ -606,7 +606,7 @@ class description(SVGelement): """ def __init__(self,text=None,**args): SVGelement.__init__(self,'desc',**args) - if text<>None: + if text!=None: self.text=text class lineargradient(SVGelement): @@ -617,15 +617,15 @@ class lineargradient(SVGelement): """ def __init__(self,x1=None,y1=None,x2=None,y2=None,id=None,**args): SVGelement.__init__(self,'linearGradient',**args) - if x1<>None: + if x1!=None: self.attributes['x1']=x1 - if y1<>None: + if y1!=None: self.attributes['y1']=y1 - if x2<>None: + if x2!=None: self.attributes['x2']=x2 - if y2<>None: + if y2!=None: self.attributes['y2']=y2 - if id<>None: + if id!=None: self.attributes['id']=id class radialgradient(SVGelement): @@ -636,17 +636,17 @@ class radialgradient(SVGelement): """ def __init__(self,cx=None,cy=None,r=None,fx=None,fy=None,id=None,**args): SVGelement.__init__(self,'radialGradient',**args) - if cx<>None: + if cx!=None: self.attributes['cx']=cx - if cy<>None: + if cy!=None: self.attributes['cy']=cy - if r<>None: + if r!=None: self.attributes['r']=r - if fx<>None: + if fx!=None: self.attributes['fx']=fx - if fy<>None: + if fy!=None: self.attributes['fy']=fy - if id<>None: + if id!=None: self.attributes['id']=id class stop(SVGelement): @@ -656,7 +656,7 @@ class stop(SVGelement): """ def __init__(self,offset,stop_color=None,**args): SVGelement.__init__(self,'stop',{'offset':offset},**args) - if stop_color<>None: + if stop_color!=None: self.attributes['stop-color']=stop_color class style(SVGelement): @@ -675,16 +675,16 @@ class image(SVGelement): """ def __init__(self,url,x=None,y=None,width=None,height=None,**args): if width==None or height==None: - if width<>None: raise ValueError, 'height is required' - if height<>None: raise ValueError, 'width is required' + if width!=None: + if height!=None: else: raise ValueError, 'both height and width are required' SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args) - if x<>None: + if x!=None: self.attributes['x']=x - if y<>None: + if y!=None: self.attributes['y']=y class cursor(SVGelement): @@ -704,17 +704,17 @@ class marker(SVGelement): """ def __init__(self,id=None,viewBox=None,refx=None,refy=None,markerWidth=None,markerHeight=None,**args): SVGelement.__init__(self,'marker',**args) - if id<>None: + if id!=None: self.attributes['id']=id - if viewBox<>None: + if viewBox!=None: self.attributes['viewBox']=_viewboxlist(viewBox) - if refx<>None: + if refx!=None: self.attributes['refX']=refx - if refy<>None: + if refy!=None: self.attributes['refY']=refy - if markerWidth<>None: + if markerWidth!=None: self.attributes['markerWidth']=markerWidth - if markerHeight<>None: + if markerHeight!=None: self.attributes['markerHeight']=markerHeight class group(SVGelement): @@ -725,7 +725,7 @@ class group(SVGelement): """ def __init__(self,id=None,**args): SVGelement.__init__(self,'g',**args) - if id<>None: + if id!=None: self.attributes['id']=id class symbol(SVGelement): @@ -739,9 +739,9 @@ class symbol(SVGelement): def __init__(self,id=None,viewBox=None,**args): SVGelement.__init__(self,'symbol',**args) - if id<>None: + if id!=None: self.attributes['id']=id - if viewBox<>None: + if viewBox!=None: self.attributes['viewBox']=_viewboxlist(viewBox) class defs(SVGelement): @@ -770,14 +770,14 @@ class use(SVGelement): """ def __init__(self,link,x=None,y=None,width=None,height=None,**args): SVGelement.__init__(self,'use',{'xlink:href':link},**args) - if x<>None: + if x!=None: self.attributes['x']=x - if y<>None: + if y!=None: self.attributes['y']=y - if width<>None: + if width!=None: self.attributes['width']=width - if height<>None: + if height!=None: self.attributes['height']=height @@ -796,7 +796,7 @@ class view(SVGelement): a view can be used to create a view with different attributes""" def __init__(self,id=None,**args): SVGelement.__init__(self,'view',**args) - if id<>None: + if id!=None: self.attributes['id']=id class script(SVGelement): @@ -815,11 +815,11 @@ class animate(SVGelement): """ def __init__(self,attribute,fr=None,to=None,dur=None,**args): SVGelement.__init__(self,'animate',{'attributeName':attribute},**args) - if fr<>None: + if fr!=None: self.attributes['from']=fr - if to<>None: + if to!=None: self.attributes['to']=to - if dur<>None: + if dur!=None: self.attributes['dur']=dur class animateMotion(SVGelement): @@ -829,9 +829,9 @@ class animateMotion(SVGelement): """ def __init__(self,pathdata,dur,**args): SVGelement.__init__(self,'animateMotion',**args) - if pathdata<>None: + if pathdata!=None: self.attributes['path']=str(pathdata) - if dur<>None: + if dur!=None: self.attributes['dur']=dur class animateTransform(SVGelement): @@ -842,13 +842,13 @@ class animateTransform(SVGelement): def __init__(self,type=None,fr=None,to=None,dur=None,**args): SVGelement.__init__(self,'animateTransform',{'attributeName':'transform'},**args) #As far as I know the attributeName is always transform - if type<>None: + if type!=None: self.attributes['type']=type - if fr<>None: + if fr!=None: self.attributes['from']=fr - if to<>None: + if to!=None: self.attributes['to']=to - if dur<>None: + if dur!=None: self.attributes['dur']=dur class animateColor(SVGelement): """ac=animateColor(attribute,type,from,to,dur,**args) @@ -857,13 +857,13 @@ class animateColor(SVGelement): """ def __init__(self,attribute,type=None,fr=None,to=None,dur=None,**args): SVGelement.__init__(self,'animateColor',{'attributeName':attribute},**args) - if type<>None: + if type!=None: self.attributes['type']=type - if fr<>None: + if fr!=None: self.attributes['from']=fr - if to<>None: + if to!=None: self.attributes['to']=to - if dur<>None: + if dur!=None: self.attributes['dur']=dur class set(SVGelement): """st=set(attribute,to,during,**args) @@ -872,9 +872,9 @@ class set(SVGelement): """ def __init__(self,attribute,to=None,dur=None,**args): SVGelement.__init__(self,'set',{'attributeName':attribute},**args) - if to<>None: + if to!=None: self.attributes['to']=to - if dur<>None: + if dur!=None: self.attributes['dur']=dur @@ -896,11 +896,11 @@ class svg(SVGelement): """ def __init__(self,viewBox=None, width=None, height=None,**args): SVGelement.__init__(self,'svg',**args) - if viewBox<>None: + if viewBox!=None: self.attributes['viewBox']=_viewboxlist(viewBox) - if width<>None: + if width!=None: self.attributes['width']=width - if height<>None: + if height!=None: self.attributes['height']=height self.namespace="http://www.w3.org/2000/svg" -- cgit v1.2.3 From 4e10f4bd8fb902810ee033abb8d509ab641308e1 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 18 Aug 2020 17:09:51 +0300 Subject: Apply pep8 * wqflask/utility/svg.py: Apply pep8 to fix indentation error when running `2to3-3.8 -w .`: ```` RefactoringTool: Can't parse ./wqflask/utility/svg.py: IndentationError: unindent does not match any outer indentation level (, line 403) ```` --- wqflask/utility/svg.py | 321 ++++++++++++++++++++++++++++--------------------- 1 file changed, 184 insertions(+), 137 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index f737d2f2..c850feb8 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -25,54 +25,56 @@ # Last updated by GeneNetwork Core Team 2010/10/20 #!/usr/bin/env python -##Copyright (c) 2002, Fedor Baart & Hans de Wit (Stichting Farmaceutische Kengetallen) -##All rights reserved. +# Copyright (c) 2002, Fedor Baart & Hans de Wit (Stichting Farmaceutische Kengetallen) +# All rights reserved. ## -##Redistribution and use in source and binary forms, with or without modification, -##are permitted provided that the following conditions are met: +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: ## -##Redistributions of source code must retain the above copyright notice, this -##list of conditions and the following disclaimer. +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. ## -##Redistributions in binary form must reproduce the above copyright notice, -##this list of conditions and the following disclaimer in the documentation and/or -##other materials provided with the distribution. +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. ## -##Neither the name of the Stichting Farmaceutische Kengetallen nor the names of -##its contributors may be used to endorse or promote products derived from this -##software without specific prior written permission. +# Neither the name of the Stichting Farmaceutische Kengetallen nor the names of +# its contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. ## -##THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -##AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -##IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -##DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -##FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -##DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -##SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -##CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -##OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -##OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Thanks to Gerald Rosennfellner for his help and useful comments. -##Thanks to Gerald Rosennfellner for his help and useful comments. - -__doc__="""Use SVGdraw to generate your SVGdrawings. +import sys +import exceptions +__doc__ = """Use SVGdraw to generate your SVGdrawings. SVGdraw uses an object model drawing and a method toXML to create SVG graphics by using easy to use classes and methods usualy you start by creating a drawing eg d=drawing() - #then you create a SVG root element + # then you create a SVG root element s=svg() - #then you add some elements eg a circle and add it to the svg root element + # then you add some elements eg a circle and add it to the svg root element c=circle() - #you can supply attributes by using named arguments. + # you can supply attributes by using named arguments. c=circle(fill='red',stroke='blue') - #or by updating the attributes attribute: + # or by updating the attributes attribute: c.attributes['stroke-width']=1 s.addElement(c) - #then you add the svg root element to the drawing + # then you add the svg root element to the drawing d.setSVG(s) - #and finaly you xmlify the drawing + # and finaly you xmlify the drawing d.toXml() @@ -82,7 +84,7 @@ This module was created using the SVG specification of www.w3c.org and the O'Reilly (www.oreilly.com) python books as information sources. A svg viewer is available from www.adobe.com""" -__version__="1.0" +__version__ = "1.0" # there are two possibilities to generate svg: # via a dom implementation and directly using text strings @@ -93,33 +95,34 @@ __version__="1.0" # Note that PyXML is required for using the dom implementation. # It is also possible to use the standard minidom. But I didn't try that one. # Anyway the text based approach is about 60 times faster than using the full dom implementation. -use_dom_implementation=0 +use_dom_implementation = 0 -import exceptions -if use_dom_implementation!=0: +if use_dom_implementation != 0: try: from xml.dom import implementation from xml.dom.ext import PrettyPrint except: - raise exceptions.ImportError("PyXML is required for using the dom implementation") -#The implementation is used for the creating the XML document. -#The prettyprint module is used for converting the xml document object to a xml file + raise exceptions.ImportError( + "PyXML is required for using the dom implementation") +# The implementation is used for the creating the XML document. +# The prettyprint module is used for converting the xml document object to a xml file + +assert sys.version_info[0] >= 2 +if sys.version_info[1] < 2: + True = 1 + False = 0 + file = open + +sys.setrecursionlimit = 50 +# The recursion limit is set conservative so mistakes like s=svg() s.addElement(s) +# won't eat up too much processor time. + +# the following code is pasted form xml.sax.saxutils +# it makes it possible to run the code without the xml sax package installed +# To make it possible to have in your text elements, it is necessary to escape the texts + -import sys -assert sys.version_info[0]>=2 -if sys.version_info[1]<2: - True=1 - False=0 - file=open - -sys.setrecursionlimit=50 -#The recursion limit is set conservative so mistakes like s=svg() s.addElement(s) -#won't eat up too much processor time. - -#the following code is pasted form xml.sax.saxutils -#it makes it possible to run the code without the xml sax package installed -#To make it possible to have in your text elements, it is necessary to escape the texts def _escape(data, entities={}): """Escape &, <, and > in a string of data. @@ -127,13 +130,14 @@ def _escape(data, entities={}): the optional entities parameter. The keys and values must all be strings; each key will be replaced with its corresponding value. """ - #data = data.replace("&", "&") + # data = data.replace("&", "&") data = data.replace("<", "<") data = data.replace(">", ">") for chars, entity in entities.items(): data = data.replace(chars, entity) return data + def _quoteattr(data, entities={}): """Escape and quote an attribute value. @@ -156,96 +160,121 @@ def _quoteattr(data, entities={}): return data - def _xypointlist(a): """formats a list of xy pairs""" - s='' - for e in a: #this could be done more elegant - s+=str(e)[1:-1] +' ' + s = '' + for e in a: # this could be done more elegant + s += str(e)[1:-1] + ' ' return s + def _viewboxlist(a): """formats a tuple""" - s='' + s = '' for e in a: - s+=str(e)+' ' + s += str(e)+' ' return s + def _pointlist(a): """formats a list of numbers""" return str(a)[1:-1] + class pathdata: """class used to create a pathdata object which can be used for a path. although most methods are pretty straightforward it might be useful to look at the SVG specification.""" - #I didn't test the methods below. - def __init__(self,x=None,y=None): - self.path=[] + # I didn't test the methods below. + + def __init__(self, x=None, y=None): + self.path = [] if x is not None and y is not None: self.path.append('M '+str(x)+' '+str(y)) + def closepath(self): """ends the path""" self.path.append('z') - def move(self,x,y): + + def move(self, x, y): """move to absolute""" self.path.append('M '+str(x)+' '+str(y)) - def relmove(self,x,y): + + def relmove(self, x, y): """move to relative""" self.path.append('m '+str(x)+' '+str(y)) - def line(self,x,y): + + def line(self, x, y): """line to absolute""" self.path.append('L '+str(x)+' '+str(y)) - def relline(self,x,y): + + def relline(self, x, y): """line to relative""" self.path.append('l '+str(x)+' '+str(y)) - def hline(self,x): + + def hline(self, x): """horizontal line to absolute""" self.path.append('H'+str(x)) - def relhline(self,x): + + def relhline(self, x): """horizontal line to relative""" self.path.append('h'+str(x)) - def vline(self,y): + + def vline(self, y): """verical line to absolute""" self.path.append('V'+str(y)) - def relvline(self,y): + + def relvline(self, y): """vertical line to relative""" self.path.append('v'+str(y)) - def bezier(self,x1,y1,x2,y2,x,y): + + def bezier(self, x1, y1, x2, y2, x, y): """bezier with xy1 and xy2 to xy absolut""" - self.path.append('C'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def relbezier(self,x1,y1,x2,y2,x,y): + self.path.append('C'+str(x1)+','+str(y1)+' '+str(x2) + + ','+str(y2)+' '+str(x)+','+str(y)) + + def relbezier(self, x1, y1, x2, y2, x, y): """bezier with xy1 and xy2 to xy relative""" - self.path.append('c'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def smbezier(self,x2,y2,x,y): + self.path.append('c'+str(x1)+','+str(y1)+' '+str(x2) + + ','+str(y2)+' '+str(x)+','+str(y)) + + def smbezier(self, x2, y2, x, y): """smooth bezier with xy2 to xy absolut""" self.path.append('S'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def relsmbezier(self,x2,y2,x,y): + + def relsmbezier(self, x2, y2, x, y): """smooth bezier with xy2 to xy relative""" self.path.append('s'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) - def qbezier(self,x1,y1,x,y): + + def qbezier(self, x1, y1, x, y): """quadratic bezier with xy1 to xy absolut""" self.path.append('Q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) - def relqbezier(self,x1,y1,x,y): + + def relqbezier(self, x1, y1, x, y): """quadratic bezier with xy1 to xy relative""" self.path.append('q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) - def smqbezier(self,x,y): + + def smqbezier(self, x, y): """smooth quadratic bezier to xy absolut""" self.path.append('T'+str(x)+','+str(y)) - def relsmqbezier(self,x,y): + + def relsmqbezier(self, x, y): """smooth quadratic bezier to xy relative""" self.path.append('t'+str(x)+','+str(y)) - def ellarc(self,rx,ry,xrot,laf,sf,x,y): + + def ellarc(self, rx, ry, xrot, laf, sf, x, y): """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy absolut""" - self.path.append('A'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) - def relellarc(self,rx,ry,xrot,laf,sf,x,y): + self.path.append('A'+str(rx)+','+str(ry)+' '+str(xrot) + + ' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) + + def relellarc(self, rx, ry, xrot, laf, sf, x, y): """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy relative""" - self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) + self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot) + + ' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) + def __repr__(self): return ' '.join(self.path) - - class SVGelement: """SVGelement(type,attributes,elements,text,namespace,**args) Creates a arbitrary svg element and is intended to be subclassed not used on its own. @@ -256,52 +285,56 @@ class SVGelement: namespace. Note the elements==None, if elements = None:self.elements=[] construction. This is done because if you default to elements=[] every object has a reference to the same empty list.""" - def __init__(self,type='',attributes=None,elements=None,text='',namespace='',cdata=None, **args): - self.type=type - if attributes==None: - self.attributes={} + + def __init__(self, type='', attributes=None, elements=None, text='', namespace='', cdata=None, **args): + self.type = type + if attributes == None: + self.attributes = {} else: - self.attributes=attributes - if elements==None: - self.elements=[] + self.attributes = attributes + if elements == None: + self.elements = [] else: - self.elements=elements - self.text=text - self.namespace=namespace - self.cdata=cdata + self.elements = elements + self.text = text + self.namespace = namespace + self.cdata = cdata for arg in args.keys(): arg2 = arg.replace("__", ":") arg2 = arg2.replace("_", "-") - self.attributes[arg2]=args[arg] - def addElement(self,SVGelement): + self.attributes[arg2] = args[arg] + + def addElement(self, SVGelement): """adds an element to a SVGelement SVGelement.addElement(SVGelement) """ self.elements.append(SVGelement) - def toXml(self,level,f): + def toXml(self, level, f): f.write('\t'*level) f.write('<'+self.type) for attkey in self.attributes.keys(): - f.write(' '+_escape(str(attkey))+'='+_quoteattr(str(self.attributes[attkey]))) + f.write(' '+_escape(str(attkey))+'=' + + _quoteattr(str(self.attributes[attkey]))) if self.namespace: - f.write(' xmlns="'+ _escape(str(self.namespace))+'" xmlns:xlink="http://www.w3.org/1999/xlink"') + f.write(' xmlns="' + _escape(str(self.namespace)) + + '" xmlns:xlink="http://www.w3.org/1999/xlink"') if self.elements or self.text or self.cdata: f.write('>') if self.elements: f.write('\n') for element in self.elements: - element.toXml(level+1,f) + element.toXml(level+1, f) if self.cdata: f.write('\n'+'\t'*(level+1)+'\n') if self.text: - if type(self.text)==type(''): #If the text is only text + if type(self.text) == type(''): # If the text is only text f.write(_escape(str(self.text))) - else: #If the text is a spannedtext class + else: # If the text is a spannedtext class f.write(str(self.text)) if self.elements: f.write('\t'*level+'\n') @@ -312,6 +345,7 @@ class SVGelement: else: f.write('/>\n') + class tspan(SVGelement): """ts=tspan(text='',**args) @@ -323,19 +357,22 @@ class tspan(SVGelement): st.addtspan(ts) t=text(3,5,st) """ - def __init__(self,text=None,**args): - SVGelement.__init__(self,'tspan',**args) - if self.text<>None: - self.text=text + + def __init__(self, text=None, **args): + SVGelement.__init__(self, 'tspan', **args) + if self.text <> None: + self.text = text + def __repr__(self): - s=" --- scripts/maintenance/QTL_Reaper_v6.py | 2 +- scripts/maintenance/readProbeSetMean_v7.py | 16 ++++++++-------- scripts/maintenance/readProbeSetSE_v7.py | 16 ++++++++-------- test/requests/link_checker.py | 3 +-- wqflask/utility/webqtlUtil.py | 2 +- wqflask/wqflask/api/router.py | 2 +- wqflask/wqflask/correlation_matrix/show_corr_matrix.py | 4 ++-- wqflask/wqflask/export_traits.py | 2 +- wqflask/wqflask/interval_analyst/GeneUtil.py | 2 +- .../wqflask/marker_regression/display_mapping_results.py | 10 +++++----- wqflask/wqflask/marker_regression/plink_mapping.py | 4 ++-- wqflask/wqflask/pbkdf2.py | 2 +- wqflask/wqflask/snp_browser/snp_browser.py | 6 +++--- 13 files changed, 35 insertions(+), 36 deletions(-) (limited to 'wqflask/utility') diff --git a/scripts/maintenance/QTL_Reaper_v6.py b/scripts/maintenance/QTL_Reaper_v6.py index 7fb56eca..2fbeb53b 100755 --- a/scripts/maintenance/QTL_Reaper_v6.py +++ b/scripts/maintenance/QTL_Reaper_v6.py @@ -23,7 +23,7 @@ for item in results: ProbeSetFreezeIds=sys.argv[1:] if ProbeSetFreezeIds: #####convert the Ids to integer - ProbeSetFreezeIds=map(int, ProbeSetFreezeIds) + ProbeSetFreezeIds=list(map(int, ProbeSetFreezeIds)) else: #####get all of the dataset that need be updated diff --git a/scripts/maintenance/readProbeSetMean_v7.py b/scripts/maintenance/readProbeSetMean_v7.py index fea26731..97767715 100755 --- a/scripts/maintenance/readProbeSetMean_v7.py +++ b/scripts/maintenance/readProbeSetMean_v7.py @@ -61,14 +61,14 @@ GeneList = [] isCont = 1 header = fp.readline() header = string.split(string.strip(header),'\t') -header = map(string.strip, header) +header = list(map(string.strip, header)) nfield = len(header) line = fp.readline() kj=0 while line: line2 = string.split(string.strip(line),'\t') - line2 = map(string.strip, line2) + line2 = list(map(string.strip, line2)) if len(line2) != nfield: print(("Error : " + line)) isCont = 0 @@ -80,7 +80,7 @@ while line: if kj%100000 == 0: print(('checked ',kj,' lines')) -GeneList = map(string.lower, GeneList) +GeneList = list(map(string.lower, GeneList)) GeneList.sort() if isCont==0: @@ -100,8 +100,8 @@ isCont = 1 fp.seek(0) header = fp.readline() header = string.split(string.strip(header),'\t') -header = map(string.strip, header) -header = map(translateAlias, header) +header = list(map(string.strip, header)) +header = list(map(translateAlias, header)) header = header[dataStart:] Ids = [] for item in header: @@ -128,7 +128,7 @@ print('Check if each ProbeSet exist in database') line = fp.readline() line = fp.readline() line2 = string.split(string.strip(line),'\t') -line2 = map(string.strip, line2) +line2 = list(map(string.strip, line2)) PId = line2[0] db.execute('select Id from ProbeSet where Name="%s" and ChipId=%d' % (PId, GeneChipId) ) @@ -148,7 +148,7 @@ for item in results: print(Names) -Names = map(string.lower, Names) +Names = list(map(string.lower, Names)) Names.sort() # -- Fixed the lower case problem of ProbeSets affx-mur_b2_at doesn't exist --# @@ -223,7 +223,7 @@ values1 = [] values2 = [] while line: line2 = string.split(string.strip(line),'\t') - line2 = map(string.strip, line2) + line2 = list(map(string.strip, line2)) PId = line2[0] recordId = NameIds[PId] diff --git a/scripts/maintenance/readProbeSetSE_v7.py b/scripts/maintenance/readProbeSetSE_v7.py index 79ed455f..7b2fee87 100755 --- a/scripts/maintenance/readProbeSetSE_v7.py +++ b/scripts/maintenance/readProbeSetSE_v7.py @@ -72,14 +72,14 @@ GeneList = [] isCont = 1 header = fp.readline() header = string.split(string.strip(header), '\t') -header = map(string.strip, header) +header = list(map(string.strip, header)) nfield = len(header) line = fp.readline() kj = 0 while line: line2 = string.split(string.strip(line), '\t') - line2 = map(string.strip, line2) + line2 = list(map(string.strip, line2)) if len(line2) != nfield: isCont = 0 print(("Error : " + line)) @@ -91,7 +91,7 @@ while line: if kj % 100000 == 0: print(('checked ', kj, ' lines')) -GeneList = map(string.lower, GeneList) +GeneList = list(map(string.lower, GeneList)) GeneList.sort() if isCont == 0: @@ -111,8 +111,8 @@ isCont = 1 fp.seek(0) header = fp.readline() header = string.split(string.strip(header), '\t') -header = map(string.strip, header) -header = map(translateAlias, header) +header = list(map(string.strip, header)) +header = list(map(translateAlias, header)) header = header[dataStart:] Ids = [] for item in header: @@ -139,7 +139,7 @@ print('Check if each ProbeSet exist in database') line = fp.readline() line = fp.readline() line2 = string.split(string.strip(line), '\t') -line2 = map(string.strip, line2) +line2 = list(map(string.strip, line2)) PId = line2[0] db.execute('select Id from ProbeSet where Name="%s" and ChipId=%d' % @@ -158,7 +158,7 @@ results = db.fetchall() Names = [] for item in results: Names.append(item[0]) - Names = map(string.lower, Names) + Names = list(map(string.lower, Names)) Names.sort() # -- Fixed the lower case problem of ProbeSets affx-mur_b2_at doesn't exist --# ##---- compare genelist with names ----## @@ -220,7 +220,7 @@ line = fp.readline() kj = 0 while line: line2 = string.split(string.strip(line), '\t') - line2 = map(string.strip, line2) + line2 = list(map(string.strip, line2)) CellId = line2[0] if not ProbeNameId.has_key(CellId): diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 715f330c..df4d32d8 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -27,8 +27,7 @@ def get_links(doc): lambda x: not ( is_root_link(x) or is_mailto_link(x)) - , map(lambda y: y.get("href") - , doc.cssselect("a"))) + , [y.get("href") for y in doc.cssselect("a")]) def verify_link(link): if link[0] == "#": diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py index 53661ae4..79991149 100644 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -107,7 +107,7 @@ def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users) if webqtlConfig.USERDICT[privilege] > webqtlConfig.USERDICT['user']: access_to_confidential_phenotype_trait = 1 else: - AuthorizedUsersList=map(string.strip, string.split(authorized_users, ',')) + AuthorizedUsersList=list(map(string.strip, string.split(authorized_users, ','))) if AuthorizedUsersList.__contains__(userName): access_to_confidential_phenotype_trait = 1 return access_to_confidential_phenotype_trait \ No newline at end of file diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index 6324cabe..3fa1d5ba 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -517,7 +517,7 @@ def all_sample_data(dataset_name, file_format = "csv"): line_list.append("x") results_list.append(line_list) - results_list = map(list, zip(*results_list)) + results_list = list(map(list, zip(*results_list))) si = StringIO.StringIO() csv_writer = csv.writer(si) diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 0ac94139..a912344f 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -278,7 +278,7 @@ def zScore(trait_data_array): stdev = math.sqrt(var/(N-1)) if stdev == 0: stdev = 1e-100 - data2 = map(lambda x:(x-mean)/stdev,data) + data2 = [(x-mean)/stdev for x in data] trait_data_array[i] = data2 i += 1 return trait_data_array @@ -299,7 +299,7 @@ def sortEigenVectors(vector): A.append(item[0]) B.append(item[1]) sum = reduce(lambda x,y: x+y, A, 0.0) - A = map(lambda x:x*100.0/sum, A) + A = [x*100.0/sum for x in A] return [A, B] except: return [] \ No newline at end of file diff --git a/wqflask/wqflask/export_traits.py b/wqflask/wqflask/export_traits.py index 3272c03d..6646cc36 100644 --- a/wqflask/wqflask/export_traits.py +++ b/wqflask/wqflask/export_traits.py @@ -122,7 +122,7 @@ def export_search_results_csv(targs): csv_rows.append(row_contents) - csv_rows = map(list, itertools.izip_longest(*[row for row in csv_rows])) + csv_rows = list(map(list, itertools.izip_longest(*[row for row in csv_rows]))) writer.writerows(csv_rows) csv_data = buff.getvalue() buff.close() diff --git a/wqflask/wqflask/interval_analyst/GeneUtil.py b/wqflask/wqflask/interval_analyst/GeneUtil.py index 2c60dd70..273168a8 100644 --- a/wqflask/wqflask/interval_analyst/GeneUtil.py +++ b/wqflask/wqflask/interval_analyst/GeneUtil.py @@ -24,7 +24,7 @@ def loadGenes(chrName, diffCol, startMb, endMb, species='mouse'): ##List current Species and other Species speciesId = speciesDict[species] - otherSpecies = map(lambda X: [X, speciesDict[X]], speciesDict.keys()) + otherSpecies = [[X, speciesDict[X]] for X in speciesDict.keys()] otherSpecies.remove([species, speciesId]) results = g.db.execute(""" diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index bda899fb..7b6e70d2 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -389,9 +389,9 @@ class DisplayMappingResults(object): Chr_Length.Name in (%s) Order by Chr_Length.OrderId - """ % (self.dataset.group.name, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", "))) + """ % (self.dataset.group.name, string.join(["'%s'" % X[0] for X in self.ChrList[1:]], ", "))) - self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList) + self.ChrLengthMbList = [x[0]/1000000.0 for x in self.ChrLengthMbList] self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) if self.ChrLengthMbList: self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval @@ -1147,8 +1147,8 @@ class DisplayMappingResults(object): tenPercentLength = geneLength*0.0001 SNPdensity = theGO["snpCount"]/geneLength - exonStarts = map(float, theGO['exonStarts'].split(",")[:-1]) - exonEnds = map(float, theGO['exonEnds'].split(",")[:-1]) + exonStarts = list(map(float, theGO['exonStarts'].split(",")[:-1])) + exonEnds = list(map(float, theGO['exonEnds'].split(",")[:-1])) cdsStart = theGO['cdsStart'] cdsEnd = theGO['cdsEnd'] accession = theGO['NM_ID'] @@ -2145,7 +2145,7 @@ class DisplayMappingResults(object): lrsEdgeWidth = 1 else: if self.additiveChecked: - additiveMax = max(map(lambda X : abs(X['additive']), self.qtlresults)) + additiveMax = max([abs(X['additive']) for X in self.qtlresults]) lrsEdgeWidth = 3 if zoom == 2: diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index 2f327faf..9571015e 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -84,7 +84,7 @@ def get_samples_from_ped_file(dataset): while line: lineList = string.split(string.strip(line), '\t') - lineList = map(string.strip, lineList) + lineList = list(map(string.strip, lineList)) sample_name = lineList[0] sample_list.append(sample_name) @@ -157,6 +157,6 @@ def parse_plink_output(output_filename, species): def build_line_list(line=None): line_list = string.split(string.strip(line),' ')# irregular number of whitespaces between columns line_list = [item for item in line_list if item <>''] - line_list = map(string.strip, line_list) + line_list = list(map(string.strip, line_list)) return line_list \ No newline at end of file diff --git a/wqflask/wqflask/pbkdf2.py b/wqflask/wqflask/pbkdf2.py index 811c83b0..731c8843 100644 --- a/wqflask/wqflask/pbkdf2.py +++ b/wqflask/wqflask/pbkdf2.py @@ -66,7 +66,7 @@ def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): def _pseudorandom(x, mac=mac): h = mac.copy() h.update(x) - return map(ord, h.digest()) + return list(map(ord, h.digest())) buf = [] for block in xrange(1, -(-keylen // mac.digest_size) + 1): rv = u = _pseudorandom(salt + _pack_int(block)) diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 1d28d76a..b18bfc62 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -459,7 +459,7 @@ class SnpBrowser(object): function_list = [] if function_details: function_list = string.split(string.strip(function_details), ",") - function_list = map(string.strip, function_list) + function_list = list(map(string.strip, function_list)) function_list[0] = function_list[0].title() function_details = ", ".join(item for item in function_list) function_details = function_details.replace("_", " ") @@ -725,11 +725,11 @@ def get_effect_details_by_category(effect_name = None, effect_value = None): codon_effect_group_list = ['Start Lost', 'Stop Gained', 'Stop Lost', 'Nonsynonymous', 'Synonymous'] effect_detail_list = string.split(string.strip(effect_value), '|') - effect_detail_list = map(string.strip, effect_detail_list) + effect_detail_list = list(map(string.strip, effect_detail_list)) for index, item in enumerate(effect_detail_list): item_list = string.split(string.strip(item), ',') - item_list = map(string.strip, item_list) + item_list = list(map(string.strip, item_list)) gene_id = item_list[0] gene_name = item_list[1] -- cgit v1.2.3 From bafbb5b7a4b7db2ca230f292eb45be7e67985259 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 02:05:05 +0300 Subject: Remove erroneous `if .. else` branch * wqflask/utility/svg.py [roct, ellipse, SVGelement]: Raise only a single value error if either height or width is not defined. Fixes parsing error when running `2to3-3.8 -f apply -w .` --- wqflask/utility/svg.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index c850feb8..d66c954e 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -445,12 +445,8 @@ class rect(SVGelement): def __init__(self, x=None, y=None, width=None, height=None, fill=None, stroke=None, stroke_width=None, **args): if width == None or height == None: - raise ValueError, 'height is required' - raise ValueError, 'width is required' - if width!=None: - if height!=None: - else: - raise ValueError, 'both height and width are required' + raise ValueError, 'both height and width are required' + SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) if x!=None: self.attributes['x']=x @@ -470,12 +466,8 @@ class ellipse(SVGelement): """ def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args): if rx==None or ry== None: - raise ValueError, 'rx is required' - raise ValueError, 'ry is required' - if rx!=None: - if ry!=None: - else: - raise ValueError, 'both rx and ry are required' + raise ValueError, 'both rx and ry are required' + SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) if cx!=None: self.attributes['cx']=cx @@ -722,12 +714,7 @@ class image(SVGelement): """ def __init__(self,url,x=None,y=None,width=None,height=None,**args): if width==None or height==None: - raise ValueError, 'height is required' - raise ValueError, 'width is required' - if width!=None: - if height!=None: - else: - raise ValueError, 'both height and width are required' + raise ValueError, 'both height and width are required' SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args) if x!=None: self.attributes['x']=x -- cgit v1.2.3 From ba123e1e0fe693f9778993c3f8e5a70a28658a4c Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 02:31:31 +0300 Subject: Fix dictionary iteration methods Run `2to3-3.8 -f dict -w .` See: and --- scripts/maintenance/load_genotypes.py | 4 +-- wqflask/base/GeneralObject.py | 8 ++--- wqflask/base/trait.py | 4 +-- wqflask/maintenance/gen_select_dataset.py | 6 ++-- .../maintenance/generate_probesetfreeze_file.py | 2 +- wqflask/utility/__init__.py | 4 +-- wqflask/utility/benchmark.py | 4 +-- wqflask/utility/gen_geno_ob.py | 2 +- wqflask/utility/helper_functions.py | 2 +- wqflask/utility/svg.py | 14 ++++---- wqflask/utility/temp_data.py | 2 +- wqflask/utility/tools.py | 2 +- wqflask/wqflask/api/correlation.py | 16 ++++----- wqflask/wqflask/api/gen_menu.py | 6 ++-- wqflask/wqflask/correlation/corr_scatter_plot.py | 6 ++-- wqflask/wqflask/correlation/show_corr_results.py | 30 ++++++++--------- wqflask/wqflask/ctl/ctl_analysis.py | 2 +- wqflask/wqflask/export_traits.py | 4 +-- wqflask/wqflask/heatmap/heatmap.py | 4 +-- wqflask/wqflask/interval_analyst/GeneUtil.py | 2 +- .../marker_regression/display_mapping_results.py | 38 +++++++++++----------- wqflask/wqflask/marker_regression/run_mapping.py | 24 +++++++------- wqflask/wqflask/resource_manager.py | 2 +- wqflask/wqflask/show_trait/export_trait_data.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 8 ++--- wqflask/wqflask/views.py | 6 ++-- 26 files changed, 102 insertions(+), 102 deletions(-) (limited to 'wqflask/utility') diff --git a/scripts/maintenance/load_genotypes.py b/scripts/maintenance/load_genotypes.py index c235a31f..51278d48 100755 --- a/scripts/maintenance/load_genotypes.py +++ b/scripts/maintenance/load_genotypes.py @@ -19,7 +19,7 @@ def fetch_parameters(config): config_dic['dataid'] = datastructure.get_nextdataid_genotype() config_dic['genofile'] = config.get('config', 'genofile') print("config dictionary:") - for k, v in config_dic.items(): + for k, v in list(config_dic.items()): print(("\t%s: %s" % (k, v))) return config_dic @@ -42,7 +42,7 @@ def parse_genofile(config, config_dic): if line.lower().startswith("chr"): # print("geno file meta dictionary:") - for k, v in meta_dic.items(): + for k, v in list(meta_dic.items()): print(("\t%s: %s" % (k, v))) # print(("geno file head:\n\t%s" % line)) diff --git a/wqflask/base/GeneralObject.py b/wqflask/base/GeneralObject.py index 0fccaab3..707569db 100644 --- a/wqflask/base/GeneralObject.py +++ b/wqflask/base/GeneralObject.py @@ -33,7 +33,7 @@ class GeneralObject: def __init__(self, *args, **kw): self.contents = list(args) - for name, value in kw.items(): + for name, value in list(kw.items()): setattr(self, name, value) def __setitem__(self, key, value): @@ -50,16 +50,16 @@ class GeneralObject: def __str__(self): s = '' - for key in self.__dict__.keys(): + for key in list(self.__dict__.keys()): if key != 'contents': s += '%s = %s\n' % (key, self.__dict__[key]) return s def __repr__(self): s = '' - for key in self.__dict__.keys(): + for key in list(self.__dict__.keys()): s += '%s = %s\n' % (key, self.__dict__[key]) return s def __cmp__(self, other): - return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys())) + return len(list(self.__dict__.keys())).__cmp__(len(list(other.__dict__.keys()))) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 7666348e..e82df226 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -118,7 +118,7 @@ class GeneralTrait(object): vals = [] the_vars = [] sample_aliases = [] - for sample_name, sample_data in self.data.items(): + for sample_name, sample_data in list(self.data.items()): if sample_data.value != None: if not include_variance or sample_data.variance != None: samples.append(sample_name) @@ -260,7 +260,7 @@ def get_sample_data(): trait_dict['pubmed_link'] = trait_ob.pubmed_link trait_dict['pubmed_text'] = trait_ob.pubmed_text - return json.dumps([trait_dict, {key: value.value for key, value in trait_ob.data.iteritems() }]) + return json.dumps([trait_dict, {key: value.value for key, value in list(trait_ob.data.items()) }]) else: return None diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index 647e58a2..78217587 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -108,7 +108,7 @@ def get_types(groups): """Build types list""" types = {} #print("Groups: ", pf(groups)) - for species, group_dict in groups.iteritems(): + for species, group_dict in list(groups.items()): types[species] = {} for group_name, _group_full_name in group_dict: # make group an alias to shorten the code @@ -195,9 +195,9 @@ def build_types(species, group): def get_datasets(types): """Build datasets list""" datasets = {} - for species, group_dict in types.iteritems(): + for species, group_dict in list(types.items()): datasets[species] = {} - for group, type_list in group_dict.iteritems(): + for group, type_list in list(group_dict.items()): datasets[species][group] = {} for type_name in type_list: these_datasets = build_datasets(species, group, type_name[0]) diff --git a/wqflask/maintenance/generate_probesetfreeze_file.py b/wqflask/maintenance/generate_probesetfreeze_file.py index b7b2dc8e..4231cc7c 100644 --- a/wqflask/maintenance/generate_probesetfreeze_file.py +++ b/wqflask/maintenance/generate_probesetfreeze_file.py @@ -82,7 +82,7 @@ def get_probeset_vals(cursor, dataset_name): def trim_strains(strains, probeset_vals): trimmed_strains = [] #print("probeset_vals is:", pf(probeset_vals)) - first_probeset = list(probeset_vals.itervalues())[0] + first_probeset = list(probeset_vals.values())[0] print("\n**** first_probeset is:", pf(first_probeset)) for strain in strains: print("\n**** strain is:", pf(strain)) diff --git a/wqflask/utility/__init__.py b/wqflask/utility/__init__.py index d9856eed..204ff59a 100644 --- a/wqflask/utility/__init__.py +++ b/wqflask/utility/__init__.py @@ -19,7 +19,7 @@ class Struct(object): ''' def __init__(self, obj): - for k, v in obj.iteritems(): + for k, v in list(obj.items()): if isinstance(v, dict): setattr(self, k, Struct(v)) else: @@ -30,6 +30,6 @@ class Struct(object): def __repr__(self): return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for - (k, v) in self.__dict__.iteritems())) + (k, v) in list(self.__dict__.items()))) diff --git a/wqflask/utility/benchmark.py b/wqflask/utility/benchmark.py index 8f1c916b..221e5151 100644 --- a/wqflask/utility/benchmark.py +++ b/wqflask/utility/benchmark.py @@ -38,9 +38,9 @@ class Bench(object): @classmethod def report(cls): - total_time = sum((time_taken for time_taken in cls.entries.itervalues())) + total_time = sum((time_taken for time_taken in list(cls.entries.values()))) print("\nTiming report\n") - for name, time_taken in cls.entries.iteritems(): + for name, time_taken in list(cls.entries.items()): percent = int(round((time_taken/total_time) * 100)) print("[{}%] {}: {}".format(percent, name, time_taken)) print() diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py index 23b0b650..ae42f834 100644 --- a/wqflask/utility/gen_geno_ob.py +++ b/wqflask/utility/gen_geno_ob.py @@ -175,7 +175,7 @@ class Locus(object): start_pos = 3 for allele in marker_row[start_pos:]: - if allele in geno_table.keys(): + if allele in list(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 9ce809b6..9a4a235a 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -13,7 +13,7 @@ logger = logging.getLogger(__name__ ) def get_species_dataset_trait(self, start_vars): #assert type(read_genotype) == type(bool()), "Expecting boolean value for read_genotype" - if "temp_trait" in start_vars.keys(): + if "temp_trait" in list(start_vars.keys()): if start_vars['temp_trait'] == "True": self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = start_vars['group']) else: diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index d66c954e..c6a5c260 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -133,7 +133,7 @@ def _escape(data, entities={}): # data = data.replace("&", "&") data = data.replace("<", "<") data = data.replace(">", ">") - for chars, entity in entities.items(): + for chars, entity in list(entities.items()): data = data.replace(chars, entity) return data @@ -299,7 +299,7 @@ class SVGelement: self.text = text self.namespace = namespace self.cdata = cdata - for arg in args.keys(): + for arg in list(args.keys()): arg2 = arg.replace("__", ":") arg2 = arg2.replace("_", "-") self.attributes[arg2] = args[arg] @@ -314,7 +314,7 @@ class SVGelement: def toXml(self, level, f): f.write('\t'*level) f.write('<'+self.type) - for attkey in self.attributes.keys(): + for attkey in list(self.attributes.keys()): f.write(' '+_escape(str(attkey))+'=' + _quoteattr(str(self.attributes[attkey]))) if self.namespace: @@ -365,7 +365,7 @@ class tspan(SVGelement): def __repr__(self): s = "\n" % (item, self.entity[item])) xml.write("]") xml.write(">\n") @@ -1015,7 +1015,7 @@ class drawing: if element.text: textnode=root.createTextNode(element.text) e.appendChild(textnode) - for attribute in element.attributes.keys(): #in element.attributes is supported from python 2.2 + for attribute in list(element.attributes.keys()): #in element.attributes is supported from python 2.2 e.setAttribute(attribute,str(element.attributes[attribute])) if element.elements: for el in element.elements: diff --git a/wqflask/utility/temp_data.py b/wqflask/utility/temp_data.py index 5bf700c9..2f2726c6 100644 --- a/wqflask/utility/temp_data.py +++ b/wqflask/utility/temp_data.py @@ -20,6 +20,6 @@ class TempData(object): if __name__ == "__main__": redis = Redis() - for key in redis.keys(): + for key in list(redis.keys()): for field in redis.hkeys(key): print("{}.{}={}".format(key, field, redis.hget(key, field))) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index f790d424..51a87fe1 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -220,7 +220,7 @@ def show_settings(): logger.info(OVERRIDES) logger.info(BLUE+"Mr. Mojo Risin 2"+ENDC) - keylist = app.config.keys() + keylist = list(app.config.keys()) print("runserver.py: ****** Webserver configuration - k,v pairs from app.config ******") keylist.sort() for k in keylist: diff --git a/wqflask/wqflask/api/correlation.py b/wqflask/wqflask/api/correlation.py index 7f5312c1..eb05645e 100644 --- a/wqflask/wqflask/api/correlation.py +++ b/wqflask/wqflask/api/correlation.py @@ -36,7 +36,7 @@ def do_correlation(start_vars): #corr_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) final_results = [] - for _trait_counter, trait in enumerate(corr_results.keys()[:corr_params['return_count']]): + for _trait_counter, trait in enumerate(list(corr_results.keys())[:corr_params['return_count']]): if corr_params['type'] == "tissue": [sample_r, num_overlap, sample_p, symbol] = corr_results[trait] result_dict = { @@ -76,20 +76,20 @@ def calculate_results(this_trait, this_dataset, target_dataset, corr_params): if corr_params['type'] == "tissue": trait_symbol_dict = this_dataset.retrieve_genes("Symbol") corr_results = do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_params) - sorted_results = collections.OrderedDict(sorted(corr_results.items(), + sorted_results = collections.OrderedDict(sorted(list(corr_results.items()), key=lambda t: -abs(t[1][1]))) elif corr_params['type'] == "literature" or corr_params['type'] == "lit": #ZS: Just so a user can use either "lit" or "literature" trait_geneid_dict = this_dataset.retrieve_genes("GeneId") corr_results = do_literature_correlation_for_all_traits(this_trait, this_dataset, trait_geneid_dict, corr_params) - sorted_results = collections.OrderedDict(sorted(corr_results.items(), + sorted_results = collections.OrderedDict(sorted(list(corr_results.items()), key=lambda t: -abs(t[1][1]))) else: - for target_trait, target_vals in target_dataset.trait_data.iteritems(): + for target_trait, target_vals in list(target_dataset.trait_data.items()): result = get_sample_r_and_p_values(this_trait, this_dataset, target_vals, target_dataset, corr_params['type']) if result is not None: corr_results[target_trait] = result - sorted_results = collections.OrderedDict(sorted(corr_results.items(), key=lambda t: -abs(t[1][0]))) + sorted_results = collections.OrderedDict(sorted(list(corr_results.items()), key=lambda t: -abs(t[1][0]))) return sorted_results @@ -100,10 +100,10 @@ def do_tissue_correlation_for_all_traits(this_trait, trait_symbol_dict, corr_par if this_trait.symbol.lower() in primary_trait_tissue_vals_dict: primary_trait_tissue_values = primary_trait_tissue_vals_dict[this_trait.symbol.lower()] - corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list=trait_symbol_dict.values()) + corr_result_tissue_vals_dict = correlation_functions.get_trait_symbol_and_tissue_values(symbol_list=list(trait_symbol_dict.values())) tissue_corr_data = {} - for trait, symbol in trait_symbol_dict.iteritems(): + for trait, symbol in list(trait_symbol_dict.items()): if symbol and symbol.lower() in corr_result_tissue_vals_dict: this_trait_tissue_values = corr_result_tissue_vals_dict[symbol.lower()] @@ -119,7 +119,7 @@ def do_literature_correlation_for_all_traits(this_trait, target_dataset, trait_g input_trait_mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), this_trait.geneid) lit_corr_data = {} - for trait, gene_id in trait_geneid_dict.iteritems(): + for trait, gene_id in list(trait_geneid_dict.items()): mouse_gene_id = convert_to_mouse_gene_id(target_dataset.group.species.lower(), gene_id) if mouse_gene_id and str(mouse_gene_id).find(";") == -1: diff --git a/wqflask/wqflask/api/gen_menu.py b/wqflask/wqflask/api/gen_menu.py index cc11e14b..71d9ee03 100644 --- a/wqflask/wqflask/api/gen_menu.py +++ b/wqflask/wqflask/api/gen_menu.py @@ -61,7 +61,7 @@ def get_types(groups): """Build types list""" types = {} - for species, group_dict in groups.iteritems(): + for species, group_dict in list(groups.items()): types[species] = {} for group_name, _group_full_name, _family_name in group_dict: if phenotypes_exist(group_name): @@ -136,9 +136,9 @@ def build_types(species, group): def get_datasets(types): """Build datasets list""" datasets = {} - for species, group_dict in types.iteritems(): + for species, group_dict in list(types.items()): datasets[species] = {} - for group, type_list in group_dict.iteritems(): + for group, type_list in list(group_dict.items()): datasets[species][group] = {} for type_name in type_list: these_datasets = build_datasets(species, group, type_name[0]) diff --git a/wqflask/wqflask/correlation/corr_scatter_plot.py b/wqflask/wqflask/correlation/corr_scatter_plot.py index 819836b1..57a8d85f 100644 --- a/wqflask/wqflask/correlation/corr_scatter_plot.py +++ b/wqflask/wqflask/correlation/corr_scatter_plot.py @@ -36,13 +36,13 @@ class CorrScatterPlot(object): samples_1, samples_2, num_overlap = corr_result_helpers.normalize_values_with_samples(self.trait_1.data, self.trait_2.data) self.data = [] - self.indIDs = samples_1.keys() + self.indIDs = list(samples_1.keys()) vals_1 = [] - for sample in samples_1.keys(): + for sample in list(samples_1.keys()): vals_1.append(samples_1[sample].value) self.data.append(vals_1) vals_2 = [] - for sample in samples_2.keys(): + for sample in list(samples_2.keys()): vals_2.append(samples_2[sample].value) self.data.append(vals_2) diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index de7a1c0c..15a21ee6 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -145,10 +145,10 @@ class CorrelationResults(object): if corr_samples_group == 'samples_other': primary_samples = [x for x in primary_samples if x not in ( self.dataset.group.parlist + self.dataset.group.f1list)] - self.process_samples(start_vars, self.this_trait.data.keys(), primary_samples) + self.process_samples(start_vars, list(self.this_trait.data.keys()), primary_samples) self.target_dataset = data_set.create_dataset(start_vars['corr_dataset']) - self.target_dataset.get_trait_data(self.sample_data.keys()) + self.target_dataset.get_trait_data(list(self.sample_data.keys())) self.header_fields = get_header_fields(self.target_dataset.type, self.corr_method) @@ -168,41 +168,41 @@ class CorrelationResults(object): tissue_corr_data = self.do_tissue_correlation_for_all_traits() if tissue_corr_data != None: - for trait in tissue_corr_data.keys()[:self.return_number]: + for trait in list(tissue_corr_data.keys())[:self.return_number]: self.get_sample_r_and_p_values(trait, self.target_dataset.trait_data[trait]) else: - for trait, values in self.target_dataset.trait_data.iteritems(): + for trait, values in list(self.target_dataset.trait_data.items()): self.get_sample_r_and_p_values(trait, values) elif self.corr_type == "lit": self.trait_geneid_dict = self.dataset.retrieve_genes("GeneId") lit_corr_data = self.do_lit_correlation_for_all_traits() - for trait in lit_corr_data.keys()[:self.return_number]: + for trait in list(lit_corr_data.keys())[:self.return_number]: self.get_sample_r_and_p_values(trait, self.target_dataset.trait_data[trait]) elif self.corr_type == "sample": - for trait, values in self.target_dataset.trait_data.iteritems(): + for trait, values in list(self.target_dataset.trait_data.items()): self.get_sample_r_and_p_values(trait, values) - self.correlation_data = collections.OrderedDict(sorted(self.correlation_data.items(), + self.correlation_data = collections.OrderedDict(sorted(list(self.correlation_data.items()), key=lambda t: -abs(t[1][0]))) if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": #ZS: Convert min/max chromosome to an int for the location range option range_chr_as_int = None - for order_id, chr_info in self.dataset.species.chromosomes.chromosomes.iteritems(): + for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): if 'loc_chr' in start_vars: if chr_info.name == self.location_chr: range_chr_as_int = order_id - for _trait_counter, trait in enumerate(self.correlation_data.keys()[:self.return_number]): + for _trait_counter, trait in enumerate(list(self.correlation_data.keys())[:self.return_number]): trait_object = create_trait(dataset=self.target_dataset, name=trait, get_qtl_info=True, get_sample_info=False) if self.target_dataset.type == "ProbeSet" or self.target_dataset.type == "Geno": #ZS: Convert trait chromosome to an int for the location range option chr_as_int = 0 - for order_id, chr_info in self.dataset.species.chromosomes.chromosomes.iteritems(): + for order_id, chr_info in list(self.dataset.species.chromosomes.chromosomes.items()): if chr_info.name == trait_object.chr: chr_as_int = order_id @@ -297,14 +297,14 @@ class CorrelationResults(object): #print("trait_gene_symbols: ", pf(trait_gene_symbols.values())) corr_result_tissue_vals_dict= correlation_functions.get_trait_symbol_and_tissue_values( - symbol_list=self.trait_symbol_dict.values()) + symbol_list=list(self.trait_symbol_dict.values())) #print("corr_result_tissue_vals: ", pf(corr_result_tissue_vals_dict)) #print("trait_gene_symbols: ", pf(trait_gene_symbols)) tissue_corr_data = {} - for trait, symbol in self.trait_symbol_dict.iteritems(): + for trait, symbol in list(self.trait_symbol_dict.items()): if symbol and symbol.lower() in corr_result_tissue_vals_dict: this_trait_tissue_values = corr_result_tissue_vals_dict[symbol.lower()] @@ -314,7 +314,7 @@ class CorrelationResults(object): tissue_corr_data[trait] = [symbol, result[0], result[2]] - tissue_corr_data = collections.OrderedDict(sorted(tissue_corr_data.items(), + tissue_corr_data = collections.OrderedDict(sorted(list(tissue_corr_data.items()), key=lambda t: -abs(t[1][1]))) return tissue_corr_data @@ -359,7 +359,7 @@ class CorrelationResults(object): input_trait_mouse_gene_id = self.convert_to_mouse_gene_id(self.dataset.group.species.lower(), self.this_trait.geneid) lit_corr_data = {} - for trait, gene_id in self.trait_geneid_dict.iteritems(): + for trait, gene_id in list(self.trait_geneid_dict.items()): mouse_gene_id = self.convert_to_mouse_gene_id(self.dataset.group.species.lower(), gene_id) if mouse_gene_id and str(mouse_gene_id).find(";") == -1: @@ -387,7 +387,7 @@ class CorrelationResults(object): else: lit_corr_data[trait] = [gene_id, 0] - lit_corr_data = collections.OrderedDict(sorted(lit_corr_data.items(), + lit_corr_data = collections.OrderedDict(sorted(list(lit_corr_data.items()), key=lambda t: -abs(t[1][1]))) return lit_corr_data diff --git a/wqflask/wqflask/ctl/ctl_analysis.py b/wqflask/wqflask/ctl/ctl_analysis.py index 35067036..f0be7a98 100644 --- a/wqflask/wqflask/ctl/ctl_analysis.py +++ b/wqflask/wqflask/ctl/ctl_analysis.py @@ -125,7 +125,7 @@ class CTL(object): gt = create_trait(name = ts[0], dataset_name = ts[1]) gt = retrieve_sample_data(gt, dataset, individuals) for ind in individuals: - if ind in gt.data.keys(): + if ind in list(gt.data.keys()): traits.append(gt.data[ind].value) else: traits.append("-999") diff --git a/wqflask/wqflask/export_traits.py b/wqflask/wqflask/export_traits.py index 6646cc36..28c6593d 100644 --- a/wqflask/wqflask/export_traits.py +++ b/wqflask/wqflask/export_traits.py @@ -61,7 +61,7 @@ def export_search_results_csv(targs): traits_by_group = sort_traits_by_group(trait_list) file_list = [] - for group in traits_by_group.keys(): + for group in list(traits_by_group.keys()): group_traits = traits_by_group[group] buff = StringIO.StringIO() writer = csv.writer(buff) @@ -135,7 +135,7 @@ def export_search_results_csv(targs): def sort_traits_by_group(trait_list=[]): traits_by_group = {} for trait in trait_list: - if trait.dataset.group.name not in traits_by_group.keys(): + if trait.dataset.group.name not in list(traits_by_group.keys()): traits_by_group[trait.dataset.group.name] = [] traits_by_group[trait.dataset.group.name].append(trait) diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py index 5098a184..577426b0 100644 --- a/wqflask/wqflask/heatmap/heatmap.py +++ b/wqflask/wqflask/heatmap/heatmap.py @@ -60,7 +60,7 @@ class Heatmap(object): chrnames = [] self.species = species.TheSpecies(dataset=self.trait_list[0][1]) - for key in self.species.chromosomes.chromosomes.keys(): + for key in list(self.species.chromosomes.chromosomes.keys()): chrnames.append([self.species.chromosomes.chromosomes[key].name, self.species.chromosomes.chromosomes[key].mb_length]) for trait_db in self.trait_list: @@ -93,7 +93,7 @@ class Heatmap(object): pos = [] markernames = [] - for trait in self.trait_results.keys(): + for trait in list(self.trait_results.keys()): lodnames.append(trait) self.dataset.group.get_markers() diff --git a/wqflask/wqflask/interval_analyst/GeneUtil.py b/wqflask/wqflask/interval_analyst/GeneUtil.py index 273168a8..a39e5d0f 100644 --- a/wqflask/wqflask/interval_analyst/GeneUtil.py +++ b/wqflask/wqflask/interval_analyst/GeneUtil.py @@ -24,7 +24,7 @@ def loadGenes(chrName, diffCol, startMb, endMb, species='mouse'): ##List current Species and other Species speciesId = speciesDict[species] - otherSpecies = [[X, speciesDict[X]] for X in speciesDict.keys()] + otherSpecies = [[X, speciesDict[X]] for X in list(speciesDict.keys())] otherSpecies.remove([species, speciesId]) results = g.db.execute(""" diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index 7b6e70d2..0328ce85 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -229,7 +229,7 @@ class DisplayMappingResults(object): self.manhattan_plot = start_vars['manhattan_plot'] - if 'permCheck' in start_vars.keys(): + if 'permCheck' in list(start_vars.keys()): self.permChecked = start_vars['permCheck'] else: self.permChecked = False @@ -242,46 +242,46 @@ class DisplayMappingResults(object): else: self.nperm = 0 - if 'bootCheck' in start_vars.keys(): + if 'bootCheck' in list(start_vars.keys()): self.bootChecked = start_vars['bootCheck'] else: self.bootChecked = False - if 'num_bootstrap' in start_vars.keys(): + if 'num_bootstrap' in list(start_vars.keys()): self.nboot = int(start_vars['num_bootstrap']) else: self.nboot = 0 - if 'bootstrap_results' in start_vars.keys(): + if 'bootstrap_results' in list(start_vars.keys()): self.bootResult = start_vars['bootstrap_results'] else: self.bootResult = [] - if 'do_control' in start_vars.keys(): + if 'do_control' in list(start_vars.keys()): self.doControl = start_vars['do_control'] else: self.doControl = "false" - if 'control_marker' in start_vars.keys(): + if 'control_marker' in list(start_vars.keys()): self.controlLocus = start_vars['control_marker'] else: self.controlLocus = "" - if 'covariates' in start_vars.keys(): + if 'covariates' in list(start_vars.keys()): self.covariates = start_vars['covariates'] - if 'maf' in start_vars.keys(): + if 'maf' in list(start_vars.keys()): self.maf = start_vars['maf'] else: self.maf = "" - if 'output_files' in start_vars.keys(): + if 'output_files' in list(start_vars.keys()): self.output_files = start_vars['output_files'] - if 'use_loco' in start_vars.keys() and self.mapping_method == "gemma": + if 'use_loco' in list(start_vars.keys()) and self.mapping_method == "gemma": self.use_loco = start_vars['use_loco'] - if 'reaper_version' in start_vars.keys() and self.mapping_method == "reaper": + if 'reaper_version' in list(start_vars.keys()) and self.mapping_method == "reaper": self.reaper_version = start_vars['reaper_version'] if 'output_files' in start_vars: self.output_files = ",".join(start_vars['output_files']) self.categorical_vars = "" self.perm_strata = "" - if 'perm_strata' in start_vars.keys() and 'categorical_vars' in start_vars.keys(): + if 'perm_strata' in list(start_vars.keys()) and 'categorical_vars' in list(start_vars.keys()): self.categorical_vars = start_vars['categorical_vars'] self.perm_strata = start_vars['perm_strata'] @@ -323,7 +323,7 @@ class DisplayMappingResults(object): self.graphWidth = self.MULT_GRAPH_DEFAULT_WIDTH ## BEGIN HaplotypeAnalyst - if 'haplotypeAnalystCheck' in start_vars.keys(): + if 'haplotypeAnalystCheck' in list(start_vars.keys()): self.haplotypeAnalystChecked = start_vars['haplotypeAnalystCheck'] else: self.haplotypeAnalystChecked = False @@ -331,25 +331,25 @@ class DisplayMappingResults(object): self.graphHeight = self.GRAPH_DEFAULT_HEIGHT self.dominanceChecked = False - if 'LRSCheck' in start_vars.keys(): + if 'LRSCheck' in list(start_vars.keys()): self.LRS_LOD = start_vars['LRSCheck'] else: self.LRS_LOD = start_vars['score_type'] self.intervalAnalystChecked = True self.draw2X = False - if 'additiveCheck' in start_vars.keys(): + if 'additiveCheck' in list(start_vars.keys()): self.additiveChecked = start_vars['additiveCheck'] else: self.additiveChecked = False - if 'viewLegend' in start_vars.keys(): + if 'viewLegend' in list(start_vars.keys()): self.legendChecked = start_vars['viewLegend'] else: self.legendChecked = False - if 'showSNP' in start_vars.keys(): + if 'showSNP' in list(start_vars.keys()): self.SNPChecked = start_vars['showSNP'] else: self.SNPChecked = False - if 'showGenes' in start_vars.keys(): + if 'showGenes' in list(start_vars.keys()): self.geneChecked = start_vars['showGenes'] else: self.geneChecked = False @@ -530,7 +530,7 @@ class DisplayMappingResults(object): showLocusForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=showLocusForm, submit=HT.Input(type='hidden')) hddn = {'FormID':'showDatabase', 'ProbeSetID':'_','database':fd.RISet+"Geno",'CellID':'_', 'RISet':fd.RISet, 'incparentsf1':'ON'} - for key in hddn.keys(): + for key in list(hddn.keys()): showLocusForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) showLocusForm.append(intImg) else: diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index c9d10f7c..145dbc77 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -347,7 +347,7 @@ class RunMapping(object): if marker['chr1'] > 0 or marker['chr1'] == "X" or marker['chr1'] == "X/Y": if marker['chr1'] > highest_chr or marker['chr1'] == "X" or marker['chr1'] == "X/Y": highest_chr = marker['chr1'] - if 'lod_score' in marker.keys(): + if 'lod_score' in list(marker.keys()): self.qtl_results.append(marker) self.trimmed_markers = results @@ -411,7 +411,7 @@ 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 marker.keys()) or ('lrs_value' in marker.keys()): + if ('lod_score' in list(marker.keys())) or ('lrs_value' in list(marker.keys())): self.qtl_results.append(marker) with Bench("Exporting Results"): @@ -538,28 +538,28 @@ def export_mapping_results(dataset, trait, markers, results_path, mapping_scale, output_file.write("Mb," + score_type) else: output_file.write("Cm," + score_type) - if "additive" in markers[0].keys(): + if "additive" in list(markers[0].keys()): output_file.write(",Additive") - if "dominance" in markers[0].keys(): + if "dominance" in list(markers[0].keys()): output_file.write(",Dominance") output_file.write("\n") for i, marker in enumerate(markers): output_file.write(marker['name'] + "," + str(marker['chr']) + "," + str(marker['Mb']) + ",") - if "lod_score" in marker.keys(): + if "lod_score" in list(marker.keys()): output_file.write(str(marker['lod_score'])) else: output_file.write(str(marker['lrs_value'])) - if "additive" in marker.keys(): + if "additive" in list(marker.keys()): output_file.write("," + str(marker['additive'])) - if "dominance" in marker.keys(): + if "dominance" in list(marker.keys()): output_file.write("," + str(marker['dominance'])) if i < (len(markers) - 1): output_file.write("\n") def trim_markers_for_figure(markers): - if 'p_wald' in markers[0].keys(): + if 'p_wald' in list(markers[0].keys()): score_type = 'p_wald' - elif 'lod_score' in markers[0].keys(): + elif 'lod_score' in list(markers[0].keys()): score_type = 'lod_score' else: score_type = 'lrs_value' @@ -617,7 +617,7 @@ def trim_markers_for_figure(markers): return filtered_markers def trim_markers_for_table(markers): - if 'lod_score' in markers[0].keys(): + if 'lod_score' in list(markers[0].keys()): sorted_markers = sorted(markers, key=lambda k: k['lod_score'], reverse=True) else: sorted_markers = sorted(markers, key=lambda k: k['lrs_value'], reverse=True) @@ -695,10 +695,10 @@ def get_genofile_samplelist(dataset): def get_perm_strata(this_trait, sample_list, categorical_vars, used_samples): perm_strata_strings = [] for sample in used_samples: - if sample in sample_list.sample_attribute_values.keys(): + if sample in list(sample_list.sample_attribute_values.keys()): combined_string = "" for var in categorical_vars: - if var in sample_list.sample_attribute_values[sample].keys(): + if var in list(sample_list.sample_attribute_values[sample].keys()): combined_string += str(sample_list.sample_attribute_values[sample][var]) else: combined_string += "NA" diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py index 39a07310..6b3e00fb 100644 --- a/wqflask/wqflask/resource_manager.py +++ b/wqflask/wqflask/resource_manager.py @@ -125,7 +125,7 @@ def add_group_to_resource(): def get_group_names(group_masks): group_masks_with_names = {} - for group_id, group_mask in group_masks.iteritems(): + for group_id, group_mask in list(group_masks.items()): this_mask = group_mask group_name = get_group_info(group_id)['name'] this_mask['name'] = group_name diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index 253c887b..68c3ad7d 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -47,7 +47,7 @@ def get_export_metadata(trait_id, dataset_name): def dict_to_sorted_list(dictionary): - sorted_list = [item for item in dictionary.iteritems()] + sorted_list = [item for item in list(dictionary.items())] sorted_list = sorted(sorted_list, cmp=cmp_samples) sorted_values = [item[1] for item in sorted_list] return sorted_values diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index f188fd9d..c156e61b 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -261,7 +261,7 @@ class ShowTrait(object): hddn['export_data'] = "" hddn['export_format'] = "excel" if len(self.scales_in_geno) < 2: - hddn['mapping_scale'] = self.scales_in_geno[self.scales_in_geno.keys()[0]][0][0] + hddn['mapping_scale'] = self.scales_in_geno[list(self.scales_in_geno.keys())[0]][0][0] # We'll need access to this_trait and hddn in the Jinja2 Template, so we put it inside self self.hddn = hddn @@ -405,7 +405,7 @@ class ShowTrait(object): if not self.temp_trait: other_sample_names = [] - for sample in self.this_trait.data.keys(): + for sample in list(self.this_trait.data.keys()): if (self.this_trait.data[sample].name2 in primary_sample_names) and (self.this_trait.data[sample].name not in primary_sample_names): primary_sample_names.append(self.this_trait.data[sample].name) primary_sample_names.remove(self.this_trait.data[sample].name2) @@ -558,7 +558,7 @@ def get_table_widths(sample_groups, has_num_cases=False): def has_num_cases(this_trait): has_n = False if this_trait.dataset.type != "ProbeSet" and this_trait.dataset.type != "Geno": - for name, sample in this_trait.data.iteritems(): + for name, sample in list(this_trait.data.items()): if sample.num_cases: has_n = True break @@ -611,7 +611,7 @@ def get_categorical_variables(this_trait, sample_list): if len(sample_list.attributes) > 0: for attribute in sample_list.attributes: attribute_vals = [] - for sample_name in this_trait.data.keys(): + for sample_name in list(this_trait.data.keys()): if sample_list.attributes[attribute].name in this_trait.data[sample_name].extra_attributes: attribute_vals.append(this_trait.data[sample_name].extra_attributes[sample_list.attributes[attribute].name]) else: diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index d67f1a2e..394a9e28 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -533,7 +533,7 @@ def heatmap_page(): result = template_vars.__dict__ - for item in template_vars.__dict__.keys(): + for item in list(template_vars.__dict__.keys()): logger.info(" ---**--- {}: {}".format(type(template_vars.__dict__[item]), item)) pickled_result = pickle.dumps(result, pickle.HIGHEST_PROTOCOL) @@ -637,7 +637,7 @@ def loading_page(): if 'wanted_inputs' in initial_start_vars: wanted = initial_start_vars['wanted_inputs'].split(",") start_vars = {} - for key, value in initial_start_vars.iteritems(): + for key, value in list(initial_start_vars.items()): if key in wanted or key.startswith(('value:')): start_vars[key] = value @@ -737,7 +737,7 @@ def mapping_results_page(): 'transform' ) start_vars = {} - for key, value in initial_start_vars.iteritems(): + for key, value in list(initial_start_vars.items()): if key in wanted or key.startswith(('value:')): start_vars[key] = value #logger.debug("Mapping called with start_vars:", start_vars) -- cgit v1.2.3 From caec08fa1e738fa9bc1b0b6bf626d8325f798712 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 03:08:08 +0300 Subject: Convert the old not-equal syntax, <>, to != Run `2to3-3.8 -f ne -w .` See: --- wqflask/utility/svg.py | 2 +- wqflask/wqflask/marker_regression/plink_mapping.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index c6a5c260..c7356e57 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -360,7 +360,7 @@ class tspan(SVGelement): def __init__(self, text=None, **args): SVGelement.__init__(self, 'tspan', **args) - if self.text <> None: + if self.text != None: self.text = text def __repr__(self): diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index 38ef7190..d4ee6fe6 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -156,7 +156,7 @@ def parse_plink_output(output_filename, species): ####################################################### def build_line_list(line=None): line_list = string.split(string.strip(line),' ')# irregular number of whitespaces between columns - line_list = [item for item in line_list if item <>''] + line_list = [item for item in line_list if item !=''] line_list = list(map(string.strip, line_list)) return line_list \ No newline at end of file -- cgit v1.2.3 From 7e60647223017220747d248ed1c986cc8374435e Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 03:13:53 +0300 Subject: Wrap `raise` statements in parenthesis Run `2to3-3.8 -f raise -w .` See: --- wqflask/base/trait.py | 2 +- wqflask/utility/svg.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index e82df226..c2d260e3 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -605,6 +605,6 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if trait.lrs != "": trait.LRS_score_repr = LRS_score_repr = '%3.1f' % trait.lrs else: - raise KeyError, `trait.name`+' information is not found in the database.' + raise KeyError(`trait.name`+' information is not found in the database.') return trait \ No newline at end of file diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index c7356e57..872f22fe 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -445,7 +445,7 @@ class rect(SVGelement): def __init__(self, x=None, y=None, width=None, height=None, fill=None, stroke=None, stroke_width=None, **args): if width == None or height == None: - raise ValueError, 'both height and width are required' + raise ValueError('both height and width are required') SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) if x!=None: @@ -466,7 +466,7 @@ class ellipse(SVGelement): """ def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args): if rx==None or ry== None: - raise ValueError, 'both rx and ry are required' + raise ValueError('both rx and ry are required') SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) if cx!=None: @@ -488,7 +488,7 @@ class circle(SVGelement): """ def __init__(self,cx=None,cy=None,r=None,fill=None,stroke=None,stroke_width=None,**args): if r==None: - raise ValueError, 'r is required' + raise ValueError('r is required') SVGelement.__init__(self,'circle',{'r':r},**args) if cx!=None: self.attributes['cx']=cx @@ -714,7 +714,7 @@ class image(SVGelement): """ def __init__(self,url,x=None,y=None,width=None,height=None,**args): if width==None or height==None: - raise ValueError, 'both height and width are required' + raise ValueError('both height and width are required') SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args) if x!=None: self.attributes['x']=x -- cgit v1.2.3 From 9d5dff44fb4d07f926659dde0c6205bf12a1ca5b Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 03:36:24 +0300 Subject: Rename xrange() to range() and wrap existing range() calls with list See: --- wqflask/maintenance/quantile_normalize.py | 2 +- wqflask/utility/Plot.py | 2 +- wqflask/wqflask/correlation/correlation_functions.py | 4 ++-- wqflask/wqflask/correlation_matrix/show_corr_matrix.py | 6 +++--- wqflask/wqflask/marker_regression/qtlreaper_mapping.py | 2 +- wqflask/wqflask/network_graph/network_graph.py | 4 ++-- wqflask/wqflask/pbkdf2.py | 4 ++-- wqflask/wqflask/search_results.py | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/maintenance/quantile_normalize.py b/wqflask/maintenance/quantile_normalize.py index 34886f44..82b695f4 100644 --- a/wqflask/maintenance/quantile_normalize.py +++ b/wqflask/maintenance/quantile_normalize.py @@ -37,7 +37,7 @@ def create_dataframe(input_file): with open(input_file) as f: ncols = len(f.readline().split("\t")) - input_array = np.loadtxt(open(input_file, "rb"), delimiter="\t", skiprows=1, usecols=range(1, ncols)) + input_array = np.loadtxt(open(input_file, "rb"), delimiter="\t", skiprows=1, usecols=list(range(1, ncols))) return pd.DataFrame(input_array) #This function taken from https://github.com/ShawnLYU/Quantile_Normalize diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 82bf6070..c9053dde 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -86,7 +86,7 @@ def frange(start, end=None, inc=1.0): # Need to adjust the count. AFAICT, it always comes up one short. count += 1 L = [start] * count - for i in xrange(1, count): + for i in range(1, count): L[i] = start + i * inc return L diff --git a/wqflask/wqflask/correlation/correlation_functions.py b/wqflask/wqflask/correlation/correlation_functions.py index 06dec795..abaa212f 100644 --- a/wqflask/wqflask/correlation/correlation_functions.py +++ b/wqflask/wqflask/correlation/correlation_functions.py @@ -50,12 +50,12 @@ from flask import Flask, g def cal_zero_order_corr_for_tiss (primaryValue=[], targetValue=[], method='pearson'): - R_primary = rpy2.robjects.FloatVector(range(len(primaryValue))) + R_primary = rpy2.robjects.FloatVector(list(range(len(primaryValue)))) N = len(primaryValue) for i in range(len(primaryValue)): R_primary[i] = primaryValue[i] - R_target = rpy2.robjects.FloatVector(range(len(targetValue))) + R_target = rpy2.robjects.FloatVector(list(range(len(targetValue)))) for i in range(len(targetValue)): R_target[i]=targetValue[i] diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index e6c817e7..832746bb 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -194,7 +194,7 @@ class CorrelationMatrix(object): if self.do_PCA == True: self.pca_works = "True" self.pca_trait_ids = [] - pca = self.calculate_pca(range(len(self.traits)), corr_eigen_value, corr_eigen_vectors) + pca = self.calculate_pca(list(range(len(self.traits))), corr_eigen_value, corr_eigen_vectors) self.loadings_array = self.process_loadings() else: self.pca_works = "False" @@ -203,8 +203,8 @@ class CorrelationMatrix(object): self.js_data = dict(traits = [trait.name for trait in self.traits], groups = groups, - cols = range(len(self.traits)), - rows = range(len(self.traits)), + cols = list(range(len(self.traits))), + rows = list(range(len(self.traits))), samples = self.all_sample_list, sample_data = self.sample_data,) # corr_results = [result[1] for result in result_row for result_row in self.corr_results]) diff --git a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py index 0c560582..189c1985 100644 --- a/wqflask/wqflask/marker_regression/qtlreaper_mapping.py +++ b/wqflask/wqflask/marker_regression/qtlreaper_mapping.py @@ -228,4 +228,4 @@ def natural_sort(marker_list): """ convert = lambda text: int(text) if text.isdigit() else text.lower() alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', str(marker_list[key]['chr'])) ] - return sorted(range(len(marker_list)), key = alphanum_key) \ No newline at end of file + return sorted(list(range(len(marker_list))), key = alphanum_key) \ No newline at end of file diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index f61c40b4..ac2ff017 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -202,8 +202,8 @@ class NetworkGraph(object): self.js_data = dict(traits = [trait.name for trait in self.traits], groups = groups, - cols = range(len(self.traits)), - rows = range(len(self.traits)), + cols = list(range(len(self.traits))), + rows = list(range(len(self.traits))), samples = self.all_sample_list, sample_data = self.sample_data, elements = self.elements,) diff --git a/wqflask/wqflask/pbkdf2.py b/wqflask/wqflask/pbkdf2.py index 0ed50790..917b9d31 100644 --- a/wqflask/wqflask/pbkdf2.py +++ b/wqflask/wqflask/pbkdf2.py @@ -68,9 +68,9 @@ def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): h.update(x) return list(map(ord, h.digest())) buf = [] - for block in xrange(1, -(-keylen // mac.digest_size) + 1): + for block in range(1, -(-keylen // mac.digest_size) + 1): rv = u = _pseudorandom(salt + _pack_int(block)) - for i in xrange(iterations - 1): + for i in range(iterations - 1): u = _pseudorandom(''.join(map(chr, u))) rv = list(starmap(xor, zip(rv, u))) buf.extend(rv) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index de4b01eb..5b3946e3 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -266,7 +266,7 @@ def get_GO_symbols(a_search): def insert_newlines(string, every=64): """ This is because it is seemingly impossible to change the width of the description column, so I'm just manually adding line breaks """ lines = [] - for i in xrange(0, len(string), every): + for i in range(0, len(string), every): lines.append(string[i:i+every]) return '\n'.join(lines) -- cgit v1.2.3 From 3aaa28ea762c496eeb84e09e45194e3fd2a51673 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 03:45:49 +0300 Subject: Make Python more idiomatic Run `2to3-3.8 -f idioms -w .` See: --- scripts/maintenance/readProbeSetMean_v7.py | 6 ++---- scripts/maintenance/readProbeSetSE_v7.py | 6 ++---- wqflask/base/data_set.py | 4 ++-- wqflask/utility/authentication_tools.py | 2 +- wqflask/utility/svg.py | 2 +- wqflask/wqflask/ctl/ctl_analysis.py | 2 +- wqflask/wqflask/show_trait/SampleList.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 2 +- wqflask/wqflask/user_login.py | 2 +- 9 files changed, 12 insertions(+), 16 deletions(-) (limited to 'wqflask/utility') diff --git a/scripts/maintenance/readProbeSetMean_v7.py b/scripts/maintenance/readProbeSetMean_v7.py index 97767715..864b4e08 100755 --- a/scripts/maintenance/readProbeSetMean_v7.py +++ b/scripts/maintenance/readProbeSetMean_v7.py @@ -80,8 +80,7 @@ while line: if kj%100000 == 0: print(('checked ',kj,' lines')) -GeneList = list(map(string.lower, GeneList)) -GeneList.sort() +GeneList = sorted(map(string.lower, GeneList)) if isCont==0: sys.exit(0) @@ -148,9 +147,8 @@ for item in results: print(Names) -Names = list(map(string.lower, Names)) +Names = sorted(map(string.lower, Names)) -Names.sort() # -- Fixed the lower case problem of ProbeSets affx-mur_b2_at doesn't exist --# ##---- compare genelist with names ----## diff --git a/scripts/maintenance/readProbeSetSE_v7.py b/scripts/maintenance/readProbeSetSE_v7.py index 833c3f5f..20a846a4 100755 --- a/scripts/maintenance/readProbeSetSE_v7.py +++ b/scripts/maintenance/readProbeSetSE_v7.py @@ -91,8 +91,7 @@ while line: if kj % 100000 == 0: print(('checked ', kj, ' lines')) -GeneList = list(map(string.lower, GeneList)) -GeneList.sort() +GeneList = sorted(map(string.lower, GeneList)) if isCont == 0: sys.exit(0) @@ -158,8 +157,7 @@ results = db.fetchall() Names = [] for item in results: Names.append(item[0]) - Names = list(map(string.lower, Names)) - Names.sort() # -- Fixed the lower case problem of ProbeSets affx-mur_b2_at doesn't exist --# + Names = sorted(map(string.lower, Names)) ##---- compare genelist with names ----## x = y = 0 diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index b0119b58..06e1c551 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -254,7 +254,7 @@ class Markers(object): logger.debug("length of self.markers:", len(self.markers)) logger.debug("length of p_values:", len(p_values)) - if type(p_values) is list: + if isinstance(p_values, list): # THIS IS only needed for the case when we are limiting the number of p-values calculated # if len(self.markers) > len(p_values): # self.markers = self.markers[:len(p_values)] @@ -270,7 +270,7 @@ class Markers(object): marker['lod_score'] = -math.log10(marker['p_value']) # Using -log(p) for the LRS; need to ask Rob how he wants to get LRS from p-values marker['lrs_value'] = -math.log10(marker['p_value']) * 4.61 - elif type(p_values) is dict: + elif isinstance(p_values, dict): filtered_markers = [] for marker in self.markers: #logger.debug("marker[name]", marker['name']) diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index ece7022c..bc03eb55 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__ ) def check_resource_availability(dataset, trait_id=None): #At least for now assume temporary entered traits are accessible - if type(dataset) == str: + if isinstance(dataset, str): return webqtlConfig.DEFAULT_PRIVILEGES if dataset.type == "Temp": return webqtlConfig.DEFAULT_PRIVILEGES diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index 872f22fe..874ada9d 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -332,7 +332,7 @@ class SVGelement: f.write('\n'+'\t'*(level+2)+line) f.write('\n'+'\t'*(level+1)+']]>\n') if self.text: - if type(self.text) == type(''): # If the text is only text + if isinstance(self.text, type('')): # If the text is only text f.write(_escape(str(self.text))) else: # If the text is a spannedtext class f.write(str(self.text)) diff --git a/wqflask/wqflask/ctl/ctl_analysis.py b/wqflask/wqflask/ctl/ctl_analysis.py index f0be7a98..e58a7b87 100644 --- a/wqflask/wqflask/ctl/ctl_analysis.py +++ b/wqflask/wqflask/ctl/ctl_analysis.py @@ -175,7 +175,7 @@ class CTL(object): sys.stdout.flush() # Create the interactive graph for cytoscape visualization (Nodes and Edges) - if not type(significant) == ri.RNULLType: + if not isinstance(significant, ri.RNULLType): for x in range(len(significant[0])): logger.debug(significant[0][x], significant[1][x], significant[2][x]) # Debug to console tsS = significant[0][x].split(':') # Source diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index ad78ebcc..21ba7f63 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -43,7 +43,7 @@ class SampleList(object): for counter, sample_name in enumerate(sample_names, 1): sample_name = sample_name.replace("_2nd_", "") - if type(self.this_trait) is list: #ZS: self.this_trait will be a list if it is a Temp trait + if isinstance(self.this_trait, list): #ZS: self.this_trait will be a list if it is a Temp trait if counter <= len(self.this_trait) and str(self.this_trait[counter-1]).upper() != 'X': sample = webqtlCaseData.webqtlCaseData(name=sample_name, value=float(self.this_trait[counter-1])) else: diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index c156e61b..65899ab2 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -625,7 +625,7 @@ def get_categorical_variables(this_trait, sample_list): def get_genotype_scales(genofiles): geno_scales = {} - if type(genofiles) is list: + if isinstance(genofiles, list): for the_file in genofiles: file_location = the_file['location'] geno_scales[file_location] = get_scales_from_genofile(file_location) diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index cfee0079..04672b45 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -193,7 +193,7 @@ def login(): if user_details: submitted_password = params['password'] pwfields = user_details['password'] - if type(pwfields) is str: + if isinstance(pwfields, str): pwfields = json.loads(pwfields) encrypted_pass_fields = encode_password(pwfields, submitted_password) password_match = pbkdf2.safe_str_cmp(encrypted_pass_fields['password'], pwfields['password']) -- cgit v1.2.3 From db41cd49b6d8ccd2c3318209118ffe098bc9293e Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 19 Aug 2020 03:57:05 +0300 Subject: Remove extra whitespace(or add it) from comma separated items See: --- etc/default_settings.py | 2 +- scripts/maintenance/QTL_Reaper_v6.py | 4 +- scripts/maintenance/readProbeSetMean_v7.py | 28 ++-- setup.py | 2 +- wqflask/base/trait.py | 6 +- wqflask/db/call.py | 10 +- wqflask/db/webqtlDatabaseFunction.py | 8 +- wqflask/maintenance/gen_select_dataset.py | 2 +- wqflask/maintenance/quantile_normalize.py | 2 +- wqflask/maintenance/set_resource_defaults.py | 2 +- wqflask/utility/Plot.py | 48 +++--- wqflask/utility/elasticsearch_tools.py | 2 +- wqflask/utility/logger.py | 26 +-- wqflask/utility/pillow_utils.py | 4 +- wqflask/utility/startup_config.py | 2 +- wqflask/utility/svg.py | 130 +++++++------- wqflask/utility/tools.py | 32 ++-- wqflask/utility/webqtlUtil.py | 16 +- wqflask/wqflask/api/router.py | 8 +- wqflask/wqflask/correlation/show_corr_results.py | 12 +- .../wqflask/correlation_matrix/show_corr_matrix.py | 8 +- wqflask/wqflask/do_search.py | 4 +- .../wqflask/external_tools/send_to_geneweaver.py | 8 +- .../marker_regression/display_mapping_results.py | 186 ++++++++++----------- wqflask/wqflask/marker_regression/plink_mapping.py | 6 +- wqflask/wqflask/marker_regression/run_mapping.py | 2 +- wqflask/wqflask/search_results.py | 2 +- wqflask/wqflask/show_trait/SampleList.py | 2 +- wqflask/wqflask/user_manager.py | 2 +- wqflask/wqflask/views.py | 8 +- 30 files changed, 287 insertions(+), 287 deletions(-) (limited to 'wqflask/utility') diff --git a/etc/default_settings.py b/etc/default_settings.py index f368237b..82c605da 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -24,7 +24,7 @@ import os import sys -GN_VERSION = open("../etc/VERSION","r").read() +GN_VERSION = open("../etc/VERSION", "r").read() GN_SERVER_URL = "http://localhost:8880/" # REST API server # ---- MySQL diff --git a/scripts/maintenance/QTL_Reaper_v6.py b/scripts/maintenance/QTL_Reaper_v6.py index 2fbeb53b..35f2d1a1 100755 --- a/scripts/maintenance/QTL_Reaper_v6.py +++ b/scripts/maintenance/QTL_Reaper_v6.py @@ -7,7 +7,7 @@ import reaper import MySQLdb import time -con = MySQLdb.Connect(db='db_webqtl',user='username',passwd='', host="localhost") +con = MySQLdb.Connect(db='db_webqtl', user='username', passwd='', host="localhost") cursor = con.cursor() genotypeDir = '/gnshare/gn/web/genotypes/' @@ -102,7 +102,7 @@ for ProbeSetFreezeId in ProbeSetFreezeIds: kj += 1 if kj%1000==0: - print((ProbeSetFreezeId, InbredSets[InbredSetId],kj)) + print((ProbeSetFreezeId, InbredSets[InbredSetId], kj)) print(ProbeSetFreezeIds) diff --git a/scripts/maintenance/readProbeSetMean_v7.py b/scripts/maintenance/readProbeSetMean_v7.py index 864b4e08..59a51cf9 100755 --- a/scripts/maintenance/readProbeSetMean_v7.py +++ b/scripts/maintenance/readProbeSetMean_v7.py @@ -39,7 +39,7 @@ fp = open("%s" % input_file_name, 'rb') try: passwd = getpass.getpass('Please enter mysql password here : ') - con = MySQLdb.Connect(db='db_webqtl',host='localhost', user='username',passwd=passwd) + con = MySQLdb.Connect(db='db_webqtl', host='localhost', user='username', passwd=passwd) db = con.cursor() print("You have successfully connected to mysql.\n") @@ -60,14 +60,14 @@ print('Checking if each line have same number of members') GeneList = [] isCont = 1 header = fp.readline() -header = string.split(string.strip(header),'\t') +header = string.split(string.strip(header), '\t') header = list(map(string.strip, header)) nfield = len(header) line = fp.readline() kj=0 while line: - line2 = string.split(string.strip(line),'\t') + line2 = string.split(string.strip(line), '\t') line2 = list(map(string.strip, line2)) if len(line2) != nfield: print(("Error : " + line)) @@ -78,7 +78,7 @@ while line: kj+=1 if kj%100000 == 0: - print(('checked ',kj,' lines')) + print(('checked ', kj, ' lines')) GeneList = sorted(map(string.lower, GeneList)) @@ -86,7 +86,7 @@ if isCont==0: sys.exit(0) -print(('used ',time.time()-time0,' seconds')) +print(('used ', time.time()-time0, ' seconds')) ######################################################################### # # Check if each strain exist in database @@ -98,7 +98,7 @@ print('Checking if each strain exist in database') isCont = 1 fp.seek(0) header = fp.readline() -header = string.split(string.strip(header),'\t') +header = string.split(string.strip(header), '\t') header = list(map(string.strip, header)) header = list(map(translateAlias, header)) header = header[dataStart:] @@ -108,14 +108,14 @@ for item in header: db.execute('select Id from Strain where Name = "%s"' % item) Ids.append(db.fetchall()[0][0]) except: - print((item,'does not exist, check the if the strain name is correct')) + print((item, 'does not exist, check the if the strain name is correct')) isCont=0 if isCont==0: sys.exit(0) -print(('used ',time.time()-time0,' seconds')) +print(('used ', time.time()-time0, ' seconds')) ######################################################################## # # Check if each ProbeSet exist in database @@ -126,7 +126,7 @@ print('Check if each ProbeSet exist in database') ##---- find PID is name or target ----## line = fp.readline() line = fp.readline() -line2 = string.split(string.strip(line),'\t') +line2 = string.split(string.strip(line), '\t') line2 = list(map(string.strip, line2)) PId = line2[0] @@ -185,7 +185,7 @@ if isCont==0: sys.exit(0) -print(('used ',time.time()-time0,' seconds')) +print(('used ', time.time()-time0, ' seconds')) ######################################################################### # # Insert data into database @@ -200,7 +200,7 @@ results = db.fetchall() NameIds = {} for item in results: NameIds[item[0]] = item[1] -print(('used ',time.time()-time0,' seconds')) +print(('used ', time.time()-time0, ' seconds')) print('inserting data') @@ -220,7 +220,7 @@ kj = 0 values1 = [] values2 = [] while line: - line2 = string.split(string.strip(line),'\t') + line2 = string.split(string.strip(line), '\t') line2 = list(map(string.strip, line2)) PId = line2[0] recordId = NameIds[PId] @@ -253,8 +253,8 @@ while line: values1=[] values2=[] - print(('Inserted ', kj,' lines')) - print(('used ',time.time()-time0,' seconds')) + print(('Inserted ', kj, ' lines')) + print(('used ', time.time()-time0, ' seconds')) line = fp.readline() diff --git a/setup.py b/setup.py index a9b71fab..8436dcd3 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup(name='genenetwork2', url = "https://github.com/genenetwork/genenetwork2/blob/master/README.md", description = 'Website and tools for genetics.', include_package_data=True, - packages=['wqflask','etc'], + packages=['wqflask', 'etc'], scripts=['bin/genenetwork2'], # package_data = { # 'etc': ['*.py'] diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 2b8f2e72..05b272c3 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -193,7 +193,7 @@ class GeneralTrait(object): ''' if self.chr and self.mb: - self.location = 'Chr %s @ %s Mb' % (self.chr,self.mb) + self.location = 'Chr %s @ %s Mb' % (self.chr, self.mb) elif self.chr: self.location = 'Chr %s @ Unknown position' % (self.chr) else: @@ -440,7 +440,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif dataset.type == 'Geno': - display_fields_string = string.join(dataset.display_fields,',Geno.') + display_fields_string = string.join(dataset.display_fields, ',Geno.') display_fields_string = 'Geno.' + display_fields_string query = """ SELECT %s @@ -459,7 +459,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): query = """SELECT %s FROM %s WHERE Name = %s""" logger.sql(query) trait_info = g.db.execute(query, - (string.join(dataset.display_fields,','), + (string.join(dataset.display_fields, ','), dataset.type, trait.name)).fetchone() if trait_info: diff --git a/wqflask/db/call.py b/wqflask/db/call.py index 82cfebb4..3b8f782e 100644 --- a/wqflask/db/call.py +++ b/wqflask/db/call.py @@ -26,8 +26,8 @@ GN_SERVER result when set (which should return a Tuple) else: res2 = result, if LOG_SQL: - logger.debug("Replaced SQL call",query) - logger.debug(path,res2) + logger.debug("Replaced SQL call", query) + logger.debug(path, res2) return res2 else: return fetchone(query) @@ -37,7 +37,7 @@ def fetchone(query): original fetchone, but with logging) """ - with Bench("SQL",LOG_SQL): + with Bench("SQL", LOG_SQL): def helper(query): res = g.db.execute(query) return res.fetchone() @@ -48,7 +48,7 @@ def fetchall(query): original fetchall, but with logging) """ - with Bench("SQL",LOG_SQL): + with Bench("SQL", LOG_SQL): def helper(query): res = g.db.execute(query) return res.fetchall() @@ -58,7 +58,7 @@ def gn_server(path): """Return JSON record by calling GN_SERVER """ - with Bench("GN_SERVER",LOG_SQL): + with Bench("GN_SERVER", LOG_SQL): res = urllib.request.urlopen(GN_SERVER_URL+path) rest = res.read() res2 = json.loads(rest) diff --git a/wqflask/db/webqtlDatabaseFunction.py b/wqflask/db/webqtlDatabaseFunction.py index 8a9dc79d..2805febd 100644 --- a/wqflask/db/webqtlDatabaseFunction.py +++ b/wqflask/db/webqtlDatabaseFunction.py @@ -35,13 +35,13 @@ def retrieve_species(group): """Get the species of a group (e.g. returns string "mouse" on "BXD" """ - result = fetch1("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % (group),"/cross/"+group+".json",lambda r: (r["species"],))[0] - logger.debug("retrieve_species result:",result) + result = fetch1("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % (group), "/cross/"+group+".json", lambda r: (r["species"],))[0] + logger.debug("retrieve_species result:", result) return result def retrieve_species_id(group): - result = fetch1("select SpeciesId from InbredSet where Name = '%s'" % (group),"/cross/"+group+".json",lambda r: (r["species_id"],))[0] - logger.debug("retrieve_species_id result:",result) + result = fetch1("select SpeciesId from InbredSet where Name = '%s'" % (group), "/cross/"+group+".json", lambda r: (r["species_id"],))[0] + logger.debug("retrieve_species_id result:", result) return result diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index 78217587..d12b328f 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -41,7 +41,7 @@ from __future__ import print_function, division import sys # NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead -sys.path.insert(0,'./') +sys.path.insert(0, './') # NEW: import app to avoid a circular dependency on utility.tools from wqflask import app diff --git a/wqflask/maintenance/quantile_normalize.py b/wqflask/maintenance/quantile_normalize.py index 82b695f4..43edfd13 100644 --- a/wqflask/maintenance/quantile_normalize.py +++ b/wqflask/maintenance/quantile_normalize.py @@ -1,7 +1,7 @@ from __future__ import absolute_import, print_function, division import sys -sys.path.insert(0,'./') +sys.path.insert(0, './') diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index 54fd8e7e..d53a255b 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -22,7 +22,7 @@ import sys import json # NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead -sys.path.insert(0,'./') +sys.path.insert(0, './') # NEW: import app to avoid a circular dependency on utility.tools from wqflask import app diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index c9053dde..4f6e694e 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -58,7 +58,7 @@ def cformat(d, rank=0): strD = "%2.6f" % d if rank == 0: - while strD[-1] in ('0','.'): + while strD[-1] in ('0', '.'): if strD[-1] == '0' and strD[-2] == '.' and len(strD) <= 4: break elif strD[-1] == '.': @@ -162,7 +162,7 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab j = int((item-xLow)/step) Count[j] += 1 - yLow, yTop, stepY=detScale(0,max(Count)) + yLow, yTop, stepY=detScale(0, max(Count)) #draw data xScale = plotWidth/(xTop-xLow) @@ -174,7 +174,7 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab xc = (dataXY[i]-xLow)*xScale+xLeftOffset yc =-(count-yLow)*yScale+yTopOffset+plotHeight im_drawer.rectangle( - xy=((xc+2,yc),(xc+barWidth-2,yTopOffset+plotHeight)), + xy=((xc+2, yc), (xc+barWidth-2, yTopOffset+plotHeight)), outline=barColor, fill=barColor) #draw drawing region @@ -183,81 +183,81 @@ def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLab ) #draw scale - scaleFont=ImageFont.truetype(font=COUR_FILE,size=11) + scaleFont=ImageFont.truetype(font=COUR_FILE, size=11) x=xLow for i in range(int(stepX)+1): xc=xLeftOffset+(x-xLow)*xScale im_drawer.line( - xy=((xc,yTopOffset+plotHeight),(xc,yTopOffset+plotHeight+5)), + xy=((xc, yTopOffset+plotHeight), (xc, yTopOffset+plotHeight+5)), fill=axesColor) strX = cformat(d=x, rank=0) im_drawer.text( text=strX, - xy=(xc-im_drawer.textsize(strX,font=scaleFont)[0]/2, - yTopOffset+plotHeight+14),font=scaleFont) + xy=(xc-im_drawer.textsize(strX, font=scaleFont)[0]/2, + yTopOffset+plotHeight+14), font=scaleFont) x+= (xTop - xLow)/stepX y=yLow for i in range(int(stepY)+1): yc=yTopOffset+plotHeight-(y-yLow)*yScale - im_drawer.line(xy=((xLeftOffset,yc),(xLeftOffset-5,yc)), fill=axesColor) + im_drawer.line(xy=((xLeftOffset, yc), (xLeftOffset-5, yc)), fill=axesColor) strY = "%d" %y im_drawer.text( text=strY, - xy=(xLeftOffset-im_drawer.textsize(strY,font=scaleFont)[0]-6,yc+5), + xy=(xLeftOffset-im_drawer.textsize(strY, font=scaleFont)[0]-6, yc+5), font=scaleFont) y+= (yTop - yLow)/stepY #draw label - labelFont=ImageFont.truetype(font=TAHOMA_FILE,size=17) + labelFont=ImageFont.truetype(font=TAHOMA_FILE, size=17) if XLabel: im_drawer.text( text=XLabel, xy=(xLeftOffset+( - plotWidth-im_drawer.textsize(XLabel,font=labelFont)[0])/2.0, + plotWidth-im_drawer.textsize(XLabel, font=labelFont)[0])/2.0, yTopOffset+plotHeight+yBottomOffset-10), - font=labelFont,fill=labelColor) + font=labelFont, fill=labelColor) if YLabel: draw_rotated_text(canvas, text=YLabel, xy=(19, yTopOffset+plotHeight-( plotHeight-im_drawer.textsize( - YLabel,font=labelFont)[0])/2.0), + YLabel, font=labelFont)[0])/2.0), font=labelFont, fill=labelColor, angle=90) - labelFont=ImageFont.truetype(font=VERDANA_FILE,size=16) + labelFont=ImageFont.truetype(font=VERDANA_FILE, size=16) if title: im_drawer.text( text=title, xy=(xLeftOffset+(plotWidth-im_drawer.textsize( - title,font=labelFont)[0])/2.0, + title, font=labelFont)[0])/2.0, 20), - font=labelFont,fill=labelColor) + font=labelFont, fill=labelColor) # This function determines the scale of the plot -def detScaleOld(min,max): +def detScaleOld(min, max): if min>=max: return None elif min == -1.0 and max == 1.0: - return [-1.2,1.2,12] + return [-1.2, 1.2, 12] else: a=max-min b=floor(log10(a)) - c=pow(10.0,b) + c=pow(10.0, b) if a < c*5.0: c/=2.0 #print a,b,c low=c*floor(min/c) high=c*ceil(max/c) - return [low,high,round((high-low)/c)] + return [low, high, round((high-low)/c)] def detScale(min=0,max=0): if min>=max: return None elif min == -1.0 and max == 1.0: - return [-1.2,1.2,12] + return [-1.2, 1.2, 12] else: a=max-min if max != 0: @@ -269,7 +269,7 @@ def detScale(min=0,max=0): min -= 0.1*a a=max-min b=floor(log10(a)) - c=pow(10.0,b) + c=pow(10.0, b) low=c*floor(min/c) high=c*ceil(max/c) n = round((high-low)/c) @@ -287,7 +287,7 @@ def detScale(min=0,max=0): high=c*ceil(max/c) n = round((high-low)/c) - return [low,high,n] + return [low, high, n] def bluefunc(x): return 1.0 / (1.0 + exp(-10*(x-0.6))) @@ -296,7 +296,7 @@ def redfunc(x): return 1.0 / (1.0 + exp(10*(x-0.5))) def greenfunc(x): - return 1 - pow(redfunc(x+0.2),2) - bluefunc(x-0.3) + return 1 - pow(redfunc(x+0.2), 2) - bluefunc(x-0.3) def colorSpectrum(n=100): multiple = 10 diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 15cdd0bc..a5580811 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -59,7 +59,7 @@ def get_elasticsearch_connection(for_user=True): try: assert(ELASTICSEARCH_HOST) assert(ELASTICSEARCH_PORT) - logger.info("ES HOST",ELASTICSEARCH_HOST) + logger.info("ES HOST", ELASTICSEARCH_HOST) es = Elasticsearch([{ "host": ELASTICSEARCH_HOST, "port": ELASTICSEARCH_PORT diff --git a/wqflask/utility/logger.py b/wqflask/utility/logger.py index 510b1041..e904eb94 100644 --- a/wqflask/utility/logger.py +++ b/wqflask/utility/logger.py @@ -42,10 +42,10 @@ class GNLogger: """ - def __init__(self,name): + def __init__(self, name): self.logger = logging.getLogger(name) - def setLevel(self,value): + def setLevel(self, value): """Set the undelying log level""" self.logger.setLevel(value) @@ -54,7 +54,7 @@ class GNLogger: level=num to filter on LOG_LEVEL_DEBUG. """ - self.collect(self.logger.debug,*args) + self.collect(self.logger.debug, *args) def debug20(self,*args): """Call logging.debug for multiple args. Use level=num to filter on @@ -63,15 +63,15 @@ LOG_LEVEL_DEBUG (NYI). """ if level <= LOG_LEVEL_DEBUG: if self.logger.getEffectiveLevel() < 20: - self.collect(self.logger.debug,*args) + self.collect(self.logger.debug, *args) def info(self,*args): """Call logging.info for multiple args""" - self.collect(self.logger.info,*args) + self.collect(self.logger.info, *args) def warning(self,*args): """Call logging.warning for multiple args""" - self.collect(self.logger.warning,*args) + self.collect(self.logger.warning, *args) # self.logger.warning(self.collect(*args)) def error(self,*args): @@ -79,13 +79,13 @@ LOG_LEVEL_DEBUG (NYI). now = datetime.datetime.utcnow() time_str = now.strftime('%H:%M:%S UTC %Y%m%d') l = [time_str]+list(args) - self.collect(self.logger.error,*l) + self.collect(self.logger.error, *l) def infof(self,*args): """Call logging.info for multiple args lazily""" # only evaluate function when logging if self.logger.getEffectiveLevel() < 30: - self.collectf(self.logger.debug,*args) + self.collectf(self.logger.debug, *args) def debugf(self,level=0,*args): """Call logging.debug for multiple args lazily and handle @@ -95,15 +95,15 @@ LOG_LEVEL_DEBUG (NYI). # only evaluate function when logging if level <= LOG_LEVEL_DEBUG: if self.logger.getEffectiveLevel() < 20: - self.collectf(self.logger.debug,*args) + self.collectf(self.logger.debug, *args) def sql(self, sqlcommand, fun = None): """Log SQL command, optionally invoking a timed fun""" if LOG_SQL: caller = stack()[1][3] - if caller in ['fetchone','fetch1','fetchall']: + if caller in ['fetchone', 'fetch1', 'fetchall']: caller = stack()[2][3] - self.info(caller,sqlcommand) + self.info(caller, sqlcommand) if fun: result = fun(sqlcommand) if LOG_SQL: @@ -119,7 +119,7 @@ LOG_LEVEL_DEBUG (NYI). if isinstance(a, str): out = out + a else: - out = out + pf(a,width=160) + out = out + pf(a, width=160) fun(out) def collectf(self,fun,*args): @@ -134,7 +134,7 @@ LOG_LEVEL_DEBUG (NYI). if isinstance(a, str): out = out + a else: - out = out + pf(a,width=160) + out = out + pf(a, width=160) fun(out) # Get the module logger. You can override log levels at the diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py index dfbf3e19..1e2ed075 100644 --- a/wqflask/utility/pillow_utils.py +++ b/wqflask/utility/pillow_utils.py @@ -10,9 +10,9 @@ WHITE = ImageColor.getrgb("white") def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90): # type: (Image, str, ImageFont, tuple, ImageColor, int) """Utility function draw rotated text""" - tmp_img = Image.new("RGBA", font.getsize(text), color=(0,0,0,0)) + tmp_img = Image.new("RGBA", font.getsize(text), color=(0, 0, 0, 0)) draw_text = ImageDraw.Draw(tmp_img) - draw_text.text(text=text, xy=(0,0), font=font, fill=fill) + draw_text.text(text=text, xy=(0, 0), font=font, fill=fill) tmp_img2 = tmp_img.rotate(angle, expand=1) tmp_img2.save("/tmp/{}.png".format(text), format="png") canvas.paste(im=tmp_img2, box=tuple([int(i) for i in xy])) diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py index 42ead709..f1aaebb6 100644 --- a/wqflask/utility/startup_config.py +++ b/wqflask/utility/startup_config.py @@ -36,4 +36,4 @@ def app_config(): # import utility.elasticsearch_tools as es # es.test_elasticsearch_connection() - print(("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL")))) + print(("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE, str(port), ENDC, get_setting("WEBSERVER_URL")))) diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index 874ada9d..19eda0ce 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -447,7 +447,7 @@ class rect(SVGelement): if width == None or height == None: raise ValueError('both height and width are required') - SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) + SVGelement.__init__(self, 'rect', {'width':width,'height':height}, **args) if x!=None: self.attributes['x']=x if y!=None: @@ -468,7 +468,7 @@ class ellipse(SVGelement): if rx==None or ry== None: raise ValueError('both rx and ry are required') - SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) + SVGelement.__init__(self, 'ellipse', {'rx':rx,'ry':ry}, **args) if cx!=None: self.attributes['cx']=cx if cy!=None: @@ -489,7 +489,7 @@ class circle(SVGelement): def __init__(self,cx=None,cy=None,r=None,fill=None,stroke=None,stroke_width=None,**args): if r==None: raise ValueError('r is required') - SVGelement.__init__(self,'circle',{'r':r},**args) + SVGelement.__init__(self, 'circle', {'r':r}, **args) if cx!=None: self.attributes['cx']=cx if cy!=None: @@ -508,7 +508,7 @@ class point(circle): very small rectangle if you use many points because a circle is difficult to render. """ def __init__(self,x,y,fill='black',**args): - circle.__init__(self,x,y,1,fill,**args) + circle.__init__(self, x, y, 1, fill, **args) class line(SVGelement): """l=line(x1,y1,x2,y2,stroke,stroke_width,**args) @@ -516,7 +516,7 @@ class line(SVGelement): A line is defined by a begin x,y pair and an end x,y pair """ def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'line',**args) + SVGelement.__init__(self, 'line', **args) if x1!=None: self.attributes['x1']=x1 if y1!=None: @@ -536,7 +536,7 @@ class polyline(SVGelement): a polyline is defined by a list of xy pairs """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'polyline',{'points':_xypointlist(points)},**args) + SVGelement.__init__(self, 'polyline', {'points':_xypointlist(points)}, **args) if fill!=None: self.attributes['fill']=fill if stroke_width!=None: @@ -550,7 +550,7 @@ class polygon(SVGelement): a polygon is defined by a list of xy pairs """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): - SVGelement.__init__(self,'polygon',{'points':_xypointlist(points)},**args) + SVGelement.__init__(self, 'polygon', {'points':_xypointlist(points)}, **args) if fill!=None: self.attributes['fill']=fill if stroke_width!=None: @@ -564,7 +564,7 @@ class path(SVGelement): a path is defined by a path object and optional width, stroke and fillcolor """ def __init__(self,pathdata,fill=None,stroke=None,stroke_width=None,id=None,**args): - SVGelement.__init__(self,'path',{'d':str(pathdata)},**args) + SVGelement.__init__(self, 'path', {'d':str(pathdata)}, **args) if stroke!=None: self.attributes['stroke']=stroke if fill!=None: @@ -581,7 +581,7 @@ class text(SVGelement): a text element can bge used for displaying text on the screen """ def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args): - SVGelement.__init__(self,'text',**args) + SVGelement.__init__(self, 'text', **args) if x!=None: self.attributes['x']=x if y!=None: @@ -602,7 +602,7 @@ class textpath(SVGelement): a textpath places a text on a path which is referenced by a link. """ def __init__(self,link,text=None,**args): - SVGelement.__init__(self,'textPath',{'xlink:href':link},**args) + SVGelement.__init__(self, 'textPath', {'xlink:href':link}, **args) if text!=None: self.text=text @@ -614,7 +614,7 @@ class pattern(SVGelement): in x and y to cover the areas to be painted. """ def __init__(self,x=None,y=None,width=None,height=None,patternUnits=None,**args): - SVGelement.__init__(self,'pattern',**args) + SVGelement.__init__(self, 'pattern', **args) if x!=None: self.attributes['x']=x if y!=None: @@ -633,7 +633,7 @@ class title(SVGelement): add at least one to the root svg element """ def __init__(self,text=None,**args): - SVGelement.__init__(self,'title',**args) + SVGelement.__init__(self, 'title', **args) if text!=None: self.text=text @@ -644,7 +644,7 @@ class description(SVGelement): Add this element before adding other elements. """ def __init__(self,text=None,**args): - SVGelement.__init__(self,'desc',**args) + SVGelement.__init__(self, 'desc', **args) if text!=None: self.text=text @@ -655,7 +655,7 @@ class lineargradient(SVGelement): stop elements van be added to define the gradient colors. """ def __init__(self,x1=None,y1=None,x2=None,y2=None,id=None,**args): - SVGelement.__init__(self,'linearGradient',**args) + SVGelement.__init__(self, 'linearGradient', **args) if x1!=None: self.attributes['x1']=x1 if y1!=None: @@ -674,7 +674,7 @@ class radialgradient(SVGelement): stop elements van be added to define the gradient colors. """ def __init__(self,cx=None,cy=None,r=None,fx=None,fy=None,id=None,**args): - SVGelement.__init__(self,'radialGradient',**args) + SVGelement.__init__(self, 'radialGradient', **args) if cx!=None: self.attributes['cx']=cx if cy!=None: @@ -694,7 +694,7 @@ class stop(SVGelement): Puts a stop color at the specified radius """ def __init__(self,offset,stop_color=None,**args): - SVGelement.__init__(self,'stop',{'offset':offset},**args) + SVGelement.__init__(self, 'stop', {'offset':offset}, **args) if stop_color!=None: self.attributes['stop-color']=stop_color @@ -704,7 +704,7 @@ class style(SVGelement): Add a CDATA element to this element for defing in line stylesheets etc.. """ def __init__(self,type,cdata=None,**args): - SVGelement.__init__(self,'style',{'type':type},cdata=cdata, **args) + SVGelement.__init__(self, 'style', {'type':type}, cdata=cdata, **args) class image(SVGelement): @@ -715,7 +715,7 @@ class image(SVGelement): def __init__(self,url,x=None,y=None,width=None,height=None,**args): if width==None or height==None: raise ValueError('both height and width are required') - SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args) + SVGelement.__init__(self, 'image', {'xlink:href':url,'width':width,'height':height}, **args) if x!=None: self.attributes['x']=x if y!=None: @@ -727,7 +727,7 @@ class cursor(SVGelement): defines a custom cursor for a element or a drawing """ def __init__(self,url,**args): - SVGelement.__init__(self,'cursor',{'xlink:href':url},**args) + SVGelement.__init__(self, 'cursor', {'xlink:href':url}, **args) class marker(SVGelement): @@ -737,7 +737,7 @@ class marker(SVGelement): add an element to it which should be used as a marker. """ def __init__(self,id=None,viewBox=None,refx=None,refy=None,markerWidth=None,markerHeight=None,**args): - SVGelement.__init__(self,'marker',**args) + SVGelement.__init__(self, 'marker', **args) if id!=None: self.attributes['id']=id if viewBox!=None: @@ -758,7 +758,7 @@ class group(SVGelement): g.addElement(SVGelement) """ def __init__(self,id=None,**args): - SVGelement.__init__(self,'g',**args) + SVGelement.__init__(self, 'g', **args) if id!=None: self.attributes['id']=id @@ -772,7 +772,7 @@ class symbol(SVGelement): """ def __init__(self,id=None,viewBox=None,**args): - SVGelement.__init__(self,'symbol',**args) + SVGelement.__init__(self, 'symbol', **args) if id!=None: self.attributes['id']=id if viewBox!=None: @@ -784,7 +784,7 @@ class defs(SVGelement): container for defining elements """ def __init__(self,**args): - SVGelement.__init__(self,'defs',**args) + SVGelement.__init__(self, 'defs', **args) class switch(SVGelement): """sw=switch(**args) @@ -794,7 +794,7 @@ class switch(SVGelement): Refer to the SVG specification for details. """ def __init__(self,**args): - SVGelement.__init__(self,'switch',**args) + SVGelement.__init__(self, 'switch', **args) class use(SVGelement): @@ -803,7 +803,7 @@ class use(SVGelement): references a symbol by linking to its id and its position, height and width """ def __init__(self,link,x=None,y=None,width=None,height=None,**args): - SVGelement.__init__(self,'use',{'xlink:href':link},**args) + SVGelement.__init__(self, 'use', {'xlink:href':link}, **args) if x!=None: self.attributes['x']=x if y!=None: @@ -822,14 +822,14 @@ class link(SVGelement): a.addElement(SVGelement) """ def __init__(self,link='',**args): - SVGelement.__init__(self,'a',{'xlink:href':link},**args) + SVGelement.__init__(self, 'a', {'xlink:href':link}, **args) class view(SVGelement): """v=view(id,**args) a view can be used to create a view with different attributes""" def __init__(self,id=None,**args): - SVGelement.__init__(self,'view',**args) + SVGelement.__init__(self, 'view', **args) if id!=None: self.attributes['id']=id @@ -840,7 +840,7 @@ class script(SVGelement): """ def __init__(self,type,cdata=None,**args): - SVGelement.__init__(self,'script',{'type':type},cdata=cdata,**args) + SVGelement.__init__(self, 'script', {'type':type}, cdata=cdata, **args) class animate(SVGelement): """an=animate(attribute,from,to,during,**args) @@ -848,7 +848,7 @@ class animate(SVGelement): animates an attribute. """ def __init__(self,attribute,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animate',{'attributeName':attribute},**args) + SVGelement.__init__(self, 'animate', {'attributeName':attribute}, **args) if fr!=None: self.attributes['from']=fr if to!=None: @@ -862,7 +862,7 @@ class animateMotion(SVGelement): animates a SVGelement over the given path in dur seconds """ def __init__(self,pathdata,dur,**args): - SVGelement.__init__(self,'animateMotion',**args) + SVGelement.__init__(self, 'animateMotion', **args) if pathdata!=None: self.attributes['path']=str(pathdata) if dur!=None: @@ -874,7 +874,7 @@ class animateTransform(SVGelement): transform an element from and to a value. """ def __init__(self,type=None,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animateTransform',{'attributeName':'transform'},**args) + SVGelement.__init__(self, 'animateTransform', {'attributeName':'transform'}, **args) # As far as I know the attributeName is always transform if type!=None: self.attributes['type']=type @@ -890,7 +890,7 @@ class animateColor(SVGelement): Animates the color of a element """ def __init__(self,attribute,type=None,fr=None,to=None,dur=None,**args): - SVGelement.__init__(self,'animateColor',{'attributeName':attribute},**args) + SVGelement.__init__(self, 'animateColor', {'attributeName':attribute}, **args) if type!=None: self.attributes['type']=type if fr!=None: @@ -905,7 +905,7 @@ class set(SVGelement): sets an attribute to a value for a """ def __init__(self,attribute,to=None,dur=None,**args): - SVGelement.__init__(self,'set',{'attributeName':attribute},**args) + SVGelement.__init__(self, 'set', {'attributeName':attribute}, **args) if to!=None: self.attributes['to']=to if dur!=None: @@ -929,7 +929,7 @@ class svg(SVGelement): d.toXml() """ def __init__(self,viewBox=None, width=None, height=None,**args): - SVGelement.__init__(self,'svg',**args) + SVGelement.__init__(self, 'svg', **args) if viewBox!=None: self.attributes['viewBox']=_viewboxlist(viewBox) if width!=None: @@ -952,7 +952,7 @@ class drawing: def __init__(self, entity={}): self.svg=None self.entity = entity - def setSVG(self,svg): + def setSVG(self, svg): self.svg=svg # Voeg een element toe aan de grafiek toe. if use_dom_implementation==0: @@ -967,12 +967,12 @@ class drawing: xml.write("\n" % (item, self.entity[item])) xml.write("]") xml.write(">\n") - self.svg.toXml(0,xml) + self.svg.toXml(0, xml) if not filename: if compress: import gzip f=cStringIO.StringIO() - zf=gzip.GzipFile(fileobj=f,mode='wb') + zf=gzip.GzipFile(fileobj=f, mode='wb') zf.write(xml.getvalue()) zf.close() f.seek(0) @@ -982,11 +982,11 @@ class drawing: else: if filename[-4:]=='svgz': import gzip - f=gzip.GzipFile(filename=filename,mode="wb", compresslevel=9) + f=gzip.GzipFile(filename=filename, mode="wb", compresslevel=9) f.write(xml.getvalue()) f.close() else: - f=file(filename,'w') + f=file(filename, 'w') f.write(xml.getvalue()) f.close() @@ -997,40 +997,40 @@ class drawing: writes a svg drawing to the screen or to a file compresses if filename ends with svgz or if compress is true """ - doctype = implementation.createDocumentType('svg',"-//W3C//DTD SVG 1.0//EN""",'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ') + doctype = implementation.createDocumentType('svg', "-//W3C//DTD SVG 1.0//EN""", 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ') global root # root is defined global so it can be used by the appender. Its also possible to use it as an arugument but # that is a bit messy. - root=implementation.createDocument(None,None,doctype) + root=implementation.createDocument(None, None, doctype) # Create the xml document. global appender - def appender(element,elementroot): + def appender(element, elementroot): """This recursive function appends elements to an element and sets the attributes and type. It stops when alle elements have been appended""" if element.namespace: - e=root.createElementNS(element.namespace,element.type) + e=root.createElementNS(element.namespace, element.type) else: e=root.createElement(element.type) if element.text: textnode=root.createTextNode(element.text) e.appendChild(textnode) for attribute in list(element.attributes.keys()): #in element.attributes is supported from python 2.2 - e.setAttribute(attribute,str(element.attributes[attribute])) + e.setAttribute(attribute, str(element.attributes[attribute])) if element.elements: for el in element.elements: - e=appender(el,e) + e=appender(el, e) elementroot.appendChild(e) return elementroot - root=appender(self.svg,root) + root=appender(self.svg, root) if not filename: import cStringIO xml=cStringIO.StringIO() - PrettyPrint(root,xml) + PrettyPrint(root, xml) if compress: import gzip f=cStringIO.StringIO() - zf=gzip.GzipFile(fileobj=f,mode='wb') + zf=gzip.GzipFile(fileobj=f, mode='wb') zf.write(xml.getvalue()) zf.close() f.seek(0) @@ -1043,13 +1043,13 @@ class drawing: import gzip import cStringIO xml=cStringIO.StringIO() - PrettyPrint(root,xml) - f=gzip.GzipFile(filename=filename,mode='wb',compresslevel=9) + PrettyPrint(root, xml) + f=gzip.GzipFile(filename=filename, mode='wb', compresslevel=9) f.write(xml.getvalue()) f.close() else: - f=open(filename,'w') - PrettyPrint(root,f) + f=open(filename, 'w') + PrettyPrint(root, f) f.close() except: print(("Cannot write SVG file: " + filename)) @@ -1070,32 +1070,32 @@ if __name__=='__main__': d=drawing() - s=svg((0,0,100,100)) - r=rect(-100,-100,300,300,'cyan') + s=svg((0, 0, 100, 100)) + r=rect(-100, -100, 300, 300, 'cyan') s.addElement(r) t=title('SVGdraw Demo') s.addElement(t) g=group('animations') - e=ellipse(0,0,5,2) + e=ellipse(0, 0, 5, 2) g.addElement(e) - c=circle(0,0,1,'red') + c=circle(0, 0, 1, 'red') g.addElement(c) - pd=pathdata(0,-10) + pd=pathdata(0, -10) for i in range(6): - pd.relsmbezier(10,5,0,10) - pd.relsmbezier(-10,5,0,10) - an=animateMotion(pd,10) + pd.relsmbezier(10, 5, 0, 10) + pd.relsmbezier(-10, 5, 0, 10) + an=animateMotion(pd, 10) an.attributes['rotate']='auto-reverse' an.attributes['repeatCount']="indefinite" g.addElement(an) s.addElement(g) - for i in range(20,120,20): - u=use('#animations',i,0) + for i in range(20, 120, 20): + u=use('#animations', i, 0) s.addElement(u) - for i in range(0,120,20): - for j in range(5,105,10): - c=circle(i,j,1,'red','black',.5) + for i in range(0, 120, 20): + for j in range(5, 105, 10): + c=circle(i, j, 1, 'red', 'black', .5) s.addElement(c) d.setSVG(s) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 51a87fe1..68ef0f04 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -15,7 +15,7 @@ OVERRIDES = {} def app_set(command_id, value): """Set application wide value""" - app.config.setdefault(command_id,value) + app.config.setdefault(command_id, value) return value def get_setting(command_id,guess=None): @@ -45,7 +45,7 @@ def get_setting(command_id,guess=None): def value(command): if command: # sys.stderr.write("Found "+command+"\n") - app_set(command_id,command) + app_set(command_id, command) return command else: return None @@ -68,7 +68,7 @@ def get_setting(command_id,guess=None): def get_setting_bool(id): v = get_setting(id) - if v not in [0,False,'False','FALSE',None]: + if v not in [0, False, 'False', 'FALSE', None]: return True return False @@ -108,16 +108,16 @@ def js_path(module=None): 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) + return get_setting("REAPER_COMMAND", guess) def gemma_command(guess=None): - return assert_bin(get_setting("GEMMA_COMMAND",guess)) + return assert_bin(get_setting("GEMMA_COMMAND", guess)) def gemma_wrapper_command(guess=None): - return assert_bin(get_setting("GEMMA_WRAPPER_COMMAND",guess)) + return assert_bin(get_setting("GEMMA_WRAPPER_COMMAND", guess)) def plink_command(guess=None): - return assert_bin(get_setting("PLINK_COMMAND",guess)) + return assert_bin(get_setting("PLINK_COMMAND", guess)) def flat_file_exists(subdir): base = get_setting("GENENETWORK_FILES") @@ -180,7 +180,7 @@ def locate(name, subdir=None): raise Exception("Can not locate "+name+" in "+base) def locate_phewas(name, subdir=None): - return locate(name,'/phewas/'+subdir) + return locate(name, '/phewas/'+subdir) def locate_ignore_error(name, subdir=None): """ @@ -204,7 +204,7 @@ def tempdir(): """ Get UNIX TMPDIR by default """ - return valid_path(get_setting("TMPDIR","/tmp")) + return valid_path(get_setting("TMPDIR", "/tmp")) BLUE = '\033[94m' GREEN = '\033[92m' @@ -225,9 +225,9 @@ def show_settings(): keylist.sort() for k in keylist: try: - print(("%s: %s%s%s%s" % (k,BLUE,BOLD,get_setting(k),ENDC))) + print(("%s: %s%s%s%s" % (k, BLUE, BOLD, get_setting(k), ENDC))) except: - print(("%s: %s%s%s%s" % (k,GREEN,BOLD,app.config[k],ENDC))) + print(("%s: %s%s%s%s" % (k, GREEN, BOLD, app.config[k], ENDC))) # Cached values @@ -279,10 +279,10 @@ 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()) +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()) +PLINK_COMMAND = app_set("PLINK_COMMAND", plink_command()) GEMMA_WRAPPER_COMMAND = gemma_wrapper_command() TEMPDIR = tempdir() # defaults to UNIX TMPDIR assert_dir(TEMPDIR) @@ -295,11 +295,11 @@ assert_dir(JS_GUIX_PATH+'/cytoscape-panzoom') CSS_PATH = JS_GUIX_PATH # The CSS is bundled together with the JS # assert_dir(JS_PATH) -JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("javascript-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")) +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 79991149..77cc3416 100644 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -41,22 +41,22 @@ ParInfo ={ 'C57BL-6JxC57BL-6NJF2':['', '', 'C57BL/6J', 'C57BL/6NJ'], 'BXD300':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], 'B6BTBRF2':['B6BTBRF1', 'BTBRB6F1', 'C57BL/6J', 'BTBRT<+>tf/J'], -'BHHBF2':['B6HF2','HB6F2','C57BL/6J','C3H/HeJ'], -'BHF2':['B6HF2','HB6F2','C57BL/6J','C3H/HeJ'], +'BHHBF2':['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'], +'BHF2':['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'], 'B6D2F2':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], 'BDF2-1999':['B6D2F2', 'D2B6F2', 'C57BL/6J', 'DBA/2J'], 'BDF2-2005':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], -'CTB6F2':['CTB6F2','B6CTF2','C57BL/6J','Castaneous'], +'CTB6F2':['CTB6F2', 'B6CTF2', 'C57BL/6J', 'Castaneous'], 'CXB':['CBF1', 'BCF1', 'C57BL/6ByJ', 'BALB/cByJ'], 'AXBXA':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'], 'AXB':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'], 'BXA':['BAF1', 'ABF1', 'C57BL/6J', 'A/J'], 'LXS':['LSF1', 'SLF1', 'ISS', 'ILS'], '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'], +'BayXSha':['BayXShaF1', 'ShaXBayF1', 'Bay-0', 'Shahdara'], +'ColXBur':['ColXBurF1', 'BurXColF1', 'Col-0', 'Bur-0'], +'ColXCvi':['ColXCviF1', 'CviXColF1', 'Col-0', 'Cvi'], +'SXM':['SMF1', 'MSF1', 'Steptoe', 'Morex'], 'HRDP':['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv'] } @@ -91,7 +91,7 @@ def readLineCSV(line): ### dcrowell July 2008 returnList[0]=returnList[0][1:] return returnList -def cmpEigenValue(A,B): +def cmpEigenValue(A, B): try: if A[0] > B[0]: return -1 diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index 3fa1d5ba..b81da0dc 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -558,10 +558,10 @@ def trait_sample_data(dataset_name, trait_name, file_format = "json"): sample_list = [] for sample in sample_data: sample_dict = { - "sample_name" : sample[0], - "sample_name_2" : sample[1], - "value" : sample[2], - "data_id" : sample[3], + "sample_name": sample[0], + "sample_name_2": sample[1], + "value": sample[2], + "data_id": sample[3], } if sample[4]: sample_dict["se"] = sample[4] diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 15a21ee6..4116e2df 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -108,17 +108,17 @@ class CorrelationResults(object): self.sample_data = {} self.corr_type = start_vars['corr_type'] self.corr_method = start_vars['corr_sample_method'] - self.min_expr = get_float(start_vars,'min_expr') - self.p_range_lower = get_float(start_vars,'p_range_lower',-1.0) - self.p_range_upper = get_float(start_vars,'p_range_upper',1.0) + self.min_expr = get_float(start_vars, 'min_expr') + self.p_range_lower = get_float(start_vars, 'p_range_lower', -1.0) + self.p_range_upper = get_float(start_vars, 'p_range_upper', 1.0) if ('loc_chr' in start_vars and 'min_loc_mb' in start_vars and 'max_loc_mb' in start_vars): - self.location_chr = get_string(start_vars,'loc_chr') - self.min_location_mb = get_int(start_vars,'min_loc_mb') - self.max_location_mb = get_int(start_vars,'max_loc_mb') + self.location_chr = get_string(start_vars, 'loc_chr') + self.min_location_mb = get_int(start_vars, 'min_loc_mb') + self.max_location_mb = get_int(start_vars, 'max_loc_mb') else: self.location_chr = self.min_location_mb = self.max_location_mb = None diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index 832746bb..b582cd23 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -275,8 +275,8 @@ def zScore(trait_data_array): i = 0 for data in trait_data_array: N = len(data) - S = reduce(lambda x,y: x+y, data, 0.) - SS = reduce(lambda x,y: x+y*y, data, 0.) + S = reduce(lambda x, y: x+y, data, 0.) + SS = reduce(lambda x, y: x+y*y, data, 0.) mean = S/N var = SS - S*S/N stdev = math.sqrt(var/(N-1)) @@ -294,7 +294,7 @@ def sortEigenVectors(vector): combines = [] i = 0 for item in eigenValues: - combines.append([eigenValues[i],eigenVectors[i]]) + combines.append([eigenValues[i], eigenVectors[i]]) i += 1 combines.sort(webqtlUtil.cmpEigenValue) A = [] @@ -302,7 +302,7 @@ def sortEigenVectors(vector): for item in combines: A.append(item[0]) B.append(item[1]) - sum = reduce(lambda x,y: x+y, A, 0.0) + sum = reduce(lambda x, y: x+y, A, 0.0) A = [x*100.0/sum for x in A] return [A, B] except: diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 1e15d28f..cc9c1860 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -46,8 +46,8 @@ class DoSearch(object): def handle_wildcard(self, str): keyword = str.strip() - keyword = keyword.replace("*",".*") - keyword = keyword.replace("?",".") + keyword = keyword.replace("*", ".*") + keyword = keyword.replace("?", ".") return keyword diff --git a/wqflask/wqflask/external_tools/send_to_geneweaver.py b/wqflask/wqflask/external_tools/send_to_geneweaver.py index 7a5dba73..9844bab4 100644 --- a/wqflask/wqflask/external_tools/send_to_geneweaver.py +++ b/wqflask/wqflask/external_tools/send_to_geneweaver.py @@ -54,10 +54,10 @@ class SendToGeneWeaver(object): trait_name_list = get_trait_name_list(self.trait_list) self.hidden_vars = { - 'client' : "genenetwork", - 'species' : species_name, - 'idtype' : self.chip_name, - 'list' : string.join(trait_name_list, ","), + 'client': "genenetwork", + 'species': species_name, + 'idtype': self.chip_name, + 'list': string.join(trait_name_list, ","), } def get_trait_name_list(trait_list): diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index c8b9c405..f282b010 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -27,8 +27,8 @@ import datetime import string from math import * -from PIL import (Image,ImageDraw,ImageFont,ImageColor) -import sys,os +from PIL import (Image, ImageDraw, ImageFont, ImageColor) +import sys, os import cPickle import httplib import json @@ -426,7 +426,7 @@ class DisplayMappingResults(object): else: continue samplelist = list(self.genotype.prgy) - for j,_geno in enumerate (self.genotype[0][1].genotype): + for j, _geno in enumerate (self.genotype[0][1].genotype): for item in smd: if item.name == samplelist[j]: self.NR_INDIVIDUALS = self.NR_INDIVIDUALS + 1 @@ -518,7 +518,7 @@ class DisplayMappingResults(object): #Scales plot differently for high resolution if self.draw2X: - intCanvasX2 = Image.new("RGBA", size=(self.graphWidth*2,self.graphHeight*2)) + intCanvasX2 = Image.new("RGBA", size=(self.graphWidth*2, self.graphHeight*2)) gifmapX2 = self.plotIntMapping(intCanvasX2, startMb = self.startMb, endMb = self.endMb, showLocusForm= showLocusForm, zoom=2) intCanvasX2.save( "{}.png".format( @@ -745,17 +745,17 @@ class DisplayMappingResults(object): bootScale = bootScale[:-1] + [highestPercent] bootOffset = 50*fontZoom - bootScaleFont=ImageFont.truetype(font=VERDANA_FILE,size=13*fontZoom) + bootScaleFont=ImageFont.truetype(font=VERDANA_FILE, size=13*fontZoom) im_drawer.rectangle( xy=((canvas.size[0]-bootOffset, yZero-bootHeightThresh), - (canvas.size[0]-bootOffset-15*zoom,yZero)), + (canvas.size[0]-bootOffset-15*zoom, yZero)), fill = YELLOW, outline=BLACK) im_drawer.line( xy=((canvas.size[0]-bootOffset+4, yZero), (canvas.size[0]-bootOffset, yZero)), fill=BLACK) TEXT_Y_DISPLACEMENT = -8 - im_drawer.text(xy=(canvas.size[0]-bootOffset+10,yZero+TEXT_Y_DISPLACEMENT), text='0%', + im_drawer.text(xy=(canvas.size[0]-bootOffset+10, yZero+TEXT_Y_DISPLACEMENT), text='0%', font=bootScaleFont, fill=BLACK) for item in bootScale: @@ -763,10 +763,10 @@ class DisplayMappingResults(object): continue bootY = yZero-bootHeightThresh*item/highestPercent im_drawer.line( - xy=((canvas.size[0]-bootOffset+4,bootY), - (canvas.size[0]-bootOffset,bootY)), + xy=((canvas.size[0]-bootOffset+4, bootY), + (canvas.size[0]-bootOffset, bootY)), fill=BLACK) - im_drawer.text(xy=(canvas.size[0]-bootOffset+10,bootY+TEXT_Y_DISPLACEMENT), + im_drawer.text(xy=(canvas.size[0]-bootOffset+10, bootY+TEXT_Y_DISPLACEMENT), text='%2.1f'%item, font=bootScaleFont, fill=BLACK) if self.legendChecked: @@ -775,7 +775,7 @@ class DisplayMappingResults(object): smallLabelFont = ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) leftOffset = xLeftOffset+(nCol-1)*200 im_drawer.rectangle( - xy=((leftOffset,startPosY-6), (leftOffset+12,startPosY+6)), + xy=((leftOffset, startPosY-6), (leftOffset+12, startPosY+6)), fill=YELLOW, outline=BLACK) im_drawer.text(xy=(leftOffset+ 20, startPosY+TEXT_Y_DISPLACEMENT), text='Frequency of the Peak LRS', @@ -872,7 +872,7 @@ class DisplayMappingResults(object): TEXT_Y_DISPLACEMENT = -8 im_drawer.text( text="Sequence Site", - xy=(leftOffset+15,startPosY+TEXT_Y_DISPLACEMENT), font=smallLabelFont, + xy=(leftOffset+15, startPosY+TEXT_Y_DISPLACEMENT), font=smallLabelFont, fill=self.TOP_RIGHT_INFO_COLOR) def drawSNPTrackNew(self, canvas, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): @@ -922,7 +922,7 @@ class DisplayMappingResults(object): def drawMultiTraitName(self, fd, canvas, gifmap, showLocusForm, offset= (40, 120, 80, 10), zoom = 1): nameWidths = [] yPaddingTop = 10 - colorFont=ImageFont.truetype(font=TREBUC_FILE,size=12) + colorFont=ImageFont.truetype(font=TREBUC_FILE, size=12) if len(self.qtlresults) >20 and self.selectedChr > -1: rightShift = 20 rightShiftStep = 60 @@ -941,20 +941,20 @@ class DisplayMappingResults(object): rightShift += rightShiftStep name = thisTrait.displayName() - nameWidth, nameHeight = im_drawer.textsize(name,font=colorFont) + nameWidth, nameHeight = im_drawer.textsize(name, font=colorFont) nameWidths.append(nameWidth) im_drawer.rectangle( - xy=((rightShift,yPaddingTop+kstep*15), - (rectWidth+rightShift,yPaddingTop+10+kstep*15)), + xy=((rightShift, yPaddingTop+kstep*15), + (rectWidth+rightShift, yPaddingTop+10+kstep*15)), fill=thisLRSColor, outline=BLACK) im_drawer.text( - text=name,xy=(rectWidth+2+rightShift,yPaddingTop+10+kstep*15), - font=colorFont,fill=BLACK) + text=name, xy=(rectWidth+2+rightShift, yPaddingTop+10+kstep*15), + font=colorFont, fill=BLACK) if thisTrait.db: - COORDS = "%d,%d,%d,%d" %(rectWidth+2+rightShift,yPaddingTop+kstep*15,rectWidth+2+rightShift+nameWidth,yPaddingTop+10+kstep*15,) + COORDS = "%d,%d,%d,%d" %(rectWidth+2+rightShift, yPaddingTop+kstep*15, rectWidth+2+rightShift+nameWidth, yPaddingTop+10+kstep*15,) HREF= "javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm, thisTrait.db.name, thisTrait.name) - Areas = HT.Area(shape='rect',coords=COORDS,href=HREF) + Areas = HT.Area(shape='rect', coords=COORDS, href=HREF) gifmap.areas.append(Areas) def drawLegendPanel(self, canvas, offset= (40, 120, 80, 10), zoom = 1): @@ -968,80 +968,80 @@ class DisplayMappingResults(object): if zoom == 2: fontZoom = 1.5 - labelFont=ImageFont.truetype(font=TREBUC_FILE,size=12*fontZoom) + labelFont=ImageFont.truetype(font=TREBUC_FILE, size=12*fontZoom) startPosY = 15 stepPosY = 12*fontZoom if self.manhattan_plot != True: im_drawer.line( - xy=((xLeftOffset,startPosY),(xLeftOffset+32,startPosY)), + xy=((xLeftOffset, startPosY), (xLeftOffset+32, startPosY)), fill=self.LRS_COLOR, width=2) im_drawer.text( - text=self.LRS_LOD, xy=(xLeftOffset+40,startPosY+TEXT_Y_DISPLACEMENT), - font=labelFont,fill=BLACK) + text=self.LRS_LOD, xy=(xLeftOffset+40, startPosY+TEXT_Y_DISPLACEMENT), + font=labelFont, fill=BLACK) startPosY += stepPosY if self.additiveChecked: startPosX = xLeftOffset im_drawer.line( - xy=((startPosX,startPosY),(startPosX+17,startPosY)), + xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.ADDITIVE_COLOR_POSITIVE, width=2) im_drawer.line( - xy=((startPosX+18,startPosY),(startPosX+32,startPosY)), + xy=((startPosX+18, startPosY), (startPosX+32, startPosY)), fill=self.ADDITIVE_COLOR_NEGATIVE, width=2) im_drawer.text( - text='Additive Effect',xy=(startPosX+40,startPosY+TEXT_Y_DISPLACEMENT), - font=labelFont,fill=BLACK) + text='Additive Effect', xy=(startPosX+40, startPosY+TEXT_Y_DISPLACEMENT), + font=labelFont, fill=BLACK) if self.genotype.type == 'intercross' and self.dominanceChecked: startPosX = xLeftOffset startPosY += stepPosY im_drawer.line( - xy=((startPosX,startPosY),(startPosX+17,startPosY)), + xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.DOMINANCE_COLOR_POSITIVE, width=4) im_drawer.line( - xy=((startPosX+18,startPosY),(startPosX+35,startPosY)), + xy=((startPosX+18, startPosY), (startPosX+35, startPosY)), fill=self.DOMINANCE_COLOR_NEGATIVE, width=4) im_drawer.text( - text='Dominance Effect', xy=(startPosX+42,startPosY+5), - font=labelFont,fill=BLACK) + text='Dominance Effect', xy=(startPosX+42, startPosY+5), + font=labelFont, fill=BLACK) if self.haplotypeAnalystChecked: startPosY += stepPosY startPosX = xLeftOffset im_drawer.line( - xy=((startPosX,startPosY),(startPosX+17,startPosY)), + xy=((startPosX, startPosY), (startPosX+17, startPosY)), fill=self.HAPLOTYPE_POSITIVE, width=4) im_drawer.line( - xy=((startPosX+18,startPosY),(startPosX+35,startPosY)), + xy=((startPosX+18, startPosY), (startPosX+35, startPosY)), fill=self.HAPLOTYPE_NEGATIVE, width=4) im_drawer.line( - xy=((startPosX+36,startPosY),(startPosX+53,startPosY)), + xy=((startPosX+36, startPosY), (startPosX+53, startPosY)), fill=self.HAPLOTYPE_HETEROZYGOUS, width=4) im_drawer.line( - xy=((startPosX+54,startPosY),(startPosX+67,startPosY)), + xy=((startPosX+54, startPosY), (startPosX+67, startPosY)), fill=self.HAPLOTYPE_RECOMBINATION, width=4) im_drawer.text( text='Haplotypes (Pat, Mat, Het, Unk)', - xy=(startPosX+76,startPosY+5),font=labelFont,fill=BLACK) + xy=(startPosX+76, startPosY+5), font=labelFont, fill=BLACK) if self.permChecked and self.nperm > 0: startPosY += stepPosY startPosX = xLeftOffset im_drawer.line( - xy=((startPosX, startPosY),( startPosX + 32, startPosY)), + xy=((startPosX, startPosY), ( startPosX + 32, startPosY)), fill=self.SIGNIFICANT_COLOR, width=self.SIGNIFICANT_WIDTH) im_drawer.line( - xy=((startPosX, startPosY + stepPosY),( startPosX + 32, startPosY + stepPosY)), + xy=((startPosX, startPosY + stepPosY), ( startPosX + 32, startPosY + stepPosY)), fill=self.SUGGESTIVE_COLOR, width=self.SUGGESTIVE_WIDTH) im_drawer.text( - text='Significant %s = %2.2f' % (self.LRS_LOD,self.significant), - xy=(xLeftOffset+42,startPosY+TEXT_Y_DISPLACEMENT),font=labelFont,fill=BLACK) + text='Significant %s = %2.2f' % (self.LRS_LOD, self.significant), + xy=(xLeftOffset+42, startPosY+TEXT_Y_DISPLACEMENT), font=labelFont, fill=BLACK) im_drawer.text( text='Suggestive %s = %2.2f' % (self.LRS_LOD, self.suggestive), - xy=(xLeftOffset+42,startPosY + TEXT_Y_DISPLACEMENT +stepPosY),font=labelFont, + xy=(xLeftOffset+42, startPosY + TEXT_Y_DISPLACEMENT +stepPosY), font=labelFont, fill=BLACK) - labelFont = ImageFont.truetype(font=VERDANA_FILE,size=12*fontZoom) + labelFont = ImageFont.truetype(font=VERDANA_FILE, size=12*fontZoom) labelColor = BLACK if self.dataset.type == "Publish" or self.dataset.type == "Geno": dataset_label = self.dataset.fullname @@ -1109,22 +1109,22 @@ class DisplayMappingResults(object): im_drawer.textsize(string2, font=labelFont)[0]) im_drawer.text( text=identification, - xy=(canvas.size[0] - xRightOffset-d,20*fontZoom),font=labelFont, + xy=(canvas.size[0] - xRightOffset-d, 20*fontZoom), font=labelFont, fill=labelColor) else: d = 4+ max( im_drawer.textsize(string1, font=labelFont)[0], im_drawer.textsize(string2, font=labelFont)[0]) im_drawer.text( - text=string1,xy=(canvas.size[0] - xRightOffset-d,35*fontZoom), - font=labelFont,fill=labelColor) + text=string1, xy=(canvas.size[0] - xRightOffset-d, 35*fontZoom), + font=labelFont, fill=labelColor) im_drawer.text( - text=string2,xy=(canvas.size[0] - xRightOffset-d,50*fontZoom), - font=labelFont,fill=labelColor) + text=string2, xy=(canvas.size[0] - xRightOffset-d, 50*fontZoom), + font=labelFont, fill=labelColor) if string3 != '': im_drawer.text( - text=string3,xy=(canvas.size[0] - xRightOffset-d,65*fontZoom), - font=labelFont,fill=labelColor) + text=string3, xy=(canvas.size[0] - xRightOffset-d, 65*fontZoom), + font=labelFont, fill=labelColor) def drawGeneBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): @@ -1345,7 +1345,7 @@ class DisplayMappingResults(object): labelText = "3'" im_drawer.text( text=labelText, - xy=(utrEndPix+2,geneYLocation+self.EACH_GENE_HEIGHT), + xy=(utrEndPix+2, geneYLocation+self.EACH_GENE_HEIGHT), font=ImageFont.truetype(font=ARIAL_FILE, size=2)) #draw the genes as rectangles @@ -1357,7 +1357,7 @@ class DisplayMappingResults(object): COORDS = "%d, %d, %d, %d" %(geneStartPix, geneYLocation, geneEndPix, (geneYLocation + self.EACH_GENE_HEIGHT)) # NL: 06-02-2011 Rob required to display NCBI info in a new window - gifmap.areas.append(HT.Area(shape='rect',coords=COORDS,href=HREF, title=TITLE,target="_blank")) + gifmap.areas.append(HT.Area(shape='rect', coords=COORDS, href=HREF, title=TITLE, target="_blank")) ## BEGIN HaplotypeAnalyst def drawHaplotypeBand(self, canvas, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): @@ -1490,7 +1490,7 @@ class DisplayMappingResults(object): counter = counter + 1 if item.name == samplelist[k]: ind = counter - maxind=max(ind,maxind) + maxind=max(ind, maxind) # lines if (oldgeno[k] == -1 and _geno == -1): @@ -1523,7 +1523,7 @@ class DisplayMappingResults(object): COORDS = "%d, %d, %d, %d" %(geneStartPix, geneYLocation+ind*self.EACH_GENE_HEIGHT, geneEndPix+1, (geneYLocation + ind*self.EACH_GENE_HEIGHT)) TITLE = "Strain: %s, marker (%s) \n Position %2.3f Mb." % (samplelist[k], _chr[j].name, float(txStart)) HREF = '' - gifmap.areas.append(HT.Area(shape='rect',coords=COORDS,href=HREF, title=TITLE)) + gifmap.areas.append(HT.Area(shape='rect', coords=COORDS, href=HREF, title=TITLE)) # if there are no more markers in a chromosome, the plotRight value calculated above will be before the plotWidth # resulting in some empty space on the right side of the plot area. This draws an "unknown" bar from plotRight to the edge. @@ -1642,14 +1642,14 @@ class DisplayMappingResults(object): WEBQTL_HREF = "javascript:rangeView('%s', %f, %f)" % (self.selectedChr - 1, max(0, (calBase-webqtlZoomWidth))/1000000.0, (calBase+webqtlZoomWidth)/1000000.0) WEBQTL_TITLE = "Click to view this section of the genome in WebQTL" - gifmap.areas.append(HT.Area(shape='rect',coords=WEBQTL_COORDS,href=WEBQTL_HREF, title=WEBQTL_TITLE)) + gifmap.areas.append(HT.Area(shape='rect', coords=WEBQTL_COORDS, href=WEBQTL_HREF, title=WEBQTL_TITLE)) im_drawer.rectangle( xy=((xBrowse1, paddingTop), (xBrowse2, (paddingTop + self.BAND_HEIGHT))), outline=self.CLICKABLE_WEBQTL_REGION_COLOR, fill=self.CLICKABLE_WEBQTL_REGION_COLOR) im_drawer.line( - xy=((xBrowse1, paddingTop),( xBrowse1, (paddingTop + self.BAND_HEIGHT))), + xy=((xBrowse1, paddingTop), ( xBrowse1, (paddingTop + self.BAND_HEIGHT))), fill=self.CLICKABLE_WEBQTL_REGION_OUTLINE_COLOR) if self.dataset.group.species == "mouse" or self.dataset.group.species == "rat": @@ -1659,14 +1659,14 @@ class DisplayMappingResults(object): else: PHENOGEN_HREF = "https://phenogen.org/gene.jsp?speciesCB=Mm&auto=Y&geneTxt=chr%s:%d-%d&genomeVer=mm10" % (self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) PHENOGEN_TITLE = "Click to view this section of the genome in PhenoGen" - gifmap.areas.append(HT.Area(shape='rect',coords=PHENOGEN_COORDS,href=PHENOGEN_HREF, title=PHENOGEN_TITLE)) + gifmap.areas.append(HT.Area(shape='rect', coords=PHENOGEN_COORDS, href=PHENOGEN_HREF, title=PHENOGEN_TITLE)) im_drawer.rectangle( xy=((xBrowse1, phenogenPaddingTop), (xBrowse2, (phenogenPaddingTop+self.BAND_HEIGHT))), outline=self.CLICKABLE_PHENOGEN_REGION_COLOR, fill=self.CLICKABLE_PHENOGEN_REGION_COLOR) im_drawer.line( - xy=((xBrowse1, phenogenPaddingTop),( xBrowse1, (phenogenPaddingTop+self.BAND_HEIGHT))), + xy=((xBrowse1, phenogenPaddingTop), ( xBrowse1, (phenogenPaddingTop+self.BAND_HEIGHT))), fill=self.CLICKABLE_PHENOGEN_REGION_OUTLINE_COLOR) UCSC_COORDS = "%d, %d, %d, %d" %(xBrowse1, ucscPaddingTop, xBrowse2, (ucscPaddingTop+self.BAND_HEIGHT)) @@ -1675,7 +1675,7 @@ class DisplayMappingResults(object): else: UCSC_HREF = "http://genome.ucsc.edu/cgi-bin/hgTracks?db=%s&position=chr%s:%d-%d" % (self._ucscDb, self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) UCSC_TITLE = "Click to view this section of the genome in the UCSC Genome Browser" - gifmap.areas.append(HT.Area(shape='rect',coords=UCSC_COORDS,href=UCSC_HREF, title=UCSC_TITLE)) + gifmap.areas.append(HT.Area(shape='rect', coords=UCSC_COORDS, href=UCSC_HREF, title=UCSC_TITLE)) im_drawer.rectangle( xy=((xBrowse1, ucscPaddingTop), (xBrowse2, (ucscPaddingTop+self.BAND_HEIGHT))), @@ -1692,7 +1692,7 @@ class DisplayMappingResults(object): else: ENSEMBL_HREF = "http://www.ensembl.org/Rattus_norvegicus/contigview?chr=%s&start=%d&end=%d" % (self.selectedChr, max(0, calBase-flankingWidthInBases), calBase+flankingWidthInBases) ENSEMBL_TITLE = "Click to view this section of the genome in the Ensembl Genome Browser" - gifmap.areas.append(HT.Area(shape='rect',coords=ENSEMBL_COORDS,href=ENSEMBL_HREF, title=ENSEMBL_TITLE)) + gifmap.areas.append(HT.Area(shape='rect', coords=ENSEMBL_COORDS, href=ENSEMBL_HREF, title=ENSEMBL_TITLE)) im_drawer.rectangle( xy=((xBrowse1, ensemblPaddingTop), (xBrowse2, (ensemblPaddingTop+self.BAND_HEIGHT))), @@ -1789,8 +1789,8 @@ class DisplayMappingResults(object): continue Xc = xLeftOffset + plotXScale*(_Mb - startMb) if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark - im_drawer.line(xy=((Xc,yZero), - (Xc,yZero+xMajorTickHeight)), + im_drawer.line(xy=((Xc, yZero), + (Xc, yZero+xMajorTickHeight)), fill=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark labelStr = str(formatStr % _Mb) # What Mbase location to put on the label @@ -1800,8 +1800,8 @@ class DisplayMappingResults(object): text=labelStr, font=MBLabelFont, fill=xAxisLabelColor) else: - im_drawer.line(xy=((Xc,yZero), - (Xc,yZero+xMinorTickHeight)), + im_drawer.line(xy=((Xc, yZero), + (Xc, yZero+xMinorTickHeight)), fill=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark @@ -1834,7 +1834,7 @@ class DisplayMappingResults(object): text="Megabases", xy=( xLeftOffset+(plotWidth-im_drawer.textsize( - "Megabases",font=megabaseLabelFont)[0])/2, + "Megabases", font=megabaseLabelFont)[0])/2, strYLoc+MBLabelFont.font.height+10*(zoom%2)), font=megabaseLabelFont, fill=BLACK) pass @@ -1889,7 +1889,7 @@ class DisplayMappingResults(object): for j, ChrInfo in enumerate(ChrAInfo): preLpos = -1 for i, item in enumerate(ChrInfo): - Lname,Lpos = item + Lname, Lpos = item if Lpos != preLpos: offsetA += stepA differ = 1 @@ -1903,17 +1903,17 @@ class DisplayMappingResults(object): Zorder = 0 if differ: im_drawer.line( - xy=((startPosX+Lpos,yZero),(xLeftOffset+offsetA,\ + xy=((startPosX+Lpos, yZero), (xLeftOffset+offsetA,\ yZero+25)), fill=lineColor) im_drawer.line( - xy=((xLeftOffset+offsetA,yZero+25),(xLeftOffset+offsetA,\ + xy=((xLeftOffset+offsetA, yZero+25), (xLeftOffset+offsetA,\ yZero+40+Zorder*(LRectWidth+3))), fill=lineColor) rectColor = ORANGE else: im_drawer.line( - xy=((xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3),(\ + xy=((xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3), (\ xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3))), fill=lineColor) rectColor = DEEPPINK @@ -1921,9 +1921,9 @@ class DisplayMappingResults(object): xy=((xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)), (xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3)+LRectWidth)), - outline=rectColor,fill=rectColor,width = 0) + outline=rectColor, fill=rectColor, width = 0) COORDS="%d,%d,%d,%d"%(xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3),\ - xLeftOffset+offsetA,yZero+40+Zorder*(LRectWidth+3)+LRectWidth) + xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)+LRectWidth) HREF="/show_trait?trait_id=%s&dataset=%s" % (Lname, self.dataset.group.name+"Geno") #HREF="javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm,fd.RISet+"Geno", Lname) Areas=HT.Area(shape='rect', coords=COORDS, href=HREF, target="_blank", title="Locus : " + Lname) @@ -1931,7 +1931,7 @@ class DisplayMappingResults(object): ##piddle bug if j == 0: im_drawer.line( - xy=((startPosX,yZero),(startPosX,yZero+40)), + xy=((startPosX, yZero), (startPosX, yZero+40)), fill=lineColor) startPosX += (self.ChrLengthDistList[j]+self.GraphInterval)*plotXScale @@ -1943,7 +1943,7 @@ class DisplayMappingResults(object): strYLoc + MBLabelFont.font.height+ 10*(zoom%2)), font=centimorganLabelFont, fill=BLACK) - im_drawer.line(xy=((xLeftOffset,yZero), (xLeftOffset+plotWidth,yZero)), + im_drawer.line(xy=((xLeftOffset, yZero), (xLeftOffset+plotWidth, yZero)), fill=BLACK, width=X_AXIS_THICKNESS) # Draw the X axis itself @@ -2079,7 +2079,7 @@ class DisplayMappingResults(object): LRS_LOD_Max = 0.000001 yTopOffset + 30*(zoom - 1) yLRS = yZero - (item/LRS_LOD_Max) * LRSHeightThresh - im_drawer.line(xy=((xLeftOffset,yLRS), (xLeftOffset-4,yLRS)), + im_drawer.line(xy=((xLeftOffset, yLRS), (xLeftOffset-4, yLRS)), fill=self.LRS_COLOR, width=1*zoom) if all_int: scaleStr = "%d" % item @@ -2127,8 +2127,8 @@ class DisplayMappingResults(object): else: sugg_title = "Suggestive LOD = %0.2f" % (self.suggestive/4.61) sig_title = "Significant LOD = %0.2f" % (self.significant/4.61) - Areas1 = HT.Area(shape='rect',coords=sugg_coords,title=sugg_title) - Areas2 = HT.Area(shape='rect',coords=sig_coords,title=sig_title) + Areas1 = HT.Area(shape='rect', coords=sugg_coords, title=sugg_title) + Areas2 = HT.Area(shape='rect', coords=sig_coords, title=sig_title) gifmap.areas.append(Areas1) gifmap.areas.append(Areas2) @@ -2316,7 +2316,7 @@ class DisplayMappingResults(object): im_drawer.text( text="5", xy=( - Xc-im_drawer.textsize("5",font=symbolFont)[0]/2+1, + Xc-im_drawer.textsize("5", font=symbolFont)[0]/2+1, Yc-4), fill=point_color, font=symbolFont) else: @@ -2383,8 +2383,8 @@ class DisplayMappingResults(object): ) else: im_drawer.line( - xy=((Xc0,yZero-(Yc0-yZero)), - (Xc,yZero-(Yc-yZero))), + xy=((Xc0, yZero-(Yc0-yZero)), + (Xc, yZero-(Yc-yZero))), fill=minusColor, width=lineWidth #, clipX=(xLeftOffset, xLeftOffset + plotWidth) ) @@ -2471,8 +2471,8 @@ class DisplayMappingResults(object): ###draw additive scale if not self.multipleInterval and self.additiveChecked: - additiveScaleFont=ImageFont.truetype(font=VERDANA_FILE,size=16*zoom) - additiveScale = Plot.detScaleOld(0,additiveMax) + additiveScaleFont=ImageFont.truetype(font=VERDANA_FILE, size=16*zoom) + additiveScale = Plot.detScaleOld(0, additiveMax) additiveStep = (additiveScale[1]-additiveScale[0])/additiveScale[2] additiveAxisList = Plot.frange(0, additiveScale[1], additiveStep) addPlotScale = AdditiveHeightThresh/additiveMax @@ -2482,18 +2482,18 @@ class DisplayMappingResults(object): for item in additiveAxisList: additiveY = yZero - item*addPlotScale im_drawer.line( - xy=((xLeftOffset + plotWidth,additiveY), - (xLeftOffset+4+ plotWidth,additiveY)), + xy=((xLeftOffset + plotWidth, additiveY), + (xLeftOffset+4+ plotWidth, additiveY)), fill=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) scaleStr = "%2.3f" % item im_drawer.text( text=scaleStr, - xy=(xLeftOffset + plotWidth +6,additiveY+TEXT_Y_DISPLACEMENT), - font=additiveScaleFont,fill=self.ADDITIVE_COLOR_POSITIVE) + xy=(xLeftOffset + plotWidth +6, additiveY+TEXT_Y_DISPLACEMENT), + font=additiveScaleFont, fill=self.ADDITIVE_COLOR_POSITIVE) im_drawer.line( - xy=((xLeftOffset+plotWidth,additiveY), - (xLeftOffset+plotWidth,yZero)), + xy=((xLeftOffset+plotWidth, additiveY), + (xLeftOffset+plotWidth, yZero)), fill=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) im_drawer.line( @@ -2553,7 +2553,7 @@ class DisplayMappingResults(object): chrFontZoom = 2 else: chrFontZoom = 1 - chrLabelFont=ImageFont.truetype(font=VERDANA_FILE,size=24*chrFontZoom) + chrLabelFont=ImageFont.truetype(font=VERDANA_FILE, size=24*chrFontZoom) for i, _chr in enumerate(self.genotype): if (i % 2 == 0): @@ -2575,10 +2575,10 @@ class DisplayMappingResults(object): TEXT_Y_DISPLACEMENT = 0 im_drawer.text(xy=(chrStartPix, yTopOffset + TEXT_Y_DISPLACEMENT), text=_chr.name, font=chrLabelFont, fill=BLACK) - COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) + COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix, yTopOffset +20) #add by NL 09-03-2010 - HREF = "javascript:chrView(%d,%s);" % (i,self.ChrLengthMbList) + HREF = "javascript:chrView(%d,%s);" % (i, self.ChrLengthMbList) #HREF = "javascript:changeView(%d,%s);" % (i,self.ChrLengthMbList) Areas = HT.Area(shape='rect', coords=COORDS, href=HREF) gifmap.areas.append(Areas) @@ -2720,7 +2720,7 @@ class DisplayMappingResults(object): else: chr_as_int = int(theGO["Chromosome"]) - 1 if refGene: - literatureCorrelationString = str(self.getLiteratureCorrelation(self.cursor,refGene,theGO['GeneID']) or "N/A") + literatureCorrelationString = str(self.getLiteratureCorrelation(self.cursor, refGene, theGO['GeneID']) or "N/A") this_row = [selectCheck.__str__(), str(tableIterationsCnt), @@ -2820,8 +2820,8 @@ class DisplayMappingResults(object): lCorr = None try: query = 'SELECT Value FROM LCorrRamin3 WHERE GeneId1 = %s and GeneId2 = %s' - for x,y in [(geneId1,geneId2),(geneId2,geneId1)]: - cursor.execute(query,(x,y)) + for x, y in [(geneId1, geneId2), (geneId2, geneId1)]: + cursor.execute(query, (x, y)) lCorr = cursor.fetchone() if lCorr: lCorr = lCorr[0] diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index d4ee6fe6..2f282adc 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -54,7 +54,7 @@ def gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = ''): for i, sample in enumerate(ped_sample_list): try: value = vals[i] - value = str(value).replace('value=','') + value = str(value).replace('value=', '') value = value.strip() except: value = -9999 @@ -78,7 +78,7 @@ def gen_pheno_txt_file_plink(this_trait, dataset, vals, pheno_filename = ''): # get strain name from ped file in order def get_samples_from_ped_file(dataset): - ped_file= open("{}{}.ped".format(flat_files('mapping'), dataset.group.name),"r") + ped_file= open("{}{}.ped".format(flat_files('mapping'), dataset.group.name), "r") line = ped_file.readline() sample_list=[] @@ -155,7 +155,7 @@ def parse_plink_output(output_filename, species): # output: lineList list ####################################################### def build_line_list(line=None): - line_list = string.split(string.strip(line),' ')# irregular number of whitespaces between columns + line_list = string.split(string.strip(line), ' ')# irregular number of whitespaces between columns line_list = [item for item in line_list if item !=''] line_list = list(map(string.strip, line_list)) diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 145dbc77..1e6dff57 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -707,7 +707,7 @@ def get_perm_strata(this_trait, sample_list, categorical_vars, used_samples): perm_strata_strings.append(combined_string) - d = dict([(y,x+1) for x,y in enumerate(sorted(set(perm_strata_strings)))]) + d = dict([(y, x+1) for x, y in enumerate(sorted(set(perm_strata_strings)))]) list_to_numbers = [d[x] for x in perm_strata_strings] perm_strata = list_to_numbers diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 5b3946e3..c07a7670 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -53,7 +53,7 @@ views.py). search = self.search_terms self.original_search_string = self.search_terms # check for dodgy search terms - rx = re.compile(r'.*\W(href|http|sql|select|update)\W.*',re.IGNORECASE) + rx = re.compile(r'.*\W(href|http|sql|select|update)\W.*', re.IGNORECASE) if rx.match(search): logger.info("Regex failed search") self.search_term_exists = False diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 21ba7f63..f17e825e 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -57,7 +57,7 @@ class SampleList(object): sample = webqtlCaseData.webqtlCaseData(name=sample_name) sample.extra_info = {} - if self.dataset.group.name == 'AXBXA' and sample_name in ('AXB18/19/20','AXB13/14','BXA8/17'): + if self.dataset.group.name == 'AXBXA' and sample_name in ('AXB18/19/20', 'AXB13/14', 'BXA8/17'): sample.extra_info['url'] = "/mouseCross.html#AXB/BXA" sample.extra_info['css_class'] = "fs12" diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index a871e91a..232cb8da 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -867,7 +867,7 @@ def forgot_password_submit(): email_address = params['email_address'] next_page = None if email_address != "": - logger.debug("Wants to send password E-mail to ",email_address) + logger.debug("Wants to send password E-mail to ", email_address) user_details = get_user_by_unique_column("email_address", email_address) if user_details: ForgotPasswordEmail(user_details["email_address"]) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 394a9e28..92c20fc7 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -55,7 +55,7 @@ from wqflask.ctl import ctl_analysis from wqflask.snp_browser import snp_browser 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 +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 from utility.helper_functions import get_species_groups from utility.authentication_tools import check_resource_availability from utility.redis_tools import get_redis_conn @@ -133,10 +133,10 @@ def handle_bad_request(e): list = [fn for fn in os.listdir("./wqflask/static/gif/error") if fn.endswith(".gif") ] animation = random.choice(list) - resp = make_response(render_template("error.html",message=err_msg,stack=formatted_lines,error_image=animation,version=GN_VERSION)) + resp = make_response(render_template("error.html", message=err_msg, stack=formatted_lines, error_image=animation, version=GN_VERSION)) # logger.error("Set cookie %s with %s" % (err_msg, animation)) - resp.set_cookie(err_msg[:32],animation) + resp.set_cookie(err_msg[:32], animation) return resp @app.route("/authentication_needed") @@ -257,7 +257,7 @@ def docedit(): @app.route('/generated/') def generated_file(filename): logger.info(request.url) - return send_from_directory(GENERATED_IMAGE_DIR,filename) + return send_from_directory(GENERATED_IMAGE_DIR, filename) @app.route("/help") def help(): -- cgit v1.2.3 From 1f4fb6b24f3508d80be1f07cd62e38ac9385ef41 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 20 Aug 2020 16:35:17 +0300 Subject: Handle module renames in the standard library Run: ``` 2to3-3.8 -f imports -w . && \ 2to3-3.8 -f imports2 -w . ``` See: and --- wqflask/base/data_set.py | 2 +- wqflask/maintenance/gen_select_dataset.py | 4 ++-- wqflask/maintenance/quantile_normalize.py | 4 ++-- wqflask/maintenance/set_resource_defaults.py | 4 ++-- wqflask/utility/svg.py | 16 ++++++++-------- wqflask/wqflask/api/router.py | 14 +++++++------- wqflask/wqflask/collect.py | 2 +- .../wqflask/comparison_bar_chart/comparison_bar_chart.py | 2 +- wqflask/wqflask/correlation/show_corr_results.py | 2 +- wqflask/wqflask/correlation_matrix/show_corr_matrix.py | 2 +- wqflask/wqflask/export_traits.py | 4 ++-- wqflask/wqflask/heatmap/heatmap.py | 4 ++-- .../wqflask/marker_regression/display_mapping_results.py | 4 ++-- wqflask/wqflask/marker_regression/run_mapping.py | 2 +- wqflask/wqflask/network_graph/network_graph.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 2 +- wqflask/wqflask/user_manager.py | 2 +- wqflask/wqflask/views.py | 12 ++++++------ 18 files changed, 42 insertions(+), 42 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 43beec26..8151a29d 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -44,7 +44,7 @@ import codecs import json import requests import gzip -import cPickle as pickle +import pickle as pickle import itertools from redis import Redis diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index d12b328f..fd65a52a 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -50,7 +50,7 @@ from utility.tools import locate, locate_ignore_error, TEMPDIR, SQL_URI import MySQLdb import simplejson as json -import urlparse +import urllib.parse #import sqlalchemy as sa @@ -66,7 +66,7 @@ from pprint import pformat as pf def parse_db_uri(): """Converts a database URI to the db name, host name, user name, and password""" - parsed_uri = urlparse.urlparse(SQL_URI) + parsed_uri = urllib.parse.urlparse(SQL_URI) db_conn_info = dict( db = parsed_uri.path[1:], diff --git a/wqflask/maintenance/quantile_normalize.py b/wqflask/maintenance/quantile_normalize.py index 43edfd13..4d6e03bf 100644 --- a/wqflask/maintenance/quantile_normalize.py +++ b/wqflask/maintenance/quantile_normalize.py @@ -6,7 +6,7 @@ sys.path.insert(0, './') import MySQLdb -import urlparse +import urllib.parse import numpy as np import pandas as pd @@ -22,7 +22,7 @@ from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT, SQL_URI def parse_db_uri(): """Converts a database URI to the db name, host name, user name, and password""" - parsed_uri = urlparse.urlparse(SQL_URI) + parsed_uri = urllib.parse.urlparse(SQL_URI) db_conn_info = dict( db = parsed_uri.path[1:], diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index d53a255b..abd5416c 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -34,7 +34,7 @@ Redis = get_redis_conn() import MySQLdb -import urlparse +import urllib.parse from utility.logger import getLogger logger = getLogger(__name__) @@ -42,7 +42,7 @@ logger = getLogger(__name__) def parse_db_uri(): """Converts a database URI to the db name, host name, user name, and password""" - parsed_uri = urlparse.urlparse(SQL_URI) + parsed_uri = urllib.parse.urlparse(SQL_URI) db_conn_info = dict( db = parsed_uri.path[1:], diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index 19eda0ce..b92cc2d1 100644 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -957,8 +957,8 @@ class drawing: # Voeg een element toe aan de grafiek toe. if use_dom_implementation==0: def toXml(self, filename='',compress=False): - import cStringIO - xml=cStringIO.StringIO() + import io + xml=io.StringIO() xml.write("\n") xml.write(" 1: - memory_file = StringIO.StringIO() + memory_file = io.StringIO() with ZipFile(memory_file, mode='w', compression=ZIP_DEFLATED) as zf: for the_file in file_list: zf.writestr(the_file[0], the_file[1]) @@ -460,7 +460,7 @@ def export_perm_data(): ["#Comment: Results sorted from low to high peak linkage"] ] - buff = StringIO.StringIO() + buff = io.StringIO() writer = csv.writer(buff) writer.writerows(the_rows) for item in perm_info['perm_data']: -- cgit v1.2.3 From 666a423b0b2f8cf98b9e70ed3dcf1c6dc3896b1d Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Sun, 23 Aug 2020 15:28:41 +0300 Subject: Use Python3 string methods * wqflask/utility/webqtlUtil.py (genRandStr): Replace "string.letters" with "string.ascii_letters". --- wqflask/utility/webqtlUtil.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py index 77cc3416..d4979011 100644 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -64,7 +64,7 @@ ParInfo ={ # Accessory Functions ######################################### -def genRandStr(prefix = "", length=8, chars=string.letters+string.digits): +def genRandStr(prefix = "", length=8, chars=string.ascii_letters+string.digits): from random import choice _str = prefix[:] for i in range(length): @@ -110,4 +110,4 @@ def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users) AuthorizedUsersList=list(map(string.strip, string.split(authorized_users, ','))) if AuthorizedUsersList.__contains__(userName): access_to_confidential_phenotype_trait = 1 - return access_to_confidential_phenotype_trait \ No newline at end of file + return access_to_confidential_phenotype_trait -- cgit v1.2.3 From 3d2ef9879305449568962db9be7fa753473ec11e Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 24 Aug 2020 10:49:58 -0500 Subject: The function draw_rotated_text_ was writing an image to /tmp, which GN2 user apparently doesn't have access to, so I replaced it with a link to the dynamically set TEMPDIR * wqflask/utility/pillow_utils.py - Replaced "/tmp/" in image location with TEMPDIR --- wqflask/utility/pillow_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py index dfbf3e19..0c2ce7af 100644 --- a/wqflask/utility/pillow_utils.py +++ b/wqflask/utility/pillow_utils.py @@ -1,5 +1,7 @@ from PIL import Image, ImageColor, ImageDraw, ImageFont +from utility.tools import TEMPDIR + import utility.logger logger = utility.logger.getLogger(__name__ ) @@ -14,7 +16,7 @@ def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90): draw_text = ImageDraw.Draw(tmp_img) draw_text.text(text=text, xy=(0,0), font=font, fill=fill) tmp_img2 = tmp_img.rotate(angle, expand=1) - tmp_img2.save("/tmp/{}.png".format(text), format="png") + tmp_img2.save("/{0}/{1}.png".format(TEMPDIR, text), format="png") canvas.paste(im=tmp_img2, box=tuple([int(i) for i in xy])) # def draw_open_polygon(canvas: Image, xy: tuple, fill: ImageColor=WHITE, outline: ImageColor=BLACK): -- cgit v1.2.3 From b3461095a21fd373656156a983038e4a586085a9 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 24 Aug 2020 14:09:26 +0300 Subject: Remove unused imports * wqflask/utility/Plot.py: Remove unused imports like "numarray". "numarray" is does not have py3 support so it's important to remove references to it. --- wqflask/utility/Plot.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index d4373412..b9b71129 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -26,16 +26,12 @@ from __future__ import print_function -from PIL import (Image, ImageColor, ImageDraw, ImageFont) -from pprint import pformat as pf +from PIL import ImageColor +from PIL import ImageDraw +from PIL import ImageFont from math import * -import random -import sys, os -from numarray import linear_algebra as la -from numarray import ones, array, dot, swapaxes -import webqtlUtil import corestats from base import webqtlConfig from utility.pillow_utils import draw_rotated_text -- cgit v1.2.3 From 3335bb967e59da17d104624be971e4a3e98e07c8 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 26 Aug 2020 01:33:43 +0300 Subject: Update corestats import * wqflask/utility/Plot.py: import corestats from the utility module. --- wqflask/utility/Plot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 7d9d7649..48a5c7ba 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -32,7 +32,7 @@ from PIL import ImageFont from math import * -import corestats +import utility.corestats as corestats from base import webqtlConfig from utility.pillow_utils import draw_rotated_text import utility.logger -- cgit v1.2.3 From 133db0e8dbc5a0812dc1f06402f2b788aecaef20 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 26 Aug 2020 17:36:23 +0300 Subject: Replace calls to "basestring with "str"" See: --- wqflask/utility/helper_functions.py | 2 +- wqflask/wqflask/collect.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 2 +- wqflask/wqflask/snp_browser/snp_browser.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py index 9a4a235a..107c9ec6 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -34,7 +34,7 @@ def get_species_dataset_trait(self, start_vars): #self.genotype = self.dataset.group.genotype def get_trait_db_obs(self, trait_db_list): - if isinstance(trait_db_list, basestring): + if isinstance(trait_db_list, str): trait_db_list = trait_db_list.split(",") self.trait_list = [] diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index d77567f8..06c00930 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -38,7 +38,7 @@ from utility.logger import getLogger logger = getLogger(__name__) def process_traits(unprocessed_traits): - if isinstance(unprocessed_traits, basestring): + if isinstance(unprocessed_traits, str): unprocessed_traits = unprocessed_traits.split(",") traits = set() for trait in unprocessed_traits: diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 738aa28a..6a74cada 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -372,7 +372,7 @@ class ShowTrait(object): this_group = self.dataset.group.name # We're checking a string here! - assert isinstance(this_group, basestring), "We need a string type thing here" + assert isinstance(this_group, str), "We need a string type thing here" if this_group[:3] == 'BXD' and this_group != "BXD-Harvested": this_group = 'BXD' diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index b18bfc62..b3d26caf 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -477,7 +477,7 @@ class SnpBrowser(object): the_bases = [] for j, item in enumerate(allele_value_list): - if item and isinstance(item, basestring): + if item and isinstance(item, str): this_base = [str(item), base_color_dict[item]] else: this_base = "" @@ -612,7 +612,7 @@ class SnpBrowser(object): this_allele_list = [] for item in self.allele_list: - if item and isinstance(item, basestring) and (item.lower() not in this_allele_list) and (item != "-"): + if item and isinstance(item, str) and (item.lower() not in this_allele_list) and (item != "-"): this_allele_list.append(item.lower()) total_allele_count = len(this_allele_list) -- cgit v1.2.3 From 303e4b71c2172da5be19c84d4be5a062329ac013 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 26 Aug 2020 19:12:33 +0300 Subject: Remove "from __future__ import new_feature" statements See: --- test/requests/link_checker.py | 1 - test/requests/main_web_functionality.py | 22 ++++++++++++---------- test/requests/mapping_tests.py | 1 - test/requests/navigation_tests.py | 1 - test/requests/test-website.py | 2 +- webtests/browser_run.py | 4 +--- webtests/correlation_matrix_test.py | 2 -- webtests/correlation_test.py | 2 -- webtests/marker_regression_test.py | 2 -- webtests/show_trait_js_test.py | 2 -- webtests/test_runner.py | 4 +--- wqflask/base/data_set.py | 1 - wqflask/base/mrna_assay_tissue_data.py | 4 +--- wqflask/base/species.py | 4 +--- wqflask/base/trait.py | 2 -- wqflask/maintenance/convert_dryad_to_bimbam.py | 3 +-- wqflask/maintenance/convert_geno_to_bimbam.py | 3 +-- wqflask/maintenance/gen_select_dataset.py | 10 +--------- .../maintenance/generate_kinship_from_bimbam.py | 3 +-- .../maintenance/generate_probesetfreeze_file.py | 2 -- wqflask/maintenance/geno_to_json.py | 3 +-- wqflask/maintenance/get_group_samplelists.py | 2 -- wqflask/maintenance/print_benchmark.py | 4 +--- wqflask/maintenance/quantile_normalize.py | 7 +------ wqflask/maintenance/set_resource_defaults.py | 4 +--- wqflask/utility/Plot.py | 2 -- wqflask/utility/after.py | 4 +--- wqflask/utility/authentication_tools.py | 2 -- wqflask/utility/benchmark.py | 2 -- wqflask/utility/chunks.py | 2 -- wqflask/utility/db_tools.py | 2 -- wqflask/utility/gen_geno_ob.py | 4 +--- wqflask/utility/genofile_parser.py | 1 - wqflask/utility/helper_functions.py | 2 -- wqflask/utility/hmac.py | 4 +--- wqflask/utility/redis_tools.py | 4 +--- wqflask/utility/temp_data.py | 1 - wqflask/wqflask/__init__.py | 2 -- wqflask/wqflask/api/correlation.py | 4 +--- wqflask/wqflask/api/gen_menu.py | 2 -- wqflask/wqflask/api/mapping.py | 2 -- wqflask/wqflask/api/router.py | 4 +--- wqflask/wqflask/collect.py | 3 --- .../comparison_bar_chart/comparison_bar_chart.py | 1 - wqflask/wqflask/correlation/corr_scatter_plot.py | 4 +--- .../wqflask/correlation/correlation_functions.py | 4 +--- wqflask/wqflask/correlation/show_corr_results.py | 2 -- .../wqflask/correlation_matrix/show_corr_matrix.py | 2 -- wqflask/wqflask/do_search.py | 2 -- wqflask/wqflask/docs.py | 4 +--- wqflask/wqflask/export_traits.py | 4 +--- wqflask/wqflask/external_tools/send_to_bnw.py | 4 +--- .../wqflask/external_tools/send_to_geneweaver.py | 4 +--- .../wqflask/external_tools/send_to_webgestalt.py | 4 +--- wqflask/wqflask/group_manager.py | 5 +---- wqflask/wqflask/gsearch.py | 2 -- wqflask/wqflask/heatmap/heatmap.py | 2 -- wqflask/wqflask/interval_analyst/GeneUtil.py | 2 -- wqflask/wqflask/marker_regression/run_mapping.py | 4 +--- wqflask/wqflask/model.py | 4 +--- wqflask/wqflask/network_graph/network_graph.py | 2 -- wqflask/wqflask/news.py | 1 - wqflask/wqflask/parser.py | 2 -- wqflask/wqflask/resource_manager.py | 4 +--- wqflask/wqflask/search_results.py | 2 -- wqflask/wqflask/send_mail.py | 2 -- wqflask/wqflask/show_trait/SampleList.py | 2 -- wqflask/wqflask/show_trait/export_trait_data.py | 4 +--- wqflask/wqflask/show_trait/show_trait.py | 2 -- wqflask/wqflask/snp_browser/snp_browser.py | 2 -- wqflask/wqflask/submit_bnw.py | 4 +--- wqflask/wqflask/update_search_results.py | 2 -- wqflask/wqflask/user_login.py | 4 +--- wqflask/wqflask/user_manager.py | 2 -- wqflask/wqflask/user_session.py | 2 -- wqflask/wqflask/views.py | 2 -- 76 files changed, 45 insertions(+), 190 deletions(-) (limited to 'wqflask/utility') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index 5e16a5cd..949a33c8 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -1,4 +1,3 @@ -from __future__ import print_function import re import requests from lxml.html import parse diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py index d070dab9..78030307 100644 --- a/test/requests/main_web_functionality.py +++ b/test/requests/main_web_functionality.py @@ -1,9 +1,7 @@ -from __future__ import print_function -import re import requests from lxml.html import parse from link_checker import check_page -from requests.exceptions import ConnectionError + def check_home(url): doc = parse(url).getroot() @@ -11,20 +9,23 @@ def check_home(url): assert(search_button[0].value == "Search") print("OK") + def check_search_page(host): data = dict( - species="mouse" - , group="BXD" - , type="Hippocampus mRNA" - , dataset="HC_M2_0606_P" - , search_terms_or="" - , search_terms_and="MEAN=(15 16) LRS=(23 46)") + species="mouse", + group="BXD", + type="Hippocampus mRNA", + dataset="HC_M2_0606_P", + search_terms_or="", + search_terms_and="MEAN=(15 16) LRS=(23 46)") result = requests.get(host+"/search", params=data) found = result.text.find("records are shown below") assert(found >= 0) assert(result.status_code == 200) print("OK") - check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + check_traits_page(host, ("/show_trait?trait_id=1435395_" + "s_at&dataset=HC_M2_0606_P")) + def check_traits_page(host, traits_url): doc = parse(host+traits_url).getroot() @@ -33,6 +34,7 @@ def check_traits_page(host, traits_url): print("OK") check_page(host, host+traits_url) + def check_main_web_functionality(args_obj, parser): print("") print("Checking main web functionality...") diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py index 5748a2a3..19b22c21 100644 --- a/test/requests/mapping_tests.py +++ b/test/requests/mapping_tests.py @@ -1,4 +1,3 @@ -from __future__ import print_function import re import copy import json diff --git a/test/requests/navigation_tests.py b/test/requests/navigation_tests.py index eda27324..6b91c1fd 100644 --- a/test/requests/navigation_tests.py +++ b/test/requests/navigation_tests.py @@ -1,4 +1,3 @@ -from __future__ import print_function import re import requests from lxml.html import parse diff --git a/test/requests/test-website.py b/test/requests/test-website.py index f90d1843..8bfb47c2 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -3,7 +3,7 @@ # env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 # # Mostly to pick up the Guix GN2_PROFILE and python modules -from __future__ import print_function + import argparse from link_checker import check_links from link_checker import check_packaged_js_files diff --git a/webtests/browser_run.py b/webtests/browser_run.py index 2ec299c5..7ee540b7 100644 --- a/webtests/browser_run.py +++ b/webtests/browser_run.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - __all__ = ('sleep', 'testmod', 'test') from doctest import testmod @@ -71,4 +69,4 @@ class Test(object): -test = Test() \ No newline at end of file +test = Test() diff --git a/webtests/correlation_matrix_test.py b/webtests/correlation_matrix_test.py index 8529c265..97114890 100644 --- a/webtests/correlation_matrix_test.py +++ b/webtests/correlation_matrix_test.py @@ -65,8 +65,6 @@ text: 0.608\n71 """ -from __future__ import absolute_import, division, print_function - from browser_run import * testmod() diff --git a/webtests/correlation_test.py b/webtests/correlation_test.py index aad3a69f..311bb847 100644 --- a/webtests/correlation_test.py +++ b/webtests/correlation_test.py @@ -44,8 +44,6 @@ text: 1.000 """ -from __future__ import absolute_import, division, print_function - from browser_run import * testmod() diff --git a/webtests/marker_regression_test.py b/webtests/marker_regression_test.py index c4f76f53..9b4a4acb 100644 --- a/webtests/marker_regression_test.py +++ b/webtests/marker_regression_test.py @@ -48,8 +48,6 @@ text: 11.511 """ -from __future__ import absolute_import, division, print_function - from browser_run import * testmod() diff --git a/webtests/show_trait_js_test.py b/webtests/show_trait_js_test.py index 0fd2c16c..34ffd3b7 100644 --- a/webtests/show_trait_js_test.py +++ b/webtests/show_trait_js_test.py @@ -35,8 +35,6 @@ style: display: none; """ -from __future__ import absolute_import, division, print_function - from browser_run import * testmod() diff --git a/webtests/test_runner.py b/webtests/test_runner.py index ef6d0d69..b5b590a6 100644 --- a/webtests/test_runner.py +++ b/webtests/test_runner.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import unittest import doctest import glob @@ -25,4 +23,4 @@ def main(): runner.run(suite) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 39a8a2ed..8ac7a279 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -18,7 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division from db.call import fetchall, fetchone, fetch1 from utility.logger import getLogger from utility.tools import USE_GN_SERVER, USE_REDIS, flat_files, flat_file_exists, GN2_BASE_URL diff --git a/wqflask/base/mrna_assay_tissue_data.py b/wqflask/base/mrna_assay_tissue_data.py index 6fec5dcd..33ce12bd 100644 --- a/wqflask/base/mrna_assay_tissue_data.py +++ b/wqflask/base/mrna_assay_tissue_data.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import collections from flask import g @@ -92,4 +90,4 @@ class MrnaAssayTissueData(object): else: symbol_values_dict[result.Symbol.lower()].append(result.value) - return symbol_values_dict \ No newline at end of file + return symbol_values_dict diff --git a/wqflask/base/species.py b/wqflask/base/species.py index 6d99af65..e3f1bc4a 100644 --- a/wqflask/base/species.py +++ b/wqflask/base/species.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import collections from flask import Flask, g @@ -59,4 +57,4 @@ class Chromosomes(object): results = g.db.execute(query).fetchall() for item in results: - self.chromosomes[item.OrderId] = IndChromosome(item.Name, item.Length) \ No newline at end of file + self.chromosomes[item.OrderId] = IndChromosome(item.Name, item.Length) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 09c41fa7..b20efd2a 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import os import string import resource diff --git a/wqflask/maintenance/convert_dryad_to_bimbam.py b/wqflask/maintenance/convert_dryad_to_bimbam.py index e833b395..12ce35e9 100644 --- a/wqflask/maintenance/convert_dryad_to_bimbam.py +++ b/wqflask/maintenance/convert_dryad_to_bimbam.py @@ -6,7 +6,6 @@ Convert data dryad files to a BIMBAM _geno and _snps file """ -from __future__ import print_function, division, absolute_import import sys sys.path.append("..") @@ -67,4 +66,4 @@ def convert_dryad_to_bimbam(filename): if __name__=="__main__": input_filename = "/home/zas1024/cfw_data/" + sys.argv[1] + ".txt" - convert_dryad_to_bimbam(input_filename) \ No newline at end of file + convert_dryad_to_bimbam(input_filename) diff --git a/wqflask/maintenance/convert_geno_to_bimbam.py b/wqflask/maintenance/convert_geno_to_bimbam.py index 528b98cf..d49742f2 100644 --- a/wqflask/maintenance/convert_geno_to_bimbam.py +++ b/wqflask/maintenance/convert_geno_to_bimbam.py @@ -9,7 +9,6 @@ code """ -from __future__ import print_function, division, absolute_import import sys sys.path.append("..") import os @@ -187,4 +186,4 @@ if __name__=="__main__": #convertob = ConvertGenoFile("/home/zas1024/gene/genotype_files/genotypes/SRxSHRSPF2.geno", "/home/zas1024/gene/genotype_files/new_genotypes/SRxSHRSPF2.json") #convertob.convert() ConvertGenoFile.process_all(Old_Geno_Directory, New_Geno_Directory) - #ConvertGenoFiles(Geno_Directory) \ No newline at end of file + #ConvertGenoFiles(Geno_Directory) diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index fd65a52a..544e2fd1 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -30,14 +30,6 @@ It needs to be run manually when database has been changed. Run it as # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import print_function, division - -#from flask import config -# -#cdict = {} -#config = config.Config(cdict).from_envvar('WQFLASK_SETTINGS') -#print("cdict is:", cdict) - import sys # NEW: Note we prepend the current path - otherwise a guix instance of GN2 may be used instead @@ -319,4 +311,4 @@ def _test_it(): if __name__ == '__main__': Conn = MySQLdb.Connect(**parse_db_uri()) Cursor = Conn.cursor() - main() \ No newline at end of file + main() diff --git a/wqflask/maintenance/generate_kinship_from_bimbam.py b/wqflask/maintenance/generate_kinship_from_bimbam.py index b53f5dda..60257b28 100644 --- a/wqflask/maintenance/generate_kinship_from_bimbam.py +++ b/wqflask/maintenance/generate_kinship_from_bimbam.py @@ -8,7 +8,6 @@ and uses GEMMA to generate their corresponding kinship/relatedness matrix file """ -from __future__ import print_function, division, absolute_import import sys sys.path.append("..") import os @@ -58,4 +57,4 @@ if __name__=="__main__": Bimbam_Directory = """/export/local/home/zas1024/genotype_files/genotype/bimbam/""" GenerateKinshipMatrices.process_all(Geno_Directory, Bimbam_Directory) - #./gemma -g /home/zas1024/genotype_files/genotype/bimbam/BXD_geno.txt -p /home/zas1024/genotype_files/genotype/bimbam/BXD_pheno.txt -gk 1 -o BXD \ No newline at end of file + #./gemma -g /home/zas1024/genotype_files/genotype/bimbam/BXD_geno.txt -p /home/zas1024/genotype_files/genotype/bimbam/BXD_pheno.txt -gk 1 -o BXD diff --git a/wqflask/maintenance/generate_probesetfreeze_file.py b/wqflask/maintenance/generate_probesetfreeze_file.py index 4231cc7c..b1e41e9a 100644 --- a/wqflask/maintenance/generate_probesetfreeze_file.py +++ b/wqflask/maintenance/generate_probesetfreeze_file.py @@ -1,7 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, print_function, division - import sys # sys.path.insert(0, "..") - why? diff --git a/wqflask/maintenance/geno_to_json.py b/wqflask/maintenance/geno_to_json.py index 9579812a..7e7fd241 100644 --- a/wqflask/maintenance/geno_to_json.py +++ b/wqflask/maintenance/geno_to_json.py @@ -9,7 +9,6 @@ code """ -from __future__ import print_function, division, absolute_import import sys sys.path.append("..") import os @@ -194,4 +193,4 @@ if __name__=="__main__": ConvertGenoFile.process_all(Old_Geno_Directory, New_Geno_Directory) #ConvertGenoFiles(Geno_Directory) - #process_csv(Input_File, Output_File) \ No newline at end of file + #process_csv(Input_File, Output_File) diff --git a/wqflask/maintenance/get_group_samplelists.py b/wqflask/maintenance/get_group_samplelists.py index fb22898a..3f9d0278 100644 --- a/wqflask/maintenance/get_group_samplelists.py +++ b/wqflask/maintenance/get_group_samplelists.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import os import glob import gzip diff --git a/wqflask/maintenance/print_benchmark.py b/wqflask/maintenance/print_benchmark.py index ae327cf3..b24ce4f1 100644 --- a/wqflask/maintenance/print_benchmark.py +++ b/wqflask/maintenance/print_benchmark.py @@ -1,7 +1,5 @@ #!/usr/bin/python -from __future__ import absolute_import, print_function, division - import time from pprint import pformat as pf @@ -40,4 +38,4 @@ def new_main(): print(pf(TheCounter.Counters)) if __name__ == '__main__': - new_main() \ No newline at end of file + new_main() diff --git a/wqflask/maintenance/quantile_normalize.py b/wqflask/maintenance/quantile_normalize.py index 4d6e03bf..701b2b50 100644 --- a/wqflask/maintenance/quantile_normalize.py +++ b/wqflask/maintenance/quantile_normalize.py @@ -1,10 +1,5 @@ -from __future__ import absolute_import, print_function, division - import sys sys.path.insert(0, './') - - - import MySQLdb import urllib.parse @@ -126,4 +121,4 @@ if __name__ == '__main__': } ) - print(response) \ No newline at end of file + print(response) diff --git a/wqflask/maintenance/set_resource_defaults.py b/wqflask/maintenance/set_resource_defaults.py index abd5416c..4177c124 100644 --- a/wqflask/maintenance/set_resource_defaults.py +++ b/wqflask/maintenance/set_resource_defaults.py @@ -16,8 +16,6 @@ To run: """ -from __future__ import print_function, division - import sys import json @@ -163,4 +161,4 @@ def main(): if __name__ == '__main__': Conn = MySQLdb.Connect(**parse_db_uri()) Cursor = Conn.cursor() - main() \ No newline at end of file + main() diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 48a5c7ba..61f408d2 100644 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -24,8 +24,6 @@ # # Last updated by GeneNetwork Core Team 2010/10/20 -from __future__ import print_function - from PIL import ImageColor from PIL import ImageDraw from PIL import ImageFont diff --git a/wqflask/utility/after.py b/wqflask/utility/after.py index b628a0a4..06091ecb 100644 --- a/wqflask/utility/after.py +++ b/wqflask/utility/after.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - """ See: http://flask.pocoo.org/docs/patterns/deferredcallbacks/#deferred-callbacks @@ -13,4 +11,4 @@ def after_this_request(f): if not hasattr(g, 'after_request_callbacks'): g.after_request_callbacks = [] g.after_request_callbacks.append(f) - return f \ No newline at end of file + return f diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index bc03eb55..0e499180 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import json import requests diff --git a/wqflask/utility/benchmark.py b/wqflask/utility/benchmark.py index 221e5151..ea5a0ab6 100644 --- a/wqflask/utility/benchmark.py +++ b/wqflask/utility/benchmark.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import collections import inspect import time diff --git a/wqflask/utility/chunks.py b/wqflask/utility/chunks.py index d91b9bf4..9a7db102 100644 --- a/wqflask/utility/chunks.py +++ b/wqflask/utility/chunks.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import math import time diff --git a/wqflask/utility/db_tools.py b/wqflask/utility/db_tools.py index 4034f39c..92bde505 100644 --- a/wqflask/utility/db_tools.py +++ b/wqflask/utility/db_tools.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from MySQLdb import escape_string as escape def create_in_clause(items): diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py index ae42f834..81085ffe 100644 --- a/wqflask/utility/gen_geno_ob.py +++ b/wqflask/utility/gen_geno_ob.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import utility.logger logger = utility.logger.getLogger(__name__ ) @@ -178,4 +176,4 @@ class Locus(object): if allele in list(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 + self.genotype.append("U") diff --git a/wqflask/utility/genofile_parser.py b/wqflask/utility/genofile_parser.py index af306731..0b736176 100644 --- a/wqflask/utility/genofile_parser.py +++ b/wqflask/utility/genofile_parser.py @@ -1,7 +1,6 @@ # CTL analysis for GN2 # Author / Maintainer: Danny Arends -from __future__ import print_function, division, absolute_import import sys import os import glob diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py index 107c9ec6..7eb7f013 100644 --- a/wqflask/utility/helper_functions.py +++ b/wqflask/utility/helper_functions.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from base import data_set from base.trait import create_trait from base.species import TheSpecies diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index b08be97e..73e28790 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import hmac import hashlib @@ -37,4 +35,4 @@ def url_for_hmac(endpoint, **values): 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 + data_hmac=data_hmac) diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 1377a564..13ac5cfe 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import uuid import simplejson as json import datetime @@ -306,4 +304,4 @@ def change_resource_owner(resource_id, new_owner_id): the_resource['owner_id'] = new_owner_id Redis.delete("resource") - Redis.hset("resources", resource_id, json.dumps(the_resource)) \ No newline at end of file + Redis.hset("resources", resource_id, json.dumps(the_resource)) diff --git a/wqflask/utility/temp_data.py b/wqflask/utility/temp_data.py index 2f2726c6..4144ae00 100644 --- a/wqflask/utility/temp_data.py +++ b/wqflask/utility/temp_data.py @@ -1,4 +1,3 @@ -from __future__ import print_function, division, absolute_import from redis import Redis import simplejson as json diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index d729aef5..e73f833f 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import sys import jinja2 diff --git a/wqflask/wqflask/api/correlation.py b/wqflask/wqflask/api/correlation.py index eb05645e..7da13121 100644 --- a/wqflask/wqflask/api/correlation.py +++ b/wqflask/wqflask/api/correlation.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import collections import scipy @@ -234,4 +232,4 @@ def init_corr_params(start_vars): 'return_count' : return_count } - return corr_params \ No newline at end of file + return corr_params diff --git a/wqflask/wqflask/api/gen_menu.py b/wqflask/wqflask/api/gen_menu.py index 41966f78..1dcafe1f 100644 --- a/wqflask/wqflask/api/gen_menu.py +++ b/wqflask/wqflask/api/gen_menu.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division - from flask import g diff --git a/wqflask/wqflask/api/mapping.py b/wqflask/wqflask/api/mapping.py index 92c27c9b..d59a69df 100644 --- a/wqflask/wqflask/api/mapping.py +++ b/wqflask/wqflask/api/mapping.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import string from base import data_set diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index 5f9b81b8..acf7ce4a 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -1,7 +1,5 @@ # GN2 API -from __future__ import absolute_import, division, print_function - import os, io, csv, json, datetime, requests, yaml import zlib from zipfile import ZipFile, ZIP_DEFLATED @@ -966,4 +964,4 @@ def get_group_id(group_name): if group_id: return group_id[0] else: - return None \ No newline at end of file + return None diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 06c00930..15383603 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -1,6 +1,3 @@ -from __future__ import print_function, division, absolute_import - - import os import hashlib import datetime diff --git a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py index 16832621..92de6073 100644 --- a/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py +++ b/wqflask/wqflask/comparison_bar_chart/comparison_bar_chart.py @@ -18,7 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division from pprint import pformat as pf from base.trait import create_trait diff --git a/wqflask/wqflask/correlation/corr_scatter_plot.py b/wqflask/wqflask/correlation/corr_scatter_plot.py index 57a8d85f..929cd2c9 100644 --- a/wqflask/wqflask/correlation/corr_scatter_plot.py +++ b/wqflask/wqflask/correlation/corr_scatter_plot.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import math from flask import g @@ -130,4 +128,4 @@ def get_intercept_coords(slope, intercept, x_range, y_range): intercept_coords.append([x1, y1]) intercept_coords.append([x2, y2]) - return intercept_coords \ No newline at end of file + return intercept_coords diff --git a/wqflask/wqflask/correlation/correlation_functions.py b/wqflask/wqflask/correlation/correlation_functions.py index abaa212f..b883e361 100644 --- a/wqflask/wqflask/correlation/correlation_functions.py +++ b/wqflask/wqflask/correlation/correlation_functions.py @@ -24,8 +24,6 @@ # # Last updated by NL 2011/03/23 -from __future__ import absolute_import, print_function, division - import math import rpy2.robjects import string @@ -114,4 +112,4 @@ def get_trait_symbol_and_tissue_values(symbol_list=None): tissue_data = MrnaAssayTissueData(gene_symbols=symbol_list) if len(tissue_data.gene_symbols): - return tissue_data.get_symbol_values_pairs() \ No newline at end of file + return tissue_data.get_symbol_values_pairs() diff --git a/wqflask/wqflask/correlation/show_corr_results.py b/wqflask/wqflask/correlation/show_corr_results.py index 5ced30b6..e5b87c6a 100644 --- a/wqflask/wqflask/correlation/show_corr_results.py +++ b/wqflask/wqflask/correlation/show_corr_results.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - import collections import json import scipy diff --git a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py index bd5aca1f..7b4bda31 100644 --- a/wqflask/wqflask/correlation_matrix/show_corr_matrix.py +++ b/wqflask/wqflask/correlation_matrix/show_corr_matrix.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - import datetime import math import numpy as np diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index cc9c1860..de8e1e78 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division - import string import requests import json diff --git a/wqflask/wqflask/docs.py b/wqflask/wqflask/docs.py index 78407e22..8628b81d 100644 --- a/wqflask/wqflask/docs.py +++ b/wqflask/wqflask/docs.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import codecs from flask import g @@ -42,4 +40,4 @@ def update_text(start_vars): sql = "UPDATE Docs SET content='{0}' WHERE entry='{1}';".format(content, start_vars['entry_type']) g.db.execute(sql) except: - pass \ No newline at end of file + pass diff --git a/wqflask/wqflask/export_traits.py b/wqflask/wqflask/export_traits.py index 2f4e9aac..3a886537 100644 --- a/wqflask/wqflask/export_traits.py +++ b/wqflask/wqflask/export_traits.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division - import csv import xlsxwriter import io @@ -140,4 +138,4 @@ def sort_traits_by_group(trait_list=[]): traits_by_group[trait.dataset.group.name].append(trait) - return traits_by_group \ No newline at end of file + return traits_by_group diff --git a/wqflask/wqflask/external_tools/send_to_bnw.py b/wqflask/wqflask/external_tools/send_to_bnw.py index 68efd10d..efa17f05 100644 --- a/wqflask/wqflask/external_tools/send_to_bnw.py +++ b/wqflask/wqflask/external_tools/send_to_bnw.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - from base.trait import GeneralTrait from utility import helper_functions, corr_result_helpers @@ -69,4 +67,4 @@ class SendToBNW(object): if has_none: continue self.form_value += ",".join(str(cell) for cell in row) - self.form_value += ";" \ No newline at end of file + self.form_value += ";" diff --git a/wqflask/wqflask/external_tools/send_to_geneweaver.py b/wqflask/wqflask/external_tools/send_to_geneweaver.py index 9844bab4..93164233 100644 --- a/wqflask/wqflask/external_tools/send_to_geneweaver.py +++ b/wqflask/wqflask/external_tools/send_to_geneweaver.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - import string from flask import Flask, g @@ -109,4 +107,4 @@ def test_chip(trait_list): chip_name = '%s_NA' % result[0] return chip_name - return chip_name \ No newline at end of file + return chip_name diff --git a/wqflask/wqflask/external_tools/send_to_webgestalt.py b/wqflask/wqflask/external_tools/send_to_webgestalt.py index 30ca024f..b255ba95 100644 --- a/wqflask/wqflask/external_tools/send_to_webgestalt.py +++ b/wqflask/wqflask/external_tools/send_to_webgestalt.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - import string from flask import Flask, g @@ -123,4 +121,4 @@ def gen_gene_id_list(trait_list): trait_name_list.append(trait.name) retrieve_trait_info(trait, trait.dataset) gene_id_list.append(str(trait.geneid)) - return trait_name_list, gene_id_list \ No newline at end of file + return trait_name_list, gene_id_list diff --git a/wqflask/wqflask/group_manager.py b/wqflask/wqflask/group_manager.py index 24848ed8..e6079c3e 100644 --- a/wqflask/wqflask/group_manager.py +++ b/wqflask/wqflask/group_manager.py @@ -1,6 +1,3 @@ - -from __future__ import print_function, division, absolute_import - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash) @@ -142,4 +139,4 @@ def send_group_invites(group_id, user_email_list = [], user_type="members"): else: send_verification_email(user_details, template_name = "email/group_verification.txt", key_prefix = "verification_code", subject = "You've been invited to join a GeneNetwork user group") -#@app.route() \ No newline at end of file +#@app.route() diff --git a/wqflask/wqflask/gsearch.py b/wqflask/wqflask/gsearch.py index c65a1415..6d797a29 100644 --- a/wqflask/wqflask/gsearch.py +++ b/wqflask/wqflask/gsearch.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import json from flask import Flask, g diff --git a/wqflask/wqflask/heatmap/heatmap.py b/wqflask/wqflask/heatmap/heatmap.py index 1f1cdb90..cca5a4fc 100644 --- a/wqflask/wqflask/heatmap/heatmap.py +++ b/wqflask/wqflask/heatmap/heatmap.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import string import os import random diff --git a/wqflask/wqflask/interval_analyst/GeneUtil.py b/wqflask/wqflask/interval_analyst/GeneUtil.py index a39e5d0f..17c8ccbf 100644 --- a/wqflask/wqflask/interval_analyst/GeneUtil.py +++ b/wqflask/wqflask/interval_analyst/GeneUtil.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import string from flask import Flask, g diff --git a/wqflask/wqflask/marker_regression/run_mapping.py b/wqflask/wqflask/marker_regression/run_mapping.py index 67512bc6..7ae84b16 100644 --- a/wqflask/wqflask/marker_regression/run_mapping.py +++ b/wqflask/wqflask/marker_regression/run_mapping.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from base.trait import GeneralTrait from base import data_set #import create_dataset @@ -711,4 +709,4 @@ def get_perm_strata(this_trait, sample_list, categorical_vars, used_samples): list_to_numbers = [d[x] for x in perm_strata_strings] perm_strata = list_to_numbers - return perm_strata \ No newline at end of file + return perm_strata diff --git a/wqflask/wqflask/model.py b/wqflask/wqflask/model.py index a135761c..772f74e4 100644 --- a/wqflask/wqflask/model.py +++ b/wqflask/wqflask/model.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import uuid import datetime @@ -168,4 +166,4 @@ def display_collapsible(number): def user_uuid(): """Unique cookie for a user""" - user_uuid = request.cookies.get('user_uuid') \ No newline at end of file + user_uuid = request.cookies.get('user_uuid') diff --git a/wqflask/wqflask/network_graph/network_graph.py b/wqflask/wqflask/network_graph/network_graph.py index 2a4c4a93..70e5dd58 100644 --- a/wqflask/wqflask/network_graph/network_graph.py +++ b/wqflask/wqflask/network_graph/network_graph.py @@ -18,8 +18,6 @@ # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import absolute_import, print_function, division - import scipy import simplejson as json from pprint import pformat as pf diff --git a/wqflask/wqflask/news.py b/wqflask/wqflask/news.py index 20319756..0675ec4b 100644 --- a/wqflask/wqflask/news.py +++ b/wqflask/wqflask/news.py @@ -1,4 +1,3 @@ -from __future__ import absolute_import, print_function, division from flask import g class News(object): diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 1ca5ecff..472dd30e 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -17,8 +17,6 @@ be acceptable.] """ -from __future__ import print_function, division - import re from pprint import pformat as pf diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py index 6b3e00fb..e883d5da 100644 --- a/wqflask/wqflask/resource_manager.py +++ b/wqflask/wqflask/resource_manager.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import json from flask import (Flask, g, render_template, url_for, request, make_response, @@ -131,4 +129,4 @@ def get_group_names(group_masks): this_mask['name'] = group_name group_masks_with_names[group_id] = this_mask - return group_masks_with_names \ No newline at end of file + return group_masks_with_names diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index c07a7670..f6c677a8 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import re import uuid from math import * diff --git a/wqflask/wqflask/send_mail.py b/wqflask/wqflask/send_mail.py index bf5d0dd8..86e8a558 100644 --- a/wqflask/wqflask/send_mail.py +++ b/wqflask/wqflask/send_mail.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, division, print_function - import datetime import time diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index f17e825e..6fcf7cec 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from flask import Flask, g from base import webqtlCaseData diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index 68c3ad7d..2d76b935 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division - import simplejson as json from pprint import pformat as pf @@ -71,4 +69,4 @@ def cmp_samples(a, b): else: return 1 else: - return -1 \ No newline at end of file + return -1 diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 6a74cada..e93b0289 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import string import os import datetime diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index b3d26caf..0db7e1fe 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from flask import Flask, g, url_for import string diff --git a/wqflask/wqflask/submit_bnw.py b/wqflask/wqflask/submit_bnw.py index 59e60dfd..a0e84c8c 100644 --- a/wqflask/wqflask/submit_bnw.py +++ b/wqflask/wqflask/submit_bnw.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - from base.trait import GeneralTrait from base import data_set from utility import helper_functions @@ -8,4 +6,4 @@ import utility.logger logger = utility.logger.getLogger(__name__ ) def get_bnw_input(start_vars): - logger.debug("BNW VARS:", start_vars) \ No newline at end of file + logger.debug("BNW VARS:", start_vars) diff --git a/wqflask/wqflask/update_search_results.py b/wqflask/wqflask/update_search_results.py index 68bea9d6..672f95b1 100644 --- a/wqflask/wqflask/update_search_results.py +++ b/wqflask/wqflask/update_search_results.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import, print_function, division - import json from flask import Flask, g diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index 04672b45..10cb7319 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import os import hashlib import datetime @@ -470,4 +468,4 @@ def register(): @app.errorhandler(401) def unauthorized(error): - return redirect(url_for('login')) \ No newline at end of file + return redirect(url_for('login')) diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 3c41e2b8..24191a15 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import os import hashlib import datetime diff --git a/wqflask/wqflask/user_session.py b/wqflask/wqflask/user_session.py index 71c31c57..c1f38396 100644 --- a/wqflask/wqflask/user_session.py +++ b/wqflask/wqflask/user_session.py @@ -1,5 +1,3 @@ -from __future__ import print_function, division, absolute_import - import datetime import time import uuid diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 83d5202e..b0489e64 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -2,8 +2,6 @@ # # Main routing table for GN2 -from __future__ import absolute_import, division, print_function - import traceback # for error page import os # for error gifs import random # for random error gif -- cgit v1.2.3 From 357ca458695fbc60c97de3d1cdf89034a8722bc5 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 27 Aug 2020 01:18:11 +0300 Subject: Replace "string.split" & "string.join" with python's inbuilt methods --- scripts/maintenance/readProbeSetMean_v7.py | 20 ++++++++++---------- scripts/maintenance/readProbeSetSE_v7.py | 14 +++++++------- wqflask/base/data_set.py | 2 +- wqflask/base/trait.py | 14 +++++++------- wqflask/utility/webqtlUtil.py | 4 ++-- wqflask/wqflask/external_tools/send_to_geneweaver.py | 2 +- wqflask/wqflask/external_tools/send_to_webgestalt.py | 2 +- wqflask/wqflask/interval_analyst/GeneUtil.py | 4 ++-- .../marker_regression/display_mapping_results.py | 2 +- wqflask/wqflask/marker_regression/plink_mapping.py | 6 +++--- wqflask/wqflask/show_trait/show_trait.py | 4 ++-- wqflask/wqflask/snp_browser/snp_browser.py | 12 ++++++------ 12 files changed, 43 insertions(+), 43 deletions(-) (limited to 'wqflask/utility') diff --git a/scripts/maintenance/readProbeSetMean_v7.py b/scripts/maintenance/readProbeSetMean_v7.py index a540796a..43f084f4 100755 --- a/scripts/maintenance/readProbeSetMean_v7.py +++ b/scripts/maintenance/readProbeSetMean_v7.py @@ -60,15 +60,15 @@ print('Checking if each line have same number of members') GeneList = [] isCont = 1 header = fp.readline() -header = string.split(string.strip(header), '\t') -header = list(map(string.strip, header)) +header = header.strip().split('\t') +header = [x.strip() for x in header] nfield = len(header) line = fp.readline() kj = 0 while line: - line2 = string.split(string.strip(line), '\t') - line2 = list(map(string.strip, line2)) + line2 = line.strip().split('\t') + line2 = [x.strip() for x in line2] if len(line2) != nfield: print(("Error : " + line)) isCont = 0 @@ -98,8 +98,8 @@ print('Checking if each strain exist in database') isCont = 1 fp.seek(0) header = fp.readline() -header = string.split(string.strip(header), '\t') -header = list(map(string.strip, header)) +header = header.strip().split('\t') +header = [x.strip() for x in header] header = list(map(translateAlias, header)) header = header[dataStart:] Ids = [] @@ -126,8 +126,8 @@ print('Check if each ProbeSet exist in database') ##---- find PID is name or target ----## line = fp.readline() line = fp.readline() -line2 = string.split(string.strip(line), '\t') -line2 = list(map(string.strip, line2)) +line2 = line.strip().split('\t') +line2 = [x.strip() for x in line2] PId = line2[0] db.execute('select Id from ProbeSet where Name="%s" and ChipId=%d' % @@ -222,8 +222,8 @@ kj = 0 values1 = [] values2 = [] while line: - line2 = string.split(string.strip(line), '\t') - line2 = list(map(string.strip, line2)) + line2 = line.strip().split('\t') + line2 = [x.strip() for x in line2] PId = line2[0] recordId = NameIds[PId] diff --git a/scripts/maintenance/readProbeSetSE_v7.py b/scripts/maintenance/readProbeSetSE_v7.py index 20a846a4..edd9e7b0 100755 --- a/scripts/maintenance/readProbeSetSE_v7.py +++ b/scripts/maintenance/readProbeSetSE_v7.py @@ -71,14 +71,14 @@ print('Checking if each line have same number of members') GeneList = [] isCont = 1 header = fp.readline() -header = string.split(string.strip(header), '\t') +header = header.strip().split('\t') header = list(map(string.strip, header)) nfield = len(header) line = fp.readline() kj = 0 while line: - line2 = string.split(string.strip(line), '\t') + line2 = line.strip().split('\t') line2 = list(map(string.strip, line2)) if len(line2) != nfield: isCont = 0 @@ -109,7 +109,7 @@ print('Checking if each strain exist in database') isCont = 1 fp.seek(0) header = fp.readline() -header = string.split(string.strip(header), '\t') +header = header.strip().split('\t') header = list(map(string.strip, header)) header = list(map(translateAlias, header)) header = header[dataStart:] @@ -137,8 +137,8 @@ print('Check if each ProbeSet exist in database') ##---- find PID is name or target ----## line = fp.readline() line = fp.readline() -line2 = string.split(string.strip(line), '\t') -line2 = list(map(string.strip, line2)) +line2 = line.strip().split('\t') +line2 = [x.strip() for x in line2] PId = line2[0] db.execute('select Id from ProbeSet where Name="%s" and ChipId=%d' % @@ -217,8 +217,8 @@ line = fp.readline() kj = 0 while line: - line2 = string.split(string.strip(line), '\t') - line2 = list(map(string.strip, line2)) + line2 = line.strip().split('\t') + line2 = [x.strip() for x in line2] CellId = line2[0] if CellId not in ProbeNameId: diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 8ac7a279..ce017fb4 100644 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -697,7 +697,7 @@ class DataSet(object): else: query = "SELECT {}.Name,".format(escape(dataset_type)) data_start_pos = 1 - query += string.join(temp, ', ') + query += ', '.join(temp) query += ' FROM ({}, {}XRef, {}Freeze) '.format(*mescape(dataset_type, self.type, self.type)) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index b20efd2a..2fd5d725 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -150,8 +150,8 @@ class GeneralTrait(object): alias = 'Not available' if getattr(self, "alias", None): - alias = string.replace(self.alias, ";", " ") - alias = string.join(string.split(alias), ", ") + alias = self.alias.replace(";", " ") + alias = ", ".join(alias.split()) return alias @@ -437,7 +437,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif dataset.type == 'Geno': - display_fields_string = string.join(dataset.display_fields, ',Geno.') + display_fields_string = ',Geno.'.join(dataset.display_fields) display_fields_string = 'Geno.' + display_fields_string query = """ SELECT %s @@ -456,8 +456,8 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): query = """SELECT %s FROM %s WHERE Name = %s""" logger.sql(query) trait_info = g.db.execute(query, - (string.join(dataset.display_fields, ','), - dataset.type, trait.name)).fetchone() + ','.join(dataset.display_fields), + dataset.type, trait.name).fetchone() if trait_info: trait.haveinfo = True @@ -501,8 +501,8 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % trait.pubmed_id if dataset.type == 'ProbeSet' and dataset.group: - description_string = str(str(trait.description).strip(codecs.BOM_UTF8), 'utf-8') - target_string = str(str(trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8') + description_string = trait.description + target_string = trait.probe_target_description if len(description_string) > 1 and description_string != 'None': description_display = description_string diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py index d4979011..5681fadf 100644 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -107,7 +107,7 @@ def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users) if webqtlConfig.USERDICT[privilege] > webqtlConfig.USERDICT['user']: access_to_confidential_phenotype_trait = 1 else: - AuthorizedUsersList=list(map(string.strip, string.split(authorized_users, ','))) - if AuthorizedUsersList.__contains__(userName): + AuthorizedUsersList=[x.strip() for x in authorized_users.split(',')] + if userName in AuthorizedUsersList: access_to_confidential_phenotype_trait = 1 return access_to_confidential_phenotype_trait diff --git a/wqflask/wqflask/external_tools/send_to_geneweaver.py b/wqflask/wqflask/external_tools/send_to_geneweaver.py index 93164233..4c958a88 100644 --- a/wqflask/wqflask/external_tools/send_to_geneweaver.py +++ b/wqflask/wqflask/external_tools/send_to_geneweaver.py @@ -55,7 +55,7 @@ class SendToGeneWeaver(object): 'client': "genenetwork", 'species': species_name, 'idtype': self.chip_name, - 'list': string.join(trait_name_list, ","), + 'list': ",".join(trait_name_list), } def get_trait_name_list(trait_list): diff --git a/wqflask/wqflask/external_tools/send_to_webgestalt.py b/wqflask/wqflask/external_tools/send_to_webgestalt.py index b255ba95..2f068792 100644 --- a/wqflask/wqflask/external_tools/send_to_webgestalt.py +++ b/wqflask/wqflask/external_tools/send_to_webgestalt.py @@ -47,7 +47,7 @@ class SendToWebGestalt(object): id_type = "entrezgene" self.hidden_vars = { - 'gene_list' : string.join(gene_id_list, "\n"), + 'gene_list' : "\n".join(gene_id_list), 'id_type' : "entrezgene", 'ref_set' : "genome", 'enriched_database_category' : "geneontology", diff --git a/wqflask/wqflask/interval_analyst/GeneUtil.py b/wqflask/wqflask/interval_analyst/GeneUtil.py index 17c8ccbf..d0dd7aea 100644 --- a/wqflask/wqflask/interval_analyst/GeneUtil.py +++ b/wqflask/wqflask/interval_analyst/GeneUtil.py @@ -31,7 +31,7 @@ def loadGenes(chrName, diffCol, startMb, endMb, species='mouse'): Chromosome = '%s' AND ((TxStart > %f and TxStart <= %f) OR (TxEnd > %f and TxEnd <= %f)) ORDER BY txStart - """ % (string.join(fetchFields, ", "), + """ % (", ".join(fetchFields), speciesId, chrName, startMb, endMb, startMb, endMb)).fetchall() @@ -66,7 +66,7 @@ def loadGenes(chrName, diffCol, startMb, endMb, species='mouse'): othSpec, othSpecId = item newdict2 = {} - resultsOther = g.db.execute("SELECT %s FROM GeneList WHERE SpeciesId = %d AND geneSymbol= '%s' LIMIT 1" % (string.join(fetchFields, ", "), + resultsOther = g.db.execute("SELECT %s FROM GeneList WHERE SpeciesId = %d AND geneSymbol= '%s' LIMIT 1" % (", ".join(fetchFields), othSpecId, newdict["GeneSymbol"])).fetchone() diff --git a/wqflask/wqflask/marker_regression/display_mapping_results.py b/wqflask/wqflask/marker_regression/display_mapping_results.py index ccdafa14..dfaa1562 100644 --- a/wqflask/wqflask/marker_regression/display_mapping_results.py +++ b/wqflask/wqflask/marker_regression/display_mapping_results.py @@ -454,7 +454,7 @@ class DisplayMappingResults(object): Chr_Length.Name in (%s) Order by Chr_Length.OrderId - """ % (self.dataset.group.name, string.join(["'%s'" % X[0] for X in self.ChrList[1:]], ", "))) + """ % (self.dataset.group.name, ", ".join(["'%s'" % X[0] for X in self.ChrList[1:]]))) self.ChrLengthMbList = [x[0]/1000000.0 for x in self.ChrLengthMbList] self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) diff --git a/wqflask/wqflask/marker_regression/plink_mapping.py b/wqflask/wqflask/marker_regression/plink_mapping.py index 2f282adc..6c38c34f 100644 --- a/wqflask/wqflask/marker_regression/plink_mapping.py +++ b/wqflask/wqflask/marker_regression/plink_mapping.py @@ -83,7 +83,7 @@ def get_samples_from_ped_file(dataset): sample_list=[] while line: - lineList = string.split(string.strip(line), '\t') + lineList = line.strip().split('\t') lineList = list(map(string.strip, lineList)) sample_name = lineList[0] @@ -155,8 +155,8 @@ def parse_plink_output(output_filename, species): # output: lineList list ####################################################### def build_line_list(line=None): - line_list = string.split(string.strip(line), ' ')# irregular number of whitespaces between columns + line_list = line.strip().split(' ')# irregular number of whitespaces between columns line_list = [item for item in line_list if item !=''] line_list = list(map(string.strip, line_list)) - return line_list \ No newline at end of file + return line_list diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index e93b0289..88cd7dca 100644 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -229,8 +229,8 @@ class ShowTrait(object): hddn = OrderedDict() if self.dataset.group.allsamples: - hddn['allsamples'] = string.join(self.dataset.group.allsamples, ' ') - hddn['primary_samples'] = string.join(self.primary_sample_names, ',') + hddn['allsamples'] = ''.join(self.dataset.group.allsamples) + hddn['primary_samples'] = ''.join(self.primary_sample_names) hddn['trait_id'] = self.trait_id hddn['trait_display_name'] = self.this_trait.display_name hddn['dataset'] = self.dataset.name diff --git a/wqflask/wqflask/snp_browser/snp_browser.py b/wqflask/wqflask/snp_browser/snp_browser.py index 0db7e1fe..2df71b12 100644 --- a/wqflask/wqflask/snp_browser/snp_browser.py +++ b/wqflask/wqflask/snp_browser/snp_browser.py @@ -456,7 +456,7 @@ class SnpBrowser(object): function_list = [] if function_details: - function_list = string.split(string.strip(function_details), ",") + function_list = function_details.strip().split(",") function_list = list(map(string.strip, function_list)) function_list[0] = function_list[0].title() function_details = ", ".join(item for item in function_list) @@ -722,11 +722,11 @@ def get_effect_details_by_category(effect_name = None, effect_value = None): new_codon_group_list = ['Start Gained'] codon_effect_group_list = ['Start Lost', 'Stop Gained', 'Stop Lost', 'Nonsynonymous', 'Synonymous'] - effect_detail_list = string.split(string.strip(effect_value), '|') + effect_detail_list = effect_value.strip().split('|') effect_detail_list = list(map(string.strip, effect_detail_list)) for index, item in enumerate(effect_detail_list): - item_list = string.split(string.strip(item), ',') + item_list = item.strip().split(',') item_list = list(map(string.strip, item_list)) gene_id = item_list[0] @@ -746,13 +746,13 @@ def get_effect_details_by_category(effect_name = None, effect_value = None): if effect_name in new_codon_group_list: new_codon = item_list[6] tmp_list = [biotype, new_codon] - function_detail_list.append(string.join(tmp_list, ", ")) + function_detail_list.append(", ".join(tmp_list)) elif effect_name in codon_effect_group_list: old_new_AA = item_list[6] old_new_codon = item_list[7] codon_num = item_list[8] tmp_list = [biotype, old_new_AA, old_new_codon, codon_num] - function_detail_list.append(string.join(tmp_list, ", ")) + function_detail_list.append(", ".join(tmp_list)) else: function_detail_list.append(biotype) @@ -852,7 +852,7 @@ def get_gene_id_name_dict(species_id, gene_name_list): if len(gene_name_list) == 0: return "" gene_name_str_list = ["'" + gene_name + "'" for gene_name in gene_name_list] - gene_name_str = string.join(gene_name_str_list, ",") + gene_name_str = ",".join(gene_name_str_list) query = """ SELECT -- cgit v1.2.3 From 391c1681eaeabfdbe65a64a1bb8b05beca30141e Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 27 Aug 2020 01:23:29 +0300 Subject: Add global method to convert binary string to plain string * wqflask/utility/db_tools.py: escape_string returns a binary string which introduces a bug when composing sql query string. The escaped strings have to be converted to plain text. --- wqflask/utility/db_tools.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/db_tools.py b/wqflask/utility/db_tools.py index 92bde505..6e19778f 100644 --- a/wqflask/utility/db_tools.py +++ b/wqflask/utility/db_tools.py @@ -1,4 +1,5 @@ -from MySQLdb import escape_string as escape +from MySQLdb import escape_string as escape_ + def create_in_clause(items): """Create an in clause for mysql""" @@ -6,8 +7,11 @@ def create_in_clause(items): in_clause = '( {} )'.format(in_clause) return in_clause + def mescape(*items): """Multiple escape""" - escaped = [escape(str(item)) for item in items] - #print("escaped is:", escaped) - return escaped + return [escape_(str(item)).decode('utf8') for item in items] + + +def escape(string_): + return escape_(string_).decode('utf8') -- cgit v1.2.3 From 46443ec8d2cdfd7c60358a889d90a90e4f7daaf4 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 27 Aug 2020 01:32:34 +0300 Subject: Replace string arguments to "hmac.new" with bytearray See: --- wqflask/utility/hmac.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index 73e28790..aa21c741 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -10,7 +10,7 @@ def hmac_creation(stringy): secret = app.config['SECRET_HMAC_CODE'] - hmaced = hmac.new(secret, stringy, hashlib.sha1) + hmaced = hmac.new(bytearray(secret, 'utf8'), bytearray(stringy, 'utf8'), 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." -- cgit v1.2.3 From 70dbeeb5832711ed5271434e482c18bc7ea095b8 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 27 Aug 2020 03:28:43 +0300 Subject: Add check for empty group_code when adding a new resource * wqflask/utility/authentication_tools.py(add_new_resource): If group_code is "None", an error is thrown when you try to: `group_code + "_" + str(trait_id)` --- wqflask/utility/authentication_tools.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 0e499180..73c39399 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -49,7 +49,10 @@ def add_new_resource(dataset, trait_id=None): } if dataset.type == "Publish": - resource_ob['name'] = get_group_code(dataset) + "_" + str(trait_id) + group_code = get_group_code(dataset) + if group_code is None: + group_code = "" + resource_ob['name'] = group_code + "_" + str(trait_id) resource_ob['data'] = { 'dataset': dataset.id, 'trait' : trait_id @@ -74,7 +77,6 @@ def add_new_resource(dataset, trait_id=None): def get_group_code(dataset): results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format(dataset.group.name)).fetchone() - return results[0] def check_admin(resource_id=None): -- cgit v1.2.3 From dba31ef2aa9e3f89621848fdb79b915dbd3c56e2 Mon Sep 17 00:00:00 2001 From: zsloan Date: Sat, 29 Aug 2020 13:47:52 -0500 Subject: Fixed issue where exporting traits would throw an error if a dataset's group didn't have an InbredSetCode set in the DB * wqflask/utility/authentication_tools.py - Changed get_group_code to return an empty string instead of None if InbredSetCode doesn't exist for a dataset group * wqflask/wqflask/views.py - Changed zipped export filename to "export_(datetime)" instead of "collection_(datetime)" since this export can occur from both the collection page and the global search page --- wqflask/utility/authentication_tools.py | 6 ++++-- wqflask/wqflask/views.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index ece7022c..3553b92b 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -76,8 +76,10 @@ def add_new_resource(dataset, trait_id=None): def get_group_code(dataset): results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format(dataset.group.name)).fetchone() - - return results[0] + if results[0]: + return results[0] + else: + return "" def check_admin(resource_id=None): the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index a898de43..91d1a279 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -419,7 +419,7 @@ def export_traits_csv(): if len(file_list) > 1: now = datetime.datetime.now() time_str = now.strftime('%H:%M_%d%B%Y') - filename = "collection_{}".format(time_str) + filename = "export_{}".format(time_str) memory_file = StringIO.StringIO() with ZipFile(memory_file, mode='w', compression=ZIP_DEFLATED) as zf: for the_file in file_list: -- cgit v1.2.3 From e754baaf51150156c159f59c8ba1fda0ba0a7269 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 31 Aug 2020 11:25:10 -0500 Subject: Fixed issue that was causing updating resource default privileges to not work * wqflask/utility/redis_tools.py - There was an issue where resources wouldn't be updated if they already existed. This is because the code didn't yet account for the "update" tag (that is meant to give the option of preventing updating resources when running the script to enter all resources into Redis). I changed the logic to add a resource if "update" is True or the resource doesn't already exist (so it won't if update is False and the resource exists). --- wqflask/utility/redis_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 1377a564..81ba04ea 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -288,7 +288,7 @@ def add_resource(resource_info, update=True): else: resource_id = hmac.hmac_creation('{}:{}'.format(str(resource_info['type']), str(resource_info['data']['dataset']))) - if not Redis.hexists("resources", resource_id): + if update or not Redis.hexists("resources", resource_id): Redis.hset("resources", resource_id, json.dumps(resource_info)) return resource_info -- cgit v1.2.3 From 90475fed0b2d1bd192a641bd417f6dfef79653d0 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 31 Aug 2020 20:34:31 +0300 Subject: Remove typo at beginning of line * wqflask/utility/authentication_tools.py: Remove accidental char at beginning of line. --- wqflask/utility/authentication_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 68bbb276..c52ebafa 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -88,7 +88,7 @@ def check_admin(resource_id=None): response = json.loads(requests.get(the_url).content)['admin'] except: resource_info = get_resource_info(resource_id) -l response = resource_info['default_mask']['admin'] + response = resource_info['default_mask']['admin'] if 'edit-admins' in response: return "edit-admins" -- cgit v1.2.3 From af0ca059da29391db9b1dfca0fe96883ce95f72f Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Tue, 15 Sep 2020 23:43:09 +0300 Subject: Remove unnecessary if branch * wqflask/utility/authentication_tools.py (check_resource_availability): Combine if statements into one boolean check in one if branch. --- wqflask/utility/authentication_tools.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 3553b92b..954f55fc 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -17,9 +17,7 @@ logger = logging.getLogger(__name__ ) def check_resource_availability(dataset, trait_id=None): #At least for now assume temporary entered traits are accessible - if type(dataset) == str: - return webqtlConfig.DEFAULT_PRIVILEGES - if dataset.type == "Temp": + if type(dataset) == str or dataset.type == "Temp": return webqtlConfig.DEFAULT_PRIVILEGES resource_id = get_resource_id(dataset, trait_id) -- cgit v1.2.3 From 23521ad683beaaff200743cb37dec68cd19cc2d5 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 16 Sep 2020 00:06:04 +0300 Subject: Apply pep8 * wqflask/utility/authentication_tools.py: Apply pep8 formatting to file. --- wqflask/utility/authentication_tools.py | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 954f55fc..239b08e3 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -1,4 +1,6 @@ from __future__ import absolute_import, print_function, division +import logging +from flask import Flask, g, redirect, url_for import json import requests @@ -9,31 +11,31 @@ from utility import hmac from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id, add_resource Redis = get_redis_conn() -from flask import Flask, g, redirect, url_for -import logging -logger = logging.getLogger(__name__ ) +logger = logging.getLogger(__name__) + def check_resource_availability(dataset, trait_id=None): - #At least for now assume temporary entered traits are accessible + # At least for now assume temporary entered traits are accessible if type(dataset) == str or dataset.type == "Temp": return webqtlConfig.DEFAULT_PRIVILEGES resource_id = get_resource_id(dataset, trait_id) - if resource_id: #ZS: This should never be false, but it's technically possible if a non-Temp dataset somehow had a type other than Publish/ProbeSet/Geno + if resource_id: # ZS: This should never be false, but it's technically possible if a non-Temp dataset somehow had a type other than Publish/ProbeSet/Geno resource_info = get_resource_info(resource_id) - if not resource_info: #ZS: If resource isn't already in redis, add it with default privileges + if not resource_info: # ZS: If resource isn't already in redis, add it with default privileges resource_info = add_new_resource(dataset, trait_id) - #ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy + # ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy if g.user_session.user_id in Redis.smembers("super_users"): - return webqtlConfig.SUPER_PRIVILEGES + return webqtlConfig.SUPER_PRIVILEGES response = None - the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/available?resource={}&user={}".format( + resource_id, g.user_session.user_id) try: response = json.loads(requests.get(the_url).content) except: @@ -41,18 +43,19 @@ def check_resource_availability(dataset, trait_id=None): return response + def add_new_resource(dataset, trait_id=None): resource_ob = { - 'owner_id' : "none", # webqtlConfig.DEFAULT_OWNER_ID, + 'owner_id': "none", # webqtlConfig.DEFAULT_OWNER_ID, 'default_mask': webqtlConfig.DEFAULT_PRIVILEGES, - 'group_masks' : {} + 'group_masks': {} } if dataset.type == "Publish": resource_ob['name'] = get_group_code(dataset) + "_" + str(trait_id) resource_ob['data'] = { 'dataset': dataset.id, - 'trait' : trait_id + 'trait': trait_id } resource_ob['type'] = 'dataset-publish' elif dataset.type == "Geno": @@ -72,15 +75,19 @@ def add_new_resource(dataset, trait_id=None): return resource_info + def get_group_code(dataset): - results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format(dataset.group.name)).fetchone() + results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format( + dataset.group.name)).fetchone() if results[0]: return results[0] else: return "" + def check_admin(resource_id=None): - the_url = "http://localhost:8080/available?resource={}&user={}".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/available?resource={}&user={}".format( + resource_id, g.user_session.user_id) try: response = json.loads(requests.get(the_url).content)['admin'] except: @@ -94,6 +101,7 @@ def check_admin(resource_id=None): else: return "not-admin" + def check_owner(dataset=None, trait_id=None, resource_id=None): if resource_id: resource_info = get_resource_info(resource_id) @@ -108,6 +116,7 @@ def check_owner(dataset=None, trait_id=None, resource_id=None): return False + def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): if not resource_id: if dataset.type == "Temp": -- cgit v1.2.3 From 225c360d0a5c57957fe2bc3299108e9b39f12929 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 17 Sep 2020 15:55:35 +0300 Subject: Apply pep8 * wqflask/utility/hmac.py: Apply pep8 and fix typo. --- wqflask/utility/hmac.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index b08be97e..fd75803e 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -7,11 +7,11 @@ from flask import url_for 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 @@ -20,10 +20,12 @@ def hmac_creation(stringy): 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""" + """Takes arbitrary 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""" @@ -36,5 +38,6 @@ def url_for_hmac(endpoint, **values): 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 + data_hmac=data_hmac) -- cgit v1.2.3 From f4a8789a5f28e1527d4c801b40176f47aa44146c Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 17 Sep 2020 17:16:28 +0300 Subject: Apply pep8 * wqflask/base/trait.py: Apply pep8. * wqflask/utility/authentication_tools.py: Ditto. --- wqflask/base/trait.py | 192 +++++++++++++++++++------------- wqflask/utility/authentication_tools.py | 32 ++++-- 2 files changed, 134 insertions(+), 90 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 6950cf11..548ccc4c 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -1,36 +1,30 @@ -import os -import string -import resource -import codecs import requests -import random +import simplejson as json +from wqflask import app from base import webqtlConfig from base.webqtlCaseData import webqtlCaseData from base.data_set import create_dataset -from db import webqtlDatabaseFunction -from utility import webqtlUtil from utility import hmac from utility.authentication_tools import check_resource_availability -from utility.tools import GN2_BASE_URL, GN_VERSION -from utility.redis_tools import get_redis_conn, get_resource_id, get_resource_info -Redis = get_redis_conn() +from utility.tools import GN2_BASE_URL +from utility.redis_tools import get_redis_conn, get_resource_id -from wqflask import app - -import simplejson as json from utility.db_tools import escape -from pprint import pformat as pf -from flask import Flask, g, request, url_for, redirect, make_response, render_template +from flask import g, request, url_for from utility.logger import getLogger -logger = getLogger(__name__ ) + +logger = getLogger(__name__) + +Redis = get_redis_conn() + def create_trait(**kw): - assert bool(kw.get('dataset')) != bool(kw.get('dataset_name')), "Needs dataset ob. or name"; + assert bool(kw.get('dataset')) != bool( + kw.get('dataset_name')), "Needs dataset ob. or name" - permitted = True if kw.get('name'): if kw.get('dataset_name'): if kw.get('dataset_name') != "Temp": @@ -40,18 +34,23 @@ def create_trait(**kw): if kw.get('dataset_name') != "Temp": if dataset.type == 'Publish': - permissions = check_resource_availability(dataset, kw.get('name')) + permissions = check_resource_availability( + dataset, kw.get('name')) else: permissions = check_resource_availability(dataset) if "view" in permissions['data']: the_trait = GeneralTrait(**kw) if the_trait.dataset.type != "Temp": - the_trait = retrieve_trait_info(the_trait, the_trait.dataset, get_qtl_info=kw.get('get_qtl_info')) + the_trait = retrieve_trait_info( + the_trait, + the_trait.dataset, + get_qtl_info=kw.get('get_qtl_info')) return the_trait else: return None + class GeneralTrait(object): """ Trait class defines a trait in webqtl, can be either Microarray, @@ -61,12 +60,17 @@ class GeneralTrait(object): def __init__(self, get_qtl_info=False, get_sample_info=True, **kw): # xor assertion - assert bool(kw.get('dataset')) != bool(kw.get('dataset_name')), "Needs dataset ob. or name"; - self.name = kw.get('name') # Trait ID, ProbeSet ID, Published ID, etc. + assert bool(kw.get('dataset')) != bool( + kw.get('dataset_name')), "Needs dataset ob. or name" + # Trait ID, ProbeSet ID, Published ID, etc. + self.name = kw.get('name') if kw.get('dataset_name'): if kw.get('dataset_name') == "Temp": temp_group = self.name.split("_")[2] - self.dataset = create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = temp_group) + self.dataset = create_dataset( + dataset_name="Temp", + dataset_type="Temp", + group_name=temp_group) else: self.dataset = create_dataset(kw.get('dataset_name')) else: @@ -74,7 +78,8 @@ class GeneralTrait(object): self.cellid = kw.get('cellid') self.identification = kw.get('identification', 'un-named trait') self.haveinfo = kw.get('haveinfo', False) - self.sequence = kw.get('sequence') # Blat sequence, available for ProbeSet + # Blat sequence, available for ProbeSet + self.sequence = kw.get('sequence') self.data = kw.get('data', {}) self.view = True @@ -100,9 +105,10 @@ class GeneralTrait(object): elif len(name2) == 3: self.dataset, self.name, self.cellid = name2 - # Todo: These two lines are necessary most of the time, but perhaps not all of the time - # So we could add a simple if statement to short-circuit this if necessary - if get_sample_info != False: + # Todo: These two lines are necessary most of the time, but + # perhaps not all of the time So we could add a simple if + # statement to short-circuit this if necessary + if get_sample_info is not False: self = retrieve_sample_data(self, self.dataset) def export_informative(self, include_variance=0): @@ -116,13 +122,13 @@ class GeneralTrait(object): the_vars = [] sample_aliases = [] for sample_name, sample_data in list(self.data.items()): - if sample_data.value != None: - if not include_variance or sample_data.variance != None: + if sample_data.value is not None: + if not include_variance or sample_data.variance is not None: samples.append(sample_name) vals.append(sample_data.value) the_vars.append(sample_data.variance) sample_aliases.append(sample_data.name2) - return samples, vals, the_vars, sample_aliases + return samples, vals, the_vars, sample_aliases @property def description_fmt(self): @@ -161,12 +167,17 @@ class GeneralTrait(object): alias = 'Not available' if self.symbol: - human_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.upper()) - mouse_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.capitalize()) - other_response = requests.get(GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.lower()) + human_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.upper()) + mouse_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.capitalize()) + other_response = requests.get( + GN2_BASE_URL + "gn3/gene/aliases/" + self.symbol.lower()) if human_response and mouse_response and other_response: - alias_list = json.loads(human_response.content) + json.loads(mouse_response.content) + json.loads(other_response.content) + alias_list = json.loads(human_response.content) + json.loads( + mouse_response.content) + \ + json.loads(other_response.content) filtered_aliases = [] seen = set() @@ -180,33 +191,34 @@ class GeneralTrait(object): return alias - @property def location_fmt(self): '''Return a text formatted location - While we're at it we set self.location in case we need it later (do we?) + While we're at it we set self.location in case we need it + later (do we?) ''' if self.chr and self.mb: - self.location = 'Chr %s @ %s Mb' % (self.chr, self.mb) + self.location = 'Chr %s @ %s Mb' % (self.chr, self.mb) elif self.chr: self.location = 'Chr %s @ Unknown position' % (self.chr) else: self.location = 'Not available' fmt = self.location - ##XZ: deal with direction + # XZ: deal with direction if self.strand_probe == '+': fmt += (' on the plus strand ') elif self.strand_probe == '-': fmt += (' on the minus strand ') return fmt - + + def retrieve_sample_data(trait, dataset, samplelist=None): - if samplelist == None: + if samplelist is None: samplelist = [] if dataset.type == "Temp": @@ -222,16 +234,19 @@ def retrieve_sample_data(trait, dataset, samplelist=None): all_samples_ordered = dataset.group.all_samples_ordered() for i, item in enumerate(results): try: - trait.data[all_samples_ordered[i]] = webqtlCaseData(all_samples_ordered[i], float(item)) + trait.data[all_samples_ordered[i]] = webqtlCaseData( + all_samples_ordered[i], float(item)) except: pass else: for item in results: name, value, variance, num_cases, name2 = item if not samplelist or (samplelist and name in samplelist): - trait.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) + # name, value, variance, num_cases) + trait.data[name] = webqtlCaseData(*item) return trait + @app.route("/trait/get_sample_data") def get_sample_data(): params = request.args @@ -247,7 +262,8 @@ def get_sample_data(): trait_dict['group'] = trait_ob.dataset.group.name trait_dict['tissue'] = trait_ob.dataset.tissue trait_dict['species'] = trait_ob.dataset.group.species - trait_dict['url'] = url_for('show_trait_page', trait_id = trait, dataset = dataset) + trait_dict['url'] = url_for( + 'show_trait_page', trait_id=trait, dataset=dataset) trait_dict['description'] = trait_ob.description_display if trait_ob.dataset.type == "ProbeSet": trait_dict['symbol'] = trait_ob.symbol @@ -257,22 +273,27 @@ def get_sample_data(): trait_dict['pubmed_link'] = trait_ob.pubmed_link trait_dict['pubmed_text'] = trait_ob.pubmed_text - return json.dumps([trait_dict, {key: value.value for key, value in list(trait_ob.data.items()) }]) + return json.dumps([trait_dict, {key: value.value for + key, value in list( + trait_ob.data.items())}]) else: return None - + + def jsonable(trait): """Return a dict suitable for using as json Actual turning into json doesn't happen here though""" - dataset = create_dataset(dataset_name = trait.dataset.name, dataset_type = trait.dataset.type, group_name = trait.dataset.group.name) - + dataset = create_dataset(dataset_name=trait.dataset.name, + dataset_type=trait.dataset.type, + group_name=trait.dataset.group.name) + if dataset.type == "ProbeSet": return dict(name=trait.name, symbol=trait.symbol, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, mean=trait.mean, location=trait.location_repr, @@ -284,7 +305,7 @@ def jsonable(trait): if trait.pubmed_id: return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, abbreviation=trait.abbreviation, authors=trait.authors, @@ -297,7 +318,7 @@ def jsonable(trait): else: return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, description=trait.description_display, abbreviation=trait.abbreviation, authors=trait.authors, @@ -309,19 +330,20 @@ def jsonable(trait): elif dataset.type == "Geno": return dict(name=trait.name, dataset=dataset.name, - dataset_name = dataset.shortname, + dataset_name=dataset.shortname, location=trait.location_repr ) else: return dict() + def jsonable_table_row(trait, dataset_name, index): """Return a list suitable for json and intended to be displayed in a table Actual turning into json doesn't happen here though""" dataset = create_dataset(dataset_name) - + if dataset.type == "ProbeSet": if trait.mean == "": mean = "N/A" @@ -333,11 +355,13 @@ def jsonable_table_row(trait, dataset_name, index): additive = "%.3f" % round(float(trait.additive), 2) return ['', index, - ''+str(trait.name)+'', + ''+str(trait.name)+'', trait.symbol, trait.description_display, trait.location_repr, - mean, + mean, trait.LRS_score_repr, trait.LRS_location_repr, additive] @@ -349,7 +373,9 @@ def jsonable_table_row(trait, dataset_name, index): if trait.pubmed_id: return ['', index, - ''+str(trait.name)+'', + ''+str(trait.name)+'', trait.description_display, trait.authors, '' + trait.pubmed_text + '', @@ -359,7 +385,9 @@ def jsonable_table_row(trait, dataset_name, index): else: return ['', index, - ''+str(trait.name)+'', + ''+str(trait.name)+'', trait.description_display, trait.authors, trait.pubmed_text, @@ -369,7 +397,9 @@ def jsonable_table_row(trait, dataset_name, index): elif dataset.type == "Geno": return ['', index, - ''+str(trait.name)+'', + ''+str(trait.name)+'', trait.location_repr] else: return dict() @@ -380,14 +410,16 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): resource_id = get_resource_id(dataset, trait.name) if dataset.type == 'Publish': - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format(resource_id, g.user_session.user_id) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view".format( + resource_id, g.user_session.user_id) else: - the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format(resource_id, g.user_session.user_id, trait.name) + the_url = "http://localhost:8080/run-action?resource={}&user={}&branch=data&action=view&trait={}".format( + resource_id, g.user_session.user_id, trait.name) try: response = requests.get(the_url).content trait_info = json.loads(response) - except: #ZS: I'm assuming the trait is viewable if the try fails for some reason; it should never reach this point unless the user has privileges, since that's dealt with in create_trait + except: # ZS: I'm assuming the trait is viewable if the try fails for some reason; it should never reach this point unless the user has privileges, since that's dealt with in create_trait if dataset.type == 'Publish': query = """ SELECT @@ -416,8 +448,8 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): logger.sql(query) trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name - #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + # XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name + # XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif dataset.type == 'ProbeSet': display_fields_string = ', ProbeSet.'.join(dataset.display_fields) display_fields_string = 'ProbeSet.' + display_fields_string @@ -430,11 +462,11 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' """ % (escape(display_fields_string), - escape(dataset.name), - escape(str(trait.name))) + escape(dataset.name), + escape(str(trait.name))) logger.sql(query) trait_info = g.db.execute(query).fetchone() - #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name + # XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif dataset.type == 'Geno': display_fields_string = ',Geno.'.join(dataset.display_fields) @@ -448,11 +480,11 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): GenoFreeze.Name = '%s' AND Geno.Name = '%s' """ % (escape(display_fields_string), - escape(dataset.name), - escape(trait.name)) + escape(dataset.name), + escape(trait.name)) logger.sql(query) trait_info = g.db.execute(query).fetchone() - else: #Temp type + else: # Temp type query = """SELECT %s FROM %s WHERE Name = %s""" logger.sql(query) trait_info = g.db.execute(query, @@ -462,7 +494,7 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): if trait_info: trait.haveinfo = True for i, field in enumerate(dataset.display_fields): - holder = trait_info[i] + holder = trait_info[i] setattr(trait, field, holder) if dataset.type == 'Publish': @@ -475,9 +507,9 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): description = trait.post_publication_description - #If the dataset is confidential and the user has access to confidential - #phenotype traits, then display the pre-publication description instead - #of the post-publication description + # If the dataset is confidential and the user has access to confidential + # phenotype traits, then display the pre-publication description instead + # of the post-publication description if trait.confidential: trait.abbreviation = trait.pre_publication_abbreviation trait.description_display = trait.pre_publication_description @@ -514,15 +546,17 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.location_repr = 'N/A' if trait.chr and trait.mb: - trait.location_repr = 'Chr%s: %.6f' % (trait.chr, float(trait.mb)) + trait.location_repr = 'Chr%s: %.6f' % ( + trait.chr, float(trait.mb)) elif dataset.type == "Geno": trait.location_repr = 'N/A' if trait.chr and trait.mb: - trait.location_repr = 'Chr%s: %.6f' % (trait.chr, float(trait.mb)) + trait.location_repr = 'Chr%s: %.6f' % ( + trait.chr, float(trait.mb)) if get_qtl_info: - #LRS and its location + # LRS and its location trait.LRS_score_repr = "N/A" trait.LRS_location_repr = "N/A" trait.locus = trait.locus_chr = trait.locus_mb = trait.lrs = trait.pvalue = trait.additive = "" @@ -594,10 +628,12 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.locus = trait.lrs = trait.additive = "" if (dataset.type == 'Publish' or dataset.type == "ProbeSet") and trait.locus_chr != "" and trait.locus_mb != "": - trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (trait.locus_chr, float(trait.locus_mb)) + trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % ( + trait.locus_chr, float(trait.locus_mb)) if trait.lrs != "": trait.LRS_score_repr = LRS_score_repr = '%3.1f' % trait.lrs else: - raise KeyError(repr(trait.name)+' information is not found in the database.') - + raise KeyError(repr(trait.name) + + ' information is not found in the database.') + return trait diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 390ad75a..ce0c0749 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -1,30 +1,37 @@ import json import requests -from base import data_set, webqtlConfig - -from utility import hmac -from utility.redis_tools import get_redis_conn, get_resource_info, get_resource_id, add_resource -Redis = get_redis_conn() +from flask import g +from base import webqtlConfig -logger = logging.getLogger(__name__) +from utility.redis_tools import (get_redis_conn, + get_resource_info, + get_resource_id, + add_resource) +Redis = get_redis_conn() def check_resource_availability(dataset, trait_id=None): - # At least for now assume temporary entered traits are accessible if type(dataset) == str or dataset.type == "Temp": return webqtlConfig.DEFAULT_PRIVILEGES resource_id = get_resource_id(dataset, trait_id) - if resource_id: # ZS: This should never be false, but it's technically possible if a non-Temp dataset somehow had a type other than Publish/ProbeSet/Geno + # ZS: This should never be false, but it's technically possible if + # a non-Temp dataset somehow had a type other than + # Publish/ProbeSet/Geno + if resource_id: resource_info = get_resource_info(resource_id) - if not resource_info: # ZS: If resource isn't already in redis, add it with default privileges + + # ZS: If resource isn't already in redis, add it with default + # privileges + if not resource_info: resource_info = add_new_resource(dataset, trait_id) - # ZS: Check if super-user - we should probably come up with some way to integrate this into the proxy + # ZS: Check if super-user - we should probably come up with some + # way to integrate this into the proxy if g.user_session.user_id in Redis.smembers("super_users"): return webqtlConfig.SUPER_PRIVILEGES @@ -76,8 +83,9 @@ def add_new_resource(dataset, trait_id=None): def get_group_code(dataset): - results = g.db.execute("SELECT InbredSetCode from InbredSet where Name='{}'".format( - dataset.group.name)).fetchone() + results = g.db.execute( + "SELECT InbredSetCode from InbredSet where Name='{}'".format( + dataset.group.name)).fetchone() if results[0]: return results[0] else: -- cgit v1.2.3 From 6064148eb2b723a308f0d29595a75ab64f47e1e2 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Thu, 17 Sep 2020 17:34:11 +0300 Subject: Replace string arguments to "hmac.new" with bytearray Same as: https://github.com/genenetwork/genenetwork2/pull/422/commits/46443ec8d2cdfd7c60358a889d90a90e4f7daaf4 --- wqflask/utility/hmac.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index 10387bb0..6623f69a 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -10,7 +10,9 @@ def hmac_creation(stringy): """Helper function to create the actual hmac""" secret = app.config['SECRET_HMAC_CODE'] - hmaced = hmac.new(secret, stringy, hashlib.sha1) + hmaced = hmac.new(bytearray(secret, "utf-8"), + bytearray(stringy, "utf-8"), + 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." -- cgit v1.2.3 From 75fe1adb2cfaf542bd22f33e8985938ca988661d Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Fri, 18 Sep 2020 02:45:26 +0300 Subject: Apply pep8 formatting --- wqflask/utility/redis_tools.py | 120 ++++++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 36 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 81ba04ea..ef02268e 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -4,23 +4,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() @@ -28,6 +26,7 @@ def is_redis_available(): return False return True + def get_user_id(column_name, column_value): user_list = Redis.hgetall("users") key_list = [] @@ -38,6 +37,7 @@ def get_user_id(column_name, column_value): return None + def get_user_by_unique_column(column_name, column_value): item_details = None @@ -52,9 +52,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 = [] @@ -74,7 +76,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)) @@ -82,6 +83,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) @@ -91,22 +93,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: @@ -114,10 +121,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: @@ -142,6 +151,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 @@ -150,6 +160,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 """ @@ -158,7 +169,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: @@ -167,9 +179,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 = [] @@ -178,7 +192,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: @@ -190,13 +205,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') } @@ -205,8 +222,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) @@ -214,9 +232,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: @@ -231,25 +255,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"]: @@ -259,22 +294,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: @@ -282,17 +323,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 @@ -301,9 +348,10 @@ 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") - Redis.hset("resources", resource_id, json.dumps(the_resource)) \ No newline at end of file + Redis.hset("resources", resource_id, json.dumps(the_resource)) -- cgit v1.2.3 From ca22bbfdd36351e2b7d8f346b5a3ab81c94f7203 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 28 Oct 2020 23:14:35 +0300 Subject: Use latin-1 encoding when converting hmac secret to bytes * wqflask/utility/hmac.py (hmac_creation): Use latin-1 when serializing the hmac secret. This ensures that the behaviour of *verify_cookie* remains the same as in the python2 tip. --- wqflask/utility/hmac.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py index 6623f69a..29891677 100644 --- a/wqflask/utility/hmac.py +++ b/wqflask/utility/hmac.py @@ -10,7 +10,7 @@ def hmac_creation(stringy): """Helper function to create the actual hmac""" secret = app.config['SECRET_HMAC_CODE'] - hmaced = hmac.new(bytearray(secret, "utf-8"), + hmaced = hmac.new(bytearray(secret, "latin-1"), bytearray(stringy, "utf-8"), hashlib.sha1) hm = hmaced.hexdigest() -- cgit v1.2.3 From 04e981ba202a6bd9d969c05855a33040928d15d0 Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 2 Nov 2020 13:21:40 -0600 Subject: Created function for encoding the column value as bytes when fetching from the JSON-formatted string pulled from Redis (since this was needed after the Python 3 switchover) * wqflask/utility/redis_tools.py - Created function load_json_from_redis that encodes the key (column_value) when fetching a value from the JSON pulled from Redis --- wqflask/utility/redis_tools.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index d855a7fa..236cc755 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -25,6 +25,10 @@ def is_redis_available(): return True +def load_json_from_redis(item_list, column_value): + return json.loads(item_list[str.encode(column_value)]) + + def get_user_id(column_name, column_value): user_list = Redis.hgetall("users") key_list = [] @@ -46,7 +50,7 @@ def get_user_by_unique_column(column_name, column_value): 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]) + item_details = load_json_from_redis(user_list, column_value) return item_details @@ -70,7 +74,7 @@ def get_users_like_unique_column(column_name, column_value): if column_value in user_ob[column_name]: matched_users.append(user_ob) else: - matched_users.append(json.loads(user_list[column_value])) + matched_users.append(load_json_from_redis(user_list, column_value)) return matched_users @@ -199,7 +203,7 @@ def get_groups_like_unique_column(column_name, column_value): if column_value in group_info[column_name]: matched_groups.append(group_info) else: - matched_groups.append(json.loads(group_list[column_value])) + matched_groups.append(load_json_from_redis(group_list, column_value)) return matched_groups -- cgit v1.2.3 From fc717c36d334f364bbae8c98f31ddf78e18d64e3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Fri, 18 Dec 2020 17:34:47 -0600 Subject: Added redirect_uri to the ORCID_AUTH_URL since it wasn't working due to missing this parameter --- wqflask/utility/tools.py | 2 +- wqflask/wqflask/user_login.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 68ef0f04..65df59c3 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -267,7 +267,7 @@ 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://orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \ - ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + "&redirect_uri=" + GN2_BRANCH_URL + "n/login/orcid_oauth2" ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index b6266b2a..bc608e84 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -25,7 +25,7 @@ from utility.logger import getLogger logger = getLogger(__name__) from smtplib import SMTP -from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD, LOG_SQL_ALCHEMY +from utility.tools import SMTP_CONNECT, SMTP_USERNAME, SMTP_PASSWORD, LOG_SQL_ALCHEMY, GN2_BRANCH_URL THREE_DAYS = 60 * 60 * 24 * 3 @@ -277,9 +277,11 @@ def orcid_oauth2(): data = { "client_id": ORCID_CLIENT_ID, "client_secret": ORCID_CLIENT_SECRET, - "grant_type": "authorization_code", + "grant_type": "authorization_code", + "redirect_uri": GN2_BRANCH_URL + "n/login/orcid_oauth2", "code": code } + result = requests.post(ORCID_TOKEN_URL, data=data) result_dict = json.loads(result.text.encode("utf-8")) -- cgit v1.2.3 From 2030cc56db878b05e5507c7c3d5ddef39ff223cb Mon Sep 17 00:00:00 2001 From: Alexanderkabui Date: Mon, 14 Dec 2020 16:15:01 +0300 Subject: replace vars with vars_obj which is a function name in python --- wqflask/utility/type_checking.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/type_checking.py b/wqflask/utility/type_checking.py index f15b17e2..6b029317 100644 --- a/wqflask/utility/type_checking.py +++ b/wqflask/utility/type_checking.py @@ -23,20 +23,20 @@ def is_str(value): except: return False -def get_float(vars,name,default=None): - if name in vars: - if is_float(vars[name]): - return float(vars[name]) +def get_float(vars_obj,name,default=None): + if name in vars_obj: + if is_float(vars_obj[name]): + return float(vars_obj[name]) return default -def get_int(vars,name,default=None): - if name in vars: - if is_int(vars[name]): - return float(vars[name]) +def get_int(vars_obj,name,default=None): + if name in vars_obj: + if is_int(vars_obj[name]): + return float(vars_obj[name]) return default -def get_string(vars,name,default=None): - if name in vars: - if not vars[name] is None: - return str(vars[name]) +def get_string(vars_obj,name,default=None): + if name in vars_obj: + if not vars_obj[name] is None: + return str(vars_obj[name]) return default -- cgit v1.2.3 From 935d618da8986ad85292836f0762e435deb37108 Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 17 Feb 2021 19:24:57 +0000 Subject: Fixed error caused by user IDs being encoded as bytes --- wqflask/utility/redis_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 236cc755..f72d9110 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -26,7 +26,7 @@ def is_redis_available(): def load_json_from_redis(item_list, column_value): - return json.loads(item_list[str.encode(column_value)]) + return json.loads(item_list[str.encode(column_value.decode("utf-8"))]) def get_user_id(column_name, column_value): -- cgit v1.2.3 From f1f80b480ea0f71b7ea34f0b23ad136a56e1bc21 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 18 Feb 2021 18:21:23 +0000 Subject: Changed authentication_tools.py to account for encoding str as bytes and dealing with the permissions response either being a list or not a list (this should be temporary until I figure out what is going on here) --- wqflask/utility/authentication_tools.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index ce0c0749..786475a8 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -11,7 +11,6 @@ from utility.redis_tools import (get_redis_conn, add_resource) Redis = get_redis_conn() - def check_resource_availability(dataset, trait_id=None): # At least for now assume temporary entered traits are accessible if type(dataset) == str or dataset.type == "Temp": @@ -32,13 +31,14 @@ def check_resource_availability(dataset, trait_id=None): # ZS: Check if super-user - we should probably come up with some # way to integrate this into the proxy - if g.user_session.user_id in Redis.smembers("super_users"): + if str.encode(g.user_session.user_id) in Redis.smembers("super_users"): return webqtlConfig.SUPER_PRIVILEGES response = None the_url = "http://localhost:8080/available?resource={}&user={}".format( resource_id, g.user_session.user_id) + try: response = json.loads(requests.get(the_url).content) except: @@ -101,12 +101,13 @@ def check_admin(resource_id=None): resource_info = get_resource_info(resource_id) response = resource_info['default_mask']['admin'] - if 'edit-admins' in response: - return "edit-admins" - elif 'edit-access' in response: - return "edit-access" - else: - return "not-admin" + if type(response) is list: + if 'edit-admins' in response: + return 'edit_admins' + elif 'edit-access' in response: + return 'edit-access' + + return response def check_owner(dataset=None, trait_id=None, resource_id=None): @@ -131,7 +132,7 @@ def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): else: resource_id = get_resource_id(dataset, trait_id) - if g.user_session.user_id in Redis.smembers("super_users"): + if str.encode(g.user_session.user_id) in Redis.smembers("super_users"): return "owner" resource_info = get_resource_info(resource_id) -- cgit v1.2.3 From cafdd7284f3c2f87e1dbb288e181f1e5aeeccc06 Mon Sep 17 00:00:00 2001 From: zsloan Date: Thu, 18 Feb 2021 18:37:16 +0000 Subject: Remove the deocde since it was throwing an error --- wqflask/utility/redis_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index f72d9110..236cc755 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -26,7 +26,7 @@ def is_redis_available(): def load_json_from_redis(item_list, column_value): - return json.loads(item_list[str.encode(column_value.decode("utf-8"))]) + return json.loads(item_list[str.encode(column_value)]) def get_user_id(column_name, column_value): -- cgit v1.2.3 From 7004219e51a6053a03ec4a997d759c52ed36bdfe Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 16 Mar 2021 17:10:50 +0000 Subject: Removed unnecessary encoding of user_id from authentication_tools.py --- wqflask/utility/authentication_tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 786475a8..672b36d5 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -31,7 +31,7 @@ def check_resource_availability(dataset, trait_id=None): # ZS: Check if super-user - we should probably come up with some # way to integrate this into the proxy - if str.encode(g.user_session.user_id) in Redis.smembers("super_users"): + if g.user_session.user_id in Redis.smembers("super_users"): return webqtlConfig.SUPER_PRIVILEGES response = None @@ -132,7 +132,7 @@ def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None): else: resource_id = get_resource_id(dataset, trait_id) - if str.encode(g.user_session.user_id) in Redis.smembers("super_users"): + if g.user_session.user_id in Redis.smembers("super_users"): return "owner" resource_info = get_resource_info(resource_id) -- cgit v1.2.3 From 02b14ccc55978742cd115f3c80bf8ef41ac77ae7 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 16 Mar 2021 17:23:45 +0000 Subject: Fixed encoding to make get_user_groups work properly, since the user IDs for groups in Redis are stored as strings --- wqflask/utility/redis_tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index 236cc755..d05de923 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -133,8 +133,8 @@ def get_user_groups(user_id): for key in groups_list: try: group_ob = json.loads(groups_list[key]) - group_admins = set(group_ob['admins']) - group_members = set(group_ob['members']) + group_admins = set([this_admin.encode('utf-8') if this_admin else None for this_admin in group_ob['admins']]) + group_members = set([this_member.encode('utf-8') if this_member else None for this_member in group_ob['members']]) if user_id in group_admins: admin_group_ids.append(group_ob['id']) elif user_id in group_members: -- cgit v1.2.3 From 696585dda43ec238940b2e1cc239028e31684dc3 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 16 Mar 2021 17:25:14 +0000 Subject: Fixed encoding in load_json_from_redis to account for the first that column values are sometimes stored as bytes and sometimes as strings --- wqflask/utility/redis_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py index d05de923..8052035f 100644 --- a/wqflask/utility/redis_tools.py +++ b/wqflask/utility/redis_tools.py @@ -26,7 +26,7 @@ def is_redis_available(): def load_json_from_redis(item_list, column_value): - return json.loads(item_list[str.encode(column_value)]) + return json.loads(item_list[column_value]) def get_user_id(column_name, column_value): -- cgit v1.2.3