示例#1
0
def get(args: dict):
    """Browse available Prompts by year or month-year combo."""
    # We always need a year
    if "year" not in args:
        return make_error_response(
            422, "At the least, a prompt year must be provided!")

    # We also have a month, meaning we're browsing an individual month
    if "month" in args:
        # Handle the month coming in as single number
        if len(args["month"]) == 1:
            args["month"] = f"0{args['month']}"

        month_data = browse_by_month(args["year"], args["month"])

        # Error out if there's no data
        if month_data["total"] != 0:
            return month_data
        return make_error_response(
            404,
            f"No prompts available for year-month {args['year']}-{args['month']}!",  # noqa
        )

    # We only have a year, so we're browsing by year
    year_results = browse_by_year(args["year"])

    # Error out if there's no data
    if year_results["total"] != 0:
        return year_results
    return make_error_response(
        404, f"No prompts available for year {args['year']}!")
示例#2
0
def post(args: dict):
    """Create a new Prompt."""
    # Format the date in the proper format before writing
    args["date"] = helpers.format_datetime_ymd(args["date"])

    # If we've not recieved an explict flag that this a duplicate data
    # (which can occur because there happened to more >1 prompt for the day),
    # we need to enforce a one-prompt-a-day constraint
    if not args["is_duplicate_date"]:
        # Don't create a prompt if it already exists
        if database.prompt.exists(pid="", date=args["date"]):
            return helpers.make_error_response(
                422, f"A prompt for {args['date']} already exists!")

    # Download the given media
    media_result = True
    if args["media"] is not None and __is_valid_url(args["media"]):
        media_url = args["media"]
        media_result = media.move(media.download(args["id"], media_url))

        # Extract the media URL
        args["media"] = media.saved_name(args["id"], media_url)

    # Write the prompt to the database
    db_result = database.prompt.create(args)

    # Return the proper status depending on adding result
    if db_result and media_result:
        return helpers.make_response(201)
    return helpers.make_error_response(422, "Unable to record new Prompt!")
示例#3
0
def get(args: dict):
    """Get a Host by their Twitter ID or handle."""
    # Return a list of all Hosts
    if "all" in args and args["all"]:
        return helpers.make_response(200, jsonify(database.host.get_all()))

    # We need something to search by
    if not args["uid"] and not args["handle"]:
        return helpers.make_error_response(
            422, "Either a Host id or handle must be provided!")

    # Both a host ID and handle cannot be provided
    if args["uid"] and args["handle"]:
        return helpers.make_error_response(
            422, "Providing a Host id and handle is not allowed!")

    # Get the host information
    found_host = database.host.get(uid=args["uid"], handle=args["handle"])
    if found_host:
        return helpers.make_response(200, jsonify(found_host))

    # Determine which param was given
    given_param = [(k, v) for k, v in args.items() if v][0]

    # We don't have that host
    return helpers.make_error_response(
        404,
        f"Unable to get details for Host {given_param[0]} {given_param[1]}!")
示例#4
0
def date_get(args: dict):
    """Get hosting period info for a Host, by either date or Host handle."""
    # Both parameters were provided. That's a nada
    if len(args) > 1:
        return helpers.make_error_response(
            422, "Only one parameter can be provided!")

    # We want to get the starting hosting date for this Host
    if "handle" in args:
        # That Host doesn't exist
        if not database.host.exists(handle=args["handle"]):
            return helpers.make_error_response(
                404,
                f"Unable to get hosting period for {args['handle']}!",
            )

        # Attempt to find the hosting period (or not)
        hosting_periods = database.host.get_date(args["handle"])
        if hosting_periods:
            return helpers.make_response(200, jsonify(hosting_periods))
        return helpers.make_error_response(
            404,
            f"Unable to get hosting period for {args['handle']}!",
        )

    # Ww want to get the Host for this specific date
    if "date" in args:
        current_host = database.host.get_by_date(
            helpers.format_datetime_ymd(args["date"]))
        if current_host:
            return helpers.make_response(200, jsonify(current_host))
        return helpers.make_error_response(
            404,
            f"Unable to get Host for {helpers.format_datetime_ymd(args['date'])}!",
        )
