Esempio n. 1
0
    def get_response( self, body ):
        body_type = body.get( 'type' )

        # Currently 5 types: verifylogin, gamelist, categories, gamecategories
        # and submitrun
        if body_type is None:
            return self.get_fail_response( "No type given." )
        
        elif body_type == 'verifylogin':
            ( valid, response ) = self.verify_login( body )
            return response

        elif body_type == 'gamelist':
            return self.get_fail_response( "Type [" + body_type + "] currently"
                                           + " not supported dynamically, but "
                                           + "you can find a static JSON "
                                           + "response at "
                                           + "https://www.dropbox.com/s/"
                                           + "xnvsmx3mt0i4nbv/gamelist.json?dl"
                                           + "=0" )

        elif body_type == 'categories':
            return self.get_fail_response( "Type [" + body_type + "] currently"
                                           + " not supported dynamically, but "
                                           + "you can find a static JSON "
                                           + "response at "
                                           + "https://www.dropbox.com/s/"
                                           + "irdj4xakh72g541/categories.json?"
                                           + "dl=0" )

        elif body_type == 'modgamelist':
            # First, verify login credentials and that we are a mod
            ( valid, response ) = self.verify_mod_login( body )
            if not valid:
                return response

            # Note that this is a different type of gamelist than the one
            # generated in games.py
            categories = self.get_categories( )
            if categories == self.OVER_QUOTA_ERROR:
                return self.get_fail_response( "PB Tracker is currently "
                                               + "experiencing an over "
                                               + "quota downtime period." )
            d = dict( )
            for game in categories.keys( ):
                d[ util.get_code( game ) ] = game
            return self.get_success_response( data=d )

        elif body_type == 'modcategories':
            # First, verify login credentials and that we are a mod
            ( valid, response ) = self.verify_mod_login( body )
            if not valid:
                return response

            categories = self.get_categories( )
            if categories == self.OVER_QUOTA_ERROR:
                return self.get_fail_response( "PB Tracker is currently "
                                               + "experiencing an over "
                                               + "quota downtime period." )
            d = dict( )
            for game, categorylist in categories.iteritems( ):
                game_code = util.get_code( game )
                for category in categorylist:
                    category_code = util.get_code( category )
                    d[ game_code + ':' + category_code ] = ( game + ' - ' 
                                                             + category )
            return self.get_success_response( data=d )

        elif body_type == 'gamecategories':
            return self.get_fail_response( "Type [" + body_type + "] currently"
                                           + " not supported, sorry." )
#            game_code = body.get( 'game' )
#            game_model = self.get_game_model( game_code )
#            if game_code is None:
#                return self.get_fail_response( 'No game specified' )
#            elif game_model is None:
#                return self.get_fail_response( 'Unknown game [' 
#                                               + game_code + '].' )
#            TODO: elif game_model == self.OVER_QUOTA_ERROR:
#            else:
#                d = dict( )
#                gameinfolist = json.loads( game_model.info )
#                for gameinfo in gameinfolist:
#                    category = gameinfo['category']
#                    d[ util.get_code( category ) ] = category
#                return self.get_success_response( data=d )

        elif body_type == 'submitrun':
            # First, verify login credentials
            ( valid, response ) = self.verify_login( body )
            if not valid:
                return response

            # Grab the params from the body
            username = body.get( 'username' )
            game_code = body.get( 'game' )
            category_code = body.get( 'category' )
            version = body.get( 'version' )
            time = body.get( 'runtime' )
            video = body.get( 'video' )
            notes = body.get( 'comment' )
            splits = body.get( 'splits' )

            # Make sure the game and category exist (can't handle new games
            # and categories just yet)
            if game_code is None:
                return self.get_fail_response( 'No game given' )
            game_model = self.get_game_model( game_code )
            if game_model is None:
                return self.get_fail_response( 'Unknown game [' 
                                               + game_code + '].' )
            if game_model == self.OVER_QUOTA_ERROR:
                return self.get_fail_response( 'PB Tracker is currently over '
                                               + "quota. Please try again "
                                               + "later." )
            if category_code is None:
                return self.get_fail_response( 'No category specified' )
            gameinfolist = json.loads( game_model.info )
            category = None
            for gameinfo in gameinfolist:
                if category_code == util.get_code( gameinfo['category'] ):
                    category = gameinfo['category']
                    break
            if category is None:
                return self.get_fail_response( 'Unknown category [' 
                                               + category_code 
                                               + '] for game [' 
                                               + game_code + '].' )

            # Parse the time into seconds and ensure it is valid
            if time is None:
                return self.get_fail_response( 'No runtime given' )
            ( seconds, time_error ) = util.timestr_to_seconds( time )
            if seconds is None:
                return self.get_fail_response( 'Bad runtime [' + time 
                                               + '] given: ' + time_error )
            # Ensure standard format
            time = util.seconds_to_timestr( seconds )

            # Make sure that the notes are not too long
            if notes is not None and len( notes ) > 140:
                return self.get_fail_response( 'Comment is too long; must be '
                                               + 'at most 140 characters.' )

            # Figure out current date in user's local timezone
            user = self.get_runner( util.get_code( username ) )
            if user == self.OVER_QUOTA_ERROR:
                return False, self.get_fail_response( 
                    "PB Tracker is currently "
                    + "experiencing an over "
                    + "quota limit down time "
                    + "period." )
            if user.timezone:
                tz = pytz.timezone( user.timezone )
                local_today = datetime.now( pytz.utc ).astimezone( tz )
            else:
                # UTC by default
                local_today = datetime.now( pytz.utc )
            date = local_today.date( )

            # Load up the needed parameters and put a new run
            params = dict( user=user,
                           game=game_model.game,
                           game_code=game_code,
                           game_model=game_model,
                           category=category,
                           category_found=True,
                           seconds=seconds,
                           time=time,
                           video=video,
                           version=version,
                           notes=notes,
                           valid=True,
                           date=date,
                           datestr=date.strftime( "%m/%d/%Y" ),
                           is_bkt=False ) 
            if self.put_new_run( params ):
                return self.get_success_response( )
            else:
                if params.get( 'video_error' ):
                    return self.get_fail_response( 'Bad video link [' 
                                                   + video + ']: ' 
                                                   + params[ 'video_error' ] )
                else:
                    return self.get_fail_response( 'Sorry, an unknown error '
                                                   + 'occurred.' )
                    
        return self.get_fail_response( "Unknown type [" + body_type + "]." )
