emojos/app.py

106 lines
3.1 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 urllib.parse
2021-02-11 21:08:12 -08:00
import requests
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:37:58 -07:00
2021-08-31 00:32:08 -07:00
def slug_filter(s):
return s.lower().replace(" ", "-")
2021-08-31 00:37:58 -07:00
2021-08-31 00:32:08 -07:00
app.jinja_env.filters["slug"] = slug_filter
2021-08-31 00:37:58 -07:00
2021-08-31 00:32:08 -07:00
@dataclass
class Emoj:
__slots__ = frozenset({"shortcode", "url"})
shortcode: str
url: str
2021-02-11 21:08:12 -08:00
2021-08-31 00:37:58 -07:00
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-09-10 18:56:09 -07:00
scheme = "http" if domain.endswith(".onion") else "https"
url = urllib.parse.urlunsplit((scheme, 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(),
2021-08-31 00:37:58 -07:00
# sort by category,
# then name within each category,
# then disambiguate by capitalization
2021-08-31 00:32:08 -07:00
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"]
2021-08-31 00:37:58 -07:00
categories[emoji.get("category")].append(
Emoj(shortcode=emoji["shortcode"], url=url)
)
2021-08-31 00:32:08 -07:00
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("/", 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")