示例#5
0
def get(args: dict):
    """Search for a Prompt by word or Host."""
    # Both parameters were provided, and that is not supported
    if len(args) > 1:
        return make_error_response(422, "Only one parameter can be provided!")

    if "prompt" in args:
        return make_response(200, search_by_prompt(args["prompt"]))
    if "host" in args:
        return make_response(200, search_by_host(args["host"]))
    return make_error_response(
        422, "At least one search parameter must be provided!")
示例#6
0
def put(args: dict):
    """PUT request to update an existing API key."""
    # That key doesn't exist
    if not database.api_key.exists(args["token"]):
        return helpers.make_error_response(
            404,
            "The requested API key does not exist!",
        )

    # Update and respond accordingly
    result = database.api_key.update(args)
    if result:
        return helpers.make_response(200)
    return helpers.make_error_response(422, "Unable to update the API key!")
示例#7
0
def date_post(args: dict):
    """Create a new hosting date for the given Host."""
    # That hosting date already exists and we can't duplicate it
    if database.host.exists_date(args["uid"], args["date"]):
        return helpers.make_error_response(
            422,
            f'A hosting date of {args["date"]} for Host {args["uid"]} already exists!',
        )

    result = database.host.create_date(args)
    if result:
        return helpers.make_response(201)
    return helpers.make_error_response(
        503, f'Unable to create new hosting date for {args["date"]}!')
示例#8
0
def put(query_args: dict, json_args: dict):
    """Update an existing Prompt."""
    # Merge the two args dicts into a single dict for easier use
    args = {**query_args, **json_args}

    # The prompt needs to exist first
    if not database.prompt.exists(pid=args["id"], date=""):
        msg = "The prompt ID '{}' does not exist!".format(args["id"])
        return helpers.make_error_response(404, msg)

    # If media is set to nothing, we want to delete it
    if args["media"] is None:
        media.delete(args["id"])

    # We want to replace the existng media
    elif (args["media"] is not None and __is_valid_url(args["media"])
          and args["media_replace"]):
        # Start by deleting the old media
        media.delete(args["id"])

        # Download the new media
        media.move(media.download(args["id"], args["media"]))

        # Set the new media file name. It's not likely to be different
        # but better safe than sorry here
        args["media"] = media.saved_name(args["id"], args["media"])

    # Format the date in the proper format
    args["date"] = helpers.format_datetime_ymd(args["date"])

    # Finally, save all this to the database
    database.prompt.update(args)
    return helpers.make_response(204)
示例#9
0
def get(args: dict):
    """Get a Prompt, either the latest or from a specific date."""
    # Hitting the endpoint without a date returns the latest prompt(s)
    if "date" not in args:
        prompts = database.prompt.get_latest()

    # We want the prompt from a particular day
    else:
        # Handle the special one year anniversary image prompts
        if (args["date"].year == 2017 and args["date"].month == 9
                and args["date"].day == 5):
            return database.prompt.get_one_year()

        # Format the date in the proper format before fetching
        date = helpers.format_datetime_ymd(args["date"])

        # A prompt for that date doesn't exist
        prompts = database.prompt.get_by_date(date, date_range=False)
        if not prompts:
            return helpers.make_error_response(
                404, f"No prompt exists for date {date}!")

    # Find out if we have a Prompt for the surrounding days
    for day_prompt in prompts:
        day_prompt["previous"] = prompt_exists(day_prompt.date, "previous")
        day_prompt["next"] = prompt_exists(day_prompt.date, "next")
    return jsonify(prompts)
示例#10
0
def post(args: dict):
    """Add an email to the mailing list."""
    # Define the error response
    error = helpers.make_error_response(
        503, "Unable to add email to mailing list!")

    # If email sending is not enabled, always pretend it was added
    if not current_app.config["ENABLE_EMAIL_SENDING"]:
        return helpers.make_response(201)

    # Because this endpoint costs money with each hit, block it off
    # unless we are running in production
    if current_app.config["ENV"] == "production":
        # Validate the address to decide if we should record it
        if not mailgun.validate(args["email"]):
            return error

    # Add the address to the local database
    db_result = database.subscription.email_create(args["email"])

    # It didn't added to the db
    if not db_result:
        return error

    # Add the address to the Mailgun mailing list
    mg_result = mailgun.create(args["email"])

    # The address was successfully recorded
    if mg_result.status_code == codes.ok:
        return helpers.make_response(201)

    # ...Welllllll... actually it didn't...
    return error