Esempio n. 2
0
    def get_response( self, body ):
        body_type = body.get( 'type' )

        # Currently 5 types: verifylogin, gamelist, categories, gamecategories
        # and submitrun
        if body_type is None:
            return self.get_fail_response( "No type given." )
        
        elif body_type == 'verifylogin':
            ( valid, response ) = self.verify_login( body )
            return response

        elif body_type == 'gamelist':
            # Note that this is a different type of gamelist than the one
            # generated in games.py
            categories = self.get_categories( )
            d = dict( )
            for game in categories.keys( ):
                d[ util.get_code( game ) ] = game
            return self.get_success_response( data=d )

        elif body_type == 'categories':
            categories = self.get_categories( )
            d = dict( )
            for game, categorylist in categories.iteritems( ):
                game_code = util.get_code( game )
                for category in categorylist:
                    category_code = util.get_code( category )
                    d[ game_code + ':' + category_code ] = ( game + ' - ' 
                                                             + category )
            return self.get_success_response( data=d )

        elif body_type == 'gamecategories':
            game_code = body.get( 'game' )
            game_model = self.get_game_model( game_code )
            if game_code is None:
                return self.get_fail_response( 'No game specified' )
            elif game_model is None:
                return self.get_fail_response( 'Unknown game [' 
                                               + game_code + '].' )
            else:
                d = dict( )
                gameinfolist = json.loads( game_model.info )
                for gameinfo in gameinfolist:
                    category = gameinfo['category']
                    d[ util.get_code( category ) ] = category
                return self.get_success_response( data=d )

        elif body_type == 'submitrun':
            # First, verify login credentials
            ( valid, response ) = self.verify_login( body )
            if not valid:
                return response

            # Grab the params from the body
            username = body.get( 'username' )
            game_code = body.get( 'game' )
            category_code = body.get( 'category' )
            version = body.get( 'version' )
            time = body.get( 'runtime' )
            video = body.get( 'video' )
            notes = body.get( 'comment' )
            splits = body.get( 'splits' )

            # Make sure the game and category exist (can't handle new games
            # and categories just yet)
            if game_code is None:
                return self.get_fail_response( 'No game given' )
            game_model = self.get_game_model( game_code )
            if game_model is None:
                return self.get_fail_response( 'Unknown game [' 
                                               + game_code + '].' )
            if category_code is None:
                return self.get_fail_response( 'No category specified' )
            gameinfolist = json.loads( game_model.info )
            category = None
            for gameinfo in gameinfolist:
                if category_code == util.get_code( gameinfo['category'] ):
                    category = gameinfo['category']
                    break
            if category is None:
                return self.get_fail_response( 'Unknown category [' 
                                               + category_code 
                                               + '] for game [' 
                                               + game_code + '].' )

            # Parse the time into seconds and ensure it is valid
            if time is None:
                return self.get_fail_response( 'No runtime given' )
            ( seconds, time_error ) = util.timestr_to_seconds( time )
            if seconds is None:
                return self.get_fail_response( 'Bad runtime [' + time 
                                               + '] given: ' + time_error )
            # Ensure standard format
            time = util.seconds_to_timestr( seconds )

            # Make sure that the notes are not too long
            if notes is not None and len( notes ) > 140:
                return self.get_fail_response( 'Comment is too long; must be '
                                               + 'at most 140 characters.' )

            # Figure out current date in user's local timezone
            user = self.get_runner( util.get_code( username ) )
            if user.timezone:
                tz = pytz.timezone( user.timezone )
                local_today = datetime.now( pytz.utc ).astimezone( tz )
            else:
                # UTC by default
                local_today = datetime.now( pytz.utc )
            date = local_today.date( )

            # Load up the needed parameters and put a new run
            params = dict( user=user,
                           game=game_model.game,
                           game_code=game_code,
                           game_model=game_model,
                           category=category,
                           category_found=True,
                           seconds=seconds,
                           time=time,
                           video=video,
                           version=version,
                           notes=notes,
                           valid=True,
                           date=date,
                           datestr=date.strftime( "%m/%d/%Y" ),
                           is_bkt=False ) 
            if self.put_new_run( params ):
                return self.get_success_response( )
            else:
                if params.get( 'video_error' ):
                    return self.get_fail_response( 'Bad video link [' 
                                                   + video + ']: ' 
                                                   + params[ 'video_error' ] )
                else:
                    return self.get_fail_response( 'Sorry, an unknown error '
                                                   + 'occurred.' )
                    
        return self.get_fail_response( "Unknown type [" + body_type + "]." )
