<commit_before>""" Module for interacting with the achievements """

import imp
import pymongo

import api

from functools import wraps
from os.path import join
from datetime import datetime
from voluptuous import Schema, Required, Range
from api.common import check, InternalException, SevereInternalException, validate, safe_fail, WebException

processor_base_path = "./processors"

achievement_schema = Schema({
    Required("name"): check(
        ("The achievement's display name must be a string.", [str])),
    Required("score"): check(
        ("Score must be a positive integer.", [int, Range(min=0)])),
    Required("event"): check(
        ("Type must be a string.", [str])),
    Required("description"): check(
        ("The description must be a string.", [str])),
    Required("processor"): check(
        ("The processor path must be a string.", [str])),
    Required("hidden"): check(
        ("An achievement's hidden state is either True or False.", [
            lambda hidden: type(hidden) == bool])),
    Required("image"): check(
        ("An achievement's image path must be a string.", [str])),
    "disabled": check(
        ("An achievement's disabled state is either True or False.", [
            lambda disabled: type(disabled) == bool])),
    "aid": check(
        ("You should not specify a aid for an achievement.", [lambda _: False])),
    "_id": check(
        ("Your achievements should not already have _ids.", [lambda id: False]))
})

def get_all_events(show_disabled=False):
    """
    Gets the set of distinct achievement events.

    Args:
        show_disabled: Whether to include events that are only on disabled achievements
    Returns:
        The set of distinct achievement events.
    """

    db = api.common.get_conn()

    match = {}
    if not show_disabled:
        match.update({"disabled": False})

    return db.achievemets.find(match).distinct("event")

def get_achievement(aid=None, name=None, show_disabled=False):
    """
    Gets a single achievement

    Args:
        aid: the achievement id
        name: the name of the achievement
        show_disabled: Boolean indicating whether or not to show disabled achievements.
    """

    db = api.common.get_conn()

    match = {}

    if aid is not None:
        match.update({'aid': aid})
    elif name is not None:
        match.update({'name': name})
    else:
        raise InternalException("Must supply aid or display name")

    if not show_disabled:
        match.update({"disabled": False})

    db = api.common.get_conn()
    achievement = db.achievements.find_one(match, {"_id":0})

    if achievement is None:
        raise SevereInternalException("Could not find achievement! You gave " + str(match))

    return achievement

def get_all_achievements(event=None, show_disabled=False):
    """
    Gets all of the achievements in the database.

    Args:
        event: Optional parameter to restrict which achievements are returned
        show_disabled: Boolean indicating whether or not to show disabled achievements.
    Returns:
        List of achievements from the database
    """

    db = api.common.get_conn()

    match = {}
    if event is not None:
        match.update({'event': event})

    if not show_disabled:
        match.update({'disabled': False})

    return list(db.achievements.find(match, {"_id":0}).sort('score', pymongo.ASCENDING))

def get_earned_achievement_entries(tid=None, uid=None, aid=None):
    """
    Gets the solved achievements for a given team or user.

    Args:
        tid: The team id
        event: Optional parameter to restrict which achievements are returned
    Returns:
        List of solved achievements
    """

    db = api.common.get_conn()

    match = {}

    if uid is not None:
        match.update({"uid": uid})
    elif tid is not None:
        match.update({"tid": tid})

    if aid is not None:
        match.update({"aid": aid})

    return list(db.earned_achievements.find(match, {"_id":0}))

def get_earned_aids(tid=None, uid=None, aid=None):
    """
    Gets the solved aids for a given team or user.

    Args:
        tid: The team id
        event: Optional parameter to restrict which achievements are returned
    Returns:
        List of solved achievement ids
    """

    return [a["aid"] for a in get_earned_achievement_entries(tid=tid, uid=uid, aid=aid)]

def set_earned_achievements_seen(tid=None, uid=None):
    """
    Sets all earned achievements from a team or user seen.

    Args:
        tid: the team id
        uid: the user id
    """

    db = api.common.get_conn()

    match = {}

    if tid is not None:
        match.update({"tid": tid})
    elif uid is not None:
        match.update({"uid": uid})
    else:
        raise InternalException("You must specify either a tid or uid")

    db.earned_achievements.update(match, {"$set": {"seen": True}}, multi=True)

def get_earned_achievements(tid=None, uid=None):
    """
    Gets the solved achievements for a given team or user.

    Args:
        tid: The team id
        tid: The user id
    Returns:
        List of solved achievement dictionaries
    """

    achievements = [get_achievement(aid=achievement["aid"]) for achievement in get_earned_achievement_entries(tid=tid, uid=uid)]
    set_earned_achievements_seen(tid=tid, uid=uid)

    for achievement in achievements:
        if achievement["hidden"]:
            achievement["description"] = ""

    return achievements

def reevaluate_earned_achievements(aid):
    """
    In the case of the achievement or processor being updated, this will reevaluate earned achievements for an achievement.

    Args:
        aid: the aid of the achievement to be reevaluated.
    """

    db = api.common.get_conn()

    get_achievement(aid=aid, show_disabled=True)

    keys = []
    for earned_achievement in get_earned_achievements():
        if not process_achievement(aid, uid=earned_achievement["uid"]):
            keys.append({"aid": aid, "tid":earned_achievement["tid"]})

    db.earned_achievements.remove({"$or": keys})

def reevaluate_all_earned_acheivements():
    """
    In the case of the achievement or processor being updated, this will reevaluate all earned achievements.
    """

    api.cache.clear_all()
    for achievement in get_earned_achievements():
        reevaluate_earned_achievements(achievement["aid"])

def set_achievement_disabled(aid, disabled):
    """
    Updates a achievement's availability.

    Args:
        aid: the achievement's aid
        disabled: whether or not the achievement should be disabled.
    Returns:
        The updated achievement object.
    """

def get_processor(aid):
    """
    Returns the processor module for a given achievement.

    Args:
        aid: the achievement id
    Returns:
        The processor module
    """

    try:
        path = get_achievement(aid=aid, show_disabled=True)["grader"]
        return imp.load_source(path[:-3], join(achievement_base_path, path))
    except FileNotFoundError:
        raise InternalException("Achievement processor is offline.")

def process_achievement(aid, data):
    """
    Determines whether or not an achievement has been earned.

    Args:
        aid: the achievement id
        data: additional data dictionary
    """

    if data.get("uid", None) is None:
        data["uid"] = api.user.get_user()["uid"]

    if data.get("tid", None) is None:
        data["tid"] = api.user.get_user(uid=data["uid"])["tid"]

    get_achievement(aid=aid, show_disabled=True)
    processor = get_processor(aid)

    return processor.process(api, data)

def insert_earned_achievement(aid, data):
    """
    Store earned achievement for a user/team.

    Args:
        aid: the achievement id
        data: the data necessary to assess the achievement
              must include tid, uid
    """

    db = api.common.get_conn()

    tid, uid = data.pop("tid"), data.pop("uid")

    db.earned_achievements.insert({
        "aid": aid,
        "tid": tid,
        "uid": uid,
        "data": data,
        "timestamp": datetime.utcnow(),
        "seen": False
    })

def process_achievements(event, data):
    """
    Process achievements of a type with data.

    Args:
        event: event type, e.g., submit
        data: dictionary with additional information necessary for assesment
    """

    if data.get("uid", None) is None:
        data["uid"] = api.user.get_user()["uid"]

    if data.get("tid", None) is None:
        data["tid"] = api.user.get_user(uid=data["uid"])["tid"]

    eligible_achievements = [
        achievement for achievement in get_all_achievements(event=event) \
            if achievement not in get_earned_achievements(tid=data["tid"])]

    for achievement in eligible_achievements:
        aid = achievement["aid"]

        if process_achievement(aid, data):
            insert_earned_achievement(aid, data)

def insert_achievement(achievement):
    """
    Inserts an achievement object into the database.

    Args:
        achievement: the achievement object loaded from json.
    Returns:
        The achievment's aid.
    """

    db = api.common.get_conn()
    validate(achievement_schema, achievement)

    achievement["disabled"] = achievement.get("disabled", False)

    achievement["aid"] = api.common.hash(achievement["name"])

    if safe_fail(get_achievement, aid=achievement["aid"]) is not None:
        raise WebException("achievement with identical aid already exists.")

    if safe_fail(get_achievement, name=achievement["name"]) is not None:
        raise WebException("achievement with identical name already exists.")

    db.achievements.insert(achievement)
    api.cache.fast_cache.clear()

    return achievement["aid"]

def update_achievement(aid, updated_achievement):
    """
    Updates a achievement with new properties.

    Args:
        aid: the aid of the achievement to update.
        updated_achievement: an updated achievement object.
    Returns:
        The updated achievement object.
    """

    db = api.common.get_conn()

    if updated_achievement.get("name", None) is not None:
        if safe_fail(get_achievement, name=updated_achievement["name"]) is not None:
            raise WebException("Achievement with identical name already exists.")

    achievement = get_achievement(aid=aid, show_disabled=True).copy()
    achievement.update(updated_achievement)

    # pass validation by removing/readding aid
    achievement.pop("aid", None)
    validate(achievement_schema, achievement)
    achievement["aid"] = aid

    db.achievements.update({"aid": aid}, achievement)
    api.cache.fast_cache.clear()

    return achievement
