Ejemplo n.º 1
0
class UserManager:
    def __init__(self, redis_manager):
        self.redis = redis_manager
        self.requests_prefix = "req/{}"
        self.emails = RedisSet('users')
        self.displayNames = RedisSet('displayNames')

    def create_user(self, email):
        session_id = self.redis.get_value("usersession: {}".format(email))
        user_data = RedisHash(email).to_dict()
        if session_id and user_data:
            return User(user_data['school'], email, user_data['displayName'],
                        session_id)
        return None

    def store_user_in_redis(self, email, password_hash, school, display_name):
        self.emails.add(email)
        self.displayNames.add(display_name)
        user_data = {'school': school, 'displayName': display_name}
        RedisHash(email).update(user_data)
        self.redis.set("hash: {}".format(email), password_hash)

    def made_request(self, email, request_id):
        return RedisSet("req/{}".format(email)).add([request_id])

    def remove_request(self, email, request_id):
        return RedisSet("req/{}".format(email)).remove(request_id)

    def made_post(self, email, post_id):
        return RedisSet("posts/{}".format(email)).add([post_id])

    def created_content(self, email, content_id):
        return RedisSet("content/{}".format(email)).add(content_id)
Ejemplo n.º 2
0
 def __init__(self):
     self.displayNames = RedisSet("displayNames")
     self.nouns = []
     self.adjectives = []
     with open("resources/nouns.txt", "r") as f:
         self.nouns = [line.strip('\n') for line in f if line.strip('\n')]
     with open("resources/adjectives_names.txt", "r") as f:
         self.adjectives = [line.strip('\n') for line in f if line]
Ejemplo n.º 3
0
 def __init__(self, redis_values, post_store, upload_store, listing_store,
              reply_store, auth_manager):
     self.redis = redis_values
     self.post = post_store
     self.upload = upload_store
     self.listing = listing_store
     self.reply = reply_store
     self.auth = auth_manager
     self.request_ids = RedisSet("requests")
Ejemplo n.º 4
0
    def create_listing(self, request):
        """
        Create a listing for a school's page.
        :param request: request data to promote to listing
        :return: listing ID if successful, otherwise None
        """
        school_id = request["sid"]
        user_email = request["uid"]
        # get new listing_id
        listing_id = self.name_provider.generate_listing_id(
            user_email, school_id)

        # upload files
        new_upload_id = self.name_provider.generate_upload_id(listing_id)
        filepaths = self.upload.promote_uploads(request["upload_id"],
                                                new_upload_id)
        RedisSet(new_upload_id).add(filepaths)

        # store listing data in redis
        return super().make_content(
            listing_id, {
                "sid": school_id,
                "title": request["title"],
                "course": request["course"],
                "kind": request["kind"],
                "uid": user_email,
                "email": request["email"],
                "upload_id": new_upload_id,
                "time": request["time"]
            })
Ejemplo n.º 5
0
 def get_posts(self, school_id):
     """
     Get all existing posts for school.
     :param school_id: ID of school
     :return: dict containing all posts for school
     """
     posts = {}
     post_set_key = self.name_provider.set_names.post(school_id)
     for post_id in RedisSet(post_set_key).values():
         posts[post_id] = super().get_content(post_id)
     app.logger.debug("fetched {} posts for sid {}".format(len(posts), school_id))
     return posts
Ejemplo n.º 6
0
 def get_replies(self, content_id):
     """
     Get all existing replies for content with given ID
     :param content_id: ID of content
     :return: dict containing all replies
     """
     replies = {}
     reply_set_key = self.name_provider.set_names.reply(content_id)
     for reply_id in RedisSet(reply_set_key).values():
         replies[reply_id] = super().get_content(reply_id)
     app.logger.debug("fetched {} replies for content {}".format(
         len(replies), content_id))
     return replies
Ejemplo n.º 7
0
    def generate(self, prefix, email, set_name):
        """
        Generate unique ID, recursively regenerate on collision. Store unique ID
        in redis set named set_name.
        :param email: email of user (used for creating hash)
        :param prefix: prefix to give to ID
        :param set_name: name of Redis set to look for ID collisions
        :return: string containing ID
        """
        identifier = self._create_id_hash(prefix, email)

        # ensure id is unique (no collisions)
        if RedisSet(set_name).add([identifier]) == 0:
            return self.generate(prefix, email, set_name)
        return identifier
