Пример #1
0
    def join_create(self, data, sesh):
        """Join

		Connects a session to an account or contact so that any messages
		associated with either are stored for later polling

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['service', 'key'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Update the sync cache
        Sync.join(sesh.id(), data['service'], data['key'])

        # Return OK
        return Services.Effect(True)
Пример #2
0
    def favourite_create(self, data, sesh):
        """Favourite (Create)

		Adds a favourite to the logged in thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # If someone tries to add themselves
        if data['id'] == sesh['thrower']['_id']:
            return Services.Effect(False)

        # Make sure the thrower exists
        if not Thrower.exists(data['id']):
            return Services.Effect(error=(1104, data['id']))

        # Add the thrower to the logged in thrower's favourites and return the
        #	result
        return Services.Effect(
            Favourites.add(sesh['thrower']['_id'], data['id']))
Пример #3
0
    def leave_create(self, data, sesh):
        """Leave

		Disconnects a session from an account or contact so that messages are
		no longer collected for it

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['service', 'key'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Update the sync cache
        Sync.leave(sesh.id(), data['service'], data['key'])

        # Return OK
        return Services.Effect(True)
Пример #4
0
    def practiceData_read(self, data, sesh):
        """Practice Data

		Returns all the data points associated with a practice session

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Fetch the practice data
        dPractice = Practice.get(data['id'], raw=['data', 'stats'])
        if not dPractice:
            return Services.Effect(error=(1104, 'practice:%s' % data['id']))

        # Return the data
        return Services.Effect(dPractice)