Esempio n. 3
0
    def post(self):
        user = self.get_user()
        if not user:
            self.redirect("/")
            return

        game = self.request.get('game')
        category = self.request.get('category')
        time = self.request.get('time')
        datestr = self.request.get('date')
        video = self.request.get('video')
        version = self.request.get('version')
        notes = self.request.get('notes')
        is_bkt = self.request.get('bkt', default_value="no")
        if is_bkt == "yes":
            is_bkt = True
        else:
            is_bkt = False
        run_id = self.request.get('edit')

        params = dict(user=user,
                      game=game,
                      category=category,
                      time=time,
                      datestr=datestr,
                      video=video,
                      version=version,
                      notes=notes,
                      run_id=run_id,
                      is_bkt=is_bkt)

        valid = True

        # Make sure the game doesn't already exist under a similar name
        game_code = util.get_code(game)
        game_model = self.get_game_model(game_code)
        if not game_code:
            params['game_error'] = "Game cannot be blank"
            valid = False
        elif game_model is not None and game != game_model.game:
            params['game_error'] = ("Game already exists under [" +
                                    game_model.game + "] (case sensitive)." +
                                    " Hit submit again to confirm.")
            params['game'] = game_model.game
            valid = False
        elif not games.valid_game_or_category(game):
            params['game_error'] = ("Game name must not use any 'funny'" +
                                    " characters and can be up to 100 " +
                                    "characters long")
            valid = False
        params['game_code'] = game_code
        params['game_model'] = game_model

        # Make sure the category doesn't already exist under a similar name
        category_code = util.get_code(category)
        category_found = False
        if not category_code:
            params['category_error'] = "Category cannot be blank"
            valid = False
        elif game_model is not None:
            infolist = json.loads(game_model.info)
            for info in infolist:
                if category_code == util.get_code(info['category']):
                    category_found = True
                    if category != info['category']:
                        params['category_error'] = (
                            "Category already exists " + "under [" +
                            info['category'] + "] " + "(case sensitive). " +
                            "Hit submit again to " + "confirm.")
                        params['category'] = info['category']
                        valid = False
                    break
        if not category_found and not games.valid_game_or_category(category):
            params['category_error'] = ("Category must not use any 'funny'" +
                                        " characters and can be up to 100 " +
                                        "characters long")
            valid = False
        params['category_found'] = category_found

        # Parse the time into seconds, ensure it is valid
        (seconds, time_error) = util.timestr_to_seconds(time)
        if seconds is None:
            params['time_error'] = "Invalid time: " + time_error
            params['seconds'] = -1
            valid = False
        else:
            time = util.seconds_to_timestr(seconds)  # Enforce standard form
            params['time'] = time
            params['seconds'] = seconds

        # Parse the date, ensure it is valid
        (params['date'], params['date_error']) = util.datestr_to_date(datestr)
        if params['date_error']:
            params['date_error'] = "Invalid date: " + params['date_error']
            valid = False

        # Check that if this is a best known time, then it beats the old
        # best known time.
        if is_bkt and game_model is not None:
            gameinfolist = json.loads(game_model.info)
            for gameinfo in gameinfolist:
                if gameinfo['category'] == params['category']:
                    if (gameinfo.get('bk_seconds') is not None
                            and gameinfo['bk_seconds'] <= seconds):
                        s = ("This time does not beat current best known " +
                             "time of " + util.seconds_to_timestr(
                                 gameinfo.get('bk_seconds')) + " by " +
                             gameinfo['bk_runner'] +
                             " (if best known time is incorrect, you can " +
                             "update best known time after submission)")
                        params['bkt_error'] = s
                        params['is_bkt'] = False
                        valid = False
                    break

        # Check that if this is not the best known time, then it doesn't beat
        # the old best known time
        if not is_bkt and game_model is not None:
            gameinfolist = json.loads(game_model.info)
            for gameinfo in gameinfolist:
                if gameinfo['category'] == params['category']:
                    if (gameinfo.get('bk_seconds') is not None
                            and seconds < gameinfo['bk_seconds']):
                        s = (
                            "This time beats the current best known time of " +
                            util.seconds_to_timestr(gameinfo.get('bk_seconds'))
                            + " by " + gameinfo['bk_runner'] +
                            " (if best known time is incorrect, you can " +
                            "update best known time after submission)")
                        params['bkt_error'] = s
                        params['is_bkt'] = True
                        valid = False
                    break

        # Make sure that the notes are not too long
        if len(notes) > 140:
            params['notes_error'] = "Notes must be at most 140 characters"
            valid = False

        params['valid'] = valid

        if run_id:
            success = self.put_existing_run(params)
        else:
            success = self.put_new_run(params)
        if success:
            self.redirect("/runner/" + util.get_code(user.username) +
                          "?q=view-all")
        else:
            # Grab all of the games for autocompleting
            params['categories'] = self.get_categories()
            params['user'] = user
            self.render("submit.html", **params)
