From 95d69ef3023b76f7d6b43051e35ada16bad6b924 Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Wed, 22 Apr 2020 14:22:33 +0100
Subject: [PATCH] Add block list report to show active blocks

---
 app.py                      | 19 +++++++++++++++
 depicts/mediawiki.py        |  4 ++++
 templates/base.html         |  7 ++++++
 templates/block_alert.html  | 25 ++++++++++++++++++++
 templates/block_report.html | 47 +++++++++++++++++++++++++++++++++++++
 5 files changed, 102 insertions(+)
 create mode 100644 templates/block_alert.html
 create mode 100644 templates/block_report.html

diff --git a/app.py b/app.py
index 6391de2..8ed97fd 100755
--- a/app.py
+++ b/app.py
@@ -22,6 +22,7 @@ import hashlib
 import json
 import os
 import locale
+import socket
 
 locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
 user_agent = 'Mozilla/5.0 (X11; Linux i586; rv:32.0) Gecko/20160101 Firefox/32.0'
@@ -112,6 +113,20 @@ def init_profile():
 def global_user():
     g.user = wikidata_oauth.get_username()
 
+@app.before_request
+def get_blocks():
+    hostname = app.config.get('HOSTNAME')
+    if not hostname:
+        return
+    g.server_ip = socket.gethostbyname(hostname)
+    try:
+        g.local_blocks = mediawiki.get_list('blocks',
+                                            bkip=g.server_ip)
+        g.global_blocks = mediawiki.get_list('globalblocks',
+                                             bgip=g.server_ip)
+    except Exception:
+        pass
+
 @app.route('/find_more_setting')
 def flip_find_more():
     session['no_find_more'] = not session.get('no_find_more')
@@ -1058,6 +1073,10 @@ def wikidata_query_list():
     q = WikidataQuery.query.order_by(WikidataQuery.start_time.desc())
     return render_template('query_list.html', q=q)
 
+@app.route('/report/blocks')
+def server_block_report():
+    return render_template('block_report.html')
+
 
 if __name__ == "__main__":
     app.debug = True
diff --git a/depicts/mediawiki.py b/depicts/mediawiki.py
index d01b669..deb99f9 100644
--- a/depicts/mediawiki.py
+++ b/depicts/mediawiki.py
@@ -23,6 +23,10 @@ def api_call(params, api_url=wikidata_url):
     r = requests.get(api_url, params=call_params, timeout=5)
     return r
 
+def get_list(list_name, **params):
+    r = api_call({'action': 'query', 'list': list_name, **params})
+    return r.json()['query'][list_name]
+
 def get_entity(qid, redirects=False):
     json_data = api_call({'action': 'wbgetentities',
                           'ids': qid,
diff --git a/templates/base.html b/templates/base.html
index faf83ae..748ab68 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -12,9 +12,16 @@
   {% block style %}{% endblock %}
 </head>
 {% from "navbar.html" import navbar with context %}
+{% from "block_alert.html" import local_block_alert, global_block_alert with context %}
 
 <body>
   {% block nav %}{{ navbar() }}{% endblock %}
+
+<div class="p-2">
+  {{ local_block_alert() }}
+  {{ global_block_alert() }}
+</div>
+
   {% block content %}{% endblock %}
 
   <script src="{{ url_for('static', filename='javascript/jquery/jquery.min.js') }}"></script>
diff --git a/templates/block_alert.html b/templates/block_alert.html
new file mode 100644
index 0000000..2cc2417
--- /dev/null
+++ b/templates/block_alert.html
@@ -0,0 +1,25 @@
+{% macro local_block_alert() %}
+{% if g.local_blocks %}
+<div class="alert alert-danger" role="alert">
+  <h4 class="alert-heading">Wikidata IP block preventing edits</h4>
+  <p>Editing is currently unavailable due to a block of the server that hosts this tool.</p>
+  {% if request.endpoint != 'server_block_report' %}
+  <hr>
+  <p class="mb-0">See the <a href="{{ url_for('server_block_report') }}">block report</a> for more details.</p>
+  {% endif %}
+</div>
+{% endif %}
+{% endmacro %}
+
+{% macro global_block_alert() %}
+{% if g.global_blocks %}
+<div class="alert alert-danger" role="alert">
+  <h4 class="alert-heading">Wikimedia global IP block preventing edits</h4>
+  <p>Editing is currently unavailable due to a block of the server that hosts this tool.</p>
+  {% if request.endpoint != 'server_block_report' %}
+  <hr>
+  <p class="mb-0">See the <a href="{{ url_for('server_block_report') }}">block report</a> for more details.</p>
+  {% endif %}
+</div>
+{% endif %}
+{% endmacro %}
diff --git a/templates/block_report.html b/templates/block_report.html
new file mode 100644
index 0000000..7d90eec
--- /dev/null
+++ b/templates/block_report.html
@@ -0,0 +1,47 @@
+{% extends "base.html" %}
+
+{% macro block_list(blocks) %}
+{% for i in blocks %}
+  <dl class="row">
+  {% for key, value in i.items() %}
+    <dt class="col-sm-1">{{ key }}</dt>
+    <dd class="col-sm-11">{{ value }}</dt>
+  {% endfor %}
+  </dl>
+{% endfor %}
+{% endmacro %}
+
+{% block content %}
+<div class="p-2">
+  <h1>Block report</h1>
+
+  <p>This report shows IP blocks on Wikidata that will prevent changes being saved.</p>
+
+  <ul>
+    <li>Server hostname: {{ config.HOSTNAME }}</li>
+    <li>Server IP: {{ g.server_ip }}</li>
+  </ul>
+
+  <h4>Local blocks on Wikidata</h4>
+  {% set url = 'https://www.wikidata.org/wiki/Special:BlockList?wpTarget=' + g.server_ip %}
+  <p><a href="{{ url }}">Check block list on Wikidata</a></p>
+
+  {% if g.local_blocks %}
+    {{ block_list(g.local_blocks) }}
+  {% else %}
+    <p>There are no local blocks for the server IP address on Wikidata</p>
+  {% endif %}
+
+  <h4>Global blocks</h4>
+  {% set url = 'https://www.wikidata.org/wiki/Special:GlobalBlockList/' + g.server_ip %}
+  <p><a href="{{ url }}">Check global block list</a></p>
+
+  {% if g.global_blocks %}
+    {{ block_list(g.global_blocks) }}
+  {% else %}
+    <p>There are no global blocks for the server IP address</p>
+  {% endif %}
+
+</div>
+
+{% endblock %}