示例#11
0
def post(args: dict):
    """POST request to create a new API key."""
    # Create the token
    result = database.api_key.create(args)

    # Respond according to if it was successful or not
    if result:
        return helpers.make_response(201, result)
    return helpers.make_error_response(422, "Unable to create a new API key!")
示例#12
0
def post(args: dict):
    """Create a new Host."""
    if database.host.exists(handle=args["handle"]):
        return helpers.make_error_response(
            422, f'Host {args["handle"]} already exists!')

    # Get the Twitter user ID for this Host
    host_id = database.host.lookup(args["handle"])
    if not host_id:
        return helpers.make_error_response(
            503, f'Unable to find Twitter username {args["handle"]}!')

    # Create a host with all their details
    args["uid"] = host_id
    result = database.host.create(args)
    if result is None:
        return helpers.make_error_response(
            503, f'Unable to create new Host {args["handle"]}!')
    return helpers.make_response(201, jsonify(result))
示例#13
0
def patch(args: dict):
    """Update a Host's handle."""
    # Attempt to find the host. They must exist to be updated
    existing_host = database.host.exists(uid=args["uid"])
    if not existing_host:
        return helpers.make_error_response(400,
                                           "Unable to update Host details!")

    # Update the host
    database.host.update(args)
    return helpers.make_response(204)
示例#14
0
def hosting_get(args: dict):
    # Except one and only one parameter is supported
    if len(args) > 1:
        return helpers.make_error_response(
            422, "Only one parameter can be provided!")

    # We want the exact starting Hosting date for this day
    if "date" in args:
        return helpers.make_response(
            200,
            jsonify([database.settings.hosting_start_date_get(args["date"])]))

    # We want the Hosting dates for this month
    if "month" in args:
        return helpers.make_response(
            200, jsonify(database.settings.hosting_period_get(args["month"])))

    # We didn't recieve any info so we don't know what to do ¯\_(ツ)_/¯
    return helpers.make_error_response(422,
                                       "A single parameter must be provided!")
示例#15
0
def delete(args: dict):
    """Delete a Host.

    This will only succeed if the Host does not have any associated
    Prompts to prevent orphaned records or an incomplete record.
    """
    result = database.host.delete(args["uid"])
    if result:
        return helpers.make_response(204)
    return helpers.make_error_response(
        403,
        f"Unable to delete Host {args['uid']}! They have Prompts associated with them.",
    )
示例#16
0
def get(args: dict):
    """GET request to fetch key permissions."""
    # Cannot request info for a single key and all keys
    if "token" in args and "all" in args:
        return helpers.make_error_response(
            422, "Cannot request individual and all key info together!")

    # We want all key info
    if "all" in args and args["all"]:
        records = database.api_key.get_all()
        return helpers.make_response(200, jsonify(records))

    # We want info on a single key
    if "token" in args:
        record = database.api_key.get(args["token"])
        if record is not None:
            return helpers.make_response(200, jsonify(record))
        return helpers.make_error_response(404,
                                           "Could not get key information!")

    # Some form of info must be requested
    return helpers.make_error_response(
        422, "Must request some form of key information!")
示例#17
0
def post(args: dict):
    """Trigger an email broadcast for the given day's prompt."""
    # Put the date in the proper format
    date = helpers.format_datetime_ymd(args["date"])

    # A prompt for that date doesn't exist
    prompts = database.prompt.get_by_date(date, date_range=False)
    if not prompts:
        return helpers.make_error_response(
            503, f"Unable to send out email broadcast for the {date} prompt!")

    # If email sending is not allowed, just pretend it worked
    if not current_app.config["ENABLE_EMAIL_SENDING"]:
        return helpers.make_response(200)

    # Pull out the exact prompt we want to broadcast.
    # If there's more than one prompt for this day,
    # it'll use whichever was requested.
    # By default, the latest recorded/only prompt is selected
    prompt = prompts[args["which"]]

    # Send an email to the MG mailing list
    # This helps us keep track of who is on the list at any given moment
    # but also resolves a crazy amount of trouble
    # when it comes to sending out a large amount of email messages
    # https://documentation.mailgun.com/en/latest/api-mailinglists.html#examples
    r = email.make_and_send(
        mailgun.mailing_list(),
        helpers.format_datetime_pretty(prompt.date),
        "email",
        **prompt,
    )
    pprint(r)

    # There's no easy way to tell if they all sent, so just pretend they did
    return helpers.make_response(200)