Compare commits
3 commits
164a93cd88
...
187214cfa1
Author | SHA1 | Date | |
---|---|---|---|
Edward Betts | 187214cfa1 | ||
Edward Betts | 87009c2247 | ||
Edward Betts | 708c5d6f58 |
33
check.py
33
check.py
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
"""Check if conference websites are live."""
|
"""Check if conference websites are live."""
|
||||||
|
|
||||||
import configparser
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import smtplib
|
import smtplib
|
||||||
import typing
|
|
||||||
import warnings
|
import warnings
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
@ -15,16 +13,10 @@ from email.utils import formatdate, make_msgid
|
||||||
import requests
|
import requests
|
||||||
import yaml
|
import yaml
|
||||||
from requests.adapters import HTTPAdapter
|
from requests.adapters import HTTPAdapter
|
||||||
from urllib3.exceptions import InsecureRequestWarning # type: ignore
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
from urllib3.util.url import parse_url # type: ignore
|
from urllib3.util.url import parse_url
|
||||||
|
|
||||||
|
from conference import LiveConference, config, load_yaml
|
||||||
class LiveConference(typing.TypedDict):
|
|
||||||
"""Live conference."""
|
|
||||||
|
|
||||||
conference: str
|
|
||||||
year: int
|
|
||||||
live: date
|
|
||||||
|
|
||||||
|
|
||||||
class AbsoluteDNSAdapter(HTTPAdapter):
|
class AbsoluteDNSAdapter(HTTPAdapter):
|
||||||
|
@ -36,6 +28,7 @@ class AbsoluteDNSAdapter(HTTPAdapter):
|
||||||
|
|
||||||
# Append a dot to the hostname if it's not already there.
|
# Append a dot to the hostname if it's not already there.
|
||||||
hostname = parsed_url.host
|
hostname = parsed_url.host
|
||||||
|
assert hostname
|
||||||
if not hostname.endswith("."):
|
if not hostname.endswith("."):
|
||||||
hostname += "."
|
hostname += "."
|
||||||
|
|
||||||
|
@ -50,16 +43,6 @@ class AbsoluteDNSAdapter(HTTPAdapter):
|
||||||
return super().send(request, **kwargs)
|
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
|
# Suppress only the single InsecureRequestWarning from urllib3
|
||||||
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
|
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
|
||||||
|
|
||||||
|
@ -95,6 +78,7 @@ not_here_list = [
|
||||||
"Wikimedia Error",
|
"Wikimedia Error",
|
||||||
"The page you requested could not be found",
|
"The page you requested could not be found",
|
||||||
"Ooops! Could Not Find It",
|
"Ooops! Could Not Find It",
|
||||||
|
"OpenStreetMap Authentication Proxy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,13 +128,6 @@ def send_mail(subject: str, body: str) -> None:
|
||||||
s.quit()
|
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:
|
def check_conference_web_site(name: str, src_url: str, year: int) -> bool:
|
||||||
"""Check if an individual web site is live."""
|
"""Check if an individual web site is live."""
|
||||||
assert "{year}" in src_url
|
assert "{year}" in src_url
|
||||||
|
|
34
conference/__init__.py
Normal file
34
conference/__init__.py
Normal 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
53
templates/index.html
Normal 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
25
web_view.py
Executable 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")
|
Loading…
Reference in a new issue