<commit_msg>Prevent leaking information from achievements.<commit_after>""" Module for interacting with the achievements """

import imp
import pymongo

import api

from functools import wraps
from os.path import join
from datetime import datetime
from voluptuous import Schema, Required, Range
from api.common import check, InternalException, SevereInternalException, validate, safe_fail, WebException

processor_base_path = "./processors"

achievement_schema = Schema({
    Required("name"): check(
        ("The achievement's display name must be a string.", [str])),
    Required("score"): check(
        ("Score must be a positive integer.", [int, Range(min=0)])),
    Required("event"): check(
        ("Type must be a string.", [str])),
    Required("description"): check(
        ("The description must be a string.", [str])),
    Required("processor"): check(
        ("The processor path must be a string.", [str])),
    Required("hidden"): check(
        ("An achievement's hidden state is either True or False.", [
            lambda hidden: type(hidden) == bool])),
    Required("image"): check(
        ("An achievement's image path must be a string.", [str])),
    "disabled": check(
        ("An achievement's disabled state is either True or False.", [
            lambda disabled: type(disabled) == bool])),
    "aid": check(
        ("You should not specify a aid for an achievement.", [lambda _: False])),
    "_id": check(
        ("Your achievements should not already have _ids.", [lambda id: False]))
})

def get_all_events(show_disabled=False):
    """
    Gets the set of distinct achievement events.

    Args:
        show_disabled: Whether to include events that are only on disabled achievements
    Returns:
        The set of distinct achievement events.
    """

    db = api.common.get_conn()

    match = {}
    if not show_disabled:
        match.update({"disabled": False})

    return db.achievemets.find(match).distinct("event")

def get_achievement(aid=None, name=None, show_disabled=False):
    """
    Gets a single achievement

    Args:
        aid: the achievement id
        name: the name of the achievement
        show_disabled: Boolean indicating whether or not to show disabled achievements.
    """

    db = api.common.get_conn()

    match = {}

    if aid is not None:
        match.update({'aid': aid})
    elif name is not None:
        match.update({'name': name})
    else:
        raise InternalException("Must supply aid or display name")

    if not show_disabled:
        match.update({"disabled": False})

    db = api.common.get_conn()
    achievement = db.achievements.find_one(match, {"_id":0})

    if achievement is None:
        raise SevereInternalException("Could not find achievement! You gave " + str(match))

    return achievement

def get_all_achievements(event=None, show_disabled=False):
    """
    Gets all of the achievements in the database.

    Args:
        event: Optional parameter to restrict which achievements are returned
        show_disabled: Boolean indicating whether or not to show disabled achievements.
    Returns:
        List of achievements from the database
    """

    db = api.common.get_conn()

    match = {}
    if event is not None:
        match.update({'event': event})

    if not show_disabled:
        match.update({'disabled': False})

    return list(db.achievements.find(match, {"_id":0}).sort('score', pymongo.ASCENDING))

def get_earned_achievement_entries(tid=None, uid=None, aid=None):
    """
    Gets the solved achievements for a given team or user.

    Args:
        tid: The team id
        event: Optional parameter to restrict which achievements are returned
    Returns:
        List of solved achievements
    """

    db = api.common.get_conn()

    match = {}

    if uid is not None:
        match.update({"uid": uid})
    elif tid is not None:
        match.update({"tid": tid})

    if aid is not None:
        match.update({"aid": aid})

    return list(db.earned_achievements.find(match, {"_id":0}))

def get_earned_aids(tid=None, uid=None, aid=None):
    """
    Gets the solved aids for a given team or user.

    Args:
        tid: The team id
        event: Optional parameter to restrict which achievements are returned
    Returns:
        List of solved achievement ids
    """

    return [a["aid"] for a in get_earned_achievement_entries(tid=tid, uid=uid, aid=aid)]

def set_earned_achievements_seen(tid=None, uid=None):
    """
    Sets all earned achievements from a team or user seen.

    Args:
        tid: the team id
        uid: the user id
    """

    db = api.common.get_conn()

    match = {}

    if tid is not None:
        match.update({"tid": tid})
    elif uid is not None:
        match.update({"uid": uid})
    else:
        raise InternalException("You must specify either a tid or uid")

    db.earned_achievements.update(match, {"$set": {"seen": True}}, multi=True)

def get_earned_achievements(tid=None, uid=None):
    """
    Gets the solved achievements for a given team or user.

    Args:
        tid: The team id
        tid: The user id
    Returns:
        List of solved achievement dictionaries
    """

    achievements = [get_achievement(aid=achievement["aid"]) for achievement in get_earned_achievement_entries(tid=tid, uid=uid)]
    set_earned_achievements_seen(tid=tid, uid=uid)

    for achievement in achievements:
        if achievement["hidden"]:
            achievement["description"] = ""
        achievement.pop("data")

    return achievements

def reevaluate_earned_achievements(aid):
    """
    In the case of the achievement or processor being updated, this will reevaluate earned achievements for an achievement.

    Args:
        aid: the aid of the achievement to be reevaluated.
    """

    db = api.common.get_conn()

    get_achievement(aid=aid, show_disabled=True)

    keys = []
    for earned_achievement in get_earned_achievements():
        if not process_achievement(aid, uid=earned_achievement["uid"]):
            keys.append({"aid": aid, "tid":earned_achievement["tid"]})

    db.earned_achievements.remove({"$or": keys})

def reevaluate_all_earned_acheivements():
    """
    In the case of the achievement or processor being updated, this will reevaluate all earned achievements.
    """

    api.cache.clear_all()
    for achievement in get_earned_achievements():
        reevaluate_earned_achievements(achievement["aid"])

def set_achievement_disabled(aid, disabled):
    """
    Updates a achievement's availability.

    Args:
        aid: the achievement's aid
        disabled: whether or not the achievement should be disabled.
    Returns:
        The updated achievement object.
    """

def get_processor(aid):
    """
    Returns the processor module for a given achievement.

    Args:
        aid: the achievement id
    Returns:
        The processor module
    """

    try:
        path = get_achievement(aid=aid, show_disabled=True)["grader"]
        return imp.load_source(path[:-3], join(achievement_base_path, path))
    except FileNotFoundError:
        raise InternalException("Achievement processor is offline.")

def process_achievement(aid, data):
    """
    Determines whether or not an achievement has been earned.

    Args:
        aid: the achievement id
        data: additional data dictionary
    """

    if data.get("uid", None) is None:
        data["uid"] = api.user.get_user()["uid"]

    if data.get("tid", None) is None:
        data["tid"] = api.user.get_user(uid=data["uid"])["tid"]

    get_achievement(aid=aid, show_disabled=True)
    processor = get_processor(aid)

    return processor.process(api, data)

def insert_earned_achievement(aid, data):
    """
    Store earned achievement for a user/team.

    Args:
        aid: the achievement id
        data: the data necessary to assess the achievement
              must include tid, uid
    """

    db = api.common.get_conn()

    tid, uid = data.pop("tid"), data.pop("uid")

    db.earned_achievements.insert({
        "aid": aid,
        "tid": tid,
        "uid": uid,
        "data": data,
        "timestamp": datetime.utcnow(),
        "seen": False
    })

def process_achievements(event, data):
    """
    Process achievements of a type with data.

    Args:
        event: event type, e.g., submit
        data: dictionary with additional information necessary for assesment
    """

    if data.get("uid", None) is None:
        data["uid"] = api.user.get_user()["uid"]

    if data.get("tid", None) is None:
        data["tid"] = api.user.get_user(uid=data["uid"])["tid"]

    eligible_achievements = [
        achievement for achievement in get_all_achievements(event=event) \
            if achievement not in get_earned_achievements(tid=data["tid"])]

    for achievement in eligible_achievements:
        aid = achievement["aid"]

        if process_achievement(aid, data):
            insert_earned_achievement(aid, data)

def insert_achievement(achievement):
    """
    Inserts an achievement object into the database.

    Args:
        achievement: the achievement object loaded from json.
    Returns:
        The achievment's aid.
    """

    db = api.common.get_conn()
    validate(achievement_schema, achievement)

    achievement["disabled"] = achievement.get("disabled", False)

    achievement["aid"] = api.common.hash(achievement["name"])

    if safe_fail(get_achievement, aid=achievement["aid"]) is not None:
        raise WebException("achievement with identical aid already exists.")

    if safe_fail(get_achievement, name=achievement["name"]) is not None:
        raise WebException("achievement with identical name already exists.")

    db.achievements.insert(achievement)
    api.cache.fast_cache.clear()

    return achievement["aid"]