Ejemplo n.º 8
0
 def get_listings(self, school_id):
     """
     Get all existing listings for school.
     :param school_id: ID of school to get listings from
     :return: dict containing all listing data for school
     """
     listings = {}
     listing_set_key = self.name_provider.set_names.listing(school_id)
     for listing_id in RedisSet(listing_set_key).values():
         try:
             listings[listing_id] = self.get_listing(listing_id)
         except Exception as e:
             app.logger.error("failed to fetch listing with id {}\n{}",
                              listing_id, str(e))
     app.logger.debug("fetched {} listings for sid {}".format(
         len(listings), school_id))
     return listings
Ejemplo n.º 9
0
class UserCache:
    def __init__(self):
        self.name_provider = NameProvider()
        self.cached = RedisSet(self.name_provider.set_names.cached_ips)

    def is_cached(self, ip_address):
        """
        Returns whether or not IP address is cached
        :param ip_address: IP address to check
        :return: boolean indicating if IP is cached
        """
        key = self._get_key_for(ip_address)
        return self.cached.exists(key)

    def get(self, ip_address):
        """
        Returns cached data for IP address
        :param ip_address: IP address to get cached data for
        :return: dict containing cached data
        """
        key = self._get_key_for(ip_address)
        return RedisHash(key).to_dict()

    def set(self, ip_address, data):
        """
        Sets cached data for given IP address
        :param ip_address: IP address to set cached data for
        :param data: data to set in cache
        """
        key = self._get_key_for(ip_address)
        return RedisHash(key).update(data)

    def delete(self, ip_address, key_to_delete):
        """
        Removes (key, value) pair from IP address hash
        :param ip_address: IP address of cached data
        :param key_to_delete: key to delete
        """
        ip_address_key = self._get_key_for(ip_address)
        return RedisHash(ip_address_key).delete(key_to_delete)

    def _get_key_for(self, ip_address):
        """
        Returns redis key for ip address cached data
        """
        return "{}{}".format(self.name_provider.prefixes.ip, ip_address)
Ejemplo n.º 10
0
class UsernameGenerator:
    def __init__(self):
        self.displayNames = RedisSet("displayNames")
        self.nouns = []
        self.adjectives = []
        with open("resources/nouns.txt", "r") as f:
            self.nouns = [line.strip('\n') for line in f if line.strip('\n')]
        with open("resources/adjectives_names.txt", "r") as f:
            self.adjectives = [line.strip('\n') for line in f if line]

    def get_username(self):
        return random.choice(self.adjectives) + random.choice(self.nouns)

    def get_usernames_in_bulk(self, count=50):
        usernames = []
        while len(usernames) < count:
            username = self.get_username()
            if not self.displayNames.exists(username):
                usernames += [username]
        return usernames
Ejemplo n.º 11
0
    def request_listing(self, form_data, file):
        """
        Request to create a listing in a school's page.
        :param form_data: raw form data submitted by user
        :param file: flask file object for uploaded PDF document
        :return: request ID if successful, otherwise None
        """
        if not super().validate_data(form_data):
            return False
        # get new request_id
        request_id = self.name_provider.generate_request_id(super().user_email)
        if request_id is None:
            return False

        # upload files
        upload_id = self.name_provider.generate_upload_id(request_id)
        filepaths, numPages = self.upload.add_file_to_listing(file, upload_id)
        if len(filepaths) == 0:
            app.logger.error("Error: no filepaths were created")
            return False
        if RedisSet(upload_id).add(filepaths) != len(filepaths):
            app.logger.error(
                "Error: not all filepaths were added to set {}".format(
                    upload_id))
            return False

        # store request data in redis
        return super().request_content(
            request_id, {
                "sid": self.school.get_school_id(form_data["school"]),
                "title": form_data["title"],
                "course": form_data["cid"],
                "kind": form_data["kind"],
                "uid": super().display_name,
                "email": super().user_email,
                "upload_id": upload_id,
                "numPages": numPages,
                "requestId": request_id
            })
