aboutsummaryrefslogtreecommitdiff
path: root/wqflask
diff options
context:
space:
mode:
authorArthur Centeno2021-10-29 17:39:27 +0000
committerArthur Centeno2021-10-29 17:39:27 +0000
commit2b0c5c94d344b839ef1d6899b5bb239f14942610 (patch)
treee08ac49c5e1190fa2be28c1238a552646c3fde13 /wqflask
parent24480fad2d67a6e35b03997e23c6d849a60623a0 (diff)
parent44bf8ee8463fe7182282ec10e259d4c9eb7526b8 (diff)
downloadgenenetwork2-2b0c5c94d344b839ef1d6899b5bb239f14942610.tar.gz
Merge github.com:genenetwork/genenetwork2 into acenteno
Diffstat (limited to 'wqflask')
-rw-r--r--wqflask/maintenance/quantile_normalize.py18
-rw-r--r--wqflask/utility/authentication_tools.py2
-rw-r--r--wqflask/utility/elasticsearch_tools.py121
-rw-r--r--wqflask/utility/hmac.py3
-rw-r--r--wqflask/utility/redis_tools.py2
-rw-r--r--wqflask/utility/tools.py5
-rw-r--r--wqflask/wqflask/__init__.py14
-rw-r--r--wqflask/wqflask/decorators.py49
-rw-r--r--wqflask/wqflask/metadata_edits.py340
-rw-r--r--wqflask/wqflask/resource_manager.py3
-rw-r--r--wqflask/wqflask/show_trait/show_trait.py30
-rw-r--r--wqflask/wqflask/templates/admin/manage_resource.html78
-rw-r--r--wqflask/wqflask/templates/edit_phenotype.html4
-rw-r--r--wqflask/wqflask/templates/edit_probeset.html70
-rw-r--r--wqflask/wqflask/templates/show_trait_details.html10
-rw-r--r--wqflask/wqflask/user_session.py1
-rw-r--r--wqflask/wqflask/views.py305
17 files changed, 473 insertions, 582 deletions
diff --git a/wqflask/maintenance/quantile_normalize.py b/wqflask/maintenance/quantile_normalize.py
index 0cc963e5..32780ca6 100644
--- a/wqflask/maintenance/quantile_normalize.py
+++ b/wqflask/maintenance/quantile_normalize.py
@@ -5,14 +5,10 @@ import urllib.parse
import numpy as np
import pandas as pd
-from elasticsearch import Elasticsearch, TransportError
-from elasticsearch.helpers import bulk
from flask import Flask, g, request
from wqflask import app
-from utility.elasticsearch_tools import get_elasticsearch_connection
-from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT, SQL_URI
def parse_db_uri():
@@ -106,20 +102,6 @@ if __name__ == '__main__':
Conn = MySQLdb.Connect(**parse_db_uri())
Cursor = Conn.cursor()
- # es = Elasticsearch([{
- # "host": ELASTICSEARCH_HOST, "port": ELASTICSEARCH_PORT
- # }], timeout=60) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None
-
- es = get_elasticsearch_connection(for_user=False)
-
- #input_filename = "/home/zas1024/cfw_data/" + sys.argv[1] + ".txt"
- #input_df = create_dataframe(input_filename)
- #output_df = quantileNormalize(input_df)
-
- #output_df.to_csv('quant_norm.csv', sep='\t')
-
- #out_filename = sys.argv[1][:-4] + '_quantnorm.txt'
-
success, _ = bulk(es, set_data(sys.argv[1]))
response = es.search(
diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py
index c4801c8c..afea69e1 100644
--- a/wqflask/utility/authentication_tools.py
+++ b/wqflask/utility/authentication_tools.py
@@ -1,7 +1,6 @@
import json
import requests
-from deprecated import deprecated
from flask import g
from base import webqtlConfig
@@ -127,7 +126,6 @@ def check_owner(dataset=None, trait_id=None, resource_id=None):
return False
-@deprecated
def check_owner_or_admin(dataset=None, trait_id=None, resource_id=None):
if not resource_id:
if dataset.type == "Temp":
diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py
deleted file mode 100644
index eae3ba03..00000000
--- a/wqflask/utility/elasticsearch_tools.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Elasticsearch support
-#
-# Some helpful commands to view the database:
-#
-# You can test the server being up with
-#
-# curl -H 'Content-Type: application/json' http://localhost:9200
-#
-# List all indices
-#
-# curl -H 'Content-Type: application/json' 'localhost:9200/_cat/indices?v'
-#
-# To see the users index 'table'
-#
-# curl http://localhost:9200/users
-#
-# To list all user ids
-#
-# curl -H 'Content-Type: application/json' http://localhost:9200/users/local/_search?pretty=true -d '
-# {
-# "query" : {
-# "match_all" : {}
-# },
-# "stored_fields": []
-# }'
-#
-# To view a record
-#
-# curl -H 'Content-Type: application/json' http://localhost:9200/users/local/_search?pretty=true -d '
-# {
-# "query" : {
-# "match" : { "email_address": "pjotr2017@thebird.nl"}
-# }
-# }'
-#
-#
-# To delete the users index and data (dangerous!)
-#
-# curl -XDELETE -H 'Content-Type: application/json' 'localhost:9200/users'
-
-
-from elasticsearch import Elasticsearch, TransportError
-import logging
-
-from utility.logger import getLogger
-logger = getLogger(__name__)
-
-from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT
-
-
-def test_elasticsearch_connection():
- es = Elasticsearch(['http://' + ELASTICSEARCH_HOST + \
- ":" + str(ELASTICSEARCH_PORT) + '/'], verify_certs=True)
- if not es.ping():
- logger.warning("Elasticsearch is DOWN")
-
-
-def get_elasticsearch_connection(for_user=True):
- """Return a connection to ES. Returns None on failure"""
- logger.info("get_elasticsearch_connection")
- es = None
- try:
- assert(ELASTICSEARCH_HOST)
- assert(ELASTICSEARCH_PORT)
- logger.info("ES HOST", ELASTICSEARCH_HOST)
-
- es = Elasticsearch([{
- "host": ELASTICSEARCH_HOST, "port": ELASTICSEARCH_PORT
- }], timeout=30, retry_on_timeout=True) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None
-
- if for_user:
- setup_users_index(es)
-
- es_logger = logging.getLogger("elasticsearch")
- es_logger.setLevel(logging.INFO)
- es_logger.addHandler(logging.NullHandler())
- except Exception as e:
- logger.error("Failed to get elasticsearch connection", e)
- es = None
-
- return es
-
-
-def setup_users_index(es_connection):
- if es_connection:
- index_settings = {
- "properties": {
- "email_address": {
- "type": "keyword"}}}
-
- es_connection.indices.create(index='users', ignore=400)
- es_connection.indices.put_mapping(
- body=index_settings, index="users", doc_type="local")
-
-
-def get_user_by_unique_column(es, column_name, column_value, index="users", doc_type="local"):
- return get_item_by_unique_column(es, column_name, column_value, index=index, doc_type=doc_type)
-
-
-def save_user(es, user, user_id):
- es_save_data(es, "users", "local", user, user_id)
-
-
-def get_item_by_unique_column(es, column_name, column_value, index, doc_type):
- item_details = None
- try:
- response = es.search(
- index=index, doc_type=doc_type, body={
- "query": {"match": {column_name: column_value}}
- })
- if len(response["hits"]["hits"]) > 0:
- item_details = response["hits"]["hits"][0]["_source"]
- except TransportError as te:
- pass
- return item_details
-
-
-def es_save_data(es, index, doc_type, data_item, data_id,):
- from time import sleep
- es.create(index, doc_type, body=data_item, id=data_id)
- sleep(1) # Delay 1 second to allow indexing
diff --git a/wqflask/utility/hmac.py b/wqflask/utility/hmac.py
index d6e515ed..29891677 100644
--- a/wqflask/utility/hmac.py
+++ b/wqflask/utility/hmac.py
@@ -1,14 +1,11 @@
import hmac
import hashlib
-from deprecated import deprecated
from flask import url_for
from wqflask import app
-@deprecated("This function leads to circular imports. "
- "If possible use wqflask.decorators.create_hmac instead.")
def hmac_creation(stringy):
"""Helper function to create the actual hmac"""
diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py
index c2a3b057..a6c5875f 100644
--- a/wqflask/utility/redis_tools.py
+++ b/wqflask/utility/redis_tools.py
@@ -4,7 +4,6 @@ import datetime
import redis # used for collections
-from deprecated import deprecated
from utility.hmac import hmac_creation
from utility.logger import getLogger
logger = getLogger(__name__)
@@ -252,7 +251,6 @@ def get_resource_id(dataset, trait_id=None):
return resource_id
-@deprecated
def get_resource_info(resource_id):
resource_info = Redis.hget("resources", resource_id)
if resource_info:
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 0efe8ca9..f28961ec 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -287,6 +287,7 @@ JS_GN_PATH = get_setting('JS_GN_PATH')
GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID')
GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET')
+GITHUB_AUTH_URL = ""
if GITHUB_CLIENT_ID != 'UNKNOWN' and GITHUB_CLIENT_SECRET:
GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id=" + \
GITHUB_CLIENT_ID + "&client_secret=" + GITHUB_CLIENT_SECRET
@@ -301,10 +302,6 @@ if ORCID_CLIENT_ID != 'UNKNOWN' and 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')
-# import utility.elasticsearch_tools as es
-# es.test_elasticsearch_connection()
SMTP_CONNECT = get_setting('SMTP_CONNECT')
SMTP_USERNAME = get_setting('SMTP_USERNAME')
diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py
index 5b2d05d1..169192c7 100644
--- a/wqflask/wqflask/__init__.py
+++ b/wqflask/wqflask/__init__.py
@@ -9,8 +9,11 @@ from typing import Tuple
from urllib.parse import urlparse
from utility import formatting
+from wqflask.access_roles import DataRole, AdminRole
from wqflask.resource_manager import resource_management
+from wqflask.metadata_edits import metadata_edit
+
from wqflask.api.markdown import glossary_blueprint
from wqflask.api.markdown import references_blueprint
from wqflask.api.markdown import links_blueprint
@@ -60,6 +63,7 @@ app.register_blueprint(news_blueprint, url_prefix="/news")
app.register_blueprint(resource_management, url_prefix="/resource-management")
+app.register_blueprint(metadata_edit, url_prefix="/datasets/")
@app.before_request
def before_request():
@@ -67,6 +71,16 @@ def before_request():
g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time)
+@app.context_processor
+def include_admin_role_class():
+ return {'AdminRole': AdminRole}
+
+
+@app.context_processor
+def include_data_role_class():
+ return {'DataRole': DataRole}
+
+
from wqflask.api import router
from wqflask import group_manager
from wqflask import resource_manager
diff --git a/wqflask/wqflask/decorators.py b/wqflask/wqflask/decorators.py
index 843539ee..1ef8c188 100644
--- a/wqflask/wqflask/decorators.py
+++ b/wqflask/wqflask/decorators.py
@@ -1,9 +1,7 @@
"""This module contains gn2 decorators"""
-import hashlib
-import hmac
import redis
-from flask import current_app, g
+from flask import current_app, g, request
from typing import Dict
from urllib.parse import urljoin
from functools import wraps
@@ -14,19 +12,13 @@ import json
import requests
-def create_hmac(data: str, secret: str) -> str:
- return hmac.new(bytearray(secret, "latin-1"),
- bytearray(data, "utf-8"),
- hashlib.sha1).hexdigest()[:20]
-
-
def login_required(f):
"""Use this for endpoints where login is required"""
@wraps(f)
def wrap(*args, **kwargs):
- user_id = (g.user_session.record.get(b"user_id",
- b"").decode("utf-8") or
- g.user_session.record.get("user_id", ""))
+ user_id = ((g.user_session.record.get(b"user_id") or
+ b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
redis_conn = redis.from_url(current_app.config["REDIS_URL"],
decode_responses=True)
if not redis_conn.hget("users", user_id):
@@ -36,32 +28,25 @@ def login_required(f):
def edit_access_required(f):
- """Use this for endpoints where people with admin or edit privileges are required"""
+ """Use this for endpoints where people with admin or edit privileges
+are required"""
@wraps(f)
def wrap(*args, **kwargs):
resource_id: str = ""
- if kwargs.get("inbredset_id"): # data type: dataset-publish
- resource_id = create_hmac(
- data=("dataset-publish:"
- f"{kwargs.get('inbredset_id')}:"
- f"{kwargs.get('name')}"),
- secret=current_app.config.get("SECRET_HMAC_CODE"))
- if kwargs.get("dataset_name"): # data type: dataset-probe
- resource_id = create_hmac(
- data=("dataset-probeset:"
- f"{kwargs.get('dataset_name')}"),
- secret=current_app.config.get("SECRET_HMAC_CODE"))
- if kwargs.get("resource_id"): # The resource_id is already provided
+ if request.args.get("resource-id"):
+ resource_id = request.args.get("resource-id")
+ elif kwargs.get("resource_id"):
resource_id = kwargs.get("resource_id")
response: Dict = {}
try:
- _user_id = g.user_session.record.get(b"user_id",
- "").decode("utf-8")
+ user_id = ((g.user_session.record.get(b"user_id") or
+ b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
response = json.loads(
requests.get(urljoin(
current_app.config.get("GN2_PROXY"),
("available?resource="
- f"{resource_id}&user={_user_id}"))).content)
+ f"{resource_id}&user={user_id}"))).content)
except:
response = {}
if max([DataRole(role) for role in response.get(
@@ -78,13 +63,14 @@ def edit_admins_access_required(f):
resource_id: str = kwargs.get("resource_id", "")
response: Dict = {}
try:
- _user_id = g.user_session.record.get(b"user_id",
- "").decode("utf-8")
+ user_id = ((g.user_session.record.get(b"user_id") or
+ b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
response = json.loads(
requests.get(urljoin(
current_app.config.get("GN2_PROXY"),
("available?resource="
- f"{resource_id}&user={_user_id}"))).content)
+ f"{resource_id}&user={user_id}"))).content)
except:
response = {}
if max([AdminRole(role) for role in response.get(
@@ -92,4 +78,3 @@ def edit_admins_access_required(f):
return "You need to have edit-admins access", 401
return f(*args, **kwargs)
return wrap
-
diff --git a/wqflask/wqflask/metadata_edits.py b/wqflask/wqflask/metadata_edits.py
new file mode 100644
index 00000000..d232b32b
--- /dev/null
+++ b/wqflask/wqflask/metadata_edits.py
@@ -0,0 +1,340 @@
+import MySQLdb
+import os
+import json
+import datetime
+import difflib
+
+
+from collections import namedtuple
+from flask import (Blueprint, current_app, redirect,
+ flash, g, render_template, request)
+from itertools import groupby
+
+from wqflask.decorators import edit_access_required
+
+from gn3.db import diff_from_dict
+from gn3.db import fetchall
+from gn3.db import fetchone
+from gn3.db import insert
+from gn3.db import update
+from gn3.db.metadata_audit import MetadataAudit
+from gn3.db.phenotypes import Phenotype
+from gn3.db.phenotypes import Probeset
+from gn3.db.phenotypes import Publication
+from gn3.db.phenotypes import PublishXRef
+from gn3.db.phenotypes import probeset_mapping
+from gn3.commands import run_cmd
+from gn3.db.traits import get_trait_csv_sample_data
+from gn3.db.traits import update_sample_data
+
+
+metadata_edit = Blueprint('metadata_edit', __name__)
+
+
+def edit_phenotype(conn, name, dataset_id):
+ publish_xref = fetchone(
+ conn=conn,
+ table="PublishXRef",
+ where=PublishXRef(id_=name,
+ inbred_set_id=dataset_id))
+ phenotype_ = fetchone(
+ conn=conn,
+ table="Phenotype",
+ where=Phenotype(id_=publish_xref.phenotype_id))
+ publication_ = fetchone(
+ conn=conn,
+ table="Publication",
+ where=Publication(id_=publish_xref.publication_id))
+ json_data = fetchall(
+ conn,
+ "metadata_audit",
+ where=MetadataAudit(dataset_id=publish_xref.id_))
+ Edit = namedtuple("Edit", ["field", "old", "new", "diff"])
+ Diff = namedtuple("Diff", ["author", "diff", "timestamp"])
+ diff_data = []
+ for data in json_data:
+ json_ = json.loads(data.json_data)
+ timestamp = json_.get("timestamp")
+ author = json_.get("author")
+ for key, value in json_.items():
+ if isinstance(value, dict):
+ for field, data_ in value.items():
+ diff_data.append(
+ Diff(author=author,
+ diff=Edit(field,
+ data_.get("old"),
+ data_.get("new"),
+ "\n".join(difflib.ndiff(
+ [data_.get("old")],
+ [data_.get("new")]))),
+ timestamp=timestamp))
+ diff_data_ = None
+ if len(diff_data) > 0:
+ diff_data_ = groupby(diff_data, lambda x: x.timestamp)
+ return {
+ "diff": diff_data_,
+ "publish_xref": publish_xref,
+ "phenotype": phenotype_,
+ "publication": publication_,
+ }
+
+
+def edit_probeset(conn, name):
+ probeset_ = fetchone(conn=conn,
+ table="ProbeSet",
+ columns=list(probeset_mapping.values()),
+ where=Probeset(name=name))
+ json_data = fetchall(
+ conn,
+ "metadata_audit",
+ where=MetadataAudit(dataset_id=probeset_.id_))
+ Edit = namedtuple("Edit", ["field", "old", "new", "diff"])
+ Diff = namedtuple("Diff", ["author", "diff", "timestamp"])
+ diff_data = []
+ for data in json_data:
+ json_ = json.loads(data.json_data)
+ timestamp = json_.get("timestamp")
+ author = json_.get("author")
+ for key, value in json_.items():
+ if isinstance(value, dict):
+ for field, data_ in value.items():
+ diff_data.append(
+ Diff(author=author,
+ diff=Edit(field,
+ data_.get("old"),
+ data_.get("new"),
+ "\n".join(difflib.ndiff(
+ [data_.get("old")],
+ [data_.get("new")]))),
+ timestamp=timestamp))
+ diff_data_ = None
+ if len(diff_data) > 0:
+ diff_data_ = groupby(diff_data, lambda x: x.timestamp)
+ return {
+ "diff": diff_data_,
+ "probeset": probeset_,
+ }
+
+
+@metadata_edit.route("/<dataset_id>/traits/<name>")
+@edit_access_required
+def display_phenotype_metadata(dataset_id: str, name: str):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ _d = edit_phenotype(conn=conn, name=name, dataset_id=dataset_id)
+ return render_template(
+ "edit_phenotype.html",
+ diff=_d.get("diff"),
+ publish_xref=_d.get("publish_xref"),
+ phenotype=_d.get("phenotype"),
+ publication=_d.get("publication"),
+ dataset_id=dataset_id,
+ resource_id=request.args.get("resource-id"),
+ version=os.environ.get("GN_VERSION"),
+ )
+
+
+@metadata_edit.route("/traits/<name>")
+@edit_access_required
+def display_probeset_metadata(name: str):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ _d = edit_probeset(conn=conn, name=name)
+ return render_template(
+ "edit_probeset.html",
+ diff=_d.get("diff"),
+ probeset=_d.get("probeset"),
+ name=name,
+ resource_id=request.args.get("resource-id"),
+ version=os.environ.get("GN_VERSION"),
+ )
+
+
+@metadata_edit.route("/<dataset_id>/traits/<name>", methods=("POST",))
+@edit_access_required
+def update_phenotype(dataset_id: str, name: str):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ data_ = request.form.to_dict()
+ TMPDIR = current_app.config.get("TMPDIR")
+ author = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
+ phenotype_id = str(data_.get('phenotype-id'))
+ if 'file' not in request.files:
+ flash("No sample-data has been uploaded", "warning")
+ else:
+ file_ = request.files['file']
+ SAMPLE_DATADIR = os.path.join(TMPDIR, "sample-data")
+ if not os.path.exists(SAMPLE_DATADIR):
+ os.makedirs(SAMPLE_DATADIR)
+ if not os.path.exists(os.path.join(SAMPLE_DATADIR,
+ "diffs")):
+ os.makedirs(os.path.join(SAMPLE_DATADIR,
+ "diffs"))
+ if not os.path.exists(os.path.join(SAMPLE_DATADIR,
+ "updated")):
+ os.makedirs(os.path.join(SAMPLE_DATADIR,
+ "updated"))
+ current_time = str(datetime.datetime.now().isoformat())
+ new_file_name = (os.path.join(TMPDIR,
+ "sample-data/updated/",
+ (f"{author}."
+ f"{name}.{phenotype_id}."
+ f"{current_time}.csv")))
+ uploaded_file_name = (os.path.join(
+ TMPDIR,
+ "sample-data/updated/",
+ (f"updated.{author}."
+ f"{request.args.get('resource-id')}."
+ f"{current_time}.csv")))
+ file_.save(new_file_name)
+ publishdata_id = ""
+ lines = []
+ with open(new_file_name, "r") as f:
+ lines = f.read()
+ first_line = lines.split('\n', 1)[0]
+ publishdata_id = first_line.split("Id:")[-1].strip()
+ with open(new_file_name, "w") as f:
+ f.write(lines.split("\n\n")[-1])
+ csv_ = get_trait_csv_sample_data(conn=conn,
+ trait_name=str(name),
+ phenotype_id=str(phenotype_id))
+ with open(uploaded_file_name, "w") as f_:
+ f_.write(csv_.split("\n\n")[-1])
+ r = run_cmd(cmd=("csvdiff "
+ f"'{uploaded_file_name}' '{new_file_name}' "
+ "--format json"))
+ diff_output = (f"{TMPDIR}/sample-data/diffs/"
+ f"{author}.{request.args.get('resource-id')}."
+ f"{current_time}.json")
+ with open(diff_output, "w") as f:
+ dict_ = json.loads(r.get("output"))
+ dict_.update({
+ "author": author,
+ "publishdata_id": publishdata_id,
+ "dataset_id": data_.get("dataset-name"),
+ "timestamp": datetime.datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S")
+ })
+ f.write(json.dumps(dict_))
+ flash("Sample-data has been successfully uploaded", "success")
+ # Run updates:
+ phenotype_ = {
+ "pre_pub_description": data_.get("pre-pub-desc"),
+ "post_pub_description": data_.get("post-pub-desc"),
+ "original_description": data_.get("orig-desc"),
+ "units": data_.get("units"),
+ "pre_pub_abbreviation": data_.get("pre-pub-abbrev"),
+ "post_pub_abbreviation": data_.get("post-pub-abbrev"),
+ "lab_code": data_.get("labcode"),
+ "submitter": data_.get("submitter"),
+ "owner": data_.get("owner"),
+ "authorized_users": data_.get("authorized-users"),
+ }
+ updated_phenotypes = update(
+ conn, "Phenotype",
+ data=Phenotype(**phenotype_),
+ where=Phenotype(id_=data_.get("phenotype-id")))
+ diff_data = {}
+ if updated_phenotypes:
+ diff_data.update({"Phenotype": diff_from_dict(old={
+ k: data_.get(f"old_{k}") for k, v in phenotype_.items()
+ if v is not None}, new=phenotype_)})
+ publication_ = {
+ "abstract": data_.get("abstract"),
+ "authors": data_.get("authors"),
+ "title": data_.get("title"),
+ "journal": data_.get("journal"),
+ "volume": data_.get("volume"),
+ "pages": data_.get("pages"),
+ "month": data_.get("month"),
+ "year": data_.get("year")
+ }
+ updated_publications = update(
+ conn, "Publication",
+ data=Publication(**publication_),
+ where=Publication(id_=data_.get("pubmed-id",
+ data_.get("old_id_"))))
+ if updated_publications:
+ diff_data.update({"Publication": diff_from_dict(old={
+ k: data_.get(f"old_{k}") for k, v in publication_.items()
+ if v is not None}, new=publication_)})
+ if diff_data:
+ diff_data.update({"dataset_id": name})
+ diff_data.update({"resource_id": request.args.get('resource-id')})
+ diff_data.update({"author": author})
+ diff_data.update({"timestamp": datetime.datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S")})
+ insert(conn,
+ table="metadata_audit",
+ data=MetadataAudit(dataset_id=name,
+ editor=author,
+ json_data=json.dumps(diff_data)))
+ flash(f"Diff-data: \n{diff_data}\nhas been uploaded", "success")
+ return redirect(f"/datasets/{dataset_id}/traits/{name}"
+ f"?resource-id={request.args.get('resource-id')}")
+
+
+@metadata_edit.route("/traits/<name>", methods=("POST",))
+@edit_access_required
+def update_probeset(name: str):
+ conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
+ user=current_app.config.get("DB_USER"),
+ passwd=current_app.config.get("DB_PASS"),
+ host=current_app.config.get("DB_HOST"))
+ data_ = request.form.to_dict()
+ probeset_ = {
+ "id_": data_.get("id"),
+ "symbol": data_.get("symbol"),
+ "description": data_.get("description"),
+ "probe_target_description": data_.get("probe_target_description"),
+ "chr_": data_.get("chr"),
+ "mb": data_.get("mb"),
+ "alias": data_.get("alias"),
+ "geneid": data_.get("geneid"),
+ "homologeneid": data_.get("homologeneid"),
+ "unigeneid": data_.get("unigeneid"),
+ "omim": data_.get("OMIM"),
+ "refseq_transcriptid": data_.get("refseq_transcriptid"),
+ "blatseq": data_.get("blatseq"),
+ "targetseq": data_.get("targetseq"),
+ "strand_probe": data_.get("Strand_Probe"),
+ "probe_set_target_region": data_.get("probe_set_target_region"),
+ "probe_set_specificity": data_.get("probe_set_specificity"),
+ "probe_set_blat_score": data_.get("probe_set_blat_score"),
+ "probe_set_blat_mb_start": data_.get("probe_set_blat_mb_start"),
+ "probe_set_blat_mb_end": data_.get("probe_set_blat_mb_end"),
+ "probe_set_strand": data_.get("probe_set_strand"),
+ "probe_set_note_by_rw": data_.get("probe_set_note_by_rw"),
+ "flag": data_.get("flag")
+ }
+ diff_data = {}
+ author = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
+ if (updated_probeset := update(
+ conn, "ProbeSet",
+ data=Probeset(**probeset_),
+ where=Probeset(id_=data_.get("id")))):
+ diff_data.update({"Probeset": diff_from_dict(old={
+ k: data_.get(f"old_{k}") for k, v in probeset_.items()
+ if v is not None}, new=probeset_)})
+ if diff_data:
+ diff_data.update({"probeset_name": data_.get("probeset_name")})
+ diff_data.update({"author": author})
+ diff_data.update({"resource_id": request.args.get('resource-id')})
+ diff_data.update({"timestamp": datetime.datetime.now().strftime(
+ "%Y-%m-%d %H:%M:%S")})
+ insert(conn,
+ table="metadata_audit",
+ data=MetadataAudit(dataset_id=data_.get("id"),
+ editor=author,
+ json_data=json.dumps(diff_data)))
+ return redirect(f"/datasets/traits/{name}"
+ f"?resource-id={request.args.get('resource-id')}")
+
diff --git a/wqflask/wqflask/resource_manager.py b/wqflask/wqflask/resource_manager.py
index 3371e59d..e338a22d 100644
--- a/wqflask/wqflask/resource_manager.py
+++ b/wqflask/wqflask/resource_manager.py
@@ -147,8 +147,7 @@ def view_resource(resource_id: str):
access_role=get_user_access_roles(
resource_id=resource_id,
user_id=user_id,
- gn_proxy_url=current_app.config.get("GN2_PROXY")),
- DataRole=DataRole, AdminRole=AdminRole)
+ gn_proxy_url=current_app.config.get("GN2_PROXY")))
@resource_management.route("/resources/<resource_id>/make-public",
diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py
index c4d1ae1c..fa1206c9 100644
--- a/wqflask/wqflask/show_trait/show_trait.py
+++ b/wqflask/wqflask/show_trait/show_trait.py
@@ -20,15 +20,16 @@ from base import data_set
from utility import helper_functions
from utility.authentication_tools import check_owner_or_admin
from utility.tools import locate_ignore_error
+from utility.tools import GN_PROXY_URL
from utility.redis_tools import get_redis_conn, get_resource_id
-from utility.logger import getLogger
+from wqflask.access_roles import AdminRole
+from wqflask.access_roles import DataRole
+from wqflask.resource_manager import get_user_access_roles
Redis = get_redis_conn()
ONE_YEAR = 60 * 60 * 24 * 365
-logger = getLogger(__name__)
-
###############################################
#
# Todo: Put in security to ensure that user has permission to access
@@ -38,14 +39,11 @@ logger = getLogger(__name__)
class ShowTrait:
- def __init__(self, kw):
+ def __init__(self, user_id, kw):
if 'trait_id' in kw and kw['dataset'] != "Temp":
self.temp_trait = False
self.trait_id = kw['trait_id']
helper_functions.get_species_dataset_trait(self, kw)
- self.resource_id = get_resource_id(self.dataset, self.trait_id)
- self.admin_status = check_owner_or_admin(
- resource_id=self.resource_id)
elif 'group' in kw:
self.temp_trait = True
self.trait_id = "Temp_" + kw['species'] + "_" + kw['group'] + \
@@ -62,9 +60,6 @@ class ShowTrait:
self.this_trait = create_trait(dataset=self.dataset,
name=self.trait_id,
cellid=None)
-
- self.admin_status = check_owner_or_admin(
- dataset=self.dataset, trait_id=self.trait_id)
else:
self.temp_trait = True
self.trait_id = kw['trait_id']
@@ -75,11 +70,13 @@ class ShowTrait:
self.this_trait = create_trait(dataset=self.dataset,
name=self.trait_id,
cellid=None)
-
self.trait_vals = Redis.get(self.trait_id).split()
- self.admin_status = check_owner_or_admin(
- dataset=self.dataset, trait_id=self.trait_id)
-
+ self.resource_id = get_resource_id(self.dataset,
+ self.trait_id)
+ self.admin_status = get_user_access_roles(
+ user_id=user_id,
+ resource_id=(self.resource_id or ""),
+ gn_proxy_url=GN_PROXY_URL)
# ZS: Get verify/rna-seq link URLs
try:
blatsequence = self.this_trait.blatseq
@@ -525,10 +522,6 @@ class ShowTrait:
sample_group_type='primary',
header="%s Only" % (self.dataset.group.name))
self.sample_groups = (primary_samples,)
- print("\nttttttttttttttttttttttttttttttttttttttttttttt\n")
- print(self.sample_groups)
- print("\nttttttttttttttttttttttttttttttttttttttttttttt\n")
-
self.primary_sample_names = primary_sample_names
self.dataset.group.allsamples = all_samples_ordered
@@ -614,7 +607,6 @@ def get_nearest_marker(this_trait, this_db):
GenoFreeze.Id = GenoXRef.GenoFreezeId AND
GenoFreeze.Name = '{}'
ORDER BY ABS( Geno.Mb - {}) LIMIT 1""".format(this_chr, this_db.group.name + "Geno", this_mb)
- logger.sql(query)
result = g.db.execute(query).fetchall()
if result == []:
diff --git a/wqflask/wqflask/templates/admin/manage_resource.html b/wqflask/wqflask/templates/admin/manage_resource.html
index 613aa70e..64d4b6eb 100644
--- a/wqflask/wqflask/templates/admin/manage_resource.html
+++ b/wqflask/wqflask/templates/admin/manage_resource.html
@@ -3,29 +3,31 @@
{% block content %}
<!-- Start of body -->
<div class="container">
+ <section>
{{ flash_me() }}
- {% set DATA_ACCESS = access_role.get('data') %}
- {% set METADATA_ACCESS = access_role.get('metadata') %}
- {% set ADMIN_STATUS = access_role.get('admin') %}
- <h1>Resource Manager</h1>
- {% if resource_info.get('owner_id') != 'none'%}
- {% set user_details = resource_info.get('owner_details') %}
- <h3>
- Current Owner: {{ user_details.get('full_name') }}
- </h3>
- {% if user_details.get('organization') %}
- <h3>
- Organization: {{ user_details.get('organization')}}
- </h3>
- {% endif %}
- {% if DATA_ACCESS > DataRole.VIEW and ADMIN_STATUS > AdminRole.NOT_ADMIN %}
- <a class="btn btn-danger" target="_blank"
- href="/resource-management/resources/{{ resource_info.get('resource_id') }}/change-owner">
- Change Owner
- </a>
- {% endif %}
- {% endif %}
- </section>
+ {% set DATA_ACCESS = access_role.get('data') %}
+ {% set METADATA_ACCESS = access_role.get('metadata') %}
+ {% set ADMIN_STATUS = access_role.get('admin') %}
+ {% set ADMIN_STATUS = access_role.get('admin') %}
+ <h1>Resource Manager</h1>
+ {% if resource_info.get('owner_id') %}
+ {% set user_details = resource_info.get('owner_details') %}
+ <h3>
+ Current Owner: {{ user_details.get('full_name') }}
+ </h3>
+ {% if user_details.get('organization') %}
+ <h3>
+ Organization: {{ user_details.get('organization')}}
+ </h3>
+ {% endif %}
+ {% if DATA_ACCESS > DataRole.VIEW and ADMIN_STATUS > AdminRole.NOT_ADMIN %}
+ <a class="btn btn-danger" target="_blank"
+ href="/resource-management/resources/{{ resource_info.get('resource_id') }}/change-owner">
+ Change Owner
+ </a>
+ {% endif %}
+ {% endif %}
+ </section>
<section class="container" style="margin-top: 2em;">
<form class="container-fluid" action="/resource-management/resources/{{ resource_info.get('resource_id') }}/make-public" method="POST">
@@ -51,7 +53,7 @@
<label class="radio-inline">
<input type="radio" name="open_to_public" value="False" {{ 'checked' if not is_open_to_public }}>
No
- </label>
+ </label>
</div>
</div>
<div class="form-group" style="padding-left: 20px;">
@@ -98,25 +100,25 @@
</div>
{% endif %}
</form>
- </section>
+ </section>
-<!-- End of body -->
+ <!-- End of body -->
-{% endblock %}
-{% block js %}
+ {% endblock %}
+ {% block js %}
<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
<script type="text/javascript" charset="utf-8">
- $('#add_group_to_resource, #save_changes, #change_owner').click(function(){
- url = $(this).data("url");
- $('#manage_resource').attr("action", url)
- $('#manage_resource').submit()
- })
+ $('#add_group_to_resource, #save_changes, #change_owner').click(function(){
+ url = $(this).data("url");
+ $('#manage_resource').attr("action", url)
+ $('#manage_resource').submit()
+ })
- {% if group_masks|length > 0 %}
- $('#groups_table').dataTable({
- 'sDom': 'tr',
- });
- {% endif %}
+ {% if group_masks|length > 0 %}
+ $('#groups_table').dataTable({
+ 'sDom': 'tr',
+ });
+ {% endif %}
</script>
-{% endblock %}
+ {% endblock %}
diff --git a/wqflask/wqflask/templates/edit_phenotype.html b/wqflask/wqflask/templates/edit_phenotype.html
index 7a841793..c3cde391 100644
--- a/wqflask/wqflask/templates/edit_phenotype.html
+++ b/wqflask/wqflask/templates/edit_phenotype.html
@@ -62,8 +62,7 @@
</div>
{% endif %}
-
-<form id="edit-form" class="form-horizontal" method="post" action="/trait/update" enctype=multipart/form-data>
+<form id="edit-form" class="form-horizontal" method="post" action="/datasets/{{dataset_id}}/traits/{{ publish_xref.id_ }}?resource-id={{ resource_id }}" enctype='multipart/form-data'>
<h2 class="text-center">Trait Information:</h2>
<div class="form-group">
<label for="pubmed-id" class="col-sm-2 control-label">Pubmed ID:</label>
@@ -226,7 +225,6 @@
<input type = "file" class="col-sm-4 control-label" name = "file" />
</div>
<div class="controls center-block" style="width: max-content;">
- <input name="dataset-name" class="changed" type="hidden" value="{{ publish_xref.id_ }}"/>
<input name="inbred-set-id" class="changed" type="hidden" value="{{ publish_xref.inbred_set_id }}"/>
<input name="phenotype-id" class="changed" type="hidden" value="{{ publish_xref.phenotype_id }}"/>
<input name="comments" class="changed" type="hidden" value="{{ publish_xref.comments }}"/>
diff --git a/wqflask/wqflask/templates/edit_probeset.html b/wqflask/wqflask/templates/edit_probeset.html
index 85d49561..ab91b701 100644
--- a/wqflask/wqflask/templates/edit_probeset.html
+++ b/wqflask/wqflask/templates/edit_probeset.html
@@ -9,52 +9,52 @@ Submit Trait | Reset
<div class="container">
<details class="col-sm-12 col-md-10 col-lg-12">
- <summary>
- <h2>Update History</h2>
- </summary>
- <table class="table">
- <tbody>
- <tr>
- <th>Timestamp</th>
- <th>Editor</th>
- <th>Field</th>
- <th>Diff</th>
- </tr>
- {% set ns = namespace(display_cell=True) %}
+ <summary>
+ <h2>Update History</h2>
+ </summary>
+ <table class="table">
+ <tbody>
+ <tr>
+ <th>Timestamp</th>
+ <th>Editor</th>
+ <th>Field</th>
+ <th>Diff</th>
+ </tr>
+ {% set ns = namespace(display_cell=True) %}
- {% for timestamp, group in diff %}
- {% set ns.display_cell = True %}
- {% for i in group %}
- <tr>
- {% if ns.display_cell and i.timestamp == timestamp %}
+ {% for timestamp, group in diff %}
+ {% set ns.display_cell = True %}
+ {% for i in group %}
+ <tr>
+ {% if ns.display_cell and i.timestamp == timestamp %}
- {% set author = i.author %}
- {% set timestamp_ = i.timestamp %}
+ {% set author = i.author %}
+ {% set timestamp_ = i.timestamp %}
- {% else %}
+ {% else %}
- {% set author = "" %}
- {% set timestamp_ = "" %}
+ {% set author = "" %}
+ {% set timestamp_ = "" %}
- {% endif %}
- <td>{{ timestamp_ }}</td>
- <td>{{ author }}</td>
- <td>{{ i.diff.field }}</td>
- <td><pre>{{ i.diff.diff }}</pre></td>
- {% set ns.display_cell = False %}
- </tr>
- {% endfor %}
- {% endfor %}
- </tbody>
- </table>
+ {% endif %}
+ <td>{{ timestamp_ }}</td>
+ <td>{{ author }}</td>
+ <td>{{ i.diff.field }}</td>
+ <td><pre>{{ i.diff.diff }}</pre></td>
+ {% set ns.display_cell = False %}
+ </tr>
+ {% endfor %}
+ {% endfor %}
+ </tbody>
+ </table>
</details>
</div>
{% endif %}
-<form id="edit-form" class="form-horizontal" method="post" action="/probeset/update">
- <h2 class="text-center">Probeset Information:</h2>
+<form id="edit-form" class="form-horizontal" method="post" action="/datasets/traits/{{ name }}?resource-id={{ resource_id }}">
+ <h2 class="text-center">Probeset Information:</h2>
<div class="form-group">
<label for="symbol" class="col-sm-2 control-label">Symbol:</label>
<div class="col-sm-4">
diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html
index 2a21dd24..3e59a3ee 100644
--- a/wqflask/wqflask/templates/show_trait_details.html
+++ b/wqflask/wqflask/templates/show_trait_details.html
@@ -234,16 +234,16 @@
{% endif %}
{% endif %}
<button type="button" id="view_in_gn1" class="btn btn-primary" title="View Trait in GN1" onclick="window.open('http://gn1.genenetwork.org/webqtl/main.py?cmd=show&db={{ this_trait.dataset.name }}&probeset={{ this_trait.name }}', '_blank')">Go to GN1</button>
- {% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %}
+ {% if admin_status.get('metadata', DataRole.VIEW) > DataRole.VIEW %}
{% if this_trait.dataset.type == 'Publish' %}
- <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/trait/{{ this_trait.name }}/edit/inbredset-id/{{ this_trait.dataset.id }}', '_blank')">Edit</button>
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/datasets/{{ this_trait.dataset.id }}/traits/{{ this_trait.name }}?resource-id={{ resource_id }}', '_blank')">Edit</button>
{% endif %}
{% if this_trait.dataset.type == 'ProbeSet' %}
- <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/trait/edit/probeset-name/{{ this_trait.name }}', '_blank')">Edit</button>
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('/datasets/traits/{{ this_trait.name }}?resource-id={{ resource_id }}', '_blank')">Edit</button>
{% endif %}
- {% if admin_status == "owner" or admin_status == "edit-admins" or admin_status == "edit-access" %}
- <button type="button" id="edit_resource" class="btn btn-success" title="Edit Resource" onclick="window.open('./resources/manage?resource_id={{ resource_id }}', '_blank')">Edit Privileges</button>
+ {% if admin_status.get('metadata', DataRole.VIEW) > DataRole.VIEW %}
+ <button type="button" id="edit_resource" class="btn btn-success" title="Edit Privileges" onclick="window.open('/resource-management/resources/{{ resource_id }}', '_blank')">Edit Privileges</button>
{% endif %}
{% endif %}
</div>
diff --git a/wqflask/wqflask/user_session.py b/wqflask/wqflask/user_session.py
index 67e2e158..d3c4a62f 100644
--- a/wqflask/wqflask/user_session.py
+++ b/wqflask/wqflask/user_session.py
@@ -10,7 +10,6 @@ from flask import (Flask, g, render_template, url_for, request, make_response,
from wqflask import app
from utility import hmac
-#from utility.elasticsearch_tools import get_elasticsearch_connection
from utility.redis_tools import get_redis_conn, get_user_id, get_user_by_unique_column, set_user_attribute, get_user_collections, save_collections
Redis = get_redis_conn()
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index b0da1f21..220d9b87 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -4,7 +4,6 @@ import MySQLdb
import array
import base64
import csv
-import difflib
import datetime
import flask
import io # Todo: Use cStringIO?
@@ -20,8 +19,6 @@ import traceback
import uuid
import xlsxwriter
-from itertools import groupby
-from collections import namedtuple
from zipfile import ZipFile
from zipfile import ZIP_DEFLATED
@@ -30,19 +27,12 @@ from wqflask import app
from gn3.commands import run_cmd
from gn3.computations.gemma import generate_hash_of_string
from gn3.db import diff_from_dict
-from gn3.db import fetchall
-from gn3.db import fetchone
from gn3.db import insert
from gn3.db import update
from gn3.db.metadata_audit import MetadataAudit
from gn3.db.phenotypes import Phenotype
from gn3.db.phenotypes import Probeset
from gn3.db.phenotypes import Publication
-from gn3.db.phenotypes import PublishXRef
-from gn3.db.phenotypes import probeset_mapping
-# from gn3.db.traits import get_trait_csv_sample_data
-# from gn3.db.traits import update_sample_data
-
from flask import current_app
from flask import g
@@ -426,289 +416,6 @@ def submit_trait_form():
version=GN_VERSION)
-@app.route("/trait/<name>/edit/inbredset-id/<inbredset_id>")
-@edit_access_required
-def edit_phenotype(name, inbredset_id):
- conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
- user=current_app.config.get("DB_USER"),
- passwd=current_app.config.get("DB_PASS"),
- host=current_app.config.get("DB_HOST"))
- publish_xref = fetchone(
- conn=conn,
- table="PublishXRef",
- where=PublishXRef(id_=name,
- inbred_set_id=inbredset_id))
- phenotype_ = fetchone(
- conn=conn,
- table="Phenotype",
- where=Phenotype(id_=publish_xref.phenotype_id))
- publication_ = fetchone(
- conn=conn,
- table="Publication",
- where=Publication(id_=publish_xref.publication_id))
- json_data = fetchall(
- conn,
- "metadata_audit",
- where=MetadataAudit(dataset_id=publish_xref.id_))
-
- Edit = namedtuple("Edit", ["field", "old", "new", "diff"])
- Diff = namedtuple("Diff", ["author", "diff", "timestamp"])
- diff_data = []
- for data in json_data:
- json_ = json.loads(data.json_data)
- timestamp = json_.get("timestamp")
- author = json_.get("author")
- for key, value in json_.items():
- if isinstance(value, dict):
- for field, data_ in value.items():
- diff_data.append(
- Diff(author=author,
- diff=Edit(field,
- data_.get("old"),
- data_.get("new"),
- "\n".join(difflib.ndiff(
- [data_.get("old")],
- [data_.get("new")]))),
- timestamp=timestamp))
- diff_data_ = None
- if len(diff_data) > 0:
- diff_data_ = groupby(diff_data, lambda x: x.timestamp)
- return render_template(
- "edit_phenotype.html",
- diff=diff_data_,
- publish_xref=publish_xref,
- phenotype=phenotype_,
- publication=publication_,
- version=GN_VERSION,
- )
-
-
-@app.route("/trait/edit/probeset-name/<dataset_name>")
-@edit_access_required
-def edit_probeset(dataset_name):
- conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
- user=current_app.config.get("DB_USER"),
- passwd=current_app.config.get("DB_PASS"),
- host=current_app.config.get("DB_HOST"))
- probeset_ = fetchone(conn=conn,
- table="ProbeSet",
- columns=list(probeset_mapping.values()),
- where=Probeset(name=dataset_name))
- json_data = fetchall(
- conn,
- "metadata_audit",
- where=MetadataAudit(dataset_id=probeset_.id_))
- Edit = namedtuple("Edit", ["field", "old", "new", "diff"])
- Diff = namedtuple("Diff", ["author", "diff", "timestamp"])
- diff_data = []
- for data in json_data:
- json_ = json.loads(data.json_data)
- timestamp = json_.get("timestamp")
- author = json_.get("author")
- for key, value in json_.items():
- if isinstance(value, dict):
- for field, data_ in value.items():
- diff_data.append(
- Diff(author=author,
- diff=Edit(field,
- data_.get("old"),
- data_.get("new"),
- "\n".join(difflib.ndiff(
- [data_.get("old")],
- [data_.get("new")]))),
- timestamp=timestamp))
- diff_data_ = None
- if len(diff_data) > 0:
- diff_data_ = groupby(diff_data, lambda x: x.timestamp)
- return render_template(
- "edit_probeset.html",
- diff=diff_data_,
- probeset=probeset_)
-
-
-@app.route("/trait/update", methods=["POST"])
-@edit_access_required
-def update_phenotype():
- conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
- user=current_app.config.get("DB_USER"),
- passwd=current_app.config.get("DB_PASS"),
- host=current_app.config.get("DB_HOST"))
- data_ = request.form.to_dict()
- TMPDIR = current_app.config.get("TMPDIR")
- author = g.user_session.record.get(b'user_name')
- if 'file' not in request.files:
- flash("No sample-data has been uploaded", "warning")
- else:
- file_ = request.files['file']
- trait_name = str(data_.get('dataset-name'))
- phenotype_id = str(data_.get('phenotype-id', 35))
- SAMPLE_DATADIR = os.path.join(TMPDIR, "sample-data")
- if not os.path.exists(SAMPLE_DATADIR):
- os.makedirs(SAMPLE_DATADIR)
- if not os.path.exists(os.path.join(SAMPLE_DATADIR,
- "diffs")):
- os.makedirs(os.path.join(SAMPLE_DATADIR,
- "diffs"))
- if not os.path.exists(os.path.join(SAMPLE_DATADIR,
- "updated")):
- os.makedirs(os.path.join(SAMPLE_DATADIR,
- "updated"))
- current_time = str(datetime.datetime.now().isoformat())
- new_file_name = (os.path.join(TMPDIR,
- "sample-data/updated/",
- (f"{author.decode('utf-8')}."
- f"{trait_name}.{phenotype_id}."
- f"{current_time}.csv")))
- uploaded_file_name = (os.path.join(
- TMPDIR,
- "sample-data/updated/",
- (f"updated.{author.decode('utf-8')}."
- f"{trait_name}.{phenotype_id}."
- f"{current_time}.csv")))
- file_.save(new_file_name)
- publishdata_id = ""
- lines = []
- with open(new_file_name, "r") as f:
- lines = f.read()
- first_line = lines.split('\n', 1)[0]
- publishdata_id = first_line.split("Id:")[-1].strip()
- with open(new_file_name, "w") as f:
- f.write(lines.split("\n\n")[-1])
- csv_ = get_trait_csv_sample_data(conn=conn,
- trait_name=str(trait_name),
- phenotype_id=str(phenotype_id))
- with open(uploaded_file_name, "w") as f_:
- f_.write(csv_.split("\n\n")[-1])
- r = run_cmd(cmd=("csvdiff "
- f"'{uploaded_file_name}' '{new_file_name}' "
- "--format json"))
- diff_output = (f"{TMPDIR}/sample-data/diffs/"
- f"{trait_name}.{author.decode('utf-8')}."
- f"{phenotype_id}.{current_time}.json")
- with open(diff_output, "w") as f:
- dict_ = json.loads(r.get("output"))
- dict_.update({
- "author": author.decode('utf-8'),
- "publishdata_id": publishdata_id,
- "dataset_id": data_.get("dataset-name"),
- "timestamp": datetime.datetime.now().strftime(
- "%Y-%m-%d %H:%M:%S")
- })
- f.write(json.dumps(dict_))
- flash("Sample-data has been successfully uploaded", "success")
- # Run updates:
- phenotype_ = {
- "pre_pub_description": data_.get("pre-pub-desc"),
- "post_pub_description": data_.get("post-pub-desc"),
- "original_description": data_.get("orig-desc"),
- "units": data_.get("units"),
- "pre_pub_abbreviation": data_.get("pre-pub-abbrev"),
- "post_pub_abbreviation": data_.get("post-pub-abbrev"),
- "lab_code": data_.get("labcode"),
- "submitter": data_.get("submitter"),
- "owner": data_.get("owner"),
- "authorized_users": data_.get("authorized-users"),
- }
- updated_phenotypes = update(
- conn, "Phenotype",
- data=Phenotype(**phenotype_),
- where=Phenotype(id_=data_.get("phenotype-id")))
- diff_data = {}
- if updated_phenotypes:
- diff_data.update({"Phenotype": diff_from_dict(old={
- k: data_.get(f"old_{k}") for k, v in phenotype_.items()
- if v is not None}, new=phenotype_)})
- publication_ = {
- "abstract": data_.get("abstract"),
- "authors": data_.get("authors"),
- "title": data_.get("title"),
- "journal": data_.get("journal"),
- "volume": data_.get("volume"),
- "pages": data_.get("pages"),
- "month": data_.get("month"),
- "year": data_.get("year")
- }
- updated_publications = update(
- conn, "Publication",
- data=Publication(**publication_),
- where=Publication(id_=data_.get("pubmed-id",
- data_.get("old_id_"))))
- if updated_publications:
- diff_data.update({"Publication": diff_from_dict(old={
- k: data_.get(f"old_{k}") for k, v in publication_.items()
- if v is not None}, new=publication_)})
- if diff_data:
- diff_data.update({"dataset_id": data_.get("dataset-name")})
- diff_data.update({"author": author.decode('utf-8')})
- diff_data.update({"timestamp": datetime.datetime.now().strftime(
- "%Y-%m-%d %H:%M:%S")})
- insert(conn,
- table="metadata_audit",
- data=MetadataAudit(dataset_id=data_.get("dataset-name"),
- editor=author.decode("utf-8"),
- json_data=json.dumps(diff_data)))
- flash(f"Diff-data: \n{diff_data}\nhas been uploaded", "success")
- return redirect(f"/trait/{data_.get('dataset-name')}"
- f"/edit/inbredset-id/{data_.get('inbred-set-id')}")
-
-
-@app.route("/probeset/update", methods=["POST"])
-@edit_access_required
-def update_probeset():
- conn = MySQLdb.Connect(db=current_app.config.get("DB_NAME"),
- user=current_app.config.get("DB_USER"),
- passwd=current_app.config.get("DB_PASS"),
- host=current_app.config.get("DB_HOST"))
- data_ = request.form.to_dict()
- probeset_ = {
- "id_": data_.get("id"),
- "symbol": data_.get("symbol"),
- "description": data_.get("description"),
- "probe_target_description": data_.get("probe_target_description"),
- "chr_": data_.get("chr"),
- "mb": data_.get("mb"),
- "alias": data_.get("alias"),
- "geneid": data_.get("geneid"),
- "homologeneid": data_.get("homologeneid"),
- "unigeneid": data_.get("unigeneid"),
- "omim": data_.get("OMIM"),
- "refseq_transcriptid": data_.get("refseq_transcriptid"),
- "blatseq": data_.get("blatseq"),
- "targetseq": data_.get("targetseq"),
- "strand_probe": data_.get("Strand_Probe"),
- "probe_set_target_region": data_.get("probe_set_target_region"),
- "probe_set_specificity": data_.get("probe_set_specificity"),
- "probe_set_blat_score": data_.get("probe_set_blat_score"),
- "probe_set_blat_mb_start": data_.get("probe_set_blat_mb_start"),
- "probe_set_blat_mb_end": data_.get("probe_set_blat_mb_end"),
- "probe_set_strand": data_.get("probe_set_strand"),
- "probe_set_note_by_rw": data_.get("probe_set_note_by_rw"),
- "flag": data_.get("flag")
- }
- updated_probeset = update(
- conn, "ProbeSet",
- data=Probeset(**probeset_),
- where=Probeset(id_=data_.get("id")))
-
- diff_data = {}
- author = g.user_session.record.get(b'user_name')
- if updated_probeset:
- diff_data.update({"Probeset": diff_from_dict(old={
- k: data_.get(f"old_{k}") for k, v in probeset_.items()
- if v is not None}, new=probeset_)})
- if diff_data:
- diff_data.update({"probeset_name": data_.get("probeset_name")})
- diff_data.update({"author": author.decode('utf-8')})
- diff_data.update({"timestamp": datetime.datetime.now().strftime(
- "%Y-%m-%d %H:%M:%S")})
- insert(conn,
- table="metadata_audit",
- data=MetadataAudit(dataset_id=data_.get("id"),
- editor=author.decode("utf-8"),
- json_data=json.dumps(diff_data)))
- return redirect(f"/trait/edit/probeset-name/{data_.get('probeset_name')}")
-
-
@app.route("/create_temp_trait", methods=('POST',))
def create_temp_trait():
logger.info(request.url)
@@ -843,8 +550,10 @@ def export_perm_data():
@app.route("/show_temp_trait", methods=('POST',))
def show_temp_trait_page():
- logger.info(request.url)
- template_vars = show_trait.ShowTrait(request.form)
+ user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
+ template_vars = show_trait.ShowTrait(user_id=user_id,
+ kw=request.form)
template_vars.js_data = json.dumps(template_vars.js_data,
default=json_default_handler,
indent=" ")
@@ -853,8 +562,10 @@ def show_temp_trait_page():
@app.route("/show_trait")
def show_trait_page():
- logger.info(request.url)
- template_vars = show_trait.ShowTrait(request.args)
+ user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8")
+ or g.user_session.record.get("user_id") or "")
+ template_vars = show_trait.ShowTrait(user_id=user_id,
+ kw=request.args)
template_vars.js_data = json.dumps(template_vars.js_data,
default=json_default_handler,
indent=" ")