emojos/app.py

118 lines
3.6 KiB
Python
Raw Normal View History

2021-02-11 21:05:27 -08:00
# Copyright (c) 2021 iliana etaoin
2018-04-01 20:23:21 -07:00
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import operator
import urllib.parse
2021-02-11 21:08:12 -08:00
import botocore.session
import requests
import serverless_wsgi
2021-08-31 00:32:08 -07:00
from collections import defaultdict
from dataclasses import dataclass
2018-04-01 20:23:21 -07:00
from flask import Flask, redirect, render_template, request, url_for
app = Flask(__name__)
2021-08-31 00:32:08 -07:00
def slug_filter(s):
return s.lower().replace(" ", "-")
app.jinja_env.filters["slug"] = slug_filter
@dataclass
class Emoj:
__slots__ = frozenset({"shortcode", "url"})
shortcode: str
url: str
2021-02-11 21:08:12 -08:00
@app.route("/<domain>")
2018-04-01 20:23:21 -07:00
def emojo(domain):
2021-02-11 21:08:12 -08:00
if request.args.get("show_all", "") == "on":
show_all = True
else:
show_all = False
2021-02-11 21:08:12 -08:00
if request.args.get("show_animated", "") == "on":
show_animated = True
else:
show_animated = False
2021-08-31 00:32:08 -07:00
url = urllib.parse.urlunsplit(
("https", domain, "/api/v1/custom_emojis", "", "")
)
2018-04-01 20:23:21 -07:00
try:
response = requests.get(url)
2021-02-11 21:08:12 -08:00
except requests.exceptions.RequestException:
return render_template("oh_no.html", domain=domain)
2018-04-01 20:23:21 -07:00
2021-08-31 00:32:08 -07:00
if response.status_code == 401:
return render_template("forbidden.html", domain=domain)
categories = defaultdict(list)
for emoji in sorted(
response.json(),
# sort by category, then name within each category, then disambiguate by capitalization
key=lambda x: (x.get("category", ""), x["shortcode"].lower(), x["shortcode"]),
):
if not show_all and not emoji.get("visible_in_picker", True):
continue
url = emoji["url" if show_animated else "static_url"]
categories[emoji.get("category")].append(Emoj(shortcode=emoji["shortcode"], url=url))
return render_template(
"emojo.html", domain=domain, categories=categories, show_animated=show_animated
)
2018-04-01 20:23:21 -07:00
2021-02-11 21:08:12 -08:00
@app.route("/favicon.ico")
@app.route("/robots.txt")
def no_content():
2021-02-11 21:08:12 -08:00
return ("", 204)
2021-02-11 21:08:12 -08:00
@app.route("/code")
2018-04-03 18:31:14 -07:00
def code():
2021-02-11 21:08:12 -08:00
context = request.environ.get("context")
2018-04-03 18:31:14 -07:00
session = botocore.session.get_session()
# region name is detected from lambda environment
2021-02-11 21:08:12 -08:00
client = session.create_client("lambda")
code = client.get_function(
FunctionName=context.function_name, Qualifier=context.function_version
)
return redirect(code["Code"]["Location"], code=303)
2018-04-03 18:31:14 -07:00
2021-02-11 21:08:12 -08:00
@app.route("/", methods=("GET", "POST"))
2018-04-01 20:23:21 -07:00
def index():
2021-02-11 21:08:12 -08:00
if request.method == "POST":
if "instance" in request.form:
show_all = request.form.get("show_all")
show_animated = request.form.get("show_animated")
return redirect(
2021-02-11 21:08:12 -08:00
url_for(
"emojo",
domain=request.form["instance"],
show_all=show_all,
show_animated=show_animated,
)
)
2018-04-01 20:23:21 -07:00
else:
2021-02-11 21:08:12 -08:00
return redirect(url_for("index"))
2018-04-01 20:23:21 -07:00
else:
2021-02-11 21:08:12 -08:00
return render_template("index.html")
2021-02-11 21:05:27 -08:00
def handle_request(event, context):
return serverless_wsgi.handle_request(app, event, context)