def update_achievement(aid, updated_achievement):
    """
    Updates a achievement with new properties.

    Args:
        aid: the aid of the achievement to update.
        updated_achievement: an updated achievement object.
    Returns:
        The updated achievement object.
    """

    db = api.common.get_conn()

    if updated_achievement.get("name", None) is not None:
        if safe_fail(get_achievement, name=updated_achievement["name"]) is not None:
            raise WebException("Achievement with identical name already exists.")

    achievement = get_achievement(aid=aid, show_disabled=True).copy()
    achievement.update(updated_achievement)

    # pass validation by removing/readding aid
    achievement.pop("aid", None)
    validate(achievement_schema, achievement)
    achievement["aid"] = aid

    db.achievements.update({"aid": aid}, achievement)
    api.cache.fast_cache.clear()

    return achievement
<|endoftext|>


<commit_before>from django.utils import six
from collections import OrderedDict
from django.core.urlresolvers import reverse
from django.core.paginator import InvalidPage, Paginator as DjangoPaginator

from rest_framework import pagination
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
from rest_framework.utils.urls import (
    replace_query_param, remove_query_param
)

class JSONAPIPagination(pagination.PageNumberPagination):
    """Custom paginator that formats responses in a JSON-API compatible format."""

    page_size_query_param = 'page[size]'

    def get_first_link(self):
        if not self.page.has_previous():
            return None
        url = self.request.build_absolute_uri()
        return remove_query_param(url, self.page_query_param)

    def get_last_link(self):
        if not self.page.has_next():
            return None
        url = self.request.build_absolute_uri()
        page_number = self.page.paginator.num_pages
        return replace_query_param(url, self.page_query_param, page_number)

    def get_paginated_response(self, data):
        response_dict = OrderedDict([
            ('data', data),
            ('links', OrderedDict([
                ('first', self.get_first_link()),
                ('last', self.get_last_link()),
                ('prev', self.get_previous_link()),
                ('next', self.get_next_link()),
                ('meta', OrderedDict([
                    ('total', self.page.paginator.count),
                    ('per_page', self.page.paginator.per_page),
                ]))
            ])),
        ])
        return Response(response_dict)

class EmbeddedPagination(JSONAPIPagination):

    def page_number_query(self, url, page_number):
        """
        Adds page param to paginated urls.
        """

        url = replace_query_param(url, self.page_query_param, page_number)

        if page_number == 1:
            return remove_query_param(url, self.page_query_param)

        return url

    def get_first_real_link(self, url):
        if not self.page.has_previous():
            return None
        return self.page_number_query(self.request.build_absolute_uri(url), 1)

    def get_last_real_link(self, url):
        if not self.page.has_next():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.paginator.num_pages
        return self.page_number_query(url, page_number)

    def get_previous_real_link(self, url):
        if not self.page.has_previous():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.previous_page_number()
        return self.page_number_query(url, page_number)

    def get_next_real_link(self, url):
        if not self.page.has_next():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.next_page_number()
        return self.page_number_query(url, page_number)

    def get_paginated_response(self, data):
        """
        Formats paginated response in accordance with JSON API.

        Creates pagination links from the view_name if embedded resource,
        rather than the location used in the request.
        """
        kwargs = self.request.parser_context['kwargs'].copy()
        embedded = kwargs.pop('no_embeds', None)
        view_name = self.request.parser_context['view'].view_name
        reversed_url = None
        if embedded:
            reversed_url = reverse(view_name, kwargs=kwargs)

        response_dict = OrderedDict([
            ('data', data),
            ('links', OrderedDict([
                ('first', self.get_first_real_link(reversed_url)),
                ('last', self.get_last_real_link(reversed_url)),
                ('prev', self.get_previous_real_link(reversed_url)),
                ('next', self.get_next_real_link(reversed_url)),
                ('meta', OrderedDict([
                    ('total', self.page.paginator.count),
                    ('per_page', self.page.paginator.per_page),
                ]))
            ])),
        ])
        return Response(response_dict)

    def paginate_queryset(self, queryset, request, view=None):
        """
        Custom pagination of queryset. Returns page object or `None` if not configured for view.

        If this is an embedded resource, returns first page, ignoring query params.
        """
        if request.parser_context['kwargs'].get('no_embeds'):
            self._handle_backwards_compat(view)
            page_size = self.get_page_size(request)
            if not page_size:
                return None
            paginator = DjangoPaginator(queryset, page_size)
            page_number = 1
            try:
                self.page = paginator.page(page_number)
            except InvalidPage as exc:
                msg = self.invalid_page_message.format(
                    page_number=page_number, message=six.text_type(exc)
                )
                raise NotFound(msg)

            if paginator.count > 1 and self.template is not None:
                # The browsable API should display pagination controls.
                self.display_page_controls = True

            self.request = request
            return list(self.page)

        else:
            return super(EmbeddedPagination, self).paginate_queryset(queryset, request, view=None)
<commit_msg>Rename new pagination class, JSONAPIPagination. Get rid of old pagination.<commit_after>from django.utils import six
from collections import OrderedDict
from django.core.urlresolvers import reverse
from django.core.paginator import InvalidPage, Paginator as DjangoPaginator

from rest_framework import pagination
from rest_framework.exceptions import NotFound
from rest_framework.response import Response
from rest_framework.utils.urls import (
    replace_query_param, remove_query_param
)

class JSONAPIPagination(pagination.PageNumberPagination):
    """
    Custom paginator that formats responses in a JSON-API compatible format.

    Properly handles pagination of embedded objects.

    """

    page_size_query_param = 'page[size]'

    def page_number_query(self, url, page_number):
        """
        Adds page param to paginated urls.
        """

        url = replace_query_param(url, self.page_query_param, page_number)

        if page_number == 1:
            return remove_query_param(url, self.page_query_param)

        return url

    def get_first_real_link(self, url):
        if not self.page.has_previous():
            return None
        return self.page_number_query(self.request.build_absolute_uri(url), 1)

    def get_last_real_link(self, url):
        if not self.page.has_next():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.paginator.num_pages
        return self.page_number_query(url, page_number)

    def get_previous_real_link(self, url):
        if not self.page.has_previous():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.previous_page_number()
        return self.page_number_query(url, page_number)

    def get_next_real_link(self, url):
        if not self.page.has_next():
            return None
        url = self.request.build_absolute_uri(url)
        page_number = self.page.next_page_number()
        return self.page_number_query(url, page_number)

    def get_paginated_response(self, data):
        """
        Formats paginated response in accordance with JSON API.

        Creates pagination links from the view_name if embedded resource,
        rather than the location used in the request.
        """
        kwargs = self.request.parser_context['kwargs'].copy()
        embedded = kwargs.pop('no_embeds', None)
        view_name = self.request.parser_context['view'].view_name
        reversed_url = None
        if embedded:
            reversed_url = reverse(view_name, kwargs=kwargs)

        response_dict = OrderedDict([
            ('data', data),
            ('links', OrderedDict([
                ('first', self.get_first_real_link(reversed_url)),
                ('last', self.get_last_real_link(reversed_url)),
                ('prev', self.get_previous_real_link(reversed_url)),
                ('next', self.get_next_real_link(reversed_url)),
                ('meta', OrderedDict([
                    ('total', self.page.paginator.count),
                    ('per_page', self.page.paginator.per_page),
                ]))
            ])),
        ])
        return Response(response_dict)

    def paginate_queryset(self, queryset, request, view=None):
        """
        Custom pagination of queryset. Returns page object or `None` if not configured for view.

        If this is an embedded resource, returns first page, ignoring query params.
        """
        if request.parser_context['kwargs'].get('no_embeds'):
            self._handle_backwards_compat(view)
            page_size = self.get_page_size(request)
            if not page_size:
                return None
            paginator = DjangoPaginator(queryset, page_size)
            page_number = 1
            try:
                self.page = paginator.page(page_number)
            except InvalidPage as exc:
                msg = self.invalid_page_message.format(
                    page_number=page_number, message=six.text_type(exc)
                )
                raise NotFound(msg)

            if paginator.count > 1 and self.template is not None:
                # The browsable API should display pagination controls.
                self.display_page_controls = True

            self.request = request
            return list(self.page)

        else:
            return super(EmbeddedPagination, self).paginate_queryset(queryset, request, view=None)
<|endoftext|>


<commit_before>from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse
from rest_framework.response import Response
from rest_framework.views import APIView

from companies.models import Company
from companies.models import Team
from companies.serializers import CompanySerializer
from companies.serializers import TeamSerializer

class TeamView(APIView):

    queryset = Team.objects.all()
    serializer_class = TeamSerializer

    def get(self, request, format=None, **kwargs):
        #antes pegar o company id para verificar se o time pertence aquela empresa
        if kwargs.get('company_id'):
        	try:
        		company = Company.objects.get(id=kwargs['company_id'])
        	except ObjectDoesNotExist:
                return Response({"error": "could not find team"}    , status=400)
        if kwargs.get('team_id'):
            try:
            	#verificar aqui se esse team pertence a company?
                team = Team.objects.get(id=kwargs['team_id'])
                team_data = TeamSerializer(team)
                return Response(team_data.data)
            except ObjectDoesNotExist:
                return Response({"error": "could not find team"}    , status=400)
        else:
            all_teams = Team.objects.all()
            all_teams_serialized = TeamSerializer(all_teams, many=True)
            return Response(all_teams_serialized.data)

    def post(self, request, format=None, **kwargs):
        response = Response()
        new_team = Team(**kwargs)
        new_team.save()

        if new_team:
            response.status_code = 201
        else:
            response.status_code = 400
        return response<commit_msg>refactor(imports): remove unused imports<commit_after>from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Company