Ejemplo n.º 12
0
 def made_request(self, email, request_id):
     return RedisSet("req/{}".format(email)).add([request_id])
Ejemplo n.º 13
0
 def __init__(self):
     self.name_provider = NameProvider()
     self.cached = RedisSet(self.name_provider.set_names.cached_ips)
Ejemplo n.º 14
0
 def created_content(self, email, content_id):
     return RedisSet("content/{}".format(email)).add(content_id)
Ejemplo n.º 15
0
 def made_post(self, email, post_id):
     return RedisSet("posts/{}".format(email)).add([post_id])
Ejemplo n.º 16
0
 def remove_request(self, email, request_id):
     return RedisSet("req/{}".format(email)).remove(request_id)
Ejemplo n.º 17
0
 def __init__(self, redis_manager):
     self.redis = redis_manager
     self.requests_prefix = "req/{}"
     self.emails = RedisSet('users')
     self.displayNames = RedisSet('displayNames')
Ejemplo n.º 18
0
class RequestStore:
    """
    Class for managing request data. A request is created each time a user wants to submit
    content to GradeTip. Once that content is approved by moderators, the request is deleted and replaced
    by the corresponding content data type.
    """
    def __init__(self, redis_values, post_store, upload_store, listing_store,
                 reply_store, auth_manager):
        self.redis = redis_values
        self.post = post_store
        self.upload = upload_store
        self.listing = listing_store
        self.reply = reply_store
        self.auth = auth_manager
        self.request_ids = RedisSet("requests")

    def get_all_requests(self):
        """
        Gets all requests submitted to GradeTip.
        :return: dict containing request_ids as keys and request data as values
        """
        if not request.headers or not self.auth.validate_headers(
                request.headers):
            return jsonify({}), 404
        requests = {}
        for request_id in self.request_ids.values():
            request_data = self.get_request(request_id)
            if request_data.get("requestType") == "listing":
                request_data["preview"] = self.upload.get_preview_from_listing(
                    request_data["upload_id"])
                del request_data["upload_id"]
            app.logger.debug("request: {}".format(request_data))
            requests[request_id] = request_data
        app.logger.debug("fetched {} requests".format(len(requests)))
        return requests

    def delete_request(self, request_id):
        """
        Deletes request and relevant request data.
        :param request_id: ID of request to be deleted
        :return: boolean indicating success of operation
        """
        app.logger.info("deleting request with id: {}".format(request_id))
        id_deleted = self.request_ids.remove(request_id)
        hash_deleted = self.redis.remove(request_id)
        return id_deleted and hash_deleted

    def pop_request(self, request_id):
        """
        Retrieves request with ID request_id and then deletes that request.
        :param request_id: ID of request to find
        :return: dict containing request data
        """
        request_data = self.get_request(request_id)
        self.delete_request(request_id)
        return request_data

    def get_request(self, request_id):
        """
        Retrieves request with ID request_id.
        :param request_id: ID of request to find
        :return: dict containing request data
        """
        app.logger.debug("fetching request with id: {}".format(request_id))
        request_data = RedisHash(request_id).to_dict()
        app.logger.debug("request id {} has data {}".format(
            request_id, request_data))
        return request_data

    def approve_request(self, request_id):
        """
        Deletes request and promotes request data to a public post.
        :param request_id:
        :return: JSON with result of operation
        """
        app.logger.info("approving request with id: {}".format(request_id))
        request_data = self.pop_request(request_id)
        result = False
        if request_data is not None:
            request_type = request_data.get("requestType")
            if request_type == "textpost":
                result = self.post.create_post(request_data)
            elif request_type == "listing":
                result = self.listing.create_listing(request_data)
            elif request_type == "reply":
                result = self.reply.create_reply(request_data)
            else:
                app.logger.error(
                    "Unknown request type {}".format(request_type))
        return jsonify({"result": result})

    def deny_request(self, request_id):
        """
        Deletes request and takes no further action
        :param request_id:
        :return: JSON with result of operation
        """
        app.logger.info("denying request with id: {}".format(request_id))
        request_data = self.pop_request(request_id)
        if request_data is not None and request_data.get(
                "requestType") == "listing":
            return jsonify(
                {"result": self.redis.remove(request_data["upload_id"])})
        return jsonify({"result": False})