Esempio n. 4
0
    def post( self ):
        user = self.get_user( )
        if not user:
            self.redirect( "/" )
            return

        game = self.request.get( 'game' )
        category = self.request.get( 'category' )
        time = self.request.get( 'time' )
        datestr = self.request.get( 'date' )
        video = self.request.get( 'video' )
        version = self.request.get( 'version' )
        notes = self.request.get( 'notes' )
        is_bkt = self.request.get( 'bkt', default_value="no" )
        if is_bkt == "yes":
            is_bkt = True
        else:
            is_bkt = False
        run_id = self.request.get( 'edit' )

        params = dict( user = user, game = game, category = category, 
                       time = time, datestr = datestr, video = video, 
                       version = version, notes = notes, run_id = run_id, 
                       is_bkt = is_bkt )

        valid = True

        # Make sure the game doesn't already exist under a similar name
        game_code = util.get_code( game )
        game_model = self.get_game_model( game_code )
        if not game_code:
            params['game_error'] = "Game cannot be blank"
            valid = False
        elif game_model is not None and game != game_model.game:
            params['game_error'] = ( "Game already exists under [" 
                                     + game_model.game + "] (case sensitive)."
                                     + " Hit submit again to confirm." )
            params['game'] = game_model.game
            valid = False
        elif not valid_game_or_category( game ):
            params['game_error'] = ( "Game name must not use any 'funny'"
                                     + " characters and can be up to 100 "
                                     + "characters long" )
            valid = False
        params[ 'game_code' ] = game_code
        params[ 'game_model' ] = game_model

        # Make sure the category doesn't already exist under a similar name
        category_code = util.get_code( category )
        category_found = False
        if not category_code:
            params['category_error'] = "Category cannot be blank"
            valid = False
        elif game_model is not None:
            infolist = json.loads( game_model.info )
            for info in infolist:
                if category_code == util.get_code( info['category'] ):
                    category_found = True
                    if category != info['category']:
                        params['category_error'] = ( "Category already exists "
                                                     + "under [" 
                                                     + info['category'] + "] "
                                                     + "(case sensitive). "
                                                     + "Hit submit again to "
                                                     + "confirm." )
                        params['category'] = info['category']
                        valid = False
                    break
        if not category_found and not valid_game_or_category( category ):
            params['category_error'] = ( "Category must not use any 'funny'"
                                         + " characters and can be up to 100 "
                                         + "characters long" )
            valid = False
        params[ 'category_found' ] = category_found

        # Parse the time into seconds, ensure it is valid
        ( seconds, time_error ) = util.timestr_to_seconds( time )
        if seconds is None:
            params['time_error'] = "Invalid time: " + time_error
            params['seconds'] = -1
            valid = False
        else:
            time = util.seconds_to_timestr( seconds ) # Enforce standard form
            params[ 'time' ] = time
            params[ 'seconds' ] = seconds

        # Parse the date, ensure it is valid
        ( params['date'], params['date_error'] ) = util.datestr_to_date( 
            datestr )
        if params['date_error']:
            params['date_error'] = "Invalid date: " + params['date_error']
            valid = False
                
        # Check that if this is a best known time, that it beats the old
        # best known time
        if is_bkt and game_model is not None:
            gameinfolist = json.loads( game_model.info )
            for gameinfo in gameinfolist:
                if gameinfo['category'] == params['category']:
                    if( gameinfo.get( 'bk_seconds' ) is not None
                        and gameinfo['bk_seconds'] <= seconds ):
                        s = ( "This time does not beat current best known "
                              + "time of " + util.seconds_to_timestr( 
                                  gameinfo.get( 'bk_seconds' ) ) 
                              + " by " + gameinfo['bk_runner'] 
                              + " (if best known time is incorrect, you can "
                              + "update best known time after submission)" )
                        params['bkt_error'] = s
                        params['is_bkt'] = False
                        valid = False
                    break

        # Make sure that the notes are not too long
        if len( notes ) > 140:
            params['notes_error'] = "Notes must be at most 140 characters"
            valid = False

        params['valid'] = valid
        
        if run_id:
            success = self.put_existing_run( params )
        else:
            success = self.put_new_run( params )
        if success:
            self.redirect( "/runner/" + util.get_code( user.username )
                           + "?q=view-all" )
        else:
            # Grab all of the games for autocompleting
            params['categories'] = self.get_categories( )            
            params['user'] = user
            self.render( "submit.html", **params )
Esempio n. 5
0
    def get_response(self, body):
        body_type = body.get('type')

        # Currently 5 types: verifylogin, gamelist, categories, gamecategories
        # and submitrun
        if body_type is None:
            return self.get_fail_response("No type given.")

        elif body_type == 'verifylogin':
            (valid, response) = self.verify_login(body)
            return response

        elif body_type == 'gamelist':
            return self.get_fail_response("Type [" + body_type +
                                          "] currently" +
                                          " not supported dynamically, but " +
                                          "you can find a static JSON " +
                                          "response at " +
                                          "https://www.dropbox.com/s/" +
                                          "xnvsmx3mt0i4nbv/gamelist.json?dl" +
                                          "=0")

        elif body_type == 'categories':
            return self.get_fail_response("Type [" + body_type +
                                          "] currently" +
                                          " not supported dynamically, but " +
                                          "you can find a static JSON " +
                                          "response at " +
                                          "https://www.dropbox.com/s/" +
                                          "irdj4xakh72g541/categories.json?" +
                                          "dl=0")

        elif body_type == 'modgamelist':
            # First, verify login credentials and that we are a mod
            (valid, response) = self.verify_mod_login(body)
            if not valid:
                return response

            # Note that this is a different type of gamelist than the one
            # generated in games.py
            categories = self.get_categories()
            if categories == self.OVER_QUOTA_ERROR:
                return self.get_fail_response("PB Tracker is currently " +
                                              "experiencing an over " +
                                              "quota downtime period.")
            d = dict()
            for game in categories.keys():
                d[util.get_code(game)] = game
            return self.get_success_response(data=d)

        elif body_type == 'modcategories':
            # First, verify login credentials and that we are a mod
            (valid, response) = self.verify_mod_login(body)
            if not valid:
                return response

            categories = self.get_categories()
            if categories == self.OVER_QUOTA_ERROR:
                return self.get_fail_response("PB Tracker is currently " +
                                              "experiencing an over " +
                                              "quota downtime period.")
            d = dict()
            for game, categorylist in categories.iteritems():
                game_code = util.get_code(game)
                for category in categorylist:
                    category_code = util.get_code(category)
                    d[game_code + ':' + category_code] = (game + ' - ' +
                                                          category)
            return self.get_success_response(data=d)

        elif body_type == 'gamecategories':
            return self.get_fail_response("Type [" + body_type +
                                          "] currently" +
                                          " not supported, sorry.")