from .models import Team
from .serializers import TeamSerializer

class TeamView(APIView):

    queryset = Team.objects.all()
    serializer_class = TeamSerializer

    def get(self, request, format=None, **kwargs):
        #antes pegar o company id para verificar se o time pertence aquela empresa
        if kwargs.get('company_id'):
        	try:
        		company = Company.objects.get(id=kwargs['company_id'])
        	except ObjectDoesNotExist:
                return Response({"error": "could not find team"}    , status=400)
        if kwargs.get('team_id'):
            try:
            	#verificar aqui se esse team pertence a company?
                team = Team.objects.get(id=kwargs['team_id'])
                team_data = TeamSerializer(team)
                return Response(team_data.data)
            except ObjectDoesNotExist:
                return Response({"error": "could not find team"}    , status=400)
        else:
            all_teams = Team.objects.all()
            all_teams_serialized = TeamSerializer(all_teams, many=True)
            return Response(all_teams_serialized.data)

    def post(self, request, format=None, **kwargs):
        response = Response()
        new_team = Team(**kwargs)
        new_team.save()

        if new_team:
            response.status_code = 201
        else:
            response.status_code = 400
        return response<|endoftext|>


<commit_before>import json
from database.MongoDBORM import MongoORM as ORM
import tornado

class HistoryHandler(tornado.web.RequestHandler):

    def post(self):
        """
        Добавления в БД, о посищении места

        @return: ответ сервера о статусе добавления данных
        """
        orm = ORM("Journey")
        #  TODO: проверка json и ответ ошибкой из доков
        data = tornado.escape.json_decode(self.request.body)
        orm.insert(data, "history")

        del orm
        self.write({"status": "ok"})

    def get(self):
        """
        Получения списка мест в кторорых был пользователь

        @param user_id: поле по которому идёт выборка из базы

        @return: ответ сервера о статусе добавления данных
        """
        data = tornado.escape.json_decode(self.request.body)
        orm = ORM("Journey")

        if data['user_id']:
            result = orm.select("history", {"user.user_id": data['user_id']})
            self.write(json.dumps(list(result)))
        else:
            self.write({})
        del orm

    def delete(self):
        """
        Удаление экземпляра истории из БД

        @param user_id: поле по которому идёт выборка из базы
        @param token: пока не используется

        @return: ответ сервера о статусе добавления данных
        """
        data = tornado.escape.json_decode(self.request.body)
        orm = ORM("Journey")

        if data['place_id'].isdigit():
            orm.delete("history", {"id": int(data['place_id'])})
            self.write({"status": "ok"})
        else:
            self.write({
                "status_code": "411",
                "status_txt": "Invalid DELETE request, check the data.",
                "status": "fail"
            })
        del orm

<commit_msg>fix post in history<commit_after>import json
from database.MongoDBORM import MongoORM as ORM
import tornado

class HistoryHandler(tornado.web.RequestHandler):

    def post(self):
        """
        Добавления в БД, о посищении места

        @return: ответ сервера о статусе добавления данных
        """
        orm = ORM("Journey")
        try:
            data = tornado.escape.json_decode(self.request.body)
            orm.insert(data, "history")
            self.write({"status": "ok"})
        except ValueError:
            self.write({
                "status_code": "417",
                 "status_txt": "Invalid POST request, check the data.",
                 "status": "fail"
            })
        del orm

    def get(self):
        """
        Получения списка мест в кторорых был пользователь

        @param user_id: поле по которому идёт выборка из базы

        @return: ответ сервера о статусе добавления данных
        """
        data = tornado.escape.json_decode(self.request.body)
        orm = ORM("Journey")

        if data['user_id']:
            result = orm.select("history", {"user.user_id": data['user_id']})
            self.write(json.dumps(list(result)))
        else:
            self.write({})
        del orm

    def delete(self):
        """
        Удаление экземпляра истории из БД

        @param user_id: поле по которому идёт выборка из базы
        @param token: пока не используется

        @return: ответ сервера о статусе добавления данных
        """
        data = tornado.escape.json_decode(self.request.body)
        orm = ORM("Journey")

        if data['place_id'].isdigit():
            orm.delete("history", {"id": int(data['place_id'])})
            self.write({"status": "ok"})
        else:
            self.write({
                "status_code": "411",
                "status_txt": "Invalid DELETE request, check the data.",
                "status": "fail"
            })
        del orm

<|endoftext|>


<commit_before>default = "sqlite"

def db(current=None):
    if current is None:
        current = "postgress"
    dbase = {
        "sqlite":{
            'test': 'sqlite:///bktest.db',
            'develop': 'sqlite:///bkdevelop.db',
            'production': 'sqlite:///bkproduction.db'
        },

        "postgres": {
            'test': 'postgresql://@127.0.0.1/bktest',
            'develop': 'postgresql://@127.0.0.1/bkdevelop',
            'production': 'postgresql://@127.0.0.1/bkproduction'
        }
    }

    return dbase[current]

db_config = db()<commit_msg>fix an error on dbase.py<commit_after>default = "sqlite"

def db(current=None):
    if current is None:
        current = "postgres"
    dbase = {
        "sqlite":{
            'test': 'sqlite:///bktest.db',
            'develop': 'sqlite:///bkdevelop.db',
            'production': 'sqlite:///bkproduction.db'
        },

        "postgres": {
            'test': 'postgresql://@127.0.0.1/bktest',
            'develop': 'postgresql://@127.0.0.1/bkdevelop',
            'production': 'postgresql://@127.0.0.1/bkproduction'
        }
    }

    return dbase[current]

db_config = db()<|endoftext|>


<commit_before>from django.db import models
from django.forms.widgets import Textarea
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

from volunteers.models import Volunteer
from coordinators.models import filter_by_district
from campaigns.admin import VolunteerParticipantInlineBase

class CampaignLocationShiftInline(VolunteerParticipantInlineBase,
        admin.TabularInline):
    verbose_name = _('Campaign shift')
    verbose_name_plural = _('Campaign shifts')
    autocomplete_fields = ['shift']
    # TODO: need to implement get_queryset to limit shifts by location

class VolunteerAdmin(admin.ModelAdmin):
    save_on_top = True
    search_fields = ['first_name', 'last_name', 'email', 'phone']
    list_display = ['first_name', 'last_name', 'email', 'phone', 'age',
            'is_group', 'participant_count']
    readonly_fields = ['registration_time']
    fieldsets = [
            (None, {'fields': ('first_name', 'last_name', 'age', 'phone',
                'email', 'notes', 'public_notes')}),
            (_('Group'), {'fields': ('is_group', 'group_name',
                'participant_count')}),
            (_('Districts'), {'fields': ('districts',)}),
            (_('Registration details'), {
                'fields': ('registration_time',
                    'registration_ip_address','registration_user_agent'),
                'classes': ('collapse',),
            }),
    ]
    formfield_overrides = {
            models.TextField: {'widget': Textarea(attrs={
                'rows': '2',
                'cols': '40',
            })},
    }
    inlines = [CampaignLocationShiftInline]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return filter_by_district(qs, request.user, 'districts')

admin.site.register(Volunteer, VolunteerAdmin)
<commit_msg>Add save as new to volunteer admin<commit_after>from django.db import models
from django.forms.widgets import Textarea
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _

from volunteers.models import Volunteer
from coordinators.models import filter_by_district
from campaigns.admin import VolunteerParticipantInlineBase

class CampaignLocationShiftInline(VolunteerParticipantInlineBase,
        admin.TabularInline):
    verbose_name = _('Campaign shift')
    verbose_name_plural = _('Campaign shifts')
    autocomplete_fields = ['shift']
    # TODO: need to implement get_queryset to limit shifts by location

class VolunteerAdmin(admin.ModelAdmin):
    save_on_top = True
    save_as = True
    search_fields = ['first_name', 'last_name', 'email', 'phone']
    list_display = ['first_name', 'last_name', 'email', 'phone', 'age',
            'is_group', 'participant_count']
    readonly_fields = ['registration_time']
    fieldsets = [
            (None, {'fields': ('first_name', 'last_name', 'age', 'phone',
                'email', 'notes', 'public_notes')}),
            (_('Group'), {'fields': ('is_group', 'group_name',
                'participant_count')}),
            (_('Districts'), {'fields': ('districts',)}),
            (_('Registration details'), {
                'fields': ('registration_time',
                    'registration_ip_address','registration_user_agent'),
                'classes': ('collapse',),
            }),
    ]
    formfield_overrides = {
            models.TextField: {'widget': Textarea(attrs={
                'rows': '2',
                'cols': '40',
            })},
    }
    inlines = [CampaignLocationShiftInline]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        return filter_by_district(qs, request.user, 'districts')

