def search_location(): lat = request.args.get("lat") long = request.args.get("long") preferences = request.args.get("preferences") if preferences is None: preferences = [] else: preferences = preferences.split(",") if len(preferences) > 0: query = Activity.select().where(Activity.id.in_(preferences)) else: query = Activity.select() activities_query = [activity.to_dict()["id"] for activity in query] query = Location.select(Location, Category.name.alias("category_name"), fn.SUM(LocationActivity.weight).alias('weight')) \ .join(LocationActivity) \ .join(Category, on=Category.id == Location.category) \ .where(LocationActivity.activity.in_(activities_query)) \ .group_by(Location) locations = [] for location in query.namedtuples(): weight = location.weight if weight == 0: weight = 1 elif len(preferences) == 0: weight = 1 activities = Activity.select().join(LocationActivity).where(LocationActivity.location == location.id) locations.append( dict( name=location.name, logo=location.logo, address=location.address, category=location.category_name, normal_weight=weight, calculated_weight=_calculate_weight(location.lat-float(lat), location.long-float(long), weight), activities=[activity.name for activity in activities], price=location.price ) ) locations.sort(key=lambda object: object["calculated_weight"]) return respond_data(locations)
def search_games(): """Searches for games (either by title or description) Query Params: - query: Query terms to search for (string) - page: The page to access (int) - per_page: The number of results to return per page (int) """ schema = ActivitySchema() try: page = int(request.args.get('page', 1)) per_page = int(request.args.get('per_page', 20)) except ValueError: raise InvalidUsage( 'page and per_page must both be integers greater than 0') query = request.args.get('query') if query: db_results = Activity.search(query, page=page, per_page=per_page) results = schema.dump(db_results.results, many=True) return jsonify(games=results, page=page, total_pages=db_results.total_pages, next_page=db_results.next_page), 200 return jsonify(games=[], page=1, total_pages=1, next_page=None)
def approve_submission(id, current_user=None): """Enables approval of game submissions from the admin panel. This marks the game as approved in the submissions table, and pushes it into the main activity table. """ if not current_user: raise AuthError("You need to be authorized to access this endpoint") submission = Submission.query.get_or_404(id) try: game = Activity(name=submission.name, url=submission.url, description=submission.description, paid=submission.paid, min_players=submission.min_players, max_players=submission.max_players, submitted_by=submission.submitted_by) db.session.add(game) submission.approved = True db.session.commit() except Exception as e: current_app.logger.error(f"Could not approve submission {id}") return jsonify(message="Could not approve submission"), 500 return jsonify(message="Approved submission"), 200
def seed_db(): """Seeds game tables with data. """ game_entries = seed_game_entries() for game in game_entries.get('games'): activity = Activity(**game) db.session.add(activity) click.echo("Games tables seeded.") db.session.commit()
def bulk_import_submissions(current_user=None): """Adds many games at once (useful for a migration to another server). Requires authentication as an admin. """ if not current_user: raise AuthError("You need to be authorized to access this endpoint") schema = ActivitySchema(many=True) try: games = request.get_json().get('games') except Exception as e: raise InvalidUsage( "Please nest games under the 'games' key in your JSON payload") try: # Attempt to validate and deserialize input data: validated = schema.load(games) deserialized_games = [] for game in validated: # TODO: Filter fields at the schema level instead of here deserialized_games.append( Activity(name=game.get('name'), description=game.get('description'), max_players=game.get('max_players'), min_players=game.get('min_players'), created_date=game.get('created_date'), paid=game.get('paid'), submitted_by=game.get('submitted_by'), url=game.get('url'))) # Then, load into the database: db.session.add_all(deserialized_games) db.session.commit() return jsonify( message=f'{len(deserialized_games)} games added to database'), 200 except ValidationError: raise except Exception as e: current_app.logger.error( f'Unhandled exception during bulk import: {e}') return jsonify(message='Internal server error'), 500
def get_location_by_id(location_id): location = Location.get_or_none(Location.id == location_id) if location is None: raise SanoException(404, NOT_FOUND, "Location not found") location_activities = LocationActivity.select().where(LocationActivity.location == location) location_activities = [location_activity.activity_id for location_activity in location_activities] activities = Activity.select().where(Activity.id.in_(location_activities)) activities = [activity.name for activity in activities] now = datetime.now() data = location.to_dict(recurse=True) data["activities"] = activities data["images"] = [image.to_dict() for image in location.images] data["events"] = [ event.to_dict() for event in location.events if event.end_date > now ] data["routines"] = [routine.to_dict() for routine in location.routines if not routine.is_stop] for routine in data["routines"]: routine["schedules"] = [schedule.to_dict() for schedule in Schedule.select().where(Schedule.routine == routine["id"])] return respond_data(data)
def app(): """Fixture to have access to the Flask application object, with the database structure already created and tables seeded. Persists once per function. """ app = create_app('src.config.TestConfig') with app.app_context(): # Run alembic migrations on the database upgrade(directory='migrations') # Seed initial records to the database for testing: game_entries = seed_game_entries() for game in game_entries.get('games'): activity = Activity(**game) db.session.add(activity) db.session.commit() yield app # Teardown: Drop all tables Alembic would've created with app.app_context(): db.engine.execute( text('drop table activity, alembic_version, submissions;'))
def get_all_activities(): query = Activity.select().dicts() return respond_data([activity for activity in query])