#            game_code = body.get( 'game' )
#            game_model = self.get_game_model( game_code )
#            if game_code is None:
#                return self.get_fail_response( 'No game specified' )
#            elif game_model is None:
#                return self.get_fail_response( 'Unknown game ['
#                                               + game_code + '].' )
#            TODO: elif game_model == self.OVER_QUOTA_ERROR:
#            else:
#                d = dict( )
#                gameinfolist = json.loads( game_model.info )
#                for gameinfo in gameinfolist:
#                    category = gameinfo['category']
#                    d[ util.get_code( category ) ] = category
#                return self.get_success_response( data=d )

        elif body_type == 'submitrun':
            # First, verify login credentials
            (valid, response) = self.verify_login(body)
            if not valid:
                return response

            # Grab the params from the body
            username = body.get('username')
            game_code = body.get('game')
            category_code = body.get('category')
            version = body.get('version')
            time = body.get('runtime')
            video = body.get('video')
            notes = body.get('comment')
            splits = body.get('splits')

            # Make sure the game and category exist (can't handle new games
            # and categories just yet)
            if game_code is None:
                return self.get_fail_response('No game given')
            game_model = self.get_game_model(game_code)
            if game_model is None:
                return self.get_fail_response('Unknown game [' + game_code +
                                              '].')
            if game_model == self.OVER_QUOTA_ERROR:
                return self.get_fail_response('PB Tracker is currently over ' +
                                              "quota. Please try again " +
                                              "later.")
            if category_code is None:
                return self.get_fail_response('No category specified')
            gameinfolist = json.loads(game_model.info)
            category = None
            for gameinfo in gameinfolist:
                if category_code == util.get_code(gameinfo['category']):
                    category = gameinfo['category']
                    break
            if category is None:
                return self.get_fail_response('Unknown category [' +
                                              category_code + '] for game [' +
                                              game_code + '].')

            # Parse the time into seconds and ensure it is valid
            if time is None:
                return self.get_fail_response('No runtime given')
            (seconds, time_error) = util.timestr_to_seconds(time)
            if seconds is None:
                return self.get_fail_response('Bad runtime [' + time +
                                              '] given: ' + time_error)
            # Ensure standard format
            time = util.seconds_to_timestr(seconds)

            # Make sure that the notes are not too long
            if notes is not None and len(notes) > 140:
                return self.get_fail_response('Comment is too long; must be ' +
                                              'at most 140 characters.')

            # Figure out current date in user's local timezone
            user = self.get_runner(util.get_code(username))
            if user == self.OVER_QUOTA_ERROR:
                return False, self.get_fail_response(
                    "PB Tracker is currently " + "experiencing an over " +
                    "quota limit down time " + "period.")
            if user.timezone:
                tz = pytz.timezone(user.timezone)
                local_today = datetime.now(pytz.utc).astimezone(tz)
            else:
                # UTC by default
                local_today = datetime.now(pytz.utc)
            date = local_today.date()

            # Load up the needed parameters and put a new run
            params = dict(user=user,
                          game=game_model.game,
                          game_code=game_code,
                          game_model=game_model,
                          category=category,
                          category_found=True,
                          seconds=seconds,
                          time=time,
                          video=video,
                          version=version,
                          notes=notes,
                          valid=True,
                          date=date,
                          datestr=date.strftime("%m/%d/%Y"),
                          is_bkt=False)
            if self.put_new_run(params):
                return self.get_success_response()
            else:
                if params.get('video_error'):
                    return self.get_fail_response('Bad video link [' + video +
                                                  ']: ' +
                                                  params['video_error'])
                else:
                    return self.get_fail_response('Sorry, an unknown error ' +
                                                  'occurred.')

        return self.get_fail_response("Unknown type [" + body_type + "].")