admin.site.register(Volunteer, VolunteerAdmin)
<|endoftext|>


<commit_before>#
# Copyright 2019, Institute for Systems Biology
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging
import json
import django
import re

from flask import request
from werkzeug.exceptions import BadRequest

from django.contrib.auth.models import User as Django_User
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.conf import settings

from cohorts.models import Cohort_Perms, Cohort, Filters
from accounts.sa_utils import auth_dataset_whitelists_for_user
from cohorts.file_helpers import cohort_files
from cohorts.utils import get_sample_case_list_bq, create_cohort as make_cohort
from projects.models import Program

from jsonschema import validate as schema_validate, ValidationError
from schemas.cohort_filter_schema import COHORT_FILTER_SCHEMA

BLACKLIST_RE = settings.BLACKLIST_RE

logger = logging.getLogger(settings.LOGGER_NAME)

def get_file_manifest(cohort_id, user):
    file_manifest = None
    inc_filters = {}

    try:
        has_access = auth_dataset_whitelists_for_user(user.id)

        params = {
            'limit': settings.MAX_FILE_LIST_REQUEST,
            'build': 'HG19',
            'access': has_access
        }

        request_data = request.get_json()

        param_set = {
            'offset': {'default': 0, 'type': int, 'name': 'offset'},
            'page': {'default': 1, 'type': int, 'name': 'page'},
            'fetch_count': {'default': 5000, 'type': int, 'name': 'limit'},
            'genomic_build': {'default': "HG19", 'type': str, 'name': 'build'},
            'case_insensitive': {'default': "True", 'type': str, 'name': 'case_insensitive'}
        }

        for param, parameter in param_set.items():
            default = parameter['default']
            param_type = parameter['type']
            name = parameter['name']
            params[name] = request_data[param] if (request_data and param in request_data) else request.args.get(param, default=default, type=param_type) if param in request.args else default
            if name == 'case_insensitive':
                params[name] = bool(params[name] == "True")

            if request_data:
                inc_filters = {
                    filter: request_data[filter]
                    for filter in request_data.keys()
                    if filter not in list(param_set.keys())
                }

        response = cohort_files(cohort_id, user=user, inc_filters=inc_filters, **params)

        file_manifest = response['file_list'] if response and response['file_list'] else None

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        file_manifest = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }
    except Exception as e:
        logger.error("[ERROR] File trieving the file manifest for Cohort {}:".format(str(cohort_id)))
        logger.exception(e)

    return file_manifest

def get_cohort_info(cohort_id, get_barcodes=False):
    cohort = None
    try:
        cohort_obj = Cohort.objects.get(id=cohort_id)
        cohort = {
            'id': cohort_obj.id,
            'name': cohort_obj.name,
            'case_count': cohort_obj.case_size(),
            'sample_count': cohort_obj.sample_size(),
            'programs': cohort_obj.get_program_names(),
            'filters': cohort_obj.get_current_filters(True)
        }

        if get_barcodes:
            cohort['barcodes'] = get_sample_case_list_bq(cohort_id)

    except ObjectDoesNotExist as e:
        logger.warn("Cohort with ID {} was not found!".format(str(cohort_id)))
    except Exception as e:
        logger.exception(e)

    return cohort

def get_cohorts(user_email):

    cohort_list = None

    try:
        user = Django_User.objects.get(email=user_email)
        cohort_perms = Cohort_Perms.objects.filter(user_id=user.id, cohort__active=1)
        cohort_list = []
        for cohort_perm in cohort_perms:
            cohort_list.append({
                'id': cohort_perm.cohort.id,
                'name': cohort_perm.cohort.name,
                'permission': cohort_perm.perm,
                'filters': cohort_perm.cohort.get_current_filters(True)
            })

    except ObjectDoesNotExist as e:
        logger.info("No cohorts found for user {}!".format(user_email))

    return cohort_list

def get_cohort_counts():

    cohort_counts = None

    try:
        request_data = request.get_json()
        schema_validate(request_data, COHORT_FILTER_SCHEMA)

        if 'filters' not in request_data:
            cohort_counts = {
                'message': 'No filters were provided; ensure that the request body contains a \'filters\' property.'
            }
        else:
            case_insensitive = request_data['case_insensitive'] if (request_data and 'case_insensitive' in request_data) else request.args.get('case_insensitive', default="True", type=str) if param in request.args else "True"

            cohort_counts = get_sample_case_list_bq(None, request_data['filters'], case_insen=bool(case_insensitive == "True"))

            if cohort_counts:
                for prog in cohort_counts:
                    if cohort_counts[prog]['case_count'] <= 0:
                        cohort_counts[prog]['message'] = "No cases or samples found which meet the filter criteria for this program."
                    cohort_counts[prog]['provided_filters'] = request_data['filters'][prog]

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_counts = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }
    except ValidationError as e:
        logger.warn('[WARNING] Filters rejected for improper formatting: {}'.format(e))
        cohort_counts = {
            'message': 'Filters were improperly formatted.'
        }
    except Exception as e:
        logger.exception(e)

    return cohort_counts

def create_cohort(user):
    cohort_info = None

    try:
        request_data = request.get_json()
        schema_validate(request_data, COHORT_FILTER_SCHEMA)

        if 'name' not in request_data:
            cohort_info = {
                'message': 'A name was not provided for this cohort. The cohort was not made.',
            }
            return cohort_info

        if 'filters' not in request_data:
            cohort_info = {
                'message': 'Filters were not provided; at least one filter must be provided for a cohort to be valid.' +
                       ' The cohort was not made.',
            }
            return cohort_info

        blacklist = re.compile(BLACKLIST_RE, re.UNICODE)
        match = blacklist.search(str(request_data['name']))

        if not match and 'desc' in request_data:
            match = blacklist.search(str(request_data['desc']))

        if match:
            cohort_info = {
                'message': 'Your cohort\'s name or description contains invalid characters; please edit them and resubmit. ' +
                    '[Saw {}]'.format(str(match)),
            }

        else:
            result = make_cohort(user, **request_data)

            if 'message' in result:
                cohort_info = result
            else:
                cohort_info = get_cohort_info(result['cohort_id'])

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_info = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }

    except ValidationError as e:
        logger.warn("[WARNING] Cohort information rejected for improper formatting: {}".format(e))
        cohort_info = {
            'message': 'Cohort information was improperly formatted - cohort not edited.',
        }

    return cohort_info

def edit_cohort(cohort_id, user, delete=False):
    match = None

    try:
        if delete:
            cohort = Cohort.objects.get(id=cohort_id)
            cohort.active = False
            cohort.save()
            cohort_info = {
                'notes': 'Cohort {} (\'{}\') has been deleted.'.format(cohort_id, cohort.name),
                'data': {'filters': cohort.get_current_filters(unformatted=True)},
            }
        else:
            request_data = request.get_json()
            if len(request_data.keys()):
                schema_validate(request_data, COHORT_FILTER_SCHEMA)

            if 'name' in request_data:
                blacklist = re.compile(BLACKLIST_RE, re.UNICODE)
                match = blacklist.search(str(request_data['name']))

            if match:
                cohort_info = {
                    'message': 'Your cohort\'s name or description contains invalid characters; please edit them and resubmit. ' +
                               '[Saw {}]'.format(str(match)),
                }
            else:
                result = make_cohort(user, source_id=cohort_id, **request_data)
                if 'message' in result:
                    cohort_info = result
                else:
                    cohort_info = get_cohort_info(result['cohort_id'])

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_info = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }

    except ObjectDoesNotExist as e:
        logger.error("[ERROR] During {} for cohort ID {}:".format(request.method,str(cohort_id)))
        logger.error("Couldn't find a cohort with that ID!")

    except ValidationError as e:
        logger.warn("[WARNING] Cohort information rejected for improper formatting: {}".format(e))
        cohort_info = {
            'message': 'Cohort information was improperly formatted - cohort not edited.',
        }

    return cohort_info
<commit_msg>-> Bug in case insensitivity...<commit_after>#
# Copyright 2019, Institute for Systems Biology
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging
import json
import django
import re

from flask import request
from werkzeug.exceptions import BadRequest

from django.contrib.auth.models import User as Django_User
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.conf import settings

from cohorts.models import Cohort_Perms, Cohort, Filters
from accounts.sa_utils import auth_dataset_whitelists_for_user
from cohorts.file_helpers import cohort_files
from cohorts.utils import get_sample_case_list_bq, create_cohort as make_cohort
from projects.models import Program

from jsonschema import validate as schema_validate, ValidationError
from schemas.cohort_filter_schema import COHORT_FILTER_SCHEMA

BLACKLIST_RE = settings.BLACKLIST_RE

logger = logging.getLogger(settings.LOGGER_NAME)

