diff options
Diffstat (limited to 'wqflask/wqflask/collect.py')
-rw-r--r-- | wqflask/wqflask/collect.py | 328 |
1 files changed, 197 insertions, 131 deletions
diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index 4ea8407c..7e7aba89 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -15,35 +15,26 @@ import urlparse import simplejson as json -#from sqlalchemy import orm - -#from redis import StrictRedis import redis Redis = redis.StrictRedis() - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash, jsonify) from wqflask import app - from pprint import pformat as pf - from wqflask.database import db_session from wqflask import model +from wqflask import user_manager from utility import Bunch, Struct from utility.formatting import numify -from wqflask import user_manager - - from base import trait - def get_collection(): if g.user_session.logged_in: return UserCollection() @@ -54,39 +45,112 @@ def get_collection(): class AnonCollection(object): """User is not logged in""" - def __init__(self): - self.anon_user = user_manager.AnonUser() - self.key = "anon_collection:v5:{}".format(self.anon_user.anon_id) - - def add_traits(self, params, collection_name): - assert collection_name == "Default", "Unexpected collection name for anonymous user" - print("params[traits]:", params['traits']) - traits = process_traits(params['traits']) - print("traits is:", traits) - print("self.key is:", self.key) - len_before = len(Redis.smembers(self.key)) - Redis.sadd(self.key, *list(traits)) - Redis.expire(self.key, 60 * 60 * 24 * 3) - print("currently in redis:", Redis.smembers(self.key)) - len_now = len(Redis.smembers(self.key)) - report_change(len_before, len_now) + def __init__(self, collection_name): + anon_user = user_manager.AnonUser() + self.key = anon_user.key + self.name = collection_name + self.id = None + self.created_timestamp = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + self.changed_timestamp = self.created_timestamp #ZS: will be updated when changes are made + + #ZS: Find id and set it if the collection doesn't already exist + if Redis.get(self.key) == "None" or Redis.get(self.key) == None: + Redis.set(self.key, None) #ZS: For some reason I get the error "Operation against a key holding the wrong kind of value" if I don't do this + else: + collections_list = json.loads(Redis.get(self.key)) + collection_position = 0 #ZS: Position of collection in collection_list, if it exists + collection_exists = False + for i, collection in enumerate(collections_list): + if collection['name'] == self.name: + collection_position = i + collection_exists = True + self.id = collection['id'] + break + if self.id == None: + self.id = str(uuid.uuid4()) + + def get_members(self): + traits = [] + collections_list = json.loads(Redis.get(self.key)) + for collection in collections_list: + if collection['id'] == self.id: + traits = collection['members'] + return traits + + @property + def num_members(self): + num_members = 0 + collections_list = json.loads(Redis.get(self.key)) + for collection in collections_list: + if collection['id'] == self.id: + num_members = collection['num_members'] + return num_members + + def add_traits(self, params): + #assert collection_name == "Default", "Unexpected collection name for anonymous user" + self.traits = list(process_traits(params['traits'])) + #len_before = len(Redis.smembers(self.key)) + existing_collections = Redis.get(self.key) + print("existing_collections:", existing_collections) + if existing_collections != None and existing_collections != "None": + collections_list = json.loads(existing_collections) + collection_position = 0 #ZS: Position of collection in collection_list, if it exists + collection_exists = False + for i, collection in enumerate(collections_list): + if collection['id'] == self.id: + collection_position = i + collection_exists = True + break + if collection_exists: + collections_list[collection_position]['members'].extend(self.traits) + collections_list[collection_position]['num_members'] = len(collections_list[collection_position]['members']) + collections_list[collection_position]['changed_timestamp'] = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + else: + collection_dict = {"id" : self.id, + "name" : self.name, + "created_timestamp" : self.created_timestamp, + "changed_timestamp" : self.changed_timestamp, + "num_members" : len(self.traits), + "members" : self.traits} + collections_list.append(collection_dict) + else: + collections_list = [] + collection_dict = {"id" : self.id, + "name" : self.name, + "created_timestamp" : self.created_timestamp, + "changed_timestamp" : self.changed_timestamp, + "num_members" : len(self.traits), + "members" : self.traits} + collections_list.append(collection_dict) + + Redis.set(self.key, json.dumps(collections_list)) + #Redis.sadd(self.key, *list(traits)) + #Redis.expire(self.key, 60 * 60 * 24 * 5) + #len_now = len(Redis.smembers(self.key)) + #report_change(len_before, len_now) def remove_traits(self, params): - traits_to_remove = params.getlist('traits[]') - print("traits_to_remove:", process_traits(traits_to_remove)) - len_before = len(Redis.smembers(self.key)) - Redis.srem(self.key, traits_to_remove) - print("currently in redis:", Redis.smembers(self.key)) - len_now = len(Redis.smembers(self.key)) + traits_to_remove = [(":").join(trait.split(":")[:2]) for trait in params.getlist('traits[]')] + existing_collections = Redis.get(self.key) + collection_position = 0 + collections_list = json.loads(existing_collections) + for i, collection in enumerate(collections_list): + if collection['id'] == self.id: + collection_position = i + collection_exists = True + break + collections_list[collection_position]['members'] = [trait for trait in collections_list[collection_position]['members'] if trait not in traits_to_remove] + collections_list[collection_position]['num_members'] = len(collections_list[collection_position]['members']) + collections_list[collection_position]['changed_timestamp'] = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + len_now = collections_list[collection_position]['num_members'] + #print("before in redis:", json.loads(Redis.get(self.key))) + Redis.set(self.key, json.dumps(collections_list)) + #print("currently in redis:", json.loads(Redis.get(self.key))) # We need to return something so we'll return this...maybe in the future # we can use it to check the results return str(len_now) - def get_traits(self): - traits = Redis.smembers(self.key) - print("traits:", traits) - return traits class UserCollection(object): """User is logged in""" @@ -101,12 +165,19 @@ class UserCollection(object): return create_new("Default") else: uc = model.UserCollection.query.get(params['existing_collection']) - members = uc.members_as_set() #set(json.loads(uc.members)) + members = list(uc.members_as_set()) #set(json.loads(uc.members)) len_before = len(members) traits = process_traits(params['traits']) - - members_now = list(members | traits) + + members_now = members + for trait in traits: + if trait in members: + continue + else: + members_now.append(trait) + + #members_now = list(members | traits) len_now = len(members_now) uc.members = json.dumps(members_now) @@ -120,28 +191,6 @@ class UserCollection(object): # Probably have to change that return redirect(url_for('view_collection', uc_id=uc.id)) - def remove_traits(self, params): - - #params = request.form - print("params are:", params) - uc_id = params['uc_id'] - uc = model.UserCollection.query.get(uc_id) - traits_to_remove = params.getlist('traits[]') - print("traits_to_remove are:", traits_to_remove) - traits_to_remove = process_traits(traits_to_remove) - print("\n\n after processing, traits_to_remove:", traits_to_remove) - all_traits = uc.members_as_set() - print(" all_traits:", all_traits) - members_now = all_traits - traits_to_remove - print(" members_now:", members_now) - print("Went from {} to {} members in set.".format(len(all_traits), len(members_now))) - uc.members = json.dumps(list(members_now)) - uc.changed_timestamp = datetime.datetime.utcnow() - db_session.commit() - - # We need to return something so we'll return this...maybe in the future - # we can use it to check the results - return str(len(members_now)) def report_change(len_before, len_now): new_length = len_now - len_before @@ -154,8 +203,6 @@ def report_change(len_before, len_now): print("No new traits were added.") - - @app.route("/collections/add") def collections_add(): traits=request.args['traits'] @@ -164,90 +211,107 @@ def collections_add(): user_collections = g.user_session.user_ob.user_collections print("user_collections are:", user_collections) return render_template("collections/add.html", - traits=traits, - user_collections = user_collections, + traits = traits, + collections = user_collections, ) else: - return render_template("collections/add_anonymous.html", - traits=traits - ) + anon_collections = user_manager.AnonUser().get_collections() + collection_names = [] + for collection in anon_collections: + print("COLLECTION:", collection) + collection_names.append({'id':collection['id'], 'name':collection['name']}) + return render_template("collections/add.html", + traits = traits, + collections = collection_names, + ) @app.route("/collections/new") def collections_new(): params = request.args - print("request.args in collections_new are:", params) + #print("request.args in collections_new are:", params) + collection_name = params['new_collection'] + if "anonymous_add" in params: - AnonCollection().add_traits(params, "Default") + AnonCollection(name=collection_name).add_traits(params, "Default") return redirect(url_for('view_collection')) - elif "sign_in" in params: + if "sign_in" in params: return redirect(url_for('login')) - collection_name = params['new_collection'] - if "create_new" in params: print("in create_new") return create_new(collection_name) elif "add_to_existing" in params: print("in add to existing") - return UserCollection().add_traits(params, collection_name) + if g.user_session.logged_in: + return UserCollection().add_traits(params, collection_name) + else: + ac = AnonCollection(collection_name) + ac.add_traits(params) + return redirect(url_for('view_collection', collection_id=ac.id)) else: print("ELSE") CauseAnError def process_traits(unprocessed_traits): - print("unprocessed_traits are:", unprocessed_traits) + #print("unprocessed_traits are:", unprocessed_traits) if isinstance(unprocessed_traits, basestring): unprocessed_traits = unprocessed_traits.split(",") traits = set() for trait in unprocessed_traits: - print("trait is:", trait) + #print("trait is:", trait) data, _separator, hmac = trait.rpartition(':') data = data.strip() - print("data is:", data) - print("hmac is:", hmac) assert hmac==user_manager.actual_hmac_creation(data), "Data tampering?" - traits.add(str(data)) + traits.add (str(data)) return traits def create_new(collection_name): params = request.args - uc = model.UserCollection() - uc.name = collection_name - print("user_session:", g.user_session.__dict__) - uc.user = g.user_session.user_id + unprocessed_traits = params['traits'] - traits = process_traits(unprocessed_traits) - - uc.members = json.dumps(list(traits)) - print("traits are:", traits) - - db_session.add(uc) - db_session.commit() - - print("Created: " + uc.name) - return redirect(url_for('view_collection', uc_id=uc.id)) + + if g.user_session.logged_in: + uc = model.UserCollection() + uc.name = collection_name + print("user_session:", g.user_session.__dict__) + uc.user = g.user_session.user_id + uc.members = json.dumps(list(traits)) + db_session.add(uc) + db_session.commit() + return redirect(url_for('view_collection', uc_id=uc.id)) + else: + current_collections = user_manager.AnonUser().get_collections() + ac = AnonCollection(collection_name) + ac.changed_timestamp = datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + ac.add_traits(params) + print("Collection ID:", ac.id) + return redirect(url_for('view_collection', collection_id=ac.id)) @app.route("/collections/list") def list_collections(): params = request.args - try: + print("PARAMS:", params) + if g.user_session.logged_in: user_collections = list(g.user_session.user_ob.user_collections) print("user_collections are:", user_collections) return render_template("collections/list.html", params = params, - user_collections = user_collections, + collections = user_collections, ) - except: - return redirect(url_for('view_collection')) + else: + anon_collections = user_manager.AnonUser().get_collections() + print("anon_collections are:", anon_collections) + return render_template("collections/list.html", + params = params, + collections = anon_collections) @app.route("/collections/remove", methods=('POST',)) def remove_traits(): - params = request.form print("params are:", params) @@ -255,19 +319,17 @@ def remove_traits(): uc_id = params['uc_id'] uc = model.UserCollection.query.get(uc_id) traits_to_remove = params.getlist('traits[]') - print("traits_to_remove are:", traits_to_remove) traits_to_remove = process_traits(traits_to_remove) print("\n\n after processing, traits_to_remove:", traits_to_remove) all_traits = uc.members_as_set() - print(" all_traits:", all_traits) members_now = all_traits - traits_to_remove print(" members_now:", members_now) - print("Went from {} to {} members in set.".format(len(all_traits), len(members_now))) uc.members = json.dumps(list(members_now)) uc.changed_timestamp = datetime.datetime.utcnow() db_session.commit() else: - members_now = AnonCollection().remove_traits(params) + collection_name = params['collection_name'] + members_now = AnonCollection(collection_name).remove_traits(params) # We need to return something so we'll return this...maybe in the future @@ -279,32 +341,43 @@ def remove_traits(): def delete_collection(): params = request.form print("params:", params) - uc_id = params['uc_id'] - uc = model.UserCollection.query.get(uc_id) - # Todo: For now having the id is good enough since it's so unique - # But might want to check ownership in the future - collection_name = uc.name - db_session.delete(uc) - db_session.commit() - flash("We've deletet the collection: {}.".format(collection_name), "alert-info") + if g.user_session.logged_in: + uc_id = params['uc_id'] + uc = model.UserCollection.query.get(uc_id) + # Todo: For now having the id is good enough since it's so unique + # But might want to check ownership in the future + collection_name = uc.name + db_session.delete(uc) + db_session.commit() + else: + collection_name = params['collection_name'] + user_manager.AnonUser().delete_collection(collection_name) + + flash("We've deleted the collection: {}.".format(collection_name), "alert-info") return redirect(url_for('list_collections')) - @app.route("/collections/view") def view_collection(): params = request.args print("PARAMS in view collection:", params) - #if "uc_id" in params: - uc_id = params['uc_id'] - uc = model.UserCollection.query.get(uc_id) - traits = json.loads(uc.members) - print("traits are:", traits) - #else: - # traits = AnonCollection().get_traits() - + if "uc_id" in params: + uc_id = params['uc_id'] + uc = model.UserCollection.query.get(uc_id) + traits = json.loads(uc.members) + print("traits are:", traits) + else: + user_collections = json.loads(Redis.get(user_manager.AnonUser().key)) + this_collection = {} + for collection in user_collections: + if collection['id'] == params['collection_id']: + this_collection = collection + break + #this_collection = user_collections[params['collection_id']] + traits = this_collection['members'] + print("in view_collection traits are:", traits) trait_obs = [] @@ -312,29 +385,22 @@ def view_collection(): for atrait in traits: print("atrait is:", atrait) - name, dataset_name = atrait.split(':') - + name, dataset_name = atrait.split(':') + trait_ob = trait.GeneralTrait(name=name, dataset_name=dataset_name) trait_ob.retrieve_info(get_qtl_info=True) trait_obs.append(trait_ob) json_version.append(trait_ob.jsonable()) - #json_version.append(dict(name=trait_ob.name, - # description=trait_ob.description_display, - # location=trait_ob.location_repr, - # mean=trait_ob.mean, - # lrs_score=trait_ob.LRS_score_repr, - # lrs_location=trait_ob.LRS_location_repr)) - # dis=trait_ob.description)) - #json_version.append(trait_ob.__dict__th) print("trait_obs:", trait_obs) if "uc_id" in params: collection_info = dict(trait_obs=trait_obs, - uc = uc) + uc = uc) else: - collection_info = dict(trait_obs=trait_obs) + collection_info = dict(trait_obs=trait_obs, + collection_name=this_collection['name']) if "json" in params: print("json_version:", json_version) return json.dumps(json_version) |