Esempio n. 6
0
    def post( self, game_code ):
        user = self.get_user( )
        if user == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html" )
            return
        return_url = self.request.get( 'from' )
        if not return_url:
            return_url = "/"

        # Get the category
        category_code = self.request.get( 'c' )
        if user is None or category_code is None:
            self.error( 404 )
            self.render( "404.html", user=user )
            return
        
        # Have to take the code of the category code because of percent
        # encoded plusses
        category_code = util.get_code( category_code )
        
        # Check to make sure that the user has run this game
        game_model = self.get_game_model( game_code )
        if game_model == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html", user=user )
            return
        user_has_run = self.get_user_has_run( user.username, game_model.game )
        if user_has_run == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html", user=user )
            return
        if not user_has_run and not user.is_mod:
            self.error( 404 )
            self.render( "404.html", user=user )
            return

        # Find the corresponding gameinfo for this category
        gameinfolist = json.loads( game_model.info )
        gameinfo = None
        for g in gameinfolist:
            if util.get_code( g['category'] ) == category_code:
                gameinfo = g
                break
        if gameinfo is None:
            self.error( 404 )
            self.render( "404.html", user=user )
            return

        # Get the inputs
        username = self.request.get( 'username' )
        time = self.request.get( 'time' )
        datestr = self.request.get( 'date' )
        video = self.request.get( 'video' )

        params = dict( user=user, game=game_model.game, game_code=game_code,
                       category=gameinfo['category'], username=username,
                       time=time, datestr=datestr, video=video, 
                       return_url=return_url )

        # Are we updating?
        if gameinfo.get( 'bk_runner' ) is None:
            params['updating'] = False
        else:
            params['updating'] = True

        valid = True

        # Check for where we came from
        if return_url[ 0 : len( '/runner/' ) ] == '/runner/':
            params['from_runnerpage'] = True
        else:
            params['from_runnerpage'] = False

        if not username and not time and not datestr and not video:
            gameinfo['bk_runner'] = None
            gameinfo['bk_seconds'] = None
            gameinfo['bk_datestr'] = None
            gameinfo['bk_video'] = None
            date = None
        else:
            # Make sure we got a username
            if not username:
                params['username_error'] = "You must enter a runner"
                valid = False

            # Parse the time into seconds, ensure it is valid
            ( seconds, time_error ) = util.timestr_to_seconds( time )
            if not seconds:
                params['time_error'] = "Invalid time: " + time_error
                valid = False

            # Parse the date, ensure it is valid
            ( date, date_error ) = util.datestr_to_date( datestr )
            if date_error:
                params['date_error'] = "Invalid date: " + date_error
                valid = False

            if not valid:
                self.render( "updatebkt.html", **params )
                return

            time = util.seconds_to_timestr( seconds ) # Standard format
            params['time'] = time

            # Store the best known time
            gameinfo['bk_runner'] = username
            gameinfo['bk_seconds'] = seconds
            gameinfo['bk_datestr'] = datestr
            gameinfo['bk_video'] = video

        gameinfo['bk_updater'] = user.username
        game_model.info = json.dumps( gameinfolist )
        game_model.put( )

        # Update game_model in memcache
        self.update_cache_game_model( game_code, game_model )

        # Update gamepage in memcache
        cached_gamepages = self.get_cached_gamepages( game_model.game,
                                                      category_code )
        if cached_gamepages is not None:
            for page_num, gamepage in cached_gamepages.iteritems( ):
                d = gamepage['d']
                d['bk_runner'] = gameinfo['bk_runner']
                d['bk_time'] = util.seconds_to_timestr(
                    gameinfo['bk_seconds'] )
                d['bk_date'] = date
                d['bk_video'] = gameinfo['bk_video']
            self.update_cache_gamepage( game_model.game, category_code,
                                        cached_gamepages )

        # All dun
        self.redirect( return_url )
Esempio n. 7
0
    def post( self, game_code ):
        user = self.get_user( )
        if user == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html" )
            return
        return_url = self.request.get( 'from' )
        if not return_url:
            return_url = "/"

        # Get the category
        category_code = self.request.get( 'c' )
        if user is None or category_code is None:
            self.error( 404 )
            self.render( "404.html", user=user )
            return
        
        # Have to take the code of the category code because of percent
        # encoded plusses
        category_code = util.get_code( category_code )
        
        # Check to make sure that the user has run this game
        game_model = self.get_game_model( game_code )
        if game_model == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html", user=user )
            return
        user_has_run = self.get_user_has_run( user.username, game_model.game )
        if user_has_run == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html", user=user )
            return
        if not user_has_run and not user.is_mod:
            self.error( 404 )
            self.render( "404.html", user=user )
            return

        # Find the corresponding gameinfo for this category
        gameinfolist = json.loads( game_model.info )
        gameinfo = None
        for g in gameinfolist:
            if util.get_code( g['category'] ) == category_code:
                gameinfo = g
                break
        if gameinfo is None:
            self.error( 404 )
            self.render( "404.html", user=user )
            return

        # Get the inputs
        username = self.request.get( 'username' )
        time = self.request.get( 'time' )
        datestr = self.request.get( 'date' )
        video = self.request.get( 'video' )

        params = dict( user=user, game=game_model.game, game_code=game_code,
                       category=gameinfo['category'], username=username,
                       time=time, datestr=datestr, video=video, 
                       return_url=return_url )

        # Are we updating?
        if gameinfo.get( 'bk_runner' ) is None:
            params['updating'] = False
        else:
            params['updating'] = True

        valid = True

        # Check for where we came from
        if return_url[ 0 : len( '/runner/' ) ] == '/runner/':
            params['from_runnerpage'] = True
        else:
            params['from_runnerpage'] = False

        if not username and not time and not datestr and not video:
            gameinfo['bk_runner'] = None
            gameinfo['bk_seconds'] = None
            gameinfo['bk_datestr'] = None
            gameinfo['bk_video'] = None
            date = None
        else:
            # Make sure we got a username
            if not username:
                params['username_error'] = "You must enter a runner"
                valid = False

            # Parse the time into seconds, ensure it is valid
            ( seconds, time_error ) = util.timestr_to_seconds( time )
            if not seconds:
                params['time_error'] = "Invalid time: " + time_error
                valid = False

            # Parse the date, ensure it is valid
            ( date, date_error ) = util.datestr_to_date( datestr )
            if date_error:
                params['date_error'] = "Invalid date: " + date_error
                valid = False

            if not valid:
                self.render( "updatebkt.html", **params )
                return

            time = util.seconds_to_timestr( seconds ) # Standard format
            params['time'] = time

            # Store the best known time
            gameinfo['bk_runner'] = username
            gameinfo['bk_seconds'] = seconds
            gameinfo['bk_datestr'] = datestr
            gameinfo['bk_video'] = video

        gameinfo['bk_updater'] = user.username
        game_model.info = json.dumps( gameinfolist )
        game_model.put( )

        # Update game_model in memcache
        self.update_cache_game_model( game_code, game_model )

        # Update gamepage in memcache
        gamepage = self.get_gamepage( game_model.game, no_refresh=True )
        if gamepage == self.OVER_QUOTA_ERROR:
            self.update_cache_gamepage( game, None )
        elif gamepage is not None:
            for d in gamepage:
                if d['category'] == gameinfo['category']:
                    d['bk_runner'] = gameinfo['bk_runner']
                    d['bk_time'] = util.seconds_to_timestr( 
                        gameinfo['bk_seconds'] )
                    d['bk_date'] = date
                    d['bk_video'] = gameinfo['bk_video']
                    break
            self.update_cache_gamepage( game_model.game, gamepage )

        # All dun
        self.redirect( return_url )
