aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2023-08-31 16:59:43 -0400
committerB. Stack <bgstack15@gmail.com>2023-08-31 16:59:43 -0400
commit60dcc4fdf3868122c0099025d94b3c5579593473 (patch)
treea5a47452573c0b52b073e5113f23885cd519ea6a
parentchg: [dependencies] Updated Python dependencies. (diff)
downloadnewspipe-stackrpms-master.tar.gz
newspipe-stackrpms-master.tar.bz2
newspipe-stackrpms-master.zip
stackrpms base plus reverse-proxystackrpms-master
-rw-r--r--instance/config.py3
-rw-r--r--instance/sqlite.py3
-rw-r--r--newspipe/bootstrap.py19
-rw-r--r--newspipe/controllers/user.py8
-rw-r--r--newspipe/static/css/custom.css72
-rw-r--r--newspipe/static/js/articles.js6
-rw-r--r--newspipe/static/js/config.js7
-rw-r--r--newspipe/templates/about.html1
-rw-r--r--newspipe/templates/about_more.html2
-rw-r--r--newspipe/templates/article.html2
-rw-r--r--newspipe/templates/duplicates.html6
-rw-r--r--newspipe/templates/history.html2
-rw-r--r--newspipe/templates/home.html10
-rw-r--r--newspipe/templates/layout.html3
-rw-r--r--newspipe/templates/login.html2
-rw-r--r--newspipe/templates/management.html2
-rw-r--r--newspipe/web/__init__.py11
-rw-r--r--newspipe/web/views/user.py1
-rw-r--r--newspipe/web/views/views.py4
19 files changed, 127 insertions, 37 deletions
diff --git a/instance/config.py b/instance/config.py
index 42e624cb..af7617a4 100644
--- a/instance/config.py
+++ b/instance/config.py
@@ -10,6 +10,9 @@ PORT = 5000
DEBUG = True
API_ROOT = "/api/v2.0"
+# Optional, and useful if you are using a reverse proxy with this virtual path prefix
+#PREFIX = "/newspipe"
+
CSRF_ENABLED = True
SECRET_KEY = "LCx3BchmHRxFzkEv4BqQJyeXRLXenf"
SECURITY_PASSWORD_SALT = "L8gTsyrpRQEF8jNWQPyvRfv7U5kJkD"
diff --git a/instance/sqlite.py b/instance/sqlite.py
index 1f8d6206..c6eaa461 100644
--- a/instance/sqlite.py
+++ b/instance/sqlite.py
@@ -10,6 +10,9 @@ PORT = 5000
DEBUG = True
API_ROOT = "/api/v2.0"
+# Optional, and useful if you are using a reverse proxy with this virtual path prefix
+#PREFIX = "/newspipe"
+
CSRF_ENABLED = True
SECRET_KEY = "LCx3BchmHRxFzkEv4BqQJyeXRLXenf"
SECURITY_PASSWORD_SALT = "L8gTsyrpRQEF8jNWQPyvRfv7U5kJkD"
diff --git a/newspipe/bootstrap.py b/newspipe/bootstrap.py
index 12044916..1c5c967d 100644
--- a/newspipe/bootstrap.py
+++ b/newspipe/bootstrap.py
@@ -44,6 +44,14 @@ def set_logging(
handler.setLevel(log_level)
logger.setLevel(log_level)
+class ReverseProxied(object):
+ def __init__(self, app, script_name):
+ self.app = app
+ self.script_name = script_name
+
+ def __call__(self, environ, start_response):
+ environ['SCRIPT_NAME'] = self.script_name
+ return self.app(environ, start_response)
# Create Flask application
application = Flask(__name__, instance_relative_config=True)
@@ -63,6 +71,11 @@ else:
set_logging(application.config["LOG_PATH"])
+_prefix = ""
+if "PREFIX" in application.config:
+ application.wsgi_app = ReverseProxied(application.wsgi_app, script_name=application.config["PREFIX"])
+ _prefix = application.config["PREFIX"]
+
db = SQLAlchemy(application)
migrate = Migrate(application, db)
@@ -100,3 +113,9 @@ application.jinja_env.filters["datetime"] = format_datetime
application.jinja_env.filters["datetimeformat"] = datetimeformat
# inject application in Jinja env
application.jinja_env.globals["application"] = application
+
+@application.context_processor
+def utility_processor():
+ def prefix():
+ return _prefix.rstrip("/")
+ return dict(prefix=prefix)
diff --git a/newspipe/controllers/user.py b/newspipe/controllers/user.py
index 00ffb96a..54137794 100644
--- a/newspipe/controllers/user.py
+++ b/newspipe/controllers/user.py
@@ -5,6 +5,7 @@ import ldap3
from ldap3.core.exceptions import LDAPBindError
from werkzeug.security import check_password_hash
from werkzeug.security import generate_password_hash
+from urllib.parse import urlparse
from .abstract import AbstractController
from newspipe.bootstrap import application
@@ -17,6 +18,11 @@ from newspipe.models import User
logger = logging.getLogger(__name__)
+# FOR LDAP
+# Reference: session_app
+import ldap3
+from ldap3.core.exceptions import LDAPBindError, LDAPPasswordIsMandatoryError
+
class UserController(AbstractController):
_db_cls = User
@@ -138,7 +144,7 @@ class LdapuserController:
namelist = []
try:
query = dns.resolver.query(f"_ldap._tcp.{domain}", "SRV")
- except dns.resolver.NXDOMAIN:
+ except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
# no records exist that match the request, so we were probably
# given a specific hostname, and an empty query will trigger
# the logic below that will add the original domain to the list.
diff --git a/newspipe/static/css/custom.css b/newspipe/static/css/custom.css
index 70a24bf8..65625f0e 100644
--- a/newspipe/static/css/custom.css
+++ b/newspipe/static/css/custom.css
@@ -1,3 +1,13 @@
+:root {
+ /* primary color, for header bar, links, etc. */
+ --main-color: #bc0900;
+ /* right side of header bar, border around some buttons, button hover color */
+ --main-shade: #7f0600;
+ /* color of active button */
+ --main-tint: #ed0b00;
+ /* very light color, not used at present, but designed for the background of (2n+1) table rows */
+ --main-accent: #fcf5f4;
+}
html {
position: relative;
min-height: 100%;
@@ -11,8 +21,9 @@ body {
img {
padding: 2px;
}
-a {
- color: #3572B0;
+a, a.nav-link {
+ /*color: #3572B0;*/
+ color: var(--main-color);
}
#sidebar {
@@ -33,28 +44,55 @@ a {
rgb(255, 255, 255, 1);
}
+a:hover,a.nav-link:hover {
+ color: var(--main-shade);
+}
+
.bg-newspipe-blue {
/* background-color: #0082c9; */
- background-image: linear-gradient(40deg, #0082c9 0%, #30b6ff 100%);
+ /* background-image: linear-gradient(40deg, #0082c9 0%, #30b6ff 100%); */
+ background-image: linear-gradient(40deg, var(--main-color) 0%, var(--main-shade) 100%);
}
.btn-primary {
- background-color: #0082c9;
+ /* background-color: #0082c9; */
+ background-color: var(--main-color);
+ border-color: var(--main-shade);
opacity: 1;
color: white;
}
.btn-secondary {
- background-color: #0082c9;
+ /* background-color: #0082c9; */
+ background-color: var(--main-color);
opacity: 0.6;
color: white;
}
+.btn-primary:hover, .btn-secondary {
+ background-color: var(--main-shade);
+}
.btn-outline-primary {
- border-color: #0082c9;
- color: #0082c9;
+ /* border-color: #0082c9;
+ color: #0082c9; */
+ border-color: var(--main-color);
+ color: var(--main-color);
+}
+
+.btn-primary:hover {
+ border-color: var(--main-shade);
+}
+
+.btn-primary:active, .btn.btn-primary:active, .btn-secondary:active, a.btn.btn-primary:active {
+ background-color: var(--main-tint);
+ border: var(--main-tint);
+}
+
+.dropdown-item:active, a.dropdown-item:active {
+ background-color: var(--main-tint);
}
.bg-primary {
- background-color: #0082c9 !important;
+ /* background-color: #0082c9 !important; */
+ background-color: var(--main-color) !important;
opacity: 1;
color: white;
text-align: center;
@@ -63,7 +101,12 @@ a {
.badge-light {
background-color: rgb(246, 248, 250);
opacity: 1;
- color: #0082c9 !important;
+ /* color: #0082c9 !important; */
+ color: var(--main-color) !important;
+}
+
+.badge:hover {
+ color: var(--main-shade);
}
/* Main table for the list of news */
@@ -113,3 +156,14 @@ a {
.pagination-page-info {
display: inline;
}
+
+.fa-square-o::before, .fa-checked-square-o::before, .fa-star-o::before {
+ color: var(--main-color);
+}
+
+/*
+ * Unnecessary
+.table-striped tbody tr:nth-of-type(2n+1) {
+ background-color: var(--main-accent);
+}
+ */
diff --git a/newspipe/static/js/articles.js b/newspipe/static/js/articles.js
index f1cee6e7..29ebac2e 100644
--- a/newspipe/static/js/articles.js
+++ b/newspipe/static/js/articles.js
@@ -86,7 +86,7 @@ Array.prototype.map.call(nodes, function(node) {
}
// sends the updates to the server
- fetch(API_ROOT + "article/" + article_id, {
+ fetch(prefix + API_ROOT + "article/" + article_id, {
method: "PUT",
headers: {
'Content-Type': 'application/json',
@@ -157,7 +157,7 @@ Array.prototype.map.call(nodes, function(node) {
}
// sends the updates to the server
- fetch(API_ROOT + "article/" + article_id, {
+ fetch(prefix + API_ROOT + "article/" + article_id, {
method: "PUT",
headers: {
'Content-Type': 'application/json',
@@ -189,7 +189,7 @@ Array.prototype.map.call(nodes, function(node) {
data = JSON.stringify(data);
// sends the updates to the server
- fetch(API_ROOT + "articles", {
+ fetch(prefix + API_ROOT + "articles", {
method: "DELETE",
headers: {
'Content-Type': 'application/json',
diff --git a/newspipe/static/js/config.js b/newspipe/static/js/config.js
new file mode 100644
index 00000000..7fad4388
--- /dev/null
+++ b/newspipe/static/js/config.js
@@ -0,0 +1,7 @@
+/*
+ * Set variables here for the javascript used by newspipe.
+ */
+var prefix = "/newspipe";
+
+/* Set exactly one trailing slash on prefix. */
+prefix = prefix.replace(/\/+$/,"/");
diff --git a/newspipe/templates/about.html b/newspipe/templates/about.html
index 45703ea0..973c086e 100644
--- a/newspipe/templates/about.html
+++ b/newspipe/templates/about.html
@@ -12,6 +12,7 @@
<p>{{ _('Found a bug? Report it <a href="https://todo.sr.ht/~cedric/newspipe">here</a>.') }}
{{ _('A documentation is available <a href="https://man.sr.ht/~cedric/newspipe">here</a>.') }}</p>
<p><a href="{{ url_for('about_more') }}">{{ _('More information') }}</a> {{ _('about this instance.') }}</p>
+ <p><a href="{{ git_url }}">This fork's source</a></p>
</div>
</div>
<br />
diff --git a/newspipe/templates/about_more.html b/newspipe/templates/about_more.html
index 0df05852..6f01681f 100644
--- a/newspipe/templates/about_more.html
+++ b/newspipe/templates/about_more.html
@@ -5,7 +5,7 @@
<div class="col">
<h2>{{ _('Information about this instance') }}</h2>
<ul class="list-group">
- <li class="list-group-item">{{ _('Newspipe version') }}: <em><a href="{{ version_url }}">{{newspipe_version}}</a></em></li>
+ <li class="list-group-item">{{ _('Newspipe version') }}: <em>{{newspipe_version}}</em></li>
<li class="list-group-item">{{ _('Python version') }}: <em>{{python_version}}</em></li>
<li class="list-group-item">{{ _('Registration') }}: <em>{{registration}}</em></li>
<li class="list-group-item">{{ _('Number of users') }}: <em>{{nb_users}}</em></li>
diff --git a/newspipe/templates/article.html b/newspipe/templates/article.html
index c62e3f0c..d9cf9a62 100644
--- a/newspipe/templates/article.html
+++ b/newspipe/templates/article.html
@@ -4,7 +4,7 @@
<div class="row" data-article="{{ article.id }}" id="filters" data-filter="{{ filter_ }}">
<div class="col">
<h2><a href="{{ article.link }}" target="_blank">{{ article.title|safe }}</a></h2>
- <h3>{{ _('from') }} <a href="/feed/{{ article.source.id }}">{{ article.source.title }}</a></h3>
+ <h3>{{ _('from') }} <a href="{{ prefix() }}/feed/{{ article.source.id }}">{{ article.source.title }}</a></h3>
<a href="{{ url_for("article.delete", article_id=article.id) }}"><i class="fa fa-times delete" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>
{% if article.like %}
<a href="#"><i class="fa fa-star like" aria-hidden="true" title="{{ _('One of your favorites') }}"></i></a>
diff --git a/newspipe/templates/duplicates.html b/newspipe/templates/duplicates.html
index 38dc52b1..d1382268 100644
--- a/newspipe/templates/duplicates.html
+++ b/newspipe/templates/duplicates.html
@@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% block content %}
<div class="container">
- <p><h1>{{ _('Duplicates in the feed') }} <a href="/feed/{{ feed.id }}">{{ feed.title }}</a>.</h1><p>
+ <p><h1>{{ _('Duplicates in the feed') }} <a href="{{ prefix() }}/feed/{{ feed.id }}">{{ feed.title }}</a>.</h1><p>
<div class="table-responsive">
<table class="table table-striped">
<thead>
@@ -19,8 +19,8 @@
{% for pair in duplicates %}
<tr>
<td>{{ loop.index }}</td>
- <td id="{{ pair[0].id }}"><a href="{{ url_for("article.delete", article_id=pair[0].id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>&nbsp;<a href="/article/{{ pair[0].id }}">{{ pair[0].title }}</a> ({{ pair[0].retrieved_date }})</td>
- <td id="{{ pair[1].id }}"><a href="{{ url_for("article.delete", article_id=pair[1].id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>&nbsp;<a href="/article/{{ pair[1].id }}">{{ pair[1].title }}</a> ({{ pair[1].retrieved_date }})</td>
+ <td id="{{ pair[0].id }}"><a href="{{ url_for("article.delete", article_id=pair[0].id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>&nbsp;<a href="{{ prefix() }}/article/{{ pair[0].id }}">{{ pair[0].title }}</a> ({{ pair[0].retrieved_date }})</td>
+ <td id="{{ pair[1].id }}"><a href="{{ url_for("article.delete", article_id=pair[1].id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>&nbsp;<a href="{{ prefix() }}/article/{{ pair[1].id }}">{{ pair[1].title }}</a> ({{ pair[1].retrieved_date }})</td>
</tr>
{% endfor %}
</tbody>
diff --git a/newspipe/templates/history.html b/newspipe/templates/history.html
index 153c2f11..00e22ef3 100644
--- a/newspipe/templates/history.html
+++ b/newspipe/templates/history.html
@@ -43,7 +43,7 @@
<ul class="list-group">
{% for date in articles_counter | sort(reverse = True) %}
{% for article in articles %}
- <li class="list-group-item">{{ article.date | datetime }} - <a href="/article/{{ article.id }}">{{ article.title | safe }}</a></li>
+ <li class="list-group-item">{{ article.date | datetime }} - <a href="{{ prefix() }}/article/{{ article.id }}">{{ article.title | safe }}</a></li>
{% endfor %}
{% endfor %}
</ul>
diff --git a/newspipe/templates/home.html b/newspipe/templates/home.html
index 631b769c..5feb18d1 100644
--- a/newspipe/templates/home.html
+++ b/newspipe/templates/home.html
@@ -42,7 +42,7 @@
{% if feed_id == feed.id %}</b>{% endif %}
</a></li>
<li class="nav-item feed-commands {% if in_error.get(fid, 0) > 0 %}d-none{% endif %}" data-bs-feed="{{ feed.id }}"><span class="nav-link">
- <a href="/feed/{{ feed.id }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
+ <a href="{{ prefix() }}/feed/{{ feed.id }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
<a href="{{ url_for('feed.form', feed_id=feed.id) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this feed') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='unread', feed_id=feed.id) }}"><i class="fa fa-square-o" aria-hidden="true" title="{{ _('Mark this feed as unread') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='read', feed_id=feed.id) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
@@ -73,7 +73,7 @@
{% if feed_id == fid %}</b>{% endif %}
</a></li>
<li class="nav-item feed-commands {% if in_error.get(fid, 0) > 0 %}d-none{% endif %}" data-bs-feed="{{ fid }}"><span class="nav-link">
- <a href="/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
+ <a href="{{ prefix() }}/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
<a href="{{ url_for('feed.form', feed_id=fid) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this feed') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='unread', feed_id=fid) }}"><i class="fa fa-square-o" aria-hidden="true" title="{{ _('Mark this feed as unread') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
@@ -102,7 +102,7 @@
{% if feed_id == fid %}</b>{% endif %}
</a></li>
<li class="nav-item feed-commands {% if in_error.get(fid, 0) > 0 %}d-none{% endif %}" data-bs-feed="{{ fid }}"><span class="nav-link">
- <a href="/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
+ <a href="{{ prefix() }}/feed/{{ fid }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Details') }}"></i></a>
<a href="{{ url_for('feed.form', feed_id=fid) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this feed') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='unread', feed_id=fid) }}"><i class="fa fa-square-o" aria-hidden="true" title="{{ _('Mark this feed as unread') }}"></i></a>
<a href="{{ url_for('article.mark_as', new_value='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></i></a>
@@ -174,11 +174,11 @@
{% if not feed_id %}
<td class="d-none d-md-block">
<img src="{{ url_for('icon.icon', url=feeds[article.source.id].icon_url) }}" width="16px">
- <a href="/article/redirect/{{ article.id}}" target="_blank">{{ article.source.title | safe }}</a>
+ <a href="{{ prefix() }}/article/redirect/{{ article.id}}" target="_blank">{{ article.source.title | safe }}</a>
</td>
{% endif %}
<td {%if filter_ == 'all' and article.readed == False %}style='font-weight:bold'{% endif %}>
- <a href="/article/{{ article.id }}" title="{{ article.title }}">{{ article.title | truncate(100, False, '...') }}</a>
+ <a href="{{ prefix() }}/article/{{ article.id }}" title="{{ article.title }}">{{ article.title | truncate(100, False, '...') }}</a>
</td>
<td class="date d-none d-lg-block">{{ article.date | datetime(format='short') }}</td>
</tr>
diff --git a/newspipe/templates/layout.html b/newspipe/templates/layout.html
index 2464040c..466ff4e2 100644
--- a/newspipe/templates/layout.html
+++ b/newspipe/templates/layout.html
@@ -21,7 +21,7 @@
{% block menu %}
<nav class="navbar navbar-expand-lg navbar-dark bg-newspipe-blue">
<div class="container-fluid">
- <a class="navbar-brand" href="/">Newspipe</a>
+ <a class="navbar-brand" href="{{ prefix() }}/">Newspipe</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
@@ -150,6 +150,7 @@
{% block content %}{% endblock %}
<!-- Placed at the end of the document so the pages load faster -->
+ <script type="text/javascript" src="{{ url_for('static', filename = 'js/config.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename = 'js/articles.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename = 'js/feed.js') }}"></script>
</body>
diff --git a/newspipe/templates/login.html b/newspipe/templates/login.html
index b9952309..78af3c4a 100644
--- a/newspipe/templates/login.html
+++ b/newspipe/templates/login.html
@@ -19,7 +19,7 @@
<div class="alert alert-warning" role="alert">{{ message }}</div>
{% endfor %}
{{ form.submit(class_="btn btn-primary") }}
- {% if self_registration %}<a href="/signup" class="btn btn-info">{{ _('Sign up') }}</a>{% endif %}
+ {% if self_registration %}<a href="{{ prefix() }}/signup" class="btn btn-info">{{ _('Sign up') }}</a>{% endif %}
</form>
</div>
</div>
diff --git a/newspipe/templates/management.html b/newspipe/templates/management.html
index 4e977f84..19dbded0 100644
--- a/newspipe/templates/management.html
+++ b/newspipe/templates/management.html
@@ -6,7 +6,7 @@
<div class="row">
<div class="col">
<h2>{{ _('Your subscriptions') }}</h2>
- <p>{{ _('You are subscribed to') }} {{ nb_feeds }} <a href="/feeds">{{ _('feeds') }}</a>. <a href="{{ url_for("feed.form") }}">{{ _('Add') }}</a> {{ _('a feed') }}.</p>
+ <p>{{ _('You are subscribed to') }} {{ nb_feeds }} <a href="{{ prefix() }}/feeds">{{ _('feeds') }}</a>. <a href="{{ url_for("feed.form") }}">{{ _('Add') }}</a> {{ _('a feed') }}.</p>
<p>{{ nb_articles }} {{ _('articles are stored in the database with') }} {{ nb_unread_articles }} {{ _('unread articles') }}.</p>
<p>{{ _('You have') }} {{ nb_categories }} <a href="{{ url_for("categories.list_")}}">{{ _('categories') }}</a>.</p>
<a href="{{ url_for("articles.expire", weeks=10) }}" class="btn btn-primary" onclick="return confirm('{{ _('You are going to delete old articles.') }}');">{{ _('Delete articles older than 10 weeks') }}</a>
diff --git a/newspipe/web/__init__.py b/newspipe/web/__init__.py
index 9cd78b88..cbda2235 100644
--- a/newspipe/web/__init__.py
+++ b/newspipe/web/__init__.py
@@ -10,11 +10,6 @@ import subprocess
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
-__version__ = (
- os.environ.get("PKGVER")
- or subprocess.run(
- ["git", "-C", BASE_DIR, "describe", "--tags"], stdout=subprocess.PIPE
- )
- .stdout.decode()
- .strip()
-)
+# bgstack15
+__version__ = "v9.5.1"
+__git_url__ = "https://bgstack15.ddns.net/cgit/newspipe"
diff --git a/newspipe/web/views/user.py b/newspipe/web/views/user.py
index 5f2240bc..6550403c 100644
--- a/newspipe/web/views/user.py
+++ b/newspipe/web/views/user.py
@@ -9,6 +9,7 @@ from flask_login import current_user
from flask_login import login_required
from flask_paginate import get_page_args
from flask_paginate import Pagination
+from werkzeug.exceptions import BadRequest
from newspipe.bootstrap import application
from newspipe.controllers import ArticleController
diff --git a/newspipe/web/views/views.py b/newspipe/web/views/views.py
index 3fc446e0..92724bb6 100644
--- a/newspipe/web/views/views.py
+++ b/newspipe/web/views/views.py
@@ -17,7 +17,7 @@ from newspipe.bootstrap import application
from newspipe.bootstrap import talisman
from newspipe.controllers import FeedController
from newspipe.controllers import UserController
-from newspipe.web import __version__
+from newspipe.web import __version__, __git_url__
from newspipe.web.lib.view_utils import etag_match
logger = logging.getLogger(__name__)
@@ -88,7 +88,7 @@ def popular():
@current_app.route("/about", methods=["GET"])
@etag_match
def about():
- return render_template("about.html", contact=application.config["ADMIN_EMAIL"])
+ return render_template("about.html", contact=application.config["ADMIN_EMAIL"], git_url=__git_url__)
@current_app.route("/about/more", methods=["GET"])
bgstack15