Пример #5
0
    def pull_read(self, data, sesh):
        """Pull

		A client is requesting an update on anything they might be looking at

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['service', 'key'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # If we have messages to delete
        if 'messages' in data and data['messages']:
            Sync.clear(sesh.id(), data['service'], data['key'],
                       data['messages'])

        # Get as many messages as possible
        lRet = Sync.pull(sesh.id(), data['service'], data['key'])

        # Return whatever was found
        return Services.Effect(lRet)
Пример #6
0
    def clear_update(self, data, sesh):
        """Clear

		Clears the given number of messages from the sync cache

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['service', 'key', 'count'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Clear the messages from the sync cache
        Sync.clear(sesh.id(), data['service'], data['key'], data['count'])

        # Return OK
        return Services.Effect(True)
Пример #7
0
    def matchRequest_create(self, data, sesh):
        """Match Request (Create)

		Creates a new match request and notifies the opponent

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['opponent', 'org'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find opponent
        dOpponent = Thrower.get(data['opponent'], raw=['alias'])
        if not dOpponent:
            return Services.Effect(error=(1104,
                                          'thrower:%s' % data['opponent']))

        # Create a new request
        try:
            oRequest = MatchRequest({
                "_created": int(time()),
                "initiator": sesh['thrower']['_id'],
                "opponent": data['opponent'],
                "org": data['org']
            })
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Store the instance
        if not oRequest.create():
            return Services.Effect(error=1100)

        # Sync the data for anyone listening
        Sync.push(
            'auth', 'requests-%s' % data['opponent'], {
                "type": 'match_request',
                "_id": oRequest['_id'],
                "initiator": sesh['thrower']['_id'],
                "alias": sesh['thrower']['alias'],
                "org": data['org']
            })

        # Return the ID of the new request
        return Services.Effect(oRequest['_id'])
Пример #8
0
    def matchRequest_update(self, data, sesh):
        """Match Request (Update)

		Accepts a match request and creates the match with the proper service,
		then notifies both throwers of the ID of the new match

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the request
        oRequest = MatchRequest.get(data['id'])
        if not oRequest:
            return Services.Effect(error=(1104,
                                          'match_request:%s' % data['id']))

        # If the accepter is not the opponent
        if sesh['thrower']['_id'] != oRequest['opponent']:
            return Services.Effect(error=1000)

        # Create a new match in the proper service
        oEffect = Services.create(
            oRequest['org'].lower(), 'match', {
                "_internal_": Services.internalKey(),
                "initiator": oRequest['initiator'],
                "opponent": oRequest['opponent']
            }, sesh)
        if oEffect.errorExists():
            return oEffect

        # Delete the request
        oRequest.delete()

        # Notify the initiator of the new match
        Sync.push('auth', 'request-%s' % data['id'], {
            "type": "accepted",
            "match": oEffect.data
        })

        # Return the ID of the new match
        return Services.Effect(oEffect.data)
Пример #9
0
    def matchRequest_delete(self, data, sesh):
        """Match Request (Delete)

		Refuses a match request and deletes it

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the request
        oRequest = MatchRequest.get(data['id'])
        if not oRequest:
            return Services.Effect(error=(1104,
                                          'match_request:%s' % data['id']))

        # If the deleter is not the initiator or opponent
        if sesh['thrower']['_id'] != oRequest['initiator'] and \
         sesh['thrower']['_id'] != oRequest['opponent']:
            return Services.Effect(error=1000)

        # Delete it
        if not oRequest.delete():
            return Services.Effect(error=1102)

        # If the initiator retracted their request
        if sesh['thrower']['_id'] == oRequest['initiator']:

            # Let the opponent know
            Sync.push('auth', 'requests-%s' % oRequest['opponent'], {
                "type": "match_request_delete",
                "id": data['id']
            })

        # Else the opponent rejected the request
        else:

            # Let the initiator know
            Sync.push('auth', 'request-%s' % data['id'], {"type": "rejected"})

        # Return OK
        return Services.Effect(True)
Пример #10
0
    def practicePattern_update(self, data, sesh):
        """Practice Pattern (Update)

		Replaces an existing Practice Pattern for the current thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['_id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the pattern
        oPattern = PracticePattern.get(data['_id'])
        if not oPattern:
            return Services.Effect(error=(1104,
                                          'practice_pattern:%s' % data['_id']))

        # If the user has no rights
        if oPattern['thrower'] != sesh['thrower']['_id']:
            return Services.Effect(error=1000)

        # Remove fields that can't be changed
        del data['_id']
        if '_created' in data: del data['_created']
        if 'thrower' in data: del data['thrower']

        # Update whatever is left, catch any invalid values
        lErrors = []
        for k in data:
            try:
                oPattern[k] = data[k]
            except ValueError as e:
                lErrors.extend(e.args[0])

        # If there's any errors
        if lErrors:
            return Services.Effect(error=(103, lErrors))

        # Update the pattern
        oPattern.save()

        # Return OK
        return Services.Effect(True)
Пример #11
0
    def match_create(self, data, sesh):
        """Match (Create)

		Creates a new match and returns its ID

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['_internal_', 'initiator', 'opponent'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Verify the key, remove it if it's ok
        if not Services.internalKey(data['_internal_']):
            return Services.Effect(error=Errors.SERVICE_INTERNAL_KEY)
        del data['_internal_']

        # Create a new match instance
        try:
            oMatch = Match({
                "_created": int(time()),
                "finished": False,
                "calculated": False,
                "initiator": data['initiator'],
                "opponent": data['opponent'],
                "game_finished": {
                    "i": False,
                    "o": False
                },
                "game": {
                    "i": {},
                    "o": {}
                }
            })
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Store the instance
        if not oMatch.create():
            return Services.Effect(error=1100)

        # Return the ID
        return Services.Effect(oMatch['_id'])
Пример #12
0
    def signin_create(self, data):
        """Signin

		Signs a user into the system

		Arguments:
			data {dict} -- The data passed to the request

		Returns:
			Result
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['alias', 'passwd'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Look for the thrower by alias
        oThrower = Thrower.get(data['alias'], index='alias', limit=1)
        if not oThrower:
            return Services.Effect(error=1201)

        # Validate the password
        if not oThrower.passwordValidate(data['passwd']):
            return Services.Effect(error=1201)

        # Create a new session
        oSesh = Sesh.create()

        # Store the thrower ID and information in it
        oSesh['thrower'] = oThrower.record()

        # Save the session
        oSesh.save()

        # Return the session ID and primary thrower data
        return Services.Effect({
            "session": oSesh.id(),
            "thrower": {
                "_id": oSesh['thrower']['_id'],
                "alias": oSesh['thrower']['alias'],
                "org": oSesh['thrower']['org']
            }
        })
Пример #13
0
    def passwdForgot_update(self, data):
        """Password Forgot (Change Password)

		Validates the key and changes the password to the given value

		Arguments:
			data {dict} -- Data sent with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['passwd', 'key'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Look for the thrower by the key
        oThrower = Thrower.get(filter={"forgot": {
            "key": data['key']
        }},
                               limit=1)
        if not oThrower:
            return Services.Effect(
                error=1203)  # Don't let people know if the key exists or not

        # Check if we even have a forgot section, or the key has expired, or the
        #	key is invalid
        if 'forgot' not in oThrower or \
         oThrower['forgot']['expires'] <= int(time()) or \
         oThrower['forgot']['key'] != data['key']:
            return Services.Effect(error=1203)

        # Make sure the new password is strong enough
        if not Thrower.passwordStrength(data['passwd']):
            return Services.Effect(error=1204)

        # Store the new password and update
        oThrower['passwd'] = Thrower.passwordHash(data['passwd'])
        oThrower.fieldDelete('forgot')
        oThrower.save(changes=False)

        # Return OK
        return Services.Effect(True)
Пример #14
0
    def throwerVerify_update(self, data):
        """Thrower Verify

		Sets the thrower's email to verified if the key is valid

		Arguments:
			data {dict} -- Data sent with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['_internal_', 'id', 'verify'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Verify the key, remove it if it's ok
        if not Services.internalKey(data['_internal_']):
            return Services.Effect(error=Errors.SERVICE_INTERNAL_KEY)
        del data['_internal_']

        # Find the thrower
        oThrower = Thrower.get(data['id'])

        # If it doesn't exist
        if not oThrower:
            return Services.Effect(error=(1104, data['id']))

        # If the thrower is already verified
        if oThrower['verified'] == True:
            return Services.Effect(True)

        # If the code is not valid
        if data['verify'] != oThrower['verified']:
            return Services.Effect(error=1205)

        # Update the thrower
        oThrower['verified'] = True
        oThrower.save(changes=False)

        # Return OK
        return Services.Effect(True)
Пример #15
0
    def match_delete(self, data, sesh):
        """Match (Delete)

		Deletes an existing match, can only be done if it's not finished

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Get the match
        dMatch = Match.get(data['id'],
                           raw=['finished', 'initiator', 'opponent'])
        if not dMatch:
            return Services.Effect(error=(1104, 'watl_match:%s' % data['id']))

        # If the thrower is neither the initiator or opponent, or the match is
        #	already marked finished
        if (dMatch['initiator'] != sesh['thrower']['_id'] and \
         dMatch['opponent'] != sesh['thrower']['_id']) or \
         dMatch['finished']:
            return Services.Effect(error=1000)

        # Else, attempt to delete the record
        Match.deleteGet(data['id'])

        # Notify anyone watching the match
        Sync.push('watl', 'match-%s' % data['id'], {"type": "deleted"})

        # Return OK
        return Services.Effect(True)
Пример #16
0
    def matchRequest_read(self, data, sesh):
        """Match Request (Read)

		Fetchs a match request and returns it

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the request
        dRequest = MatchRequest.get(data['id'], raw=True)
        if not dRequest:
            return Services.Effect(error=(1104,
                                          'match_request:%s' % data['id']))

        # Get the ID of the other thrower
        if sesh['thrower']['_id'] == dRequest['initiator']:
            sID = dRequest['opponent']
        elif sesh['thrower']['_id'] == dRequest['opponent']:
            sID = dRequest['initiator']
        else:
            return Services.Effect(error=1000)

        # Get the other thrower's alias and add it to the request
        dAlias = Thrower.get(sID, raw=['alias'])
        dRequest['alias'] = dAlias and dAlias['alias'] or 'N/A'

        # Return the request
        return Services.Effect(dRequest)
Пример #17
0
    def throwerOrg_update(self, data, sesh):
        """Thrower Org

		Changes the default organisation for the current signed in user

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the user

		Returns:
			Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['org'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the thrower
        oThrower = Thrower.get(sesh['thrower']['_id'])
        if not oThrower:
            return Services.Effect(error=1104)

        # Set the new org
        try:
            oThrower['org'] = data['org']
        except ValueError:
            return Services.Effect(error=(1000, [('org', 'invalid')]))

        # Save
        oThrower.save(changes={"creator": sesh['thrower']['_id']})

        # Update the session
        sesh['thrower']['org'] = data['org']
        sesh.save()

        # Return OK
        return Services.Effect(True)
Пример #18
0
    def match_read(self, data, sesh):
        """Match (Read)

		Fetches and returns the stats from an existing match

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the match
        dMatch = Match.get(data['id'], raw=True)
        if not dMatch:
            return Services.Effect(error=(1104, 'watl_match:%s' % data['id']))

        # Get the aliases of both throwers
        oEffect = Services.read(
            'auth', 'thrower/aliases', {
                "_internal_": Services.internalKey(),
                "ids": [dMatch['opponent'], dMatch['initiator']]
            })
        if oEffect.errorExists():
            return oEffect

        # Add the aliases
        dMatch['initiator_alias'] = oEffect.data[dMatch['initiator']]
        dMatch['opponent_alias'] = oEffect.data[dMatch['opponent']]

        # Else return the match
        return Services.Effect(dMatch)
Пример #19
0
    def search_read(self, data, sesh):
        """Search

		Looks up throwers by alias

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['q'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Run a search and return the results
        return Services.Effect(Thrower.search(data['q']))
Пример #20
0
    def throwerPasswd_update(self, data, sesh):
        """Thrower Password

		Changes the password for the current signed in user

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the user

		Returns:
			Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['passwd', 'new_passwd'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the thrower
        oThrower = Thrower.get(sesh['thrower']['_id'])
        if not oThrower:
            return Services.Effect(error=1104)

        # Validate the password
        if not oThrower.passwordValidate(data['passwd']):
            return Services.Effect(error=(1001, [('passwd', 'invalid')]))

        # Make sure the new password is strong enough
        if not Thrower.passwordStrength(data['new_passwd']):
            return Services.Effect(error=1204)

        # Set the new password and save
        oThrower['passwd'] = Thrower.passwordHash(data['new_passwd'])
        oThrower.save(changes={"creator": sesh['thrower']['_id']})

        # Return OK
        return Services.Effect(True)
Пример #21
0
    def throwerAlias_update(self, data, sesh):
        """Thrower Alias

		Changes the alias associated with the thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['alias'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # If the alias is invalid
        if not Thrower.struct()['tree']['alias'].valid(data['alias']):
            return Services.Effect(error=(1001, [('alias', 'invalid')]))

        # Look for someone else with that alias
        dThrower = Thrower.get(data['alias'], index='alias', raw=['_id'])
        if dThrower:
            return Services.Effect(error=(1200, data['alias']))

        # Try to change the alias
        if not Thrower.alias(sesh['thrower']['_id'], data['alias']):
            return Services.Effect(False)

        # Update the session
        sesh['thrower']['alias'] = data['alias']
        sesh.save()

        # Return OK
        return Services.Effect(True)
Пример #22
0
    def practicePattern_create(self, data, sesh):
        """Practice Pattern (Create)

		Creates a new Practice Pattern for the current thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['title', 'descr', 'throws'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Create the instance
        try:
            oPattern = PracticePattern({
                "_created": int(time()),
                "thrower": sesh['thrower']['_id'],
                "title": data['title'],
                "descr": data['descr'],
                "throws": data['throws']
            })
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Store the instance
        if not oPattern.create():
            return Services.Effect(error=1100)

        # Return the new ID
        return Services.Effect(oPattern['_id'])
Пример #23
0
    def throwerAliases_read(self, data):
        """Thrower Aliases

		Recieves a list of thrower IDs and returns a dictionary of IDs to
		aliases

		Arguments:
			data {dict} -- Data sent with the request

		Returns:
			Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['_internal_', 'ids'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Verify the key, remove it if it's ok
        if not Services.internalKey(data['_internal_']):
            return Services.Effect(error=Errors.SERVICE_INTERNAL_KEY)
        del data['_internal_']

        # If the IDs are not a list
        if not isinstance(data['ids'], list):
            return Services.Effect(error=(1001, [('ids', 'not a list')]))

        # If the list is empty
        if not data['ids']:
            return Services.Effect({})

        # Get and return all the thrower aliases
        return Services.Effect({
            d['_id']: d['alias']
            for d in Thrower.get(data['ids'], raw=['_id', 'alias'])
        })
Пример #24
0
    def practicePattern_delete(self, data, sesh):
        """Practice Pattern (Delete)

		Deletes an existing Practice Pattern for the current thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Find the pattern
        oPattern = PracticePattern.get(data['id'])
        if not oPattern:
            return Services.Effect(error=(1104,
                                          'practice_pattern:%s' % data['id']))

        # If the user has no rights
        if oPattern['thrower'] != sesh['thrower']['_id']:
            return Services.Effect(error=1000)

        # Delete the pattern
        if not oPattern.delete():
            return Services.Effect(False)

        # Return OK
        return Services.Effect(True)
Пример #25
0
    def favourite_delete(self, data, sesh):
        """Favourite (Delete)

		Removes a favourite from the logged in thrower

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- The session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Remove the thrower from the logged in thrower's favourites and return
        #	the result
        return Services.Effect(
            Favourites.remove(sesh['thrower']['_id'], data['id']))
Пример #26
0
    def matchFinishOvertime_update(self, data, sesh):
        """Match Finish Overtime

		Marks the overtime part as finished. If both throwers are finished,
		verifies and notifies if the game is over

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Get the match
        dMatch = Match.get(
            data['id'], raw=['finished', 'initiator', 'opponent', 'overtime'])
        if not dMatch:
            return Services.Effect(error=(1104, 'watl_match:%s' % data['id']))

        # If the match is already finished
        if dMatch['finished']:
            return Services.Effect(error=1002)

        # Is the thrower the initiator or the opponent?
        if sesh['thrower']['_id'] == dMatch['initiator']:
            sIs = 'i'
        elif sesh['thrower']['_id'] == dMatch['opponent']:
            sIs = 'o'
        else:
            return Services.Effect(error=1000)

        # If the thrower already marked the match as finished
        if dMatch['overtime']['finished'][sIs]:
            return Services.Effect(True)

        # Update the finished state
        Match.finishOvertime(data['id'], sIs)

        # Fetch the updated data
        dMatch = Match.get(data['id'], raw=['overtime'])

        # If both sides are done
        if dMatch['overtime']['finished'] == {'i': True, 'o': True}:

            # If the lengths don't match
            if len(dMatch['overtime']['i']) != len(dMatch['overtime']['o']):

                # Reset finished
                Match.finishOvertimeReset(data['id'])

                # Notify throwers we aren't finished
                Sync.push('watl', 'match-%s' % data['id'], {
                    "type": "overtime",
                    "subtype": "notfinished"
                })

                # Return failure
                return Services.Effect(False)

            # Init the consecutive successes
            iCons = 0

            # Count up until we have a clear winner or loser
            for i in range(len(dMatch['overtime']['i'])):

                # If we got a drop, consider it a zero
                if dMatch['overtime']['i'][i] == 'd':
                    dMatch['overtime']['i'][i] = 0
                if dMatch['overtime']['o'][i] == 'd':
                    dMatch['overtime']['o'][i] = 0

                # If they aren't the same
                if dMatch['overtime']['i'][i] != dMatch['overtime']['o'][i]:

                    # Mark as finished
                    Match.finished(data['id'])

                    # Notify throwers
                    Sync.push(
                        'watl', 'match-%s' % data['id'], {
                            "type":
                            "winner",
                            "is":
                            dMatch['overtime']['i'][i] >
                            dMatch['overtime']['o'][i] and 'i' or 'o'
                        })

                    # Break out of the loop
                    break

            # If we didn't get a winner, something is wrong
            else:

                # Reset finished
                Match.finishOvertimeReset(data['id'])

                # Notify throwers we aren't finished
                Sync.push('watl', 'match-%s' % data['id'], {
                    "type": "overtime",
                    "subtype": "notfinished"
                })

                # Return failure
                return Services.Effect(False)

        # Return OK
        return Services.Effect(True)
Пример #27
0
    def practice_create(self, data, sesh):
        """Practice Create

		Stores the details of a practice session

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['points'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Make sure the value is a list of data points
        if not isinstance(data['points'], list):
            return Services.Effect(error=(1001, [('points',
                                                  'must be a list')]))

        # Init the stored structure
        dData = {
            "_created": int(time()),
            "data": [],
            "thrower": sesh['thrower']['_id'],
            "stats": {
                "ksLeft": {
                    "attempts": 0,
                    "drops": 0,
                    "hits": 0,
                    "points": 0
                },
                "ksRight": {
                    "attempts": 0,
                    "drops": 0,
                    "hits": 0,
                    "points": 0
                },
                "regular": {
                    "attempts": 0,
                    "sixes": 0,
                    "fours": 0,
                    "threes": 0,
                    "twos": 0,
                    "ones": 0,
                    "zeros": 0,
                    "drops": 0,
                    "hits": 0,
                    "points": 0
                }
            }
        }

        # Go through every set
        for l in data['points']:

            # If it's a killshot
            if l[0] == 'L':

                # Increase the attempts
                dData['stats']['ksLeft']['attempts'] += 1

                # If it's a drop
                if l[1] == 'd':
                    dData['stats']['ksLeft']['drops'] += 1

                # If it's a hit
                elif l[1] == 8:
                    dData['stats']['ksLeft']['hits'] += 1
                    dData['stats']['ksLeft']['points'] += 8

                # Add the points
                else:
                    dData['stats']['ksLeft']['points'] += l[1]

            elif l[0] == 'R':

                # Increase the attempts
                dData['stats']['ksRight']['attempts'] += 1

                # If it's a drop
                if l[1] == 'd':
                    dData['stats']['ksRight']['drops'] += 1

                # If it's a hit
                elif l[1] == 8:
                    dData['stats']['ksRight']['hits'] += 1
                    dData['stats']['ksRight']['points'] += 8

                # Add the points
                else:
                    dData['stats']['ksRight']['points'] += l[1]

            # Else it's a standard throw
            else:

                # Increase the attempts
                dData['stats']['regular']['attempts'] += 1

                # Increase the appropriate value
                if l[1] == 'd':
                    dData['stats']['regular']['drops'] += 1
                elif l[1] == 6:
                    dData['stats']['regular']['sixes'] += 1
                    dData['stats']['regular']['hits'] += 1
                    dData['stats']['regular']['points'] += 5
                elif l[1] == 4:
                    dData['stats']['regular']['fours'] += 1
                    dData['stats']['regular']['hits'] += 1
                    dData['stats']['regular']['points'] += 5
                elif l[1] == 3:
                    dData['stats']['regular']['threes'] += 1
                    dData['stats']['regular']['hits'] += 1
                    dData['stats']['regular']['points'] += 3
                elif l[1] == 2:
                    dData['stats']['regular']['twos'] += 1
                    dData['stats']['regular']['hits'] += 1
                    dData['stats']['regular']['points'] += 3
                elif l[1] == 1:
                    dData['stats']['regular']['ones'] += 1
                    dData['stats']['regular']['hits'] += 1
                    dData['stats']['regular']['points'] += 1
                elif l[1] == 0:
                    dData['stats']['regular']['zeros'] += 1

            # Append the set
            dData['data'].append({"killshot": l[0], "value": l[1]})

        # Create a new instance of the practice
        try:
            oPractice = Practice(dData)
        except ValueError as e:
            return Services.Effect(error=(1001, e.args[0]))

        # Store the instance
        if not oPractice.create():
            return Services.Effect(error=1100)

        # Update the total stats
        PracticeStats.add(sesh['thrower']['_id'], dData['stats'])

        # Return OK
        return Services.Effect(True)
Пример #28
0
    def matchGame_update(self, data, sesh):
        """Match Game Update

		Takes a new throw value and stores it, then notifies the opponent

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id', 'throw', 'value'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Get the match
        dMatch = Match.get(
            data['id'],
            raw=['finished', 'game_finished', 'initiator', 'opponent'])
        if not dMatch:
            return Services.Effect(error=(1104, 'natf_match:%s' % data['id']))

        # If the match is already finished
        if dMatch['finished']:
            return Services.Effect(error=1002)

        # Is the thrower the initiator or the opponent?
        if sesh['thrower']['_id'] == dMatch['initiator']:
            sIs = 'i'
        elif sesh['thrower']['_id'] == dMatch['opponent']:
            sIs = 'o'
        else:
            return Services.Effect(error=1000)

        # If the thrower already marked the match as finished
        if dMatch['game_finished'][sIs]:
            return Services.Effect(error=1002)

        # If the throw is not a valid value
        if data['throw'] not in [
                '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'
        ]:
            return Services.Effect(error=(1001, [('throw', 'invalid')]))

        # Validate the value
        dStruct = Match.struct()
        if not dStruct['tree']['game'][sIs][data['throw']].valid(
                data['value']):
            return Services.Effect(error=(1001, [('value',
                                                  'invalid data.value')]))

        # If it's throw 5, and clutch is set, but we didn't get 'd', 0, or 7
        if data['throw'] in ['5', '10']:
            if data['value']['killshot'] != '0':
                if data['value']['value'] not in ['d', 0, 8]:
                    return Services.Effect(
                        error=(1001, [('value', 'invalid data.value.value')]))

        # Update the throw
        Match.updateThrow(data['id'], sIs, data['throw'], data['value'])

        # Notify anyone listening
        Sync.push(
            'watl', 'match-%s' % data['id'], {
                "type": "throw",
                "thrower": sIs,
                "throw": data['throw'],
                "value": data['value']
            })

        # Return OK
        return Services.Effect(True)
Пример #29
0
    def matchFinishGame_update(self, data, sesh):
        """Match Finish Game

		Marks the game as finished. If both throwers are finished, calculates
		if there's a winner or it's a tie

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # Get the match
        dMatch = Match.get(
            data['id'],
            raw=['finished', 'game_finished', 'initiator', 'opponent'])
        if not dMatch:
            return Services.Effect(error=(1104, 'natf_match:%s' % data['id']))

        # If the match is already finished
        if dMatch['finished']:
            return Services.Effect(error=1002)

        # Is the thrower the initiator or the opponent?
        if sesh['thrower']['_id'] == dMatch['initiator']:
            sIs = 'i'
        elif sesh['thrower']['_id'] == dMatch['opponent']:
            sIs = 'o'
        else:
            return Services.Effect(error=1000)

        # If the thrower already marked the match as finished
        if dMatch['game_finished'][sIs]:
            return Services.Effect(True)

        # Update the finished state
        Match.finishGame(data['id'], sIs)

        # Fetch the updated data
        dMatch = Match.get(data['id'], raw=['game', 'game_finished'])

        # If both sides are done
        if dMatch['game_finished']['i'] and dMatch['game_finished']['o']:

            # Calculate the stats
            dPoints = {"i": 0, "o": 0}
            for w in ["i", "o"]:
                for t in ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]:
                    if t in ['5', '10']:
                        if dMatch['game'][w][t]['value'] != 'd':
                            dPoints[w] += dMatch['game'][w][t]['value']
                    else:
                        if dMatch['game'][w][t] != 'd':
                            dPoints[w] += dMatch['game'][w][t]

            # If we don't have a winner
            if dPoints['i'] == dPoints['o']:

                # Add the overtime section
                Match.addOvertime(data['id'])

                # Start overtime mode
                Sync.push('watl', 'match-%s' % data['id'], {
                    "type": "overtime",
                    "subtype": "start"
                })

            # Else, send back the winner
            else:

                # Mark as finished
                Match.finished(data['id'])

                # Notify the throwers
                Sync.push(
                    'watl', 'match-%s' % data['id'], {
                        "type": "winner",
                        "is": dPoints['i'] > dPoints['o'] and 'i' or 'o'
                    })

        # Return OK
        return Services.Effect(True)
Пример #30
0
    def matchOvertime_update(self, data, sesh):
        """Match Overtime

		Takes a new throw for overtime and records it, then notifies the opponent

		Arguments:
			data {dict} -- Data sent with the request
			sesh {Sesh._Session} -- Session associated with the request

		Returns:
			Services.Effect
		"""

        # Verify fields
        try:
            DictHelper.eval(data, ['id', 'throw', 'value'])
        except ValueError as e:
            return Services.Effect(error=(1001, [(f, "missing")
                                                 for f in e.args]))

        # If the throw is not an int
        if not isinstance(data['throw'], int):
            return Services.Effect(error=(1001, [('throw', 'not an int')]))

        # If the value is anything other than 'd', 0, or 1
        if data['value'] not in ['d', 0, 1]:
            return Services.Effect(error=(1001, [('value', 'invalid')]))

        # Get the match
        dMatch = Match.get(
            data['id'], raw=['finished', 'initiator', 'opponent', 'overtime'])
        if not dMatch:
            return Services.Effect(error=(1104, 'watl_match:%s' % data['id']))

        # If the match is already finished
        if dMatch['finished']:
            return Services.Effect(error=1002)

        # Is the thrower the initiator or the opponent?
        if sesh['thrower']['_id'] == dMatch['initiator']:
            sIs = 'i'
        elif sesh['thrower']['_id'] == dMatch['opponent']:
            sIs = 'o'
        else:
            return Services.Effect(error=1000)

        # If the thrower already marked the section as finished
        if dMatch['overtime']['finished'][sIs]:
            return Services.Effect(error=1002)

        # If the value doesn't exist
        if len(dMatch['overtime'][sIs]) == data['throw']:
            dMatch['overtime'][sIs].append(data['value'])

        # Else, overwrite it
        else:
            dMatch['overtime'][sIs][data['throw']] = data['value']

        # Store the changes
        Match.updateOvertime(data['id'], sIs, dMatch['overtime'])

        # Notify anyone listening
        Sync.push(
            'watl', 'match-%s' % data['id'], {
                "type": "overtime",
                "subtype": "throw",
                "thrower": sIs,
                "throw": data['throw'],
                "value": data['value']
            })

        # Return OK
        return Services.Effect(True)