예제 #1
0
def browse():
    # Handle the archive file possibly being unavailable
    try:
        archive_name = api.get("archive")
    except HTTPError:
        archive_name = None

    render_opts = {
        "years": api.get("browse", "years"),
        "archive": archive_name,
    }
    return render_template("root/browse.html", **render_opts)
예제 #2
0
def view_date(date: str):
    """Build out the daily prompt page."""
    # Try to get the prompt for this day
    try:
        available_prompts = api.get(
            "prompt",
            params={"date": date_format.create_datetime(date).isoformat()})

    # There is no prompt for this day
    except HTTPError:
        abort(404)

    # Load the special 1 year prompt archive page if requested
    if date == "2017-09-05":
        return view_one_year(available_prompts)

    # Create a proper date object for each prompt
    # There are some older days that have multiple prompts,
    # and we need to handle these special cases
    prompts = []
    for prompt in available_prompts:
        prompt["date"] = date_format.create_datetime(prompt["date"])
        prompts.append(prompt)

    render_opts = {
        "prompts": prompts,
        "previous": prompts[0]["previous"],
        "next": prompts[0]["next"],
    }
    return render_template("root/tweet.html", **render_opts)
예제 #3
0
def by_host(query: str) -> SearchResult:
    """Search for Prompts from a specific Host."""
    if query:
        try:
            response = api.get("search", params={"host": query})

            # There doesn't appear any prompts from that Host
            if response["total"] == 0:
                raise HTTPError

        # The search was not successful
        except HTTPError:
            return SearchResult(
                msg=f"No prompts from {query} could be found.",
                url=url_for("search.index"),
                error=True,
            )

        # We got a single result, go directly to the prompt
        if response["total"] == 1:
            date = create_datetime(response["prompts"][0]["date"])
            return SearchResult(
                url=url_for("root.view_date", date=format_datetime_ymd(date)),
                error=False,
            )

        # More than one result came back, display them all
        return SearchResult(results=response, error=False)

    # That Host was not provided
    return SearchResult(
        msg="A Host name must be provided to search.",
        url=url_for("search.index"),
        error=True,
    )
예제 #4
0
class PromptSearchByHost(FlaskForm):
    type = HiddenField(default="host")
    query = SelectField(
        "Host search",
        id="input-search-host",
        validators=[InputRequired()],
        choices=[(host["handle"], host["handle"])
                 for host in api.get("host", params={"all": True})],
    )
예제 #5
0
def save():
    # Access all of the forms
    form_prompt_position = forms.FormPromptPosition()
    form_identifier_hashtags = forms.FormIdentifierHashtags()
    form_filtered_hashtags = forms.FormFilteredHashtags()
    form_finder_timings = forms.FormFinderTimings()

    # Get the form data regardless of what form was submitted
    form_data = {
        "identifiers": form_identifier_hashtags.identifiers.data,
        "additionals": form_filtered_hashtags.filtered.data,
        "word_index": form_prompt_position.position.data,
        "timings": form_finder_timings.timings.data,
    }

    # Map field specific converters to format the data correctly
    converters = {
        "word_index":
        lambda x: (int(x) - 1 if x is not None and int(x) - 1 >= 0 else None),
        "identifiers":
        partial(split_hashtags_into_list, add_hashtag=True),
        "additionals":
        split_hashtags_into_list,
        "timings":
        lambda x: x.strip().split("\r\n") if x.strip() else None,
    }

    # Determine which form was submitted and cleanup the data
    cleaned_data = {
        key: converters[key](value)
        for key, value in form_data.items() if key in converters
    }

    # Update the timings only if needed
    if cleaned_data["timings"] is not None:
        api.put("settings",
                "timings",
                json={"timings": cleaned_data["timings"]})

    # Next, get the existing config
    current_config = api.get("settings")

    # We're changing something other than the timings
    if cleaned_data["timings"] is None:
        # Merge the changed config values into the existing config
        for key, value in cleaned_data.items():
            if value is not None:
                current_config[key] = value

        # Save the updated config
        api.put("settings", json=current_config)

    # Go back to the config page
    flash("Configuration successfully updated.")
    return redirect(url_for("config.index"))
예제 #6
0
def browse_by_year(year: str):
    # Get the host's list and group them up if needed
    try:
        prompt_months: list = api.get("browse",
                                      "months",
                                      params={"year": year})
    except HTTPError:
        abort(404)

    render_opts = {"months": prompt_months, "year": year}
    return render_template("root/browse-year.html", **render_opts)
