flickr-mail/templates/combined.html
Edward Betts a2d29d7937 Show recent Commons uploads obtained via Flickr mail
Display recent Wikimedia Commons uploads on the home page, filtered to
only show images that were obtained by contacting creators via Flickr
mail. Each upload shows:
- Thumbnail linking to Commons
- Creator name linking to their Flickr profile
- Link to the illustrated Wikipedia article (or Wikidata item)

Features:
- Parse sent mail messages to extract Flickr and Wikipedia URLs
- Match Commons uploads with sent mail by normalized Flickr URL
- Cache Commons API thumbnail responses and sent mail index
- Handle Wikidata item URLs (Q-numbers) with correct links
- Add update_flickr_uploads.py script to find uploads from UploadWizard
  contributions by checking Commons API metadata

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 10:43:45 +00:00

194 lines
7.6 KiB
HTML

{% extends "base.html" %}
{% block title %}Flickr mail{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<h1>Flickr mail</h1>
<form action="{{ url_for(request.endpoint) }}">
<div class="mb-3">
<label for="enwp" class="form-label">Wikipedia article URL or title:</label>
<input type="text" class="form-control" id="enwp" name="enwp" value="{{ enwp }}" required>
</div>
<input type="submit" value="Submit">
</form>
{% if recent_uploads is defined and recent_uploads and not name %}
<div class="mt-4">
<h5>Recent uploads to Wikimedia Commons</h5>
<p class="text-muted small">Photos obtained via Flickr mail requests</p>
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3">
{% for upload in recent_uploads %}
<div class="col">
<div class="card h-100">
<div class="row g-0">
<div class="col-4">
<a href="{{ upload.commons_url }}">
<img src="{{ upload.thumb_url }}" alt="{{ upload.title }}" class="img-fluid rounded-start" style="aspect-ratio: 1; object-fit: cover; width: 100%;">
</a>
</div>
<div class="col-8">
<div class="card-body p-2">
<p class="card-text small mb-1 text-truncate" title="{{ upload.title }}">
<a href="{{ upload.commons_url }}" class="text-decoration-none">{{ upload.title }}</a>
</p>
<p class="card-text small mb-1">
{% if upload.creator_profile_url %}
<a href="{{ upload.creator_profile_url }}" class="text-muted text-decoration-none">{{ upload.creator }}</a>
{% else %}
<span class="text-muted">{{ upload.creator }}</span>
{% endif %}
</p>
{% if upload.wikipedia_url %}
<p class="card-text small mb-0">
<a href="{{ upload.wiki_link_url }}" class="text-decoration-none"><small>{{ upload.wiki_link_label }}</small></a>
</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if name and search_result is defined and search_result.photos %}
<p>Wikipedia article: {{ name }}</p>
<p>Select a photo to compose a message ({{ search_result.total_photos | default(0) }} results):</p>
<div class="row row-cols-2 row-cols-md-3 row-cols-lg-4 g-3 mb-3">
{% for photo in search_result.photos %}
<div class="col">
<div class="card h-100">
<a href="{{ url_for(request.endpoint, enwp=enwp, flickr=photo.flickr_url, img=photo.medium_url) }}">
<img src="{{ photo.thumb_url }}" alt="{{ photo.title }}" class="card-img-top" style="aspect-ratio: 1; object-fit: cover;">
</a>
<div class="card-body p-2">
<p class="card-text small mb-1 text-truncate" title="{{ photo.realname or photo.username }}">{{ photo.realname or photo.username }}</p>
<span class="badge {{ 'bg-success' if photo.license in [4, 5, 7, 8, 9, 10] else 'bg-secondary' }}">{{ photo.license_name }}</span>
</div>
</div>
</div>
{% endfor %}
</div>
{% if search_result.total_pages > 1 %}
<nav aria-label="Search results pagination">
<ul class="pagination justify-content-center">
{% if search_result.current_page > 1 %}
<li class="page-item">
<a class="page-link" href="{{ url_for(request.endpoint, enwp=enwp, page=search_result.current_page - 1) }}">Previous</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Previous</span>
</li>
{% endif %}
{% set start_page = [1, search_result.current_page - 2] | max %}
{% set end_page = [search_result.total_pages, search_result.current_page + 2] | min %}
{% if start_page > 1 %}
<li class="page-item">
<a class="page-link" href="{{ url_for(request.endpoint, enwp=enwp, page=1) }}">1</a>
</li>
{% if start_page > 2 %}
<li class="page-item disabled"><span class="page-link">...</span></li>
{% endif %}
{% endif %}
{% for p in range(start_page, end_page + 1) %}
<li class="page-item {{ 'active' if p == search_result.current_page else '' }}">
<a class="page-link" href="{{ url_for(request.endpoint, enwp=enwp, page=p) }}">{{ p }}</a>
</li>
{% endfor %}
{% if end_page < search_result.total_pages %}
{% if end_page < search_result.total_pages - 1 %}
<li class="page-item disabled"><span class="page-link">...</span></li>
{% endif %}
<li class="page-item">
<a class="page-link" href="{{ url_for(request.endpoint, enwp=enwp, page=search_result.total_pages) }}">{{ search_result.total_pages }}</a>
</li>
{% endif %}
{% if search_result.current_page < search_result.total_pages %}
<li class="page-item">
<a class="page-link" href="{{ url_for(request.endpoint, enwp=enwp, page=search_result.current_page + 1) }}">Next</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Next</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
<p class="text-muted small">
<a href="https://flickr.com/search/?view_all=1&text={{ '"' + name + '"' | urlencode }}" target="_blank">View full search on Flickr</a>
</p>
{% elif name and not flickr_url %}
<p>Wikipedia article: {{ name }}</p>
<p class="text-warning">No photos found. Try a different search term.</p>
<p><a href="https://flickr.com/search/?view_all=1&text={{ '"' + name + '"' | urlencode }}" target="_blank">Search on Flickr directly</a></p>
{% endif %}
{% if flickr_url %}
<div class="row">
{% if img_url %}
<div class="col-md-4 mb-3">
<a href="{{ flickr_url }}" target="_blank">
<img src="{{ img_url }}" alt="Selected photo" class="img-fluid rounded">
</a>
<p class="mt-2 small"><a href="{{ flickr_url }}" target="_blank">View on Flickr</a></p>
</div>
<div class="col-md-8">
{% else %}
<div class="col-12">
{% endif %}
<p><a href="https://www.flickr.com/mail/write/?to={{nsid}}" class="btn btn-primary">Send message on Flickr</a></p>
<div class="mb-2"><strong>Subject:</strong> {{ subject }} <button class="btn btn-sm btn-outline-secondary" id="copy-subject">copy</button></div>
<div>
<h5>Message <button class="btn btn-sm btn-outline-secondary" id="copy-message">copy</button></h5>
{% for p in lines %}
<p>{{ p }}</p>
{% endfor %}
</div>
</div>
</div>
{% endif %}
<div class="mt-3">Written by <a href="/">Edward Betts</a>. Source code and bug reports: <a href="https://git.4angle.com/edward/flickr-mail">https://git.4angle.com/edward/flickr-mail</div>
</div>
</div>
{% endblock %}
{% block scripts %}
{% if subject and lines %}
<script>
var copy_subject = document.getElementById("copy-subject");
var copy_message = document.getElementById("copy-message");
var subject = {{ subject | tojson }};
var message = {{ "\n\n".join(lines) | tojson }};
copy_subject.addEventListener("click", function(e) {
navigator.clipboard.writeText(subject);
});
copy_message.addEventListener("click", function(e) {
navigator.clipboard.writeText(message);
});
</script>
{% endif %}
{% endblock %}