def get_file_manifest(cohort_id, user):
    file_manifest = None
    inc_filters = {}

    try:
        has_access = auth_dataset_whitelists_for_user(user.id)

        params = {
            'limit': settings.MAX_FILE_LIST_REQUEST,
            'build': 'HG19',
            'access': has_access
        }

        request_data = request.get_json()

        param_set = {
            'offset': {'default': 0, 'type': int, 'name': 'offset'},
            'page': {'default': 1, 'type': int, 'name': 'page'},
            'fetch_count': {'default': 5000, 'type': int, 'name': 'limit'},
            'genomic_build': {'default': "HG19", 'type': str, 'name': 'build'},
            'case_insensitive': {'default': "True", 'type': str, 'name': 'case_insensitive'}
        }

        for param, parameter in param_set.items():
            default = parameter['default']
            param_type = parameter['type']
            name = parameter['name']
            params[name] = request_data[param] if (request_data and param in request_data) else request.args.get(param, default=default, type=param_type) if param in request.args else default
            if name == 'case_insensitive':
                params[name] = bool(params[name] == "True")

            if request_data:
                inc_filters = {
                    filter: request_data[filter]
                    for filter in request_data.keys()
                    if filter not in list(param_set.keys())
                }

        response = cohort_files(cohort_id, user=user, inc_filters=inc_filters, **params)

        file_manifest = response['file_list'] if response and response['file_list'] else None

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        file_manifest = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }
    except Exception as e:
        logger.error("[ERROR] File trieving the file manifest for Cohort {}:".format(str(cohort_id)))
        logger.exception(e)

    return file_manifest

def get_cohort_info(cohort_id, get_barcodes=False):
    cohort = None
    try:
        cohort_obj = Cohort.objects.get(id=cohort_id)
        cohort = {
            'id': cohort_obj.id,
            'name': cohort_obj.name,
            'case_count': cohort_obj.case_size(),
            'sample_count': cohort_obj.sample_size(),
            'programs': cohort_obj.get_program_names(),
            'filters': cohort_obj.get_current_filters(True)
        }

        if get_barcodes:
            cohort['barcodes'] = get_sample_case_list_bq(cohort_id)

    except ObjectDoesNotExist as e:
        logger.warn("Cohort with ID {} was not found!".format(str(cohort_id)))
    except Exception as e:
        logger.exception(e)

    return cohort

def get_cohorts(user_email):

    cohort_list = None

    try:
        user = Django_User.objects.get(email=user_email)
        cohort_perms = Cohort_Perms.objects.filter(user_id=user.id, cohort__active=1)
        cohort_list = []
        for cohort_perm in cohort_perms:
            cohort_list.append({
                'id': cohort_perm.cohort.id,
                'name': cohort_perm.cohort.name,
                'permission': cohort_perm.perm,
                'filters': cohort_perm.cohort.get_current_filters(True)
            })

    except ObjectDoesNotExist as e:
        logger.info("No cohorts found for user {}!".format(user_email))

    return cohort_list

def get_cohort_counts():

    cohort_counts = None

    try:
        request_data = request.get_json()
        schema_validate(request_data, COHORT_FILTER_SCHEMA)

        if 'filters' not in request_data:
            cohort_counts = {
                'message': 'No filters were provided; ensure that the request body contains a \'filters\' property.'
            }
        else:
            case_insensitive = request_data['case_insensitive'] if (request_data and 'case_insensitive' in request_data) else request.args.get('case_insensitive', default="True", type=str) if 'case_insensitive' in request.args else "True"

            cohort_counts = get_sample_case_list_bq(None, request_data['filters'], case_insen=bool(case_insensitive == "True"))

            if cohort_counts:
                for prog in cohort_counts:
                    if cohort_counts[prog]['case_count'] <= 0:
                        cohort_counts[prog]['message'] = "No cases or samples found which meet the filter criteria for this program."
                    cohort_counts[prog]['provided_filters'] = request_data['filters'][prog]

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_counts = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }
    except ValidationError as e:
        logger.warn('[WARNING] Filters rejected for improper formatting: {}'.format(e))
        cohort_counts = {
            'message': 'Filters were improperly formatted.'
        }
    except Exception as e:
        logger.exception(e)

    return cohort_counts

def create_cohort(user):
    cohort_info = None

    try:
        request_data = request.get_json()
        schema_validate(request_data, COHORT_FILTER_SCHEMA)

        if 'name' not in request_data:
            cohort_info = {
                'message': 'A name was not provided for this cohort. The cohort was not made.',
            }
            return cohort_info

        if 'filters' not in request_data:
            cohort_info = {
                'message': 'Filters were not provided; at least one filter must be provided for a cohort to be valid.' +
                       ' The cohort was not made.',
            }
            return cohort_info

        blacklist = re.compile(BLACKLIST_RE, re.UNICODE)
        match = blacklist.search(str(request_data['name']))

        if not match and 'desc' in request_data:
            match = blacklist.search(str(request_data['desc']))

        if match:
            cohort_info = {
                'message': 'Your cohort\'s name or description contains invalid characters; please edit them and resubmit. ' +
                    '[Saw {}]'.format(str(match)),
            }

        else:
            result = make_cohort(user, **request_data)

            if 'message' in result:
                cohort_info = result
            else:
                cohort_info = get_cohort_info(result['cohort_id'])

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_info = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }

    except ValidationError as e:
        logger.warn("[WARNING] Cohort information rejected for improper formatting: {}".format(e))
        cohort_info = {
            'message': 'Cohort information was improperly formatted - cohort not edited.',
        }

    return cohort_info

def edit_cohort(cohort_id, user, delete=False):
    match = None

    try:
        if delete:
            cohort = Cohort.objects.get(id=cohort_id)
            cohort.active = False
            cohort.save()
            cohort_info = {
                'notes': 'Cohort {} (\'{}\') has been deleted.'.format(cohort_id, cohort.name),
                'data': {'filters': cohort.get_current_filters(unformatted=True)},
            }
        else:
            request_data = request.get_json()
            if len(request_data.keys()):
                schema_validate(request_data, COHORT_FILTER_SCHEMA)

            if 'name' in request_data:
                blacklist = re.compile(BLACKLIST_RE, re.UNICODE)
                match = blacklist.search(str(request_data['name']))

            if match:
                cohort_info = {
                    'message': 'Your cohort\'s name or description contains invalid characters; please edit them and resubmit. ' +
                               '[Saw {}]'.format(str(match)),
                }
            else:
                result = make_cohort(user, source_id=cohort_id, **request_data)
                if 'message' in result:
                    cohort_info = result
                else:
                    cohort_info = get_cohort_info(result['cohort_id'])

    except BadRequest as e:
        logger.warn("[WARNING] Received bad request - couldn't load JSON.")
        cohort_info = {
            'message': 'The JSON provided in this request appears to be improperly formatted.',
        }

    except ObjectDoesNotExist as e:
        logger.error("[ERROR] During {} for cohort ID {}:".format(request.method,str(cohort_id)))
        logger.error("Couldn't find a cohort with that ID!")

    except ValidationError as e:
        logger.warn("[WARNING] Cohort information rejected for improper formatting: {}".format(e))
        cohort_info = {
            'message': 'Cohort information was improperly formatted - cohort not edited.',
        }

    return cohort_info
<|endoftext|>


<commit_before>from src.webapp.pyspyInit import *
from src.webapp.jsonifyDF import *
from pyspark.sql.types import *         # for defining schema with various datatypes
import pyspark.sql.functions as func    # for ETL, data processing on Dataframes
from pyspark.sql.functions import udf

import ast                              # for evaluating and converting to a dict
from datetime import *                  # for datetime datatype for schema
from dateutil.parser import parse       # for string parse to date
from bokeh.palettes import *                                       # brewer color palette

########### Common Modules ###########
def get_match_df():
    match_rdd = sc.textFile(data_path + "matches.csv")        # reading csv files into RDD

    match_header = match_rdd.filter(lambda l: "id,season" in l)     # storing the header tuple
    match_no_header = match_rdd.subtract(match_header)              # subtracting it from RDD
    match_temp_rdd = match_no_header.map(lambda k: k.split(','))\
    .map(lambda p: (int(p[0]), p[1],p[2],parse(p[3]).date(),p[4]\
                    ,p[5],p[6],p[7],p[8],p[9]=='1',p[10],int(p[11])\
                    ,int(p[12]),p[13],p[14],p[15],p[16],p[17]))     # Transforming csv file data

    match_df = sql.createDataFrame(match_temp_rdd, match_rdd.first().split(','))  # converting to PysparkDF
    match_df = match_df.orderBy(match_df.id.asc())                                # asc sort by id
    return match_df

def dtype_cast(data, dtype):
    if dtype == "int":
        return int(data)
    elif dtype == "str":
        return str(data)
    elif dtype == "long":
        return long(data)
    elif dtype == "date":
        return parse(data).date()
    elif dtype == "string":
        return str(data)
    else:
        return dtype

def get_color_list(paletteName,numRows):
    return all_palettes[paletteName][numRows]

def get_dropdown_list(srcDF, attr, sort_req, dtype):
    attrDF = srcDF.select(attr).distinct()

    if sort_req:
        attrDF = attrDF.orderBy(attr)

    attr_range = [dtype_cast(i[0], dtype) for i in attrDF.collect()]
    return attr_range

