Compare commits

...

3 commits

Author SHA1 Message Date
Edward Betts 187214cfa1 Add Web UI to see when conference websites appeared
Closes: #4
2024-07-21 10:53:22 +09:00
Edward Betts 87009c2247 Make mypy happy 2024-07-15 00:55:18 +08:00
Edward Betts 708c5d6f58 urllib3 now has types 2024-07-14 23:28:16 +08:00
4 changed files with 117 additions and 28 deletions

View file

@ -2,11 +2,9 @@
"""Check if conference websites are live."""
import configparser
import os
import re
import smtplib
import typing
import warnings
from datetime import date
from email.mime.text import MIMEText
@ -15,16 +13,10 @@ from email.utils import formatdate, make_msgid
import requests
import yaml
from requests.adapters import HTTPAdapter
from urllib3.exceptions import InsecureRequestWarning # type: ignore
from urllib3.util.url import parse_url # type: ignore
from urllib3.exceptions import InsecureRequestWarning
from urllib3.util.url import parse_url
class LiveConference(typing.TypedDict):
"""Live conference."""
conference: str
year: int
live: date
from conference import LiveConference, config, load_yaml
class AbsoluteDNSAdapter(HTTPAdapter):
@ -36,6 +28,7 @@ class AbsoluteDNSAdapter(HTTPAdapter):
# Append a dot to the hostname if it's not already there.
hostname = parsed_url.host
assert hostname
if not hostname.endswith("."):
hostname += "."
@ -50,16 +43,6 @@ class AbsoluteDNSAdapter(HTTPAdapter):
return super().send(request, **kwargs)
config_file_path = os.path.expanduser(
os.path.join(
os.getenv("XDG_CONFIG_HOME", "~/.config"), "conference-check", "config"
)
)
config = configparser.ConfigParser()
config.read(os.path.expanduser(config_file_path))
# Suppress only the single InsecureRequestWarning from urllib3
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
@ -95,6 +78,7 @@ not_here_list = [
"Wikimedia Error",
"The page you requested could not be found",
"Ooops! Could Not Find It",
"OpenStreetMap Authentication Proxy",
]
@ -144,13 +128,6 @@ def send_mail(subject: str, body: str) -> None:
s.quit()
def load_yaml(name: str) -> typing.Any:
"""Load YAML."""
filename = os.path.expanduser(config["data"][name])
assert os.path.exists(filename)
return yaml.safe_load(open(filename))
def check_conference_web_site(name: str, src_url: str, year: int) -> bool:
"""Check if an individual web site is live."""
assert "{year}" in src_url

34
conference/__init__.py Normal file
View file

@ -0,0 +1,34 @@
"""Conference classes and functions."""
import configparser
import os
import typing
from datetime import date
import yaml
config_file_path = os.path.expanduser(
os.path.join(
os.getenv("XDG_CONFIG_HOME", "~/.config"), "conference-check", "config"
)
)
assert os.path.exists(config_file_path)
config = configparser.ConfigParser()
config.read(os.path.expanduser(config_file_path))
class LiveConference(typing.TypedDict, total=False):
"""Live conference."""
conference: str
year: int
live: date
url: str | None
def load_yaml(name: str) -> typing.Any:
"""Load YAML."""
filename = os.path.expanduser(config["data"][name])
assert os.path.exists(filename)
return yaml.safe_load(open(filename))

53
templates/index.html Normal file
View file

@ -0,0 +1,53 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Conference check</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
h1 {
font-size: 2.5rem;
font-weight: 500;
margin-top: 0;
margin-bottom: 0.5rem;
}
a {
color: #0d6efd;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.text-right {
text-align: right;
}
</style>
</head>
<body>
<h1>Conference check</h1>
<p>Date when website went live.</p>
<table>
{% for l in live %}
<td class="text-right">
{{ l.live.strftime("%a, %d %b %Y") }}
🌍🎉
</td>
<td>
<a href="{{ l.url }}">{{ l.conference }} {{ l.year }}</a>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>

25
web_view.py Executable file
View file

@ -0,0 +1,25 @@
#!/usr/bin/python3
"""When conference websites appeared."""
import flask
from conference import LiveConference, load_yaml
app = flask.Flask(__name__)
app.debug = False
@app.route("/")
async def index() -> str:
"""Index page."""
conferences = load_yaml("conferences")
live: list[LiveConference] = load_yaml("live")
for c in live:
c["url"] = conferences[c["conference"]].format(year=c["year"])
return flask.render_template("index.html", live=live, conferences=conferences)
if __name__ == "__main__":
app.run(host="0.0.0.0")