aboutsummaryrefslogtreecommitdiff
path: root/wqflask/wqflask
diff options
context:
space:
mode:
authorSam2013-10-30 19:53:09 -0500
committerSam2013-10-30 19:53:09 -0500
commit74d803b0de60edf324b1a6ce589d12a055ef312b (patch)
treef14022873a7f898e7b9258b01a0ac1a9c30a2cdf /wqflask/wqflask
parentde7abc1d2ac9fef87796baa7330cbaaaadbbec2a (diff)
downloadgenenetwork2-74d803b0de60edf324b1a6ce589d12a055ef312b.tar.gz
More work on collections
Diffstat (limited to 'wqflask/wqflask')
-rw-r--r--wqflask/wqflask/collect.py36
-rw-r--r--wqflask/wqflask/do_search.py120
-rw-r--r--wqflask/wqflask/model.py12
-rw-r--r--wqflask/wqflask/static/packages/bootstrap/css/docs.css16
-rw-r--r--wqflask/wqflask/templates/admin/ind_user_manager.html6
-rw-r--r--wqflask/wqflask/templates/collections/list.html50
-rw-r--r--wqflask/wqflask/templates/collections/view.html105
7 files changed, 206 insertions, 139 deletions
diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py
index 39a63a1f..ef7b37df 100644
--- a/wqflask/wqflask/collect.py
+++ b/wqflask/wqflask/collect.py
@@ -40,6 +40,7 @@ from utility import Bunch, Struct
from wqflask import user_manager
+from base import trait
@@ -116,4 +117,37 @@ def create_new():
db_session.add(uc)
db_session.commit()
- return "Created: " + uc.name
+ print("Created: " + uc.name)
+ return redirect(url_for('view_collection', uc_id=uc.id))
+
+@app.route("/collections/list")
+def list_collections():
+ user_collections = g.user_session.user_ob.user_collections
+ return render_template("collections/list.html",
+ user_collections = user_collections,
+ )
+
+
+
+@app.route("/collections/view")
+def view_collection():
+ params = request.args
+ uc_id = params['uc_id']
+ uc = model.UserCollection.query.get(uc_id)
+ traits = json.loads(uc.members)
+
+ print("in view_collection traits are:", traits)
+
+ trait_obs = []
+
+ for atrait in traits:
+ name, dataset_name = atrait.split(':')
+
+ trait_ob = trait.GeneralTrait(name=name, dataset_name=dataset_name)
+ trait_ob.get_info()
+ trait_obs.append(trait_ob)
+
+ return render_template("collections/view.html",
+ trait_obs=trait_obs,
+ uc = uc,
+ )
diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py
index 5eb09aa1..31f96ced 100644
--- a/wqflask/wqflask/do_search.py
+++ b/wqflask/wqflask/do_search.py
@@ -26,12 +26,12 @@ class DoSearch(object):
assert search_operator in (None, "=", "<", ">", "<=", ">="), "Bad search operator"
self.search_operator = search_operator
self.dataset = dataset
-
+
if self.dataset:
print("self.dataset is boo: ", type(self.dataset), pf(self.dataset))
print("self.dataset.group is: ", pf(self.dataset.group))
#Get group information for dataset and the species id
- self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group.name)
+ self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group.name)
def execute(self, query):
"""Executes query and returns results"""
@@ -44,7 +44,7 @@ class DoSearch(object):
#def escape(self, stringy):
# """Shorter name than self.db_conn.escape_string"""
# return escape(str(stringy))
-
+
def mescape(self, *items):
"""Multiple escape"""
escaped = [escape(item) for item in items]
@@ -63,9 +63,9 @@ class DoSearch(object):
class QuickMrnaAssaySearch(DoSearch):
"""A general search for mRNA assays"""
-
+
DoSearch.search_types['quick_mrna_assay'] = "QuickMrnaAssaySearch"
-
+
base_query = """SELECT ProbeSet.Name as ProbeSet_Name,
ProbeSet.Symbol as ProbeSet_Symbol,
ProbeSet.description as ProbeSet_Description,
@@ -73,9 +73,9 @@ class QuickMrnaAssaySearch(DoSearch):
ProbeSet.Mb as ProbeSet_Mb,
ProbeSet.name_num as ProbeSet_name_num
FROM ProbeSet """
-
+
header_fields = ['',
- 'Record ID',
+ 'Record',
'Symbol',
'Location']
@@ -112,7 +112,7 @@ class MrnaAssaySearch(DoSearch):
FROM ProbeSetXRef, ProbeSet """
header_fields = ['',
- 'Record ID',
+ 'Record',
'Symbol',
'Description',
'Location',
@@ -122,7 +122,7 @@ class MrnaAssaySearch(DoSearch):
def compile_final_query(self, from_clause = '', where_clause = ''):
"""Generates the final query string"""
-
+
from_clause = self.normalize_spaces(from_clause)
query = (self.base_query +
@@ -132,7 +132,7 @@ class MrnaAssaySearch(DoSearch):
and ProbeSetXRef.ProbeSetFreezeId = %s
""" % (escape(from_clause),
where_clause,
- escape(self.dataset.id)))
+ escape(self.dataset.id)))
#print("query is:", pf(query))
@@ -149,9 +149,9 @@ class MrnaAssaySearch(DoSearch):
GenbankId,
UniGeneId,
Probe_Target_Description)
- AGAINST ('%s' IN BOOLEAN MODE))
+ AGAINST ('%s' IN BOOLEAN MODE))
and ProbeSet.Id = ProbeSetXRef.ProbeSetId
- and ProbeSetXRef.ProbeSetFreezeId = %s
+ and ProbeSetXRef.ProbeSetFreezeId = %s
""" % (escape(self.search_term[0]),
escape(str(self.dataset.id)))
@@ -159,7 +159,7 @@ class MrnaAssaySearch(DoSearch):
return self.execute(query)
-
+
class PhenotypeSearch(DoSearch):
"""A search within a phenotype dataset"""
@@ -181,9 +181,9 @@ class PhenotypeSearch(DoSearch):
'Publication.Title',
'Publication.Authors',
'PublishXRef.Id')
-
+
header_fields = ['',
- 'Record ID',
+ 'Record',
'Description',
'Authors',
'Year',
@@ -237,9 +237,9 @@ class PhenotypeSearch(DoSearch):
class QuickPhenotypeSearch(PhenotypeSearch):
"""A search across all phenotype datasets"""
-
+
DoSearch.search_types['quick_phenotype'] = "QuickPhenotypeSearch"
-
+
base_query = """SELECT Species.Name as Species_Name,
PublishFreeze.FullName as Dataset_Name,
PublishFreeze.Name,
@@ -262,8 +262,8 @@ class QuickPhenotypeSearch(PhenotypeSearch):
'Publication.PubMed_ID',
'Publication.Abstract',
'Publication.Title',
- 'Publication.Authors')
-
+ 'Publication.Authors')
+
def compile_final_query(self, where_clause = ''):
"""Generates the final query string"""
@@ -277,7 +277,7 @@ class QuickPhenotypeSearch(PhenotypeSearch):
print("query is:", pf(query))
return query
-
+
def run(self):
"""Generates and runs a search across all phenotype datasets"""
@@ -299,10 +299,10 @@ class GenotypeSearch(DoSearch):
FROM GenoXRef, GenoFreeze, Geno """
search_fields = ('Name', 'Chr')
-
+
header_fields = ['',
- 'Record ID',
- 'Location']
+ 'Record',
+ 'Location']
def get_fields_clause(self):
"""Generate clause for part of the WHERE portion of query"""
@@ -310,7 +310,7 @@ class GenotypeSearch(DoSearch):
# This adds a clause to the query that matches the search term
# against each field in search_fields (above)
fields_clause = []
-
+
if "'" not in self.search_term[0]:
self.search_term = "[[:<:]]" + self.search_term[0] + "[[:>:]]"
@@ -419,13 +419,13 @@ class LrsSearch(MrnaAssaySearch):
"""
DoSearch.search_types['LRS'] = 'LrsSearch'
-
+
def run(self):
-
+
self.search_term = [float(value) for value in self.search_term]
-
+
self.from_clause = ", Geno"
-
+
if self.search_operator == "=":
assert isinstance(self.search_term, (list, tuple))
self.lrs_min, self.lrs_max = self.search_term[:2]
@@ -444,8 +444,8 @@ class LrsSearch(MrnaAssaySearch):
self.sub_clause += """ Geno.Mb > %s and
Geno.Mb < %s and
""" % self.mescape(min(self.mb_low, self.mb_high),
- max(self.mb_low, self.mb_high))
- print("self.sub_clause is:", pf(self.sub_clause))
+ max(self.mb_low, self.mb_high))
+ print("self.sub_clause is:", pf(self.sub_clause))
else:
# Deal with >, <, >=, and <=
self.sub_clause = """ %sXRef.LRS %s %s and """ % self.mescape(self.dataset.type,
@@ -474,20 +474,20 @@ class CisTransLrsSearch(LrsSearch):
print("self.search_term is:", self.search_term)
self.search_term = [float(value) for value in self.search_term]
self.mb_buffer = 5 # default
-
+
self.from_clause = ", Geno "
if self.search_operator == "=":
if len(self.search_term) == 2:
self.lrs_min, self.lrs_max = self.search_term
#[int(value) for value in self.search_term]
-
+
elif len(self.search_term) == 3:
self.lrs_min, self.lrs_max, self.mb_buffer = self.search_term
-
+
else:
SomeError
-
+
self.sub_clause = """ %sXRef.LRS > %s and
%sXRef.LRS < %s and """ % (
escape(self.dataset.type),
@@ -510,12 +510,12 @@ class CisTransLrsSearch(LrsSearch):
%s.Chr = Geno.Chr""" % (
escape(self.dataset.type),
the_operator,
- escape(self.mb_buffer),
+ escape(self.mb_buffer),
escape(self.dataset.type),
escape(self.species_id),
escape(self.dataset.type)
)
-
+
print("where_clause is:", pf(self.where_clause))
self.query = self.compile_final_query(self.from_clause, self.where_clause)
@@ -560,7 +560,7 @@ class TransLrsSearch(CisTransLrsSearch):
(where the area is determined by the mb_buffer that the user can choose). Opposite of cis-eQTL.
"""
-
+
DoSearch.search_types['TRANSLRS'] = "TransLrsSearch"
def run(self):
@@ -573,7 +573,7 @@ class MeanSearch(MrnaAssaySearch):
DoSearch.search_types['MEAN'] = "MeanSearch"
def run(self):
-
+
self.search_term = [float(value) for value in self.search_term]
if self.search_operator == "=":
@@ -599,11 +599,11 @@ class MeanSearch(MrnaAssaySearch):
class RangeSearch(MrnaAssaySearch):
"""Searches for genes with a range of expression varying between two values"""
-
+
DoSearch.search_types['RANGE'] = "RangeSearch"
-
+
def run(self):
-
+
self.search_term = [float(value) for value in self.search_term]
if self.search_operator == "=":
@@ -632,10 +632,10 @@ class RangeSearch(MrnaAssaySearch):
class PositionSearch(DoSearch):
"""Searches for genes/markers located within a specified range on a specified chromosome"""
-
+
for search_key in ('POSITION', 'POS', 'MB'):
- DoSearch.search_types[search_key] = "PositionSearch"
-
+ DoSearch.search_types[search_key] = "PositionSearch"
+
def setup(self):
self.search_term = [float(value) for value in self.search_term]
self.chr, self.mb_min, self.mb_max = self.search_term[:3]
@@ -646,24 +646,24 @@ class PositionSearch(DoSearch):
self.dataset.type,
min(self.mb_min, self.mb_max),
self.dataset.type,
- max(self.mb_min, self.mb_max))
-
+ max(self.mb_min, self.mb_max))
+
def real_run(self):
self.query = self.compile_final_query(where_clause = self.where_clause)
- return self.execute(self.query)
+ return self.execute(self.query)
class MrnaPositionSearch(MrnaAssaySearch, PositionSearch):
"""Searches for genes located within a specified range on a specified chromosome"""
-
+
def run(self):
self.setup()
self.query = self.compile_final_query(where_clause = self.where_clause)
return self.execute(self.query)
-
+
class GenotypePositionSearch(GenotypeSearch, PositionSearch):
"""Searches for genes located within a specified range on a specified chromosome"""
@@ -673,12 +673,12 @@ class GenotypePositionSearch(GenotypeSearch, PositionSearch):
self.query = self.compile_final_query(where_clause = self.where_clause)
return self.execute(self.query)
-
+
class PvalueSearch(MrnaAssaySearch):
"""Searches for traits with a permutationed p-value between low and high"""
-
+
def run(self):
-
+
self.search_term = [float(value) for value in self.search_term]
if self.search_operator == "=":
@@ -703,19 +703,19 @@ class PvalueSearch(MrnaAssaySearch):
self.query = self.compile_final_query(where_clause = self.where_clause)
return self.execute(self.query)
-
+
class AuthorSearch(PhenotypeSearch):
"""Searches for phenotype traits with specified author(s)"""
-
- DoSearch.search_types["NAME"] = "AuthorSearch"
-
+
+ DoSearch.search_types["NAME"] = "AuthorSearch"
+
def run(self):
self.where_clause = """ Publication.Authors REGEXP "[[:<:]]%s[[:>:]]" and
""" % (self.search_term[0])
-
+
self.query = self.compile_final_query(where_clause = self.where_clause)
-
+
return self.execute(self.query)
@@ -741,7 +741,7 @@ if __name__ == "__main__":
dataset_name = "HC_M2_0606_P"
dataset = create_dataset(db_conn, dataset_name)
-
+
#cursor.execute("""
# SELECT ProbeSet.Name as TNAME, 0 as thistable,
# ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS,
@@ -769,4 +769,4 @@ if __name__ == "__main__":
#results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run()
#results = GoSearch("0045202", dataset, cursor, db_conn).run()
- print("results are:", pf(results)) \ No newline at end of file
+ print("results are:", pf(results))
diff --git a/wqflask/wqflask/model.py b/wqflask/wqflask/model.py
index c1ad0a78..cf9e58e1 100644
--- a/wqflask/wqflask/model.py
+++ b/wqflask/wqflask/model.py
@@ -10,7 +10,8 @@ from flask.ext.sqlalchemy import SQLAlchemy
from wqflask import app
-from sqlalchemy import Column, Integer, String, Table, ForeignKey, Unicode, Boolean, DateTime, Text
+from sqlalchemy import (Column, Integer, String, Table, ForeignKey, Unicode, Boolean, DateTime,
+ Text, Index)
from sqlalchemy.orm import relationship, backref
from wqflask.database import Base, init_db
@@ -98,10 +99,17 @@ class UserCollection(Base):
__tablename__ = "user_collection"
id = Column(Unicode(36), primary_key=True, default=lambda: unicode(uuid.uuid4()))
user = Column(Unicode(36), ForeignKey('user.id'))
- name = Column(Text)
+
+ # I'd prefer this to not have a length, but for the index below it needs one
+ name = Column(Unicode(50))
created_timestamp = Column(DateTime(), default=lambda: datetime.datetime.utcnow())
changed_timestamp = Column(DateTime(), default=lambda: datetime.datetime.utcnow())
members = Column(Text) # We're going to store them as a json list
# This index ensures a user doesn't have more than one collection with the same name
__table_args__ = (Index('usercollection_index', "user", "name"), )
+
+ @property
+ def num_members(self):
+ print("members are:", json.loads(self.members))
+ return len(json.loads(self.members))
diff --git a/wqflask/wqflask/static/packages/bootstrap/css/docs.css b/wqflask/wqflask/static/packages/bootstrap/css/docs.css
index 7efd72cd..967989a7 100644
--- a/wqflask/wqflask/static/packages/bootstrap/css/docs.css
+++ b/wqflask/wqflask/static/packages/bootstrap/css/docs.css
@@ -558,22 +558,6 @@ h2 + .row {
border-radius: 4px;
}
-/* Echo out a label for the example */
-.bs-docs-example:after {
- content: "Results";
- position: absolute;
- top: -1px;
- left: -1px;
- padding: 3px 7px;
- font-size: 12px;
- font-weight: bold;
- background-color: #f5f5f5;
- border: 1px solid #ddd;
- color: #9da0a4;
- -webkit-border-radius: 4px 0 4px 0;
- -moz-border-radius: 4px 0 4px 0;
- border-radius: 4px 0 4px 0;
-}
/* Remove spacing between an example and it's code */
.bs-docs-example + .prettyprint {
diff --git a/wqflask/wqflask/templates/admin/ind_user_manager.html b/wqflask/wqflask/templates/admin/ind_user_manager.html
index f99243ac..03a86e63 100644
--- a/wqflask/wqflask/templates/admin/ind_user_manager.html
+++ b/wqflask/wqflask/templates/admin/ind_user_manager.html
@@ -46,7 +46,7 @@
<td>Confirmed</td>
{% if user.confirmed_at %}
- <td>{{ timeago(user.confirmed_at) }}</td>
+ <td>{{ timeago(user.confirmed_at + "Z") }}</td>
{% else %}
<td><span class="label label-warning">Unconfirmed</span></td>
{% endif %}
@@ -55,7 +55,7 @@
<tr>
<td>Most recent login</td>
{% if user.most_recent_login %}
- <td>{{ timeago(user.most_recent_login.timestamp) }} from {{ user.most_recent_login.ip_address }}</td>
+ <td>{{ timeago(user.most_recent_login.timestamp.isoformat() + "Z") }} from {{ user.most_recent_login.ip_address }}</td>
{% else %}
<td><span class="label label-warning">Never</span></td>
{% endif %}
@@ -86,5 +86,5 @@
<script>
$('body').timeago();
</script>
-
+
{% endblock %}
diff --git a/wqflask/wqflask/templates/collections/list.html b/wqflask/wqflask/templates/collections/list.html
new file mode 100644
index 00000000..111d761f
--- /dev/null
+++ b/wqflask/wqflask/templates/collections/list.html
@@ -0,0 +1,50 @@
+{% extends "base.html" %}
+{% block title %}Your Collections{% endblock %}
+{% block content %}
+<!-- Start of body -->
+ {{ header("Your Collections",
+ 'You have {}.'.format(numify(user_collections|count, "collection", "collections"))) }}
+
+ <div class="container">
+ <div class="page-header">
+ <h1>Collections owned by {{ g.user_session.user_ob.full_name }}</h1>
+ </div>
+
+ <div class="bs-docs-example">
+ <table class="table table-hover" id='trait_table'>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Created</th>
+ <th>Last Changed</th>
+ <th># Records</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for uc in user_collections %}
+ <tr>
+ <td><a href="{{ url_for('view_collection', uc_id=uc.id) }}">{{ uc.name }}</a></td>
+ <td>{{ timeago(uc.created_timestamp.isoformat() + "Z") }}</td>
+ <td>{{ timeago(uc.changed_timestamp.isoformat() + "Z") }}</td>
+ <td>{{ uc.num_members }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+
+ </div>
+ </div>
+
+<!-- End of body -->
+
+{% endblock %}
+
+{% block js %}
+
+ <script type="text/javascript" src="/static/packages/smart-time-ago/lib/timeago.js"></script>
+ <script>
+ $('body').timeago();
+ </script>
+
+{% endblock %}
diff --git a/wqflask/wqflask/templates/collections/view.html b/wqflask/wqflask/templates/collections/view.html
index 3fa83d4a..0ab004d9 100644
--- a/wqflask/wqflask/templates/collections/view.html
+++ b/wqflask/wqflask/templates/collections/view.html
@@ -3,73 +3,64 @@
{% block content %}
<!-- Start of body -->
{{ header(uc.name,
- 'This collection has {}.'.format(numify(results|count, "record", "records"))) }}
+ 'This collection has {}.'.format(numify(trait_obs|count, "record", "records"))) }}
- <div class="bs-docs-example">
- <table class="table table-hover" id='trait_table'>
- <thead>
- <tr>
- <th>Dataset</th>
- <th>Traid ID</th>
- <th>Symbol</th>
- <th>Description</th>
- <th>Location</th>
- <th>Mean</th>
- <th>N</th>
- <th>Max LRS</th>
- <th>Max LRS Location</th>
- </tr>
- </thead>
+ <div class="container">
+ <div class="page-header">
+ <h1>Your Collection</h1>
+ </div>
- <tbody>
- {% for this_trait in trait_obs %}
- <TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}">
- <TD>
- <INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox"
- VALUE="{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }}">
- </TD>
- <TD>
- <a href="{{ url_for('show_trait_page',
- trait_id = this_trait.name,
- dataset = this_trait.dataset.name
- )}}">
- {{ this_trait.name }}
- </a>
- </TD>
- {% if this_trait.dataset.type == 'ProbeSet' %}
- <TD>{{ this_trait.symbol }}</TD>
- <TD>{{ this_trait.description_display }}</TD>
- <TD>{{ this_trait.location_repr }}</TD>
- <TD>{{ this_trait.mean }}</TD>
- <TD>{{ this_trait.LRS_score_repr }}</TD>
- <TD>{{ this_trait.LRS_location_repr }}</TD>
- {% elif this_trait.dataset.type == 'Publish' %}
- <TD>{{ this_trait.description_display }}</TD>
- <TD>{{ this_trait.authors }}</TD>
+ <div class="bs-docs-example">
+ <table class="table table-hover" id='trait_table'>
+ <thead>
+ <tr>
+ <th></th>
+ <th>Record</th>
+ <th>Description</th>
+ <th>Location</th>
+ <th>Mean</th>
+ <th>Max LRS</th>
+ <th>Max LRS Location</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for this_trait in trait_obs %}
+ <TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}">
<TD>
- <a href="{{ this_trait.pubmed_link }}">
- {{ this_trait.pubmed_text }}
+ <INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox"
+ VALUE="{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }}">
+ </TD>
+ <TD>
+ <a href="{{ url_for('show_trait_page',
+ trait_id = this_trait.name,
+ dataset = this_trait.dataset.name
+ )}}">
+ {{ this_trait.name }}
</a>
</TD>
+
+ <TD>{{ this_trait.description_display }}</TD>
+ <TD>{{ this_trait.location_repr }}</TD>
+ <TD>{{ this_trait.mean }}</TD>
<TD>{{ this_trait.LRS_score_repr }}</TD>
<TD>{{ this_trait.LRS_location_repr }}</TD>
- {% elif this_trait.dataset.type == 'Geno' %}
- <TD>{{ this_trait.location_repr }}</TD>
- {% endif %}
- </TR>
- {% endfor %}
- </tbody>
- </table>
+ </TR>
+ {% endfor %}
+ </tbody>
+
+ </table>
- <br />
+ <br />
- <button class="btn" id="select_all"><i class="icon-ok"></i> Select All</button>
- <button class="btn" id="deselect_all"><i class="icon-remove"></i> Deselect All</button>
- <button class="btn" id="invert"><i class="icon-resize-vertical"></i> Invert</button>
- <button class="btn" id="add"><i class="icon-plus-sign"></i> Add</button>
- <button class="btn btn-primary pull-right"><i class="icon-download icon-white"></i> Download Table</button>
-</div>
+ <button class="btn" id="select_all"><i class="icon-ok"></i> Select All</button>
+ <button class="btn" id="deselect_all"><i class="icon-remove"></i> Deselect All</button>
+ <button class="btn" id="invert"><i class="icon-resize-vertical"></i> Invert</button>
+ <button class="btn" id="add"><i class="icon-plus-sign"></i> Add</button>
+ <button class="btn btn-primary pull-right"><i class="icon-download icon-white"></i> Download Table</button>
+ </div>
+ </div>
<!-- End of body -->