########### Overall Standings Module ###########
def get_overall_ranks_df(season_num, srcDF):
    overall_ranking = srcDF.filter(srcDF.season == season_num)\
                    .groupBy("winner").count().orderBy("count",ascending=0) # extracting required columns into another DF

    overall_ranking = overall_ranking.filter("winner != '' ")                          # Deleting records of tied matches
    overall_ranking = overall_ranking.selectExpr("winner as Team", "count as Wins")   # Renaming columns
    return overall_ranking

def overall_rank_jsonify(srcDF, season_num):
    result_DF = get_overall_ranks_df(season_num, srcDF)
    return toJsonObj(result_DF)

########### Performance Consistency Module ###########
def get_consistency_DF(srcDF, season_lbound, season_ubound):
    consistency_df = srcDF.select("season","winner")\
    .groupBy("season","winner").count().orderBy("winner")                  # extracting required columns

    consistency_df = consistency_df.filter("winner!='' ")                  # filtering out tied matches records

    cond1 = func.col("season") >= season_lbound
    cond2 = func.col("season") <= season_ubound
    consistency_df = consistency_df.filter(cond1 & cond2)
    return consistency_df

def get_constraints(srcDF):
    # constraint : teams that haven't played more than three season aren't considered
    constraint_df = srcDF.groupBy("winner","season")\
                .count().orderBy("winner")                                 # extracting list of season-wise winner teams

    constraint_df = constraint_df.groupBy("winner").count()\
                .filter("count>3 and winner!='' ")                       # filtering out teams that don't satisfy constraint
    return constraint_df

def filter_using_constraints(consistency_df, constraint_list):
    consistency_df = consistency_df.where(func.col("winner")\
                    .isin(constraint_list))                                # applying the constraint list

    consistency_df = consistency_df.groupBy("winner")\
                    .agg(func.stddev_pop("count").alias("stddev"),\
                    func.sum("count").alias("total_wins"))\
                    .orderBy("stddev","total_wins")                        # calculating the performance consistency
    return consistency_df

def calc_consistency(consistency_df):
    consistency_df = consistency_df.withColumn("final_deviations",\
                    ((10-consistency_df.stddev)/10)*100)\
                    .orderBy("final_deviations", ascending=False)          # scaling to appropriate scale

    consistency_df = consistency_df.selectExpr("winner as Teams", "final_deviations as Consistency")
    return consistency_df

def consistency_jsonify(srcDF, season_lbound = 2008, season_ubound = 2016):
    result_DF = get_consistency_DF(srcDF, season_lbound, season_ubound)      # extracting required columns
    constraints_df = get_constraints(srcDF)
    constraints_list = [i.winner for i in constraints_df.collect()]          # storing a list of filtered teams
    result_DF = filter_using_constraints(result_DF, constraints_list)
    result_DF = calc_consistency(result_DF)

    return toJsonObj(result_DF)

########### Team Vs Team Win Percentage Module ###########
def get_winnerDF(srcDF):
    return srcDF.select(srcDF.team1,srcDF.team2,srcDF.winner)

def team_vs_team_jsonify(srcDF, team1, team2):
    if team1 == team2:                          #check whether the two teams selected are same or not.
        return "SAME TEAM"
    else:
        winnerDF = get_winnerDF(srcDF)

        team1_= winnerDF.filter(winnerDF.team1 == team1)
        team11_ = winnerDF.filter(winnerDF.team2 == team1)
        team2_= team1_.filter(team1_.team2 == team2)
        team22_ = team11_.filter(team11_.team1 == team2)

        winners1_ = team2_.filter(team2_.winner == team1)#checking the matches won by the team1
        winners11_ = team22_.filter(team22_.winner == team1)
        winners2_ = team2_.filter(team2_.winner == team2)  #checking the matches won by the team2
        winners22_ = team22_.filter(team22_.winner == team2)

        #number of matches won by first team
        team1_win = winners1_.count()
        team1_win2 = winners11_.count()

        #number of matches won by second team
        team2_win = winners2_.count()
        team2_win2 = winners22_.count()

        total_matches = team22_.count() + team2_.count() #taking the count of total number of matches

        if team1_win+team2_win+team1_win2+team2_win2 != total_matches:    #checking for any matches without any result
            total_matches = total_matches - (total_matches -(team1_win + team2_win + team1_win2 + team2_win2))  #calculating new total matches played with significant result

        if total_matches == 0:  #checking if the teams ever played a match between each other
            return "NO MATCHES PLAYED BEFORE"
        else:
            team1_percent = ((team1_win + team1_win2) * 100)/float(total_matches) #calculating the percentage win for first team
            team2_percent = ((team2_win + team2_win2) * 100)/float(total_matches) #calculating the percentage win for second team
            return jsonify_Percents(team1, team2, team1_percent, team2_percent)

########### Dream Team Module ###########
def dream_team_jsonify(season1 = 2008, season2 = 2016):
    teamDF = (sql.read.format("com.databricks.spark.csv").\
            option("header","true").load(data_opath + "dreamTeam" + season1+"_"+season2+".csv"))
    teamDF.printSchema()
    teamDF = teamDF.drop('_c0')
    teamDF.printSchema()
    return toJsonObj(teamDF)

########### Player Performance Module ###########
def get_fieldDF():
    field = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "fielder.csv"))
    return field

def get_batDF():
    bat = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "batsman.csv"))
    return bat

def get_bowlDF():
    bowl = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "bowler.csv"))
    return bowl

