#!/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 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)) ] 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")