aboutsummaryrefslogtreecommitdiff
path: root/wqflask/utility
diff options
context:
space:
mode:
authorArthur Centeno2021-04-09 20:38:21 +0000
committerArthur Centeno2021-04-09 20:38:21 +0000
commite2b04a322f26670782fe7f7c39bcebc508fdabdd (patch)
treea51c32bae4d544cc0beea19f455ccc52f0544a4c /wqflask/utility
parent187cd40bd3273b50d2813bfccf98bfadbb8c14ff (diff)
parentef51e08753defdfc7f3e67f8788cd1362d2cf631 (diff)
downloadgenenetwork2-e2b04a322f26670782fe7f7c39bcebc508fdabdd.tar.gz
Merge branch 'testing' of github.com:genenetwork/genenetwork2 into acenteno
Diffstat (limited to 'wqflask/utility')
-rw-r--r--wqflask/utility/Plot.py127
-rw-r--r--wqflask/utility/__init__.py4
-rw-r--r--wqflask/utility/after.py4
-rw-r--r--wqflask/utility/authentication_tools.py145
-rw-r--r--wqflask/utility/benchmark.py6
-rw-r--r--wqflask/utility/chunks.py65
-rw-r--r--wqflask/utility/corr_result_helpers.py26
-rw-r--r--wqflask/utility/db_tools.py12
-rw-r--r--wqflask/utility/elasticsearch_tools.py2
-rw-r--r--wqflask/utility/formatting.py29
-rw-r--r--wqflask/utility/gen_geno_ob.py6
-rw-r--r--wqflask/utility/genofile_parser.py1
-rw-r--r--wqflask/utility/helper_functions.py17
-rw-r--r--wqflask/utility/hmac.py17
-rw-r--r--wqflask/utility/logger.py26
-rw-r--r--wqflask/utility/pillow_utils.py27
-rw-r--r--wqflask/utility/redis_tools.py271
-rw-r--r--wqflask/utility/startup_config.py4
-rw-r--r--wqflask/utility/svg.py692
-rw-r--r--wqflask/utility/temp_data.py3
-rw-r--r--wqflask/utility/tools.py44
-rw-r--r--wqflask/utility/type_checking.py24
-rw-r--r--wqflask/utility/webqtlUtil.py24
23 files changed, 960 insertions, 616 deletions
diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py
index cce8435d..61f408d2 100644
--- a/wqflask/utility/Plot.py
+++ b/wqflask/utility/Plot.py
@@ -24,32 +24,35 @@
#
# Last updated by GeneNetwork Core Team 2010/10/20
-from __future__ import print_function
-
-import piddle as pid
-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 reaper
-import webqtlUtil
-import corestats
+import utility.corestats as corestats
from base import webqtlConfig
-
+from utility.pillow_utils import draw_rotated_text
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 = "./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):
'custom string format'
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] == '.':
@@ -77,7 +80,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
@@ -88,7 +91,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,
@@ -116,7 +119,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
@@ -152,7 +156,7 @@ def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid
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)
@@ -163,67 +167,91 @@ 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)
+ 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:
- 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):
+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:
@@ -235,7 +263,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)
@@ -253,7 +281,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)))
@@ -262,21 +290,26 @@ 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
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
@@ -292,4 +325,4 @@ def _test():
if __name__=="__main__":
- _test() \ No newline at end of file
+ _test()
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/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
new file mode 100644
index 00000000..672b36d5
--- /dev/null
+++ b/wqflask/utility/authentication_tools.py
@@ -0,0 +1,145 @@
+import json
+import requests
+
+from flask import g
+from base import webqtlConfig
+
+
+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)
+
+ # 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)
+
+ # 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
+ 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:
+ response = json.loads(requests.get(the_url).content)
+ except:
+ response = resource_info['default_mask']
+
+ return response
+
+
+def add_new_resource(dataset, trait_id=None):
+ resource_ob = {
+ 'owner_id': "none", # webqtlConfig.DEFAULT_OWNER_ID,
+ 'default_mask': webqtlConfig.DEFAULT_PRIVILEGES,
+ 'group_masks': {}
+ }
+
+ if dataset.type == "Publish":
+ 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
+ }
+ 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()
+ 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)
+ try:
+ response = json.loads(requests.get(the_url).content)['admin']
+ except:
+ resource_info = get_resource_info(resource_id)
+ response = resource_info['default_mask']['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):
+ 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 not resource_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 "owner"
+
+ resource_info = get_resource_info(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"
diff --git a/wqflask/utility/benchmark.py b/wqflask/utility/benchmark.py
index 8f1c916b..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
@@ -38,9 +36,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/chunks.py b/wqflask/utility/chunks.py
index b0e33c08..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
@@ -31,66 +29,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()
diff --git a/wqflask/utility/corr_result_helpers.py b/wqflask/utility/corr_result_helpers.py
index b543c589..ea3ababf 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):
@@ -37,20 +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
-
-
-
-if __name__ == '__main__':
- import doctest
- doctest.testmod() \ No newline at end of file
+ return a_new, b_new, len(a_new)
diff --git a/wqflask/utility/db_tools.py b/wqflask/utility/db_tools.py
index 4034f39c..6e19778f 100644
--- a/wqflask/utility/db_tools.py
+++ b/wqflask/utility/db_tools.py
@@ -1,6 +1,5 @@
-from __future__ import absolute_import, print_function, division
+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"""
@@ -8,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')
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/formatting.py b/wqflask/utility/formatting.py
index e53dda22..1da3e9b7 100644
--- a/wqflask/utility/formatting.py
+++ b/wqflask/utility/formatting.py
@@ -28,21 +28,20 @@ def numify(number, singular=None, plural=None):
'12,334 hippopotami'
"""
- num_repr = {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:
diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py
index 23b0b650..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__ )
@@ -175,7 +173,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
+ 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 <Danny.Arends@gmail.com>
-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 e7c04fef..7eb7f013 100644
--- a/wqflask/utility/helper_functions.py
+++ b/wqflask/utility/helper_functions.py
@@ -1,7 +1,5 @@
-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,10 +9,9 @@ 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():
+ 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:
@@ -24,7 +21,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,9 +31,8 @@ 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):
+ if isinstance(trait_db_list, str):
trait_db_list = trait_db_list.split(",")
self.trait_list = []
@@ -49,10 +45,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/hmac.py b/wqflask/utility/hmac.py
index d8a0eace..29891677 100644
--- a/wqflask/utility/hmac.py
+++ b/wqflask/utility/hmac.py
@@ -1,16 +1,18 @@
-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):
"""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, "latin-1"),
+ 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."
@@ -18,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"""
@@ -34,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)
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
new file mode 100644
index 00000000..c486abba
--- /dev/null
+++ b/wqflask/utility/pillow_utils.py
@@ -0,0 +1,27 @@
+from PIL import Image, ImageColor, ImageDraw, ImageFont
+
+from utility.tools import TEMPDIR
+
+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)
+ """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("/{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):
+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)
diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py
index ca42f7b7..8052035f 100644
--- a/wqflask/utility/redis_tools.py
+++ b/wqflask/utility/redis_tools.py
@@ -1,17 +1,22 @@
-from __future__ import print_function, division, absolute_import
-
+import uuid
import simplejson as json
+import datetime
-import redis # used for collections
-Redis = redis.StrictRedis()
-
-import logging
-
-from flask import (render_template, flash)
+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()
@@ -19,8 +24,14 @@ def is_redis_available():
return False
return True
+
+def load_json_from_redis(item_list, column_value):
+ return json.loads(item_list[column_value])
+
+
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:
@@ -28,6 +39,7 @@ def get_user_id(column_name, column_value):
return None
+
def get_user_by_unique_column(column_name, column_value):
item_details = None
@@ -38,16 +50,42 @@ 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
+
+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 "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)
+ else:
+ matched_users.append(load_json_from_redis(user_list, column_value))
+
+ return matched_users
+
+
def set_user_attribute(user_id, column_name, column_value):
user_info = json.loads(Redis.hget("users", user_id))
user_info[column_name] = column_value
Redis.hset("users", user_id, json.dumps(user_info))
+
def get_user_collections(user_id):
collections = None
collections = Redis.hget("collections", user_id)
@@ -57,45 +95,64 @@ 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)
- return email_address
if email_address:
- user_details = get_user_by_unique_column('email_address', email_address)
- return user_details
+ user_details = get_user_by_unique_column(
+ 'email_address', email_address)
+ 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
- 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:
- group_ob = json.loads(groups_list[key])
- group_admins = set(group_ob['admins'])
- group_users = set(group_ob['users'])
- if user_id in group_admins:
- admin_group_ids.append(group_ob['id'])
- elif user_id in group_users:
- user_group_ids.append(group_ob['id'])
- else:
+ try:
+ group_ob = json.loads(groups_list[key])
+ 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:
+ user_group_ids.append(group_ob['id'])
+ else:
+ continue
+ except:
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)
@@ -105,23 +162,71 @@ def get_group_info(group_id):
return group_info
-def create_group(admin_member_ids, user_member_ids = [], group_name = ""):
+
+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])
+ # 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:
+ if group_info[column_name] == column_value:
+ matched_groups.append(group_info)
+
+ 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])
+ # 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:
+ if column_name in group_info:
+ if column_value in group_info[column_name]:
+ matched_groups.append(group_info)
+ else:
+ matched_groups.append(load_json_from_redis(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())
new_group = {
- "id" : group_id,
- "admins": admin_member_ids,
- "users" : user_member_ids,
- "name" : group_name,
+ "id": group_id,
+ "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
+
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)
@@ -129,13 +234,19 @@ 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:
- 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)
@@ -144,27 +255,105 @@ 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')
+ 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 = "users"): #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)
+ # 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 -= 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')
+ 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"]:
group_info["name"] = new_name
+ Redis.hset("groups", group_id, json.dumps(group_info))
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, trait_id=None):
+ resource_id = False
+ if dataset.type == "Publish":
+ if trait_id:
+ resource_id = hmac_creation("{}:{}:{}".format(
+ 'dataset-publish', dataset.id, trait_id))
+ elif dataset.type == "ProbeSet":
+ resource_id = hmac_creation(
+ "{}:{}".format('dataset-probeset', dataset.id))
+ elif dataset.type == "Geno":
+ 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:
+ return json.loads(resource_info)
+ else:
+ return None
+
+
+def add_resource(resource_info, update=True):
+ if 'trait' in resource_info['data']:
+ resource_id = hmac_creation('{}:{}:{}'.format(
+ str(resource_info['type']), str(
+ resource_info['data']['dataset']),
+ str(resource_info['data']['trait'])))
+ else:
+ 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
+
+ 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))
diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py
index 817284dd..f1aaebb6 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..b92cc2d1 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 <element>text</element> 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 <rubbish> 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 <rubbish> 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("&", "&amp;")
+ # data = data.replace("&", "&amp;")
data = data.replace("<", "&lt;")
data = data.replace(">", "&gt;")
- for chars, entity in entities.items():
+ for chars, entity in list(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
- for arg in args.keys():
+ self.elements = elements
+ self.text = text
+ self.namespace = namespace
+ self.cdata = cdata
+ for arg in list(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])))
+ for attkey in list(self.attributes.keys()):
+ 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)+'<![CDATA[')
for line in self.cdata.splitlines():
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
+ else: # If the text is a spannedtext class
f.write(str(self.text))
if self.elements:
f.write('\t'*level+'</'+self.type+'>\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="<tspan"
- for key,value in self.attributes.items():
- s+= ' %s="%s"' % (key,value)
- s+='>'
- s+=self.text
- s+='</tspan>'
+ s = "<tspan"
+ for key, value in list(self.attributes.items()):
+ s += ' %s="%s"' % (key, value)
+ s += '>'
+ s += self.text
+ s += '</tspan>'
return s
+
class tref(SVGelement):
"""tr=tref(link='',**args)
@@ -346,16 +383,19 @@ class tref(SVGelement):
st.addtref(tr)
t=text(3,5,st)
"""
- def __init__(self,link,**args):
- SVGelement.__init__(self,'tref',{'xlink:href':link},**args)
+
+ def __init__(self, link, **args):
+ SVGelement.__init__(self, 'tref', {'xlink:href': link}, **args)
+
def __repr__(self):
- s="<tref"
+ s = "<tref"
- for key,value in self.attributes.items():
- s+= ' %s="%s"' % (key,value)
- s+='/>'
+ for key, value in list(self.attributes.items()):
+ s += ' %s="%s"' % (key, value)
+ s += '/>'
return s
+
class spannedtext:
"""st=spannedtext(textlist=[])
@@ -374,46 +414,49 @@ class spannedtext:
st.addtext('This text is not bold')
t=text(3,5,st)
"""
- def __init__(self,textlist=None):
- if textlist==None:
- self.textlist=[]
+
+ def __init__(self, textlist=None):
+ if textlist == None:
+ self.textlist = []
else:
- self.textlist=textlist
- def addtext(self,text=''):
+ self.textlist = textlist
+
+ def addtext(self, text=''):
self.textlist.append(text)
- def addtspan(self,tspan):
+
+ def addtspan(self, tspan):
self.textlist.append(tspan)
- def addtref(self,tref):
+
+ def addtref(self, tref):
self.textlist.append(tref)
+
def __repr__(self):
- s=""
+ s = ""
for element in self.textlist:
- s+=str(element)
+ s += str(element)
return s
+
class rect(SVGelement):
"""r=rect(width,height,x,y,fill,stroke,stroke_width,**args)
a rectangle is defined by a width and height and a xy pair
"""
- 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'
- else:
- raise ValueError, 'both height and width are required'
- SVGelement.__init__(self,'rect',{'width':width,'height':height},**args)
- if x<>None:
+
+ 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')
+
+ SVGelement.__init__(self, 'rect', {'width':width,'height':height}, **args)
+ 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 +466,18 @@ 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'
- else:
- raise ValueError, 'both rx and ry are required'
- SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args)
- if cx<>None:
+ raise ValueError('both rx and ry are required')
+
+ SVGelement.__init__(self, 'ellipse', {'rx':rx,'ry':ry}, **args)
+ 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
@@ -449,17 +488,17 @@ 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)
- if cx<>None:
+ raise ValueError('r is required')
+ SVGelement.__init__(self, 'circle', {'r':r}, **args)
+ 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):
@@ -469,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)
@@ -477,18 +516,18 @@ 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)
- if x1<>None:
+ SVGelement.__init__(self, 'line', **args)
+ 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):
@@ -497,12 +536,12 @@ 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)
- if fill<>None:
+ SVGelement.__init__(self, 'polyline', {'points':_xypointlist(points)}, **args)
+ 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):
@@ -511,12 +550,12 @@ 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)
- if fill<>None:
+ SVGelement.__init__(self, 'polygon', {'points':_xypointlist(points)}, **args)
+ 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):
@@ -525,14 +564,14 @@ 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)
- if stroke<>None:
+ SVGelement.__init__(self, 'path', {'d':str(pathdata)}, **args)
+ 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
@@ -542,18 +581,18 @@ 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)
- if x<>None:
+ SVGelement.__init__(self, 'text', **args)
+ 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
@@ -563,8 +602,8 @@ 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)
- if text<>None:
+ SVGelement.__init__(self, 'textPath', {'xlink:href':link}, **args)
+ if text!=None:
self.text=text
class pattern(SVGelement):
@@ -575,16 +614,16 @@ 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)
- if x<>None:
+ SVGelement.__init__(self, 'pattern', **args)
+ 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):
@@ -594,8 +633,8 @@ class title(SVGelement):
add at least one to the root svg element
"""
def __init__(self,text=None,**args):
- SVGelement.__init__(self,'title',**args)
- if text<>None:
+ SVGelement.__init__(self, 'title', **args)
+ if text!=None:
self.text=text
class description(SVGelement):
@@ -605,8 +644,8 @@ class description(SVGelement):
Add this element before adding other elements.
"""
def __init__(self,text=None,**args):
- SVGelement.__init__(self,'desc',**args)
- if text<>None:
+ SVGelement.__init__(self, 'desc', **args)
+ if text!=None:
self.text=text
class lineargradient(SVGelement):
@@ -616,16 +655,16 @@ 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)
- if x1<>None:
+ SVGelement.__init__(self, 'linearGradient', **args)
+ 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):
@@ -635,18 +674,18 @@ 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)
- if cx<>None:
+ SVGelement.__init__(self, 'radialGradient', **args)
+ 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):
@@ -655,8 +694,8 @@ 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)
- if stop_color<>None:
+ SVGelement.__init__(self, 'stop', {'offset':offset}, **args)
+ if stop_color!=None:
self.attributes['stop-color']=stop_color
class style(SVGelement):
@@ -665,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):
@@ -675,16 +714,11 @@ 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'
- else:
- raise ValueError, 'both height and width are required'
- SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args)
- if x<>None:
+ 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
- if y<>None:
+ if y!=None:
self.attributes['y']=y
class cursor(SVGelement):
@@ -693,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):
@@ -703,18 +737,18 @@ 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)
- if id<>None:
+ SVGelement.__init__(self, 'marker', **args)
+ 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):
@@ -724,8 +758,8 @@ class group(SVGelement):
g.addElement(SVGelement)
"""
def __init__(self,id=None,**args):
- SVGelement.__init__(self,'g',**args)
- if id<>None:
+ SVGelement.__init__(self, 'g', **args)
+ if id!=None:
self.attributes['id']=id
class symbol(SVGelement):
@@ -738,10 +772,10 @@ class symbol(SVGelement):
"""
def __init__(self,id=None,viewBox=None,**args):
- SVGelement.__init__(self,'symbol',**args)
- if id<>None:
+ SVGelement.__init__(self, 'symbol', **args)
+ if id!=None:
self.attributes['id']=id
- if viewBox<>None:
+ if viewBox!=None:
self.attributes['viewBox']=_viewboxlist(viewBox)
class defs(SVGelement):
@@ -750,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)
@@ -760,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):
@@ -769,15 +803,15 @@ 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)
- if x<>None:
+ SVGelement.__init__(self, 'use', {'xlink:href':link}, **args)
+ 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
@@ -788,15 +822,15 @@ 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)
- if id<>None:
+ SVGelement.__init__(self, 'view', **args)
+ if id!=None:
self.attributes['id']=id
class script(SVGelement):
@@ -806,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)
@@ -814,12 +848,12 @@ class animate(SVGelement):
animates an attribute.
"""
def __init__(self,attribute,fr=None,to=None,dur=None,**args):
- SVGelement.__init__(self,'animate',{'attributeName':attribute},**args)
- if fr<>None:
+ SVGelement.__init__(self, 'animate', {'attributeName':attribute}, **args)
+ 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):
@@ -828,10 +862,10 @@ class animateMotion(SVGelement):
animates a SVGelement over the given path in dur seconds
"""
def __init__(self,pathdata,dur,**args):
- SVGelement.__init__(self,'animateMotion',**args)
- if pathdata<>None:
+ SVGelement.__init__(self, 'animateMotion', **args)
+ if pathdata!=None:
self.attributes['path']=str(pathdata)
- if dur<>None:
+ if dur!=None:
self.attributes['dur']=dur
class animateTransform(SVGelement):
@@ -840,15 +874,15 @@ 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)
- #As far as I know the attributeName is always transform
- if type<>None:
+ SVGelement.__init__(self, 'animateTransform', {'attributeName':'transform'}, **args)
+ # As far as I know the attributeName is always transform
+ 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)
@@ -856,14 +890,14 @@ 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)
- if type<>None:
+ SVGelement.__init__(self, 'animateColor', {'attributeName':attribute}, **args)
+ 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)
@@ -871,10 +905,10 @@ 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)
- if to<>None:
+ SVGelement.__init__(self, 'set', {'attributeName':attribute}, **args)
+ if to!=None:
self.attributes['to']=to
- if dur<>None:
+ if dur!=None:
self.attributes['dur']=dur
@@ -895,12 +929,12 @@ class svg(SVGelement):
d.toXml()
"""
def __init__(self,viewBox=None, width=None, height=None,**args):
- SVGelement.__init__(self,'svg',**args)
- if viewBox<>None:
+ SVGelement.__init__(self, 'svg', **args)
+ 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"
@@ -918,27 +952,27 @@ 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.
+ # 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("<?xml version='1.0' encoding='UTF-8'?>\n")
xml.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"")
if self.entity:
xml.write(" [\n")
- for item in self.entity.keys():
+ for item in list(self.entity.keys()):
xml.write("<!ENTITY %s \"%s\">\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')
+ f=io.StringIO()
+ zf=gzip.GzipFile(fileobj=f, mode='wb')
zf.write(xml.getvalue())
zf.close()
f.seek(0)
@@ -948,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()
@@ -963,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)
- #Create the xml document.
+ # 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)
+ # 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 element.attributes.keys(): #in element.attributes is supported from python 2.2
- e.setAttribute(attribute,str(element.attributes[attribute]))
+ 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:
- 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)
+ import io
+ xml=io.StringIO()
+ PrettyPrint(root, xml)
if compress:
import gzip
- f=cStringIO.StringIO()
- zf=gzip.GzipFile(fileobj=f,mode='wb')
+ f=io.StringIO()
+ zf=gzip.GzipFile(fileobj=f, mode='wb')
zf.write(xml.getvalue())
zf.close()
f.seek(0)
@@ -1007,23 +1041,23 @@ class drawing:
try:
if filename[-4:]=='svgz':
import gzip
- import cStringIO
- xml=cStringIO.StringIO()
- PrettyPrint(root,xml)
- f=gzip.GzipFile(filename=filename,mode='wb',compresslevel=9)
+ import io
+ xml=io.StringIO()
+ 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
+ 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,38 +1065,38 @@ 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__':
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)
- print d.toXml()
+ print((d.toXml()))
diff --git a/wqflask/utility/temp_data.py b/wqflask/utility/temp_data.py
index 5bf700c9..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
@@ -20,6 +19,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 89d88516..65df59c3 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'
@@ -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()
+ keylist = list(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
@@ -267,11 +267,11 @@ 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')
-# 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()
@@ -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/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
diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py
index 53661ae4..5681fadf 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']
}
@@ -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):
@@ -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
@@ -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, ','))
- 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 \ No newline at end of file
+ return access_to_confidential_phenotype_trait