def Player_Performance_jsonify(player):

    batc = get_batDF()
    bowlc = get_bowlDF()
    fieldc = get_fieldDF()

    field_max_overall = int(fieldc.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #droping the duplicate rows having fielder, overall and ratings common.

    field2 = fieldc.dropDuplicates(['fielder','overall','ratings'])

    #calcuating the overall ratings of every fielder relative to the maximum

    fielder_ratings = field2.withColumn('ratings_overall', (fieldc.overall / field_max_overall*100)).sort("overall",ascending=0)

    #toIntfunc is a function which converts the values to integer.

    toIntfunc = udf(lambda x: int(x),IntegerType())

    #converting the column "overall" to integer.

    bat2 = batc.withColumn("overall",toIntfunc(batc['overall']))

    #computing the batsman's overall maximum

    bat_max_overall = int (bat2.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #calcuating the overall ratings of every batsman relative to the maximum

    batsman_ratings = bat2.withColumn('ratings_overall', (bat2.overall / bat_max_overall*100)).sort("overall",ascending=0)

    #converting the column "overall" to integer.

    bowl2 = bowlc.withColumn("overall",toIntfunc(bowlc['overall']))

    #computing the bowler's overall maximum

    bowl_max_overall = int (bowl2.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #calcuating the overall ratings of every bowler relative to the maximum

    bowler_ratings = bowl2.withColumn('ratings_overall', (bowl2.overall / bowl_max_overall*100)).sort("overall",ascending=0)

    #converting the new overall ratings to integer.

    bowler_ratings2 = bowler_ratings.withColumn("ratings_overall",toIntfunc(bowler_ratings['ratings_overall']))
    fielder_ratings2 = fielder_ratings.withColumn("ratings_overall",toIntfunc(fielder_ratings['ratings_overall']))
    batsman_ratings2 = batsman_ratings.withColumn("ratings_overall",toIntfunc(batsman_ratings['ratings_overall']))

    batsman_name = batsman_ratings2.filter(batsman_ratings2.batsman == player)
    bowler_name = bowler_ratings2.filter(bowler_ratings2.bowler == player)
    fielder_name = fielder_ratings2.filter(fielder_ratings2.fielder == player)

    if batsman_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        bat = 10
    else:
        bat = int(batsman_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    if bowler_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        bowl = 5
    else:
        bowl = int(bowler_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    if fielder_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        field = 25
    else:
        field = int(fielder_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    return jsonify_Ratings(player,bat,bowl,field)

<commit_msg>removed print schema and corrected base score<commit_after>from src.webapp.pyspyInit import *
from src.webapp.jsonifyDF import *
from pyspark.sql.types import *         # for defining schema with various datatypes
import pyspark.sql.functions as func    # for ETL, data processing on Dataframes
from pyspark.sql.functions import udf

import ast                              # for evaluating and converting to a dict
from datetime import *                  # for datetime datatype for schema
from dateutil.parser import parse       # for string parse to date
from bokeh.palettes import *                                       # brewer color palette

########### Common Modules ###########
def get_match_df():
    match_rdd = sc.textFile(data_path + "matches.csv")        # reading csv files into RDD

    match_header = match_rdd.filter(lambda l: "id,season" in l)     # storing the header tuple
    match_no_header = match_rdd.subtract(match_header)              # subtracting it from RDD
    match_temp_rdd = match_no_header.map(lambda k: k.split(','))\
    .map(lambda p: (int(p[0]), p[1],p[2],parse(p[3]).date(),p[4]\
                    ,p[5],p[6],p[7],p[8],p[9]=='1',p[10],int(p[11])\
                    ,int(p[12]),p[13],p[14],p[15],p[16],p[17]))     # Transforming csv file data

    match_df = sql.createDataFrame(match_temp_rdd, match_rdd.first().split(','))  # converting to PysparkDF
    match_df = match_df.orderBy(match_df.id.asc())                                # asc sort by id
    return match_df

def dtype_cast(data, dtype):
    if dtype == "int":
        return int(data)
    elif dtype == "str":
        return str(data)
    elif dtype == "long":
        return long(data)
    elif dtype == "date":
        return parse(data).date()
    elif dtype == "string":
        return str(data)
    else:
        return dtype

def get_color_list(paletteName,numRows):
    return all_palettes[paletteName][numRows]

def get_dropdown_list(srcDF, attr, sort_req, dtype):
    attrDF = srcDF.select(attr).distinct()

    if sort_req:
        attrDF = attrDF.orderBy(attr)

    attr_range = [dtype_cast(i[0], dtype) for i in attrDF.collect()]
    return attr_range

########### Overall Standings Module ###########
def get_overall_ranks_df(season_num, srcDF):
    overall_ranking = srcDF.filter(srcDF.season == season_num)\
                    .groupBy("winner").count().orderBy("count",ascending=0) # extracting required columns into another DF

    overall_ranking = overall_ranking.filter("winner != '' ")                          # Deleting records of tied matches
    overall_ranking = overall_ranking.selectExpr("winner as Team", "count as Wins")   # Renaming columns
    return overall_ranking

def overall_rank_jsonify(srcDF, season_num):
    result_DF = get_overall_ranks_df(season_num, srcDF)
    return toJsonObj(result_DF)

########### Performance Consistency Module ###########
def get_consistency_DF(srcDF, season_lbound, season_ubound):
    consistency_df = srcDF.select("season","winner")\
    .groupBy("season","winner").count().orderBy("winner")                  # extracting required columns

    consistency_df = consistency_df.filter("winner!='' ")                  # filtering out tied matches records

    cond1 = func.col("season") >= season_lbound
    cond2 = func.col("season") <= season_ubound
    consistency_df = consistency_df.filter(cond1 & cond2)
    return consistency_df

def get_constraints(srcDF):
    # constraint : teams that haven't played more than three season aren't considered
    constraint_df = srcDF.groupBy("winner","season")\
                .count().orderBy("winner")                                 # extracting list of season-wise winner teams

    constraint_df = constraint_df.groupBy("winner").count()\
                .filter("count>3 and winner!='' ")                       # filtering out teams that don't satisfy constraint
    return constraint_df

def filter_using_constraints(consistency_df, constraint_list):
    consistency_df = consistency_df.where(func.col("winner")\
                    .isin(constraint_list))                                # applying the constraint list

    consistency_df = consistency_df.groupBy("winner")\
                    .agg(func.stddev_pop("count").alias("stddev"),\
                    func.sum("count").alias("total_wins"))\
                    .orderBy("stddev","total_wins")                        # calculating the performance consistency
    return consistency_df

def calc_consistency(consistency_df):
    consistency_df = consistency_df.withColumn("final_deviations",\
                    ((10-consistency_df.stddev)/10)*100)\
                    .orderBy("final_deviations", ascending=False)          # scaling to appropriate scale

    consistency_df = consistency_df.selectExpr("winner as Teams", "final_deviations as Consistency")
    return consistency_df

def consistency_jsonify(srcDF, season_lbound = 2008, season_ubound = 2016):
    result_DF = get_consistency_DF(srcDF, season_lbound, season_ubound)      # extracting required columns
    constraints_df = get_constraints(srcDF)
    constraints_list = [i.winner for i in constraints_df.collect()]          # storing a list of filtered teams
    result_DF = filter_using_constraints(result_DF, constraints_list)
    result_DF = calc_consistency(result_DF)

    return toJsonObj(result_DF)

########### Team Vs Team Win Percentage Module ###########
def get_winnerDF(srcDF):
    return srcDF.select(srcDF.team1,srcDF.team2,srcDF.winner)

def team_vs_team_jsonify(srcDF, team1, team2):
    if team1 == team2:                          #check whether the two teams selected are same or not.
        return "SAME TEAM"
    else:
        winnerDF = get_winnerDF(srcDF)

        team1_= winnerDF.filter(winnerDF.team1 == team1)
        team11_ = winnerDF.filter(winnerDF.team2 == team1)
        team2_= team1_.filter(team1_.team2 == team2)
        team22_ = team11_.filter(team11_.team1 == team2)

        winners1_ = team2_.filter(team2_.winner == team1)#checking the matches won by the team1
        winners11_ = team22_.filter(team22_.winner == team1)
        winners2_ = team2_.filter(team2_.winner == team2)  #checking the matches won by the team2
        winners22_ = team22_.filter(team22_.winner == team2)

        #number of matches won by first team
        team1_win = winners1_.count()
        team1_win2 = winners11_.count()

        #number of matches won by second team
        team2_win = winners2_.count()
        team2_win2 = winners22_.count()

        total_matches = team22_.count() + team2_.count() #taking the count of total number of matches

        if team1_win+team2_win+team1_win2+team2_win2 != total_matches:    #checking for any matches without any result
            total_matches = total_matches - (total_matches -(team1_win + team2_win + team1_win2 + team2_win2))  #calculating new total matches played with significant result

        if total_matches == 0:  #checking if the teams ever played a match between each other
            return "NO MATCHES PLAYED BEFORE"
        else:
            team1_percent = ((team1_win + team1_win2) * 100)/float(total_matches) #calculating the percentage win for first team
            team2_percent = ((team2_win + team2_win2) * 100)/float(total_matches) #calculating the percentage win for second team
            return jsonify_Percents(team1, team2, team1_percent, team2_percent)

########### Dream Team Module ###########
def dream_team_jsonify(season1 = 2008, season2 = 2016):
    teamDF = (sql.read.format("com.databricks.spark.csv").\
            option("header","true").load(data_opath + "dreamTeam" + season1+"_"+season2+".csv"))
    teamDF = teamDF.drop('_c0')
    return toJsonObj(teamDF)

########### Player Performance Module ###########
def get_fieldDF():
    field = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "fielder.csv"))
    return field

def get_batDF():
    bat = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "batsman.csv"))
    return bat

def get_bowlDF():
    bowl = (sql.read.format("com.databricks.spark.csv").option("header", "true").load(data_opath + "bowler.csv"))
    return bowl

def Player_Performance_jsonify(player):

    batc = get_batDF()
    bowlc = get_bowlDF()
    fieldc = get_fieldDF()

    field_max_overall = int(fieldc.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #droping the duplicate rows having fielder, overall and ratings common.

    field2 = fieldc.dropDuplicates(['fielder','overall','ratings'])

    #calcuating the overall ratings of every fielder relative to the maximum

    fielder_ratings = field2.withColumn('ratings_overall', (fieldc.overall / field_max_overall*100)).sort("overall",ascending=0)

    #toIntfunc is a function which converts the values to integer.

    toIntfunc = udf(lambda x: int(x),IntegerType())

    #converting the column "overall" to integer.

    bat2 = batc.withColumn("overall",toIntfunc(batc['overall']))

    #computing the batsman's overall maximum

    bat_max_overall = int (bat2.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #calcuating the overall ratings of every batsman relative to the maximum

    batsman_ratings = bat2.withColumn('ratings_overall', (bat2.overall / bat_max_overall*100)).sort("overall",ascending=0)

    #converting the column "overall" to integer.

    bowl2 = bowlc.withColumn("overall",toIntfunc(bowlc['overall']))

    #computing the bowler's overall maximum

    bowl_max_overall = int (bowl2.describe(['overall']).filter("summary == 'max'").select('overall').collect()[0][0])

    #calcuating the overall ratings of every bowler relative to the maximum

    bowler_ratings = bowl2.withColumn('ratings_overall', (bowl2.overall / bowl_max_overall*100)).sort("overall",ascending=0)

    #converting the new overall ratings to integer.

    bowler_ratings2 = bowler_ratings.withColumn("ratings_overall",toIntfunc(bowler_ratings['ratings_overall']))
    fielder_ratings2 = fielder_ratings.withColumn("ratings_overall",toIntfunc(fielder_ratings['ratings_overall']))
    batsman_ratings2 = batsman_ratings.withColumn("ratings_overall",toIntfunc(batsman_ratings['ratings_overall']))

    batsman_name = batsman_ratings2.filter(batsman_ratings2.batsman == player)
    bowler_name = bowler_ratings2.filter(bowler_ratings2.bowler == player)
    fielder_name = fielder_ratings2.filter(fielder_ratings2.fielder == player)

    if batsman_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        bat = 5
    else:
        bat = int(batsman_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    if bowler_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        bowl = 2
    else:
        bowl = int(bowler_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    if fielder_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0] is None:
        field = 5
    else:
        field = int(fielder_name.describe(['ratings_overall']).filter("summary == 'max'").select('ratings_overall').collect()[0][0])

    return jsonify_Ratings(player,bat,bowl,field)

<|endoftext|>