feat: enhance proxy URL handling and add static CSS

Extended proxy URL support to include maps.wikimedia.org, improving the range of URLs that can be proxied. Established a static folder for serving CSS files by modifying the application’s static folder path. Transferred inline CSS from the base HTML template into an external stylesheet to improve maintainability and separation of concerns.

Fixes #2, also some progress on #1.
This commit is contained in:
Kumi 2024-08-17 09:27:46 +02:00
parent 11d1c610a8
commit dbb3ab0e98
Signed by: kumi
GPG key ID: ECBCC9082395383F
3 changed files with 398 additions and 80 deletions

View file

@ -5,9 +5,11 @@ from html import escape
import json
import os
import logging
import pathlib
from bs4 import BeautifulSoup
app = Flask(__name__)
app.static_folder = pathlib.Path(__file__).parent / "static"
logging.basicConfig(level=logging.DEBUG)
@ -54,7 +56,9 @@ def get_proxy_url(url):
if url.startswith("//"):
url = "https:" + url
if not url.startswith("https://upload.wikimedia.org/"):
if not url.startswith("https://upload.wikimedia.org/") and not url.startswith(
"https://maps.wikimedia.org/"
):
logger.debug(f"Not generating proxy URL for {url}")
return url
@ -66,7 +70,10 @@ def get_proxy_url(url):
def proxy():
url = request.args.get("url")
if not url or not url.startswith("https://upload.wikimedia.org/"):
if not url or not (
url.startswith("https://upload.wikimedia.org/")
or url.startswith("https://maps.wikimedia.org/")
):
logger.error(f"Invalid URL for proxying: {url}")
return "Invalid URL"
@ -213,11 +220,13 @@ logger.debug(
f"Loaded {len(app.wikimedia_projects)} Wikimedia projects and {len(app.languages)} languages"
)
def main():
port = int(os.environ.get("PORT", 8109))
host = os.environ.get("HOST", "0.0.0.0")
debug = os.environ.get("DEBUG", False)
app.run(port=port, host=host, debug=debug)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,385 @@
/* General styling */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f8f9fa;
}
/* Link styling */
a {
color: #1e90ff;
text-decoration: none;
}
/* Header styling */
#header {
background-color: #ffffff;
border-bottom: 1px solid #a2a9b1;
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
#header h1 {
margin: 0;
font-size: 1.5em;
}
#header h1 a {
text-decoration: none;
color: #333;
}
/* Search styling */
#search-form {
margin: 0;
padding: 0;
display: flex;
align-items: center;
}
#search-form input[type="text"] {
width: 300px;
padding: 5px;
}
#search-form select {
padding: 5px;
}
#search-form button {
padding: 5px 10px;
}
/* Content styling */
#content {
padding: 20px;
}
h1 {
font-size: 2em;
padding-bottom: 10px;
margin-bottom: 20px;
}
.sidebar {
float: right;
width: 250px;
margin-left: 20px;
background-color: #ffffff;
border: 1px solid #a2a9b1;
padding: 10px;
box-sizing: border-box;
}
.toc {
list-style-type: none;
padding: 0;
}
.toc li {
margin-bottom: 5px;
}
.toc a {
text-decoration: none;
color: #333;
}
.toc a:hover {
text-decoration: underline;
}
#footer {
background-color: #ffffff;
border-top: 1px solid #a2a9b1;
padding: 10px;
text-align: center;
}
/* General table styling */
.table {
margin: 1em auto;
font-size: small;
border-collapse: collapse;
width: 100%;
max-width: 100%;
background-color: #f9f9f9;
border: 1px solid #ddd;
}
.table th {
background-color: #1e90ff;
color: white;
font-weight: bold;
text-align: center;
padding: 10px;
}
.table td {
text-align: center;
padding: 10px;
border: 1px solid #ddd;
}
.table a {
color: #1e90ff;
text-decoration: none;
}
.table a:hover {
text-decoration: underline;
}
.table tr:nth-child(even) {
background-color: #f2f2f2;
}
.table tr:hover {
background-color: #ddd;
}
.table td div {
font-weight: bold;
}
/* Specific class styling */
.succession-box {
clear: both;
}
.noprint {
display: none;
}
.navbox {
padding: 3px;
background-color: #f9f9f9;
margin-bottom: 1em;
}
.navbox-title {
background-color: #bbddff;
color: #000;
font-size: 114%;
margin: 0 4em;
text-align: center;
padding: 10px;
}
.navbox-group {
background-color: #bbddff;
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.navbox-list {
padding: 0;
}
.navbox-list a {
color: #1e90ff;
}
.navbox-list a:hover {
text-decoration: underline;
}
.navbox-image img {
width: 80px;
height: auto;
}
.navbox-abovebelow {
background-color: #bbddff;
padding: 10px;
text-align: center;
}
.navbox-inner {
border-spacing: 0;
background: transparent;
color: inherit;
}
.navbar {
text-align: center;
padding: 5px;
}
.navbox-list-with-group {
padding: 0;
margin: 0;
border-bottom: 1px solid #ddd;
}
.hlist ul {
list-style: none;
padding: 0;
margin: 0;
}
.hlist ul li {
display: inline;
margin-right: 10px;
}
.hlist ul li a {
color: #1e90ff;
}
.hlist ul li a:hover {
text-decoration: underline;
}
/* Authority control styling */
.authority-control {
padding: 3px;
text-align: left;
margin-bottom: 1em;
border: 1px solid #ddd;
}
.uid a {
color: #1e90ff;
}
.uid a:hover {
text-decoration: underline;
}
/* Sidebar styling */
.infobox {
float: right;
margin: 1em;
width: 300px;
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 10px;
font-size: small;
border-collapse: collapse;
}
.infobox-above {
background-color: #1e90ff;
color: white;
font-weight: bold;
text-align: center;
padding: 10px;
}
.infobox-above a {
color: white;
}
.infobox-subheader {
background-color: #bbddff;
text-align: center;
padding: 5px;
font-weight: bold;
}
.infobox-full-data {
text-align: center;
padding: 5px;
border-bottom: 1px solid #ddd;
}
.infobox-label {
background-color: #f2f2f2;
padding: 5px;
text-align: left;
font-weight: bold;
border-bottom: 1px solid #ddd;
}
.infobox-data {
padding: 5px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.ib-settlement-cols {
display: flex;
justify-content: space-around;
padding: 10px 0;
}
.ib-settlement-cols-cell {
text-align: center;
}
.ib-settlement-caption-link {
margin-top: 5px;
}
.ib-settlement-caption {
text-align: center;
font-style: italic;
margin-top: 5px;
}
.ib-settlement-nickname {
font-style: italic;
}
.infobox-header {
background-color: #1e90ff;
color: white;
font-weight: bold;
text-align: center;
padding: 10px;
border-bottom: 1px solid #ddd;
}
/* Figure styling */
figure, .tmulti {
margin: 1em 0;
padding: 10px;
background-color: #f9f9f9;
border: 1px solid #ddd;
display: inline-block;
}
figure img, .mw-file-element {
max-width: 100%;
height: auto;
border: 1px solid #ddd;
padding: 5px;
display: block;
margin-left: auto;
margin-right: auto;
}
figcaption, .thumbcaption {
margin-top: 10px;
font-size: small;
text-align: left;
color: #555;
text-align: center;
}
.mw-halign-left {
float: left;
margin-right: 1em;
}
.mw-halign-center {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.mw-halign-right {
float: right;
margin-left: 1em;
}
/* Reference styling */
.reflist-lower-alpha .references {
list-style-type: lower-alpha;
}

View file

@ -4,83 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}{% if title %} &dash; {% endif %}Wikimore</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f8f9fa;
}
#header {
background-color: #ffffff;
border-bottom: 1px solid #a2a9b1;
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
#header h1 {
margin: 0;
font-size: 1.5em;
}
#header h1 a {
text-decoration: none;
color: #333;
}
#search-form {
margin: 0;
padding: 0;
display: flex;
align-items: center;
}
#search-form input[type="text"] {
width: 300px;
padding: 5px;
}
#search-form select {
padding: 5px;
}
#search-form button {
padding: 5px 10px;
}
#content {
padding: 20px;
}
h1 {
font-size: 2em;
padding-bottom: 10px;
margin-bottom: 20px;
}
.sidebar {
float: right;
width: 250px;
margin-left: 20px;
background-color: #ffffff;
border: 1px solid #a2a9b1;
padding: 10px;
box-sizing: border-box;
}
.toc {
list-style-type: none;
padding: 0;
}
.toc li {
margin-bottom: 5px;
}
.toc a {
text-decoration: none;
color: #333;
}
.toc a:hover {
text-decoration: underline;
}
#footer {
background-color: #ffffff;
border-top: 1px solid #a2a9b1;
padding: 10px;
text-align: center;
}
</style>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<div id="header">