flickr-mail/main.py

144 lines
3.7 KiB
Python
Raw Normal View History

2023-09-08 01:10:09 +01:00
#!/usr/bin/python3
2023-09-29 12:28:23 +01:00
"""Find photos on flickr for Wikipedia articles and contact the photographer."""
2023-09-08 01:10:09 +01:00
2023-09-08 11:01:50 +01:00
import collections
2023-09-09 15:06:01 +01:00
import inspect
2023-09-08 11:01:50 +01:00
import json
2023-09-09 15:06:01 +01:00
import sys
import traceback
2023-09-08 11:01:50 +01:00
import typing
2023-09-08 01:10:09 +01:00
from urllib.parse import unquote
import flask
2023-09-08 11:01:50 +01:00
import requests
2023-09-09 15:06:01 +01:00
import werkzeug
from werkzeug.debug.tbtools import DebugTraceback
2023-09-08 01:10:09 +01:00
app = flask.Flask(__name__)
2023-09-09 15:06:01 +01:00
app.debug = False
2023-09-08 01:10:09 +01:00
enwiki = "en.wikipedia.org/wiki/"
2023-09-09 15:06:01 +01:00
@app.errorhandler(werkzeug.exceptions.InternalServerError)
def exception_handler(e: werkzeug.exceptions.InternalServerError) -> tuple[str, int]:
"""Handle exception."""
exec_type, exc_value, current_traceback = sys.exc_info()
assert exc_value
tb = DebugTraceback(exc_value)
summary = tb.render_traceback_html(include_title=False)
exc_lines = "".join(tb._te.format_exception_only())
last_frame = list(traceback.walk_tb(current_traceback))[-1][0]
last_frame_args = inspect.getargs(last_frame.f_code)
return (
flask.render_template(
"show_error.html",
plaintext=tb.render_traceback_text(),
exception=exc_lines,
exception_type=tb._te.exc_type.__name__,
summary=summary,
last_frame=last_frame,
last_frame_args=last_frame_args,
),
500,
)
2023-09-08 01:10:09 +01:00
@app.route("/")
def start() -> str:
2023-09-08 01:10:09 +01:00
"""Start form."""
enwp = flask.request.args.get("enwp")
if not enwp:
return flask.render_template("combined.html")
enwp = enwp.strip()
if not enwp:
2023-09-08 12:11:42 +01:00
return flask.render_template("combined.html")
input_is = "url" if enwp.startswith(enwiki) else "title"
wikipedia_url: str
wiki_part1: str
wiki_part2: str
if input_is == "url":
start = enwp.find(enwiki) + len(enwiki)
wiki_part2 = unquote(enwp[start:])
name = wiki_part2
wiki_part1 = enwp[:start]
wikipedia_url = enwp
else:
name = enwp
wiki_part1 = enwiki
wiki_part2 = name.replace(" ", "_")
wikipedia_url = wiki_part1 + wiki_part2
if "_(" in name:
name = name[: name.find("_(")]
name = name.replace("_", " ")
flickr_url = flask.request.args.get("flickr")
if not flickr_url:
return flask.render_template(
"combined.html",
name=name,
enwp=enwp,
)
if "/in/" in flickr_url:
flickr_url = flickr_url[: flickr_url.find("/in/")]
flickr_start = "https://flickr.com/photos/"
assert flickr_url.startswith(flickr_start)
flickr_username = flickr_url[
len(flickr_start) : flickr_url.find("/", len(flickr_start))
]
2023-09-08 19:03:51 +01:00
nsid = flickr_usrename_to_nsid(flickr_username)
assert nsid
print(nsid)
msg = flask.render_template(
"message.jinja",
flickr_url=flickr_url,
enwp=enwp,
wikipedia_url=wikipedia_url,
name=name,
wiki_part1=wiki_part1,
wiki_part2=wiki_part2,
)
subject = f"Request to use your photo of {name} on Wikipedia"
lines = msg.split("\n\n")
return flask.render_template(
2023-09-08 12:11:42 +01:00
"combined.html",
name=name,
enwp=enwp,
flickr_url=flickr_url,
subject=subject,
lines=lines,
nsid=nsid,
)
2023-09-08 01:10:09 +01:00
2023-09-08 11:01:50 +01:00
def get_params(line_iter: collections.abc.Iterable[str]) -> str:
"""Find and return params from flickr profile page."""
look_for = 'params: {"isEditingTestimonial":false,'
return next(line[line.find("{") :] for line in line_iter if look_for in line)
def flickr_usrename_to_nsid(username: str) -> str:
"""Get NSID from flickr username."""
url = f"https://www.flickr.com/people/{username}/"
r = requests.get(url)
params = json.loads(get_params(r.text.splitlines()))
return typing.cast(str, params["nsid"])
2023-09-08 01:10:09 +01:00
if __name__ == "__main__":
app.run(host="0.0.0.0")