flickr-mail/main.py
2023-10-30 06:43:45 +00:00

144 lines
3.7 KiB
Python
Executable file

#!/usr/bin/python3
"""Find photos on flickr for Wikipedia articles and contact the photographer."""
import collections
import inspect
import json
import sys
import traceback
import typing
from urllib.parse import unquote
import flask
import requests
import werkzeug
from werkzeug.debug.tbtools import DebugTraceback
app = flask.Flask(__name__)
app.debug = False
enwiki = "en.wikipedia.org/wiki/"
@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,
)
@app.route("/")
def start() -> str:
"""Start form."""
enwp = flask.request.args.get("enwp")
if not enwp:
return flask.render_template("combined.html")
enwp = enwp.strip()
if not enwp:
return flask.render_template("combined.html")
input_is = "url" if enwiki in enwp 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 = "https://" + 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))
]
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(
"combined.html",
name=name,
enwp=enwp,
flickr_url=flickr_url,
subject=subject,
lines=lines,
nsid=nsid,
)
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"])
if __name__ == "__main__":
app.run(host="0.0.0.0")