예제 #7
0
def index():
    # Get the finder settings from the API
    finder_settings = api.get("settings")
    finder_timings = api.get("settings", "timings")
    render_opts = {
        "form_prompt_position": forms.FormPromptPosition(),
        "form_identifier_hashtags": forms.FormIdentifierHashtags(),
        "form_filtered_hashtags": forms.FormFilteredHashtags(),
        "form_finder_timings": forms.FormFinderTimings(),
        "finder_settings": finder_settings,
    }

    # Because wtforms doesn't permit setting a default <textarea> body
    # in Jinja2, we must set it here, in code :\
    render_opts["form_identifier_hashtags"].identifiers.data = "\n".join(
        hashtag.lstrip("#") for hashtag in finder_settings["identifiers"])
    render_opts["form_filtered_hashtags"].filtered.data = "\n".join(
        finder_settings["additionals"])
    render_opts["form_finder_timings"].timings.data = "\n".join(finder_timings)
    return render_template("config/index.html", **render_opts)
예제 #8
0
def dash():
    """Landing page after successful login."""
    today = datetime.now()
    current_hosting_date = api.get(
        "settings",
        "hosting",
        user_token=False,
        params={"date": today.isoformat()},
    )[0]
    render_opts = {
        "prompt":
        api.get("prompt")[0],
        "host":
        api.get(
            "host",
            "date",
            user_token=False,
            params={"date": today.replace(day=current_hosting_date)},
        ),
    }
    return render_template("root/dash.html", **render_opts)
예제 #9
0
def browse_by_year_month(year: str, month: str) -> str:
    try:
        month_prompts: dict = api.get("browse",
                                      params={
                                          "year": year,
                                          "month": month
                                      })
    except HTTPError:
        abort(404)

    render_opts = {
        "date": date_format.format_month_year(f"{year}-{month}-01"),
        "month_prompts": month_prompts["prompts"],
    }
    return render_template("root/browse-month.html", **render_opts)
예제 #10
0
def index():
    # Create a proper date object for each prompt
    # There are some older days that have multiple prompts,
    # and we need to handle these special cases
    available_prompts = api.get("prompt")
    prompts = []
    for prompt in available_prompts:
        prompt["date"] = date_format.create_datetime(prompt["date"])
        prompts.append(prompt)

    render_opts = {
        "prompts": prompts,
        "previous": prompts[0]["previous"],
        "next": None,
    }

    return render_template("root/tweet.html", **render_opts)
예제 #11
0
def get_info(username: str) -> User:
    """Get the user's information."""
    sql = get_sql("user-fetch-info")

    # Start by getting the user's account info
    with connect_to_db() as db:
        db.execute(sql, {"username": username})
        user_info = convert_int_to_bool(dict(db.fetchone()))

    # Get the user's token permissions
    token_perms: dict = api.get("api-key",
                                user_token=False,
                                params={"token": user_info["api_token"]})

    # Store the permissions in a dataclass too
    token_perms = {
        k: v
        for k, v in token_perms.items() if k.startswith("has_")
    }
    token = Token(user_info["api_token"], **token_perms)
    return User(username, **user_info), token
예제 #12
0
def by_word(query: str) -> SearchResult:
    """Search for Prompts by a specific word."""
    # Only search if we have a query and it's not a single letter
    query = query.strip()
    if query and len(query) >= 2:
        # Connect to the API to search
        try:
            response = api.get("search", params={"prompt": query})

            # There doesn't appear any prompts with that word
            if response["total"] == 0:
                raise HTTPError

        # The search was not successful
        except HTTPError:
            return SearchResult(
                msg=f"No prompts containing {query} could be found.",
                url=url_for("search.index"),
                error=True,
            )

        # We got multiple search results
        if response["total"] >= 2:
            return SearchResult(results=response, error=False)

        # We got a single response back, go directly to the prompt
        if response["total"] == 1:
            date = create_datetime(response["prompts"][0]["date"])
            return SearchResult(
                url=url_for("root.view_date", date=format_datetime_ymd(date)),
                error=False,
            )

    # No search results were returned
    return SearchResult(
        msg=f"We were unable to find prompts containing '{query}'. "
        "Please try using a different term.",
        url=url_for("search.index"),
        error=True,
    )
예제 #13
0
def index():
    render_opts = {"api_keys": api.get("api-key", params={"all": True})}
    return render_template("api-key/index.html", **render_opts)