Esempio n. 8
0
    def post( self, game_code ):
        user = self.get_user( )
        if not user:
            self.redirect( "/" )
            return
        elif user == self.OVER_QUOTA_ERROR:
            self.error( 403 )
            self.render( "403.html" )
            return

        category = self.request.get( 'category' )
        time = self.request.get( 'time' )
        datestr = self.request.get( 'date' )
        video = self.request.get( 'video' )
        version = self.request.get( 'version' )
        notes = self.request.get( 'notes' )
        is_bkt = self.request.get( 'bkt', default_value="no" )
        if is_bkt == "yes":
            is_bkt = True
        else:
            is_bkt = False
        run_id = self.request.get( 'edit' )

        # Have to take the code of the game code because of percent
        # encoded plusses
        game_code = util.get_code( game_code )

        params = dict( user = user, game_code = game_code,
                       category = category, 
                       time = time, datestr = datestr, video = video, 
                       version = version, notes = notes, run_id = run_id, 
                       is_bkt = is_bkt )

        valid = True

        # Make sure the game already exists
        game_model = self.get_game_model( game_code )
        game = ''
        if not game_code:
            params['game_error'] = "Game cannot be blank"
            valid = False
        elif game_model is None:
            params['game_error'] = ( "That's weird, we could not find any "
                                     + "records for that game" )
            valid = False
        elif game_model == self.OVER_QUOTA_ERROR:
            params['game_error'] = ( "PB Tracker is currently over its quota"
                                     + " limit for the day. Please try again "
                                     + "tomorrow." )
            valid = False
        else:
            game = game_model.game
        params[ 'game' ] = game
        params[ 'game_model' ] = game_model

        # Make sure the category doesn't already exist under a similar name
        category_code = util.get_code( category )
        category_found = False
        if not category_code:
            params['category_error'] = "Category cannot be blank"
            valid = False
        elif game_model is not None:
            infolist = json.loads( game_model.info )
            for info in infolist:
                if category_code == util.get_code( info['category'] ):
                    category_found = True
                    if category != info['category']:
                        params['category_error'] = ( "Category already exists "
                                                     + "under [" 
                                                     + info['category'] + "] "
                                                     + "(case sensitive). "
                                                     + "Hit submit again to "
                                                     + "confirm." )
                        params['category'] = info['category']
                        valid = False
                    break
        if not category_found and not games.valid_game_or_category( category ):
            params['category_error'] = ( "Category must not use any 'funny'"
                                         + " characters and can be up to 100 "
                                         + "characters long" )
            valid = False
        params[ 'category_found' ] = category_found

        # Parse the time into seconds, ensure it is valid
        ( seconds, time_error ) = util.timestr_to_seconds( time )
        if seconds is None:
            params['time_error'] = "Invalid time: " + time_error
            params['seconds'] = -1
            valid = False
        else:
            time = util.seconds_to_timestr( seconds ) # Enforce standard form
            params[ 'time' ] = time
            params[ 'seconds' ] = seconds

        # Parse the date, ensure it is valid
        ( params['date'], params['date_error'] ) = util.datestr_to_date( 
            datestr )
        if params['date_error']:
            params['date_error'] = "Invalid date: " + params['date_error']
            valid = False
                
        # Check that if this is a best known time, then it beats the old
        # best known time.
        if is_bkt and game_model is not None:
            gameinfolist = json.loads( game_model.info )
            for gameinfo in gameinfolist:
                if gameinfo['category'] == params['category']:
                    if( gameinfo.get( 'bk_seconds' ) is not None
                        and gameinfo['bk_seconds'] <= seconds ):
                        s = ( "This time does not beat current best known "
                              + "time of " + util.seconds_to_timestr( 
                                  gameinfo.get( 'bk_seconds' ) ) 
                              + " by " + gameinfo['bk_runner'] 
                              + " (if best known time is incorrect, you can "
                              + "update best known time after submission)" )
                        params['bkt_error'] = s
                        params['is_bkt'] = False
                        valid = False
                    break
                
        # Check that if this is not the best known time, then it doesn't beat
        # the old best known time
        if not is_bkt and game_model is not None:
            gameinfolist = json.loads( game_model.info )
            for gameinfo in gameinfolist:
                if gameinfo['category'] == params['category']:
                    if( gameinfo.get( 'bk_seconds' ) is not None
                        and seconds < gameinfo['bk_seconds'] ):
                        s = ( "This time beats the current best known time of "
                              + util.seconds_to_timestr( 
                                gameinfo.get( 'bk_seconds' ) )
                              + " by " + gameinfo['bk_runner']
                              + " (if best known time is incorrect, you can "
                              + "update best known time after submission)" )
                        params['bkt_error'] = s
                        params['is_bkt'] = True
                        valid = False
                    break

        # Make sure that the notes are not too long
        if len( notes ) > 140:
            params['notes_error'] = "Notes must be at most 140 characters"
            valid = False

        params['valid'] = valid
        
        if run_id:
            success = self.put_existing_run( params )
        else:
            success = self.put_new_run( params )
        if success:
            self.redirect( "/runner/" + util.get_code( user.username )
                           + "?q=view-all" )
        elif game_model is not None:
            try:
                # Grab all of the categories for autocompleting
                params['categories'] = game_model.categories( )
                params['user'] = user
                self.render( "submit.html", **params )
            except DeadlineExceededError, msg:
                logging.error( msg )
                self.error( 403 )
                self.render( "deadline_exceeded.html", user=user )
Esempio n. 9
0
    def get_response(self, body):
        body_type = body.get('type')

        # Currently 5 types: verifylogin, gamelist, categories, gamecategories
        # and submitrun
        if body_type is None:
            return self.get_fail_response("No type given.")

        elif body_type == 'verifylogin':
            (valid, response) = self.verify_login(body)
            return response

        elif body_type == 'gamelist':
            # Note that this is a different type of gamelist than the one
            # generated in games.py
            categories = self.get_categories()
            d = dict()
            for game in categories.keys():
                d[util.get_code(game)] = game
            return self.get_success_response(data=d)

        elif body_type == 'categories':
            categories = self.get_categories()
            d = dict()
            for game, categorylist in categories.iteritems():
                game_code = util.get_code(game)
                for category in categorylist:
                    category_code = util.get_code(category)
                    d[game_code + ':' + category_code] = (game + ' - ' +
                                                          category)
            return self.get_success_response(data=d)

        elif body_type == 'gamecategories':
            game_code = body.get('game')
            game_model = self.get_game_model(game_code)
            if game_code is None:
                return self.get_fail_response('No game specified')
            elif game_model is None:
                return self.get_fail_response('Unknown game [' + game_code +
                                              '].')
            else:
                d = dict()
                gameinfolist = json.loads(game_model.info)
                for gameinfo in gameinfolist:
                    category = gameinfo['category']
                    d[util.get_code(category)] = category
                return self.get_success_response(data=d)

        elif body_type == 'submitrun':
            # First, verify login credentials
            (valid, response) = self.verify_login(body)
            if not valid:
                return response

            # Grab the params from the body
            username = body.get('username')
            game_code = body.get('game')
            category_code = body.get('category')
            version = body.get('version')
            time = body.get('runtime')
            video = body.get('video')
            notes = body.get('comment')
            splits = body.get('splits')

            # Make sure the game and category exist (can't handle new games
            # and categories just yet)
            if game_code is None:
                return self.get_fail_response('No game given')
            game_model = self.get_game_model(game_code)
            if game_model is None:
                return self.get_fail_response('Unknown game [' + game_code +
                                              '].')
            if category_code is None:
                return self.get_fail_response('No category specified')
            gameinfolist = json.loads(game_model.info)
            category = None
            for gameinfo in gameinfolist:
                if category_code == util.get_code(gameinfo['category']):
                    category = gameinfo['category']
                    break
            if category is None:
                return self.get_fail_response('Unknown category [' +
                                              category_code + '] for game [' +
                                              game_code + '].')

            # Parse the time into seconds and ensure it is valid
            if time is None:
                return self.get_fail_response('No runtime given')
            (seconds, time_error) = util.timestr_to_seconds(time)
            if seconds is None:
                return self.get_fail_response('Bad runtime [' + time +
                                              '] given: ' + time_error)
            # Ensure standard format
            time = util.seconds_to_timestr(seconds)

            # Make sure that the notes are not too long
            if notes is not None and len(notes) > 140:
                return self.get_fail_response('Comment is too long; must be ' +
                                              'at most 140 characters.')

            # Figure out current date in user's local timezone
            user = self.get_runner(util.get_code(username))
            if user.timezone:
                tz = pytz.timezone(user.timezone)
                local_today = datetime.now(pytz.utc).astimezone(tz)
            else:
                # UTC by default
                local_today = datetime.now(pytz.utc)
            date = local_today.date()

            # Load up the needed parameters and put a new run
            params = dict(user=user,
                          game=game_model.game,
                          game_code=game_code,
                          game_model=game_model,
                          category=category,
                          category_found=True,
                          seconds=seconds,
                          time=time,
                          video=video,
                          version=version,
                          notes=notes,
                          valid=True,
                          date=date,
                          datestr=date.strftime("%m/%d/%Y"),
                          is_bkt=False)
            if self.put_new_run(params):
                return self.get_success_response()
            else:
                if params.get('video_error'):
                    return self.get_fail_response('Bad video link [' + video +
                                                  ']: ' +
                                                  params['video_error'])
                else:
                    return self.get_fail_response('Sorry, an unknown error ' +
                                                  'occurred.')

        return self.get_fail_response("Unknown type [" + body_type + "].")