about summary refs log tree commit diff
path: root/wqflask/utility/redis_tools.py
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/redis_tools.py
parent187cd40bd3273b50d2813bfccf98bfadbb8c14ff (diff)
parentef51e08753defdfc7f3e67f8788cd1362d2cf631 (diff)
downloadgenenetwork2-e2b04a322f26670782fe7f7c39bcebc508fdabdd.tar.gz
Merge branch 'testing' of github.com:genenetwork/genenetwork2 into acenteno
Diffstat (limited to 'wqflask/utility/redis_tools.py')
-rw-r--r--wqflask/utility/redis_tools.py271
1 files changed, 230 insertions, 41 deletions
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))