aboutsummaryrefslogtreecommitdiff
path: root/newspipe/templates
diff options
context:
space:
mode:
authorCédric Bonhomme <cedric@cedricbonhomme.org>2020-03-09 23:16:05 +0100
committerCédric Bonhomme <cedric@cedricbonhomme.org>2020-03-09 23:16:05 +0100
commit3ab6290d4994b33cdbf831523938cdb18a13bf49 (patch)
tree685980f53aaa3eda4e27ddfc7032554f55528e57 /newspipe/templates
parentImproved method to detect current version of the Newspipe instance. (diff)
downloadnewspipe-3ab6290d4994b33cdbf831523938cdb18a13bf49.tar.gz
newspipe-3ab6290d4994b33cdbf831523938cdb18a13bf49.tar.bz2
newspipe-3ab6290d4994b33cdbf831523938cdb18a13bf49.zip
Refactoring the backend.
Diffstat (limited to 'newspipe/templates')
-rw-r--r--newspipe/templates/about.html26
-rw-r--r--newspipe/templates/about_more.html11
-rw-r--r--newspipe/templates/admin/create_user.html26
-rw-r--r--newspipe/templates/admin/dashboard.html68
-rw-r--r--newspipe/templates/article.html35
-rw-r--r--newspipe/templates/article_pub.html24
-rw-r--r--newspipe/templates/bookmarks.html81
-rw-r--r--newspipe/templates/categories.html36
-rw-r--r--newspipe/templates/duplicates.html30
-rw-r--r--newspipe/templates/edit_bookmark.html84
-rw-r--r--newspipe/templates/edit_category.html23
-rw-r--r--newspipe/templates/edit_feed.html98
-rw-r--r--newspipe/templates/emails/account_activation.txt9
-rw-r--r--newspipe/templates/emails/new_password.txt8
-rw-r--r--newspipe/templates/errors/404.html12
-rw-r--r--newspipe/templates/errors/500.html12
-rw-r--r--newspipe/templates/feed.html76
-rw-r--r--newspipe/templates/feed_list.html55
-rw-r--r--newspipe/templates/feed_list_per_categories.html52
-rw-r--r--newspipe/templates/feed_list_simple.html35
-rw-r--r--newspipe/templates/feeds.html7
-rw-r--r--newspipe/templates/history.html26
-rw-r--r--newspipe/templates/home.html135
-rw-r--r--newspipe/templates/inactives.html26
-rw-r--r--newspipe/templates/layout.html140
-rw-r--r--newspipe/templates/login.html32
-rw-r--r--newspipe/templates/management.html99
-rw-r--r--newspipe/templates/opml.xml13
-rw-r--r--newspipe/templates/popular.html27
-rw-r--r--newspipe/templates/profile.html68
-rw-r--r--newspipe/templates/profile_public.html45
-rw-r--r--newspipe/templates/signup.html24
-rw-r--r--newspipe/templates/user_stream.html70
33 files changed, 1513 insertions, 0 deletions
diff --git a/newspipe/templates/about.html b/newspipe/templates/about.html
new file mode 100644
index 00000000..43d8c73d
--- /dev/null
+++ b/newspipe/templates/about.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="card">
+ <div class="card-body">
+ <h2>{{ _('About') }}</h2>
+ <p>
+ {{ _('Newspipe is a news aggregator platform.') }}
+ <p>{{ _('This software is under AGPLv3 license. You are welcome to copy, modify or
+ redistribute the <a href="https://git.sr.ht/~cedric/newspipe">source code</a>
+ according to the <a href="https://www.gnu.org/licenses/agpl-3.0.html">Affero GPL</a> license.') }}</p>
+ <p>{{ _('Found a bug? Report it <a href="https://todo.sr.ht/~cedric/newspipe">here</a>.') }}</p>
+ <p><a href="{{ url_for('about_more') }}">{{ _('More information') }}</a> {{ _('about this instance.') }}</p>
+ </div>
+ </div>
+ <br />
+ <div class="card">
+ <div class="card-body">
+ <h2>{{ _('Help') }}</h2>
+ <p>{{ _('Contact')}}: <a href="mailto:{{ contact }}">{{ contact }}</a></p>
+ <p>{{ _('You can subscribe to new feeds with a bookmarklet. Drag the following button to your browser bookmarks.') }}</p>
+ {{ _('<a class="btn btn-primary" href="%(bookmarklet)s" rel="bookmark">Subscribe to this feed using Newspipe</a>', bookmarklet='javascript:window.location="%s?url="+encodeURIComponent(document.location)' % url_for('feed.bookmarklet', _external=True)) }}
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/about_more.html b/newspipe/templates/about_more.html
new file mode 100644
index 00000000..94a01c07
--- /dev/null
+++ b/newspipe/templates/about_more.html
@@ -0,0 +1,11 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <ul class="list-group">
+ <li class="list-group-item">{{ _('Newspipe version') }}: <a href="{{ version_url }}">{{newspipe_version}}</a></li>
+ <li class="list-group-item">{{ _('Registration') }}: {{registration}}</li>
+ <li class="list-group-item">{{ _('Python version') }}: {{python_version}}</li>
+ <li class="list-group-item">{{ _('Number of users') }}: {{nb_users}}</li>
+ </ul>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/admin/create_user.html b/newspipe/templates/admin/create_user.html
new file mode 100644
index 00000000..8844f987
--- /dev/null
+++ b/newspipe/templates/admin/create_user.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block head%}
+{{super()}}
+{% endblock %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h2>{{ message | safe }}</h2>
+ <form action="" method="post" name="saveprofileform" id="profileform">
+ {{ form.hidden_tag() }}
+
+ {{ form.nickname.label }}
+ {{ form.nickname(class_="form-control") }} {% for error in form.nickname.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.password.label }}
+ {{ form.password(class_="form-control") }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.automatic_crawling.label }}
+ {{ form.automatic_crawling(class_="form-control") }} {% for error in form.automatic_crawling.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ <br />
+ {{ form.submit(class_="btn btn-primary") }}
+ </form>
+ </div>
+</div>
+{% endblock %}
diff --git a/newspipe/templates/admin/dashboard.html b/newspipe/templates/admin/dashboard.html
new file mode 100644
index 00000000..8bcc2db0
--- /dev/null
+++ b/newspipe/templates/admin/dashboard.html
@@ -0,0 +1,68 @@
+{% extends "layout.html" %}
+{% block head%}
+{{super()}}
+{% endblock %}
+{% block content %}
+<div class="container">
+<h1>{{ _('Registered users') }}</h1>
+<table id="table-users" class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Nickname') }}</th>
+ <th>{{ _('Member since') }}</th>
+ <th>{{ _('Last seen') }}</th>
+ <th>{{ _('Actions') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for user in users %}
+ <tr {% if not user.is_active %}class="warning"{% endif %}>
+ <td>{{ loop.index }}</td>
+ <td>
+ {% if user.is_public_profile %}
+ <a href="{{ url_for("user.profile_public", nickname=user.nickname) }}">{{ user.nickname }}</a>
+ {% else %}
+ {{ user.nickname }}
+ {% endif %}
+ {% if user.id == current_user.id %}&nbsp;(It's you!){% endif %}
+ </td>
+ <td class="date">{{ user.date_created | datetime }}</td>
+ <td class="date">{{ user.last_seen | datetime }}</td>
+ <td>
+ <a href="{{ url_for("admin.user_form", user_id=user.id) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title="{{ _('Edit this user') }}"></i></a>
+ {% if user.id != current_user.id %}
+ <a href="{{ url_for("admin.toggle_user", user_id=user.id) }}">
+ {% if user.is_active %}
+ <i class="fa fa-ban" title="{{ _("Disable this account") }}"></i>
+ {% else %}
+ <i class="fa fa-check-circle-o" aria-hidden="true" title="{{ _("Enable this account") }}"></i>
+ {% endif %}
+ </a>
+ <a href="{{ url_for("admin.delete_user", user_id=user.id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this user') }}" onclick="return confirm('{{ _('You are going to delete this account.') }}');"></i></a>
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+<a href="{{ url_for("admin.user_form") }}" class="btn btn-primary">{{ _('Add a new user') }}</a>
+</div>
+<script>
+$(document).ready(function() {
+ $('#table-users').DataTable( {
+ responsive: true,
+ columnDefs: [
+ {
+ targets: [0, 4],
+ "searchable": false
+ },
+ {
+ targets: [3],
+ "orderSequence": ["desc"]
+ }
+ ]
+ });
+});
+</script>
+{% endblock %}
diff --git a/newspipe/templates/article.html b/newspipe/templates/article.html
new file mode 100644
index 00000000..884bf677
--- /dev/null
+++ b/newspipe/templates/article.html
@@ -0,0 +1,35 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container" data-article="{{ article.id }}">
+ <div class="well">
+ <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>
+ <a href="{{ url_for("article.delete", article_id=article.id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>
+ {% if article.like %}
+ <a href="#"><i class="fa fa-star" aria-hidden="true" title="{{ _('One of your favorites') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="fa fa-star-o" aria-hidden="true" title="{{ _('Click if you like this article') }}"></i></a>
+ {% endif %}
+ {% if article.readed %}
+ <a href="#"><i class="fa fa-check-square readed" title="{{ _('Mark this article as unread') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="fa fa-check-square-o readed" aria-hidden="true" aria-hidden="true" title="{{ _('Mark this article as read') }}"></i></a>
+ {% endif %}
+ <h6>{{ article.date | datetime }}</h6>
+ </div>
+ <div class="well">
+ {{ article.content | safe }}
+ </div>
+ <div class="well">
+ <a href="https://api.pinboard.in/v1/posts/add?url={{ article.link }}&description={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/pinboard.png') }}" title="{{ _('Share on') }} Pinboard" />
+ </a>
+ <a href="https://reddit.com/submit?url={{ article.link }}&title={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/reddit.png') }}" title="{{ _('Share on') }} reddit" />
+ </a>
+ <a href="https://twitter.com/intent/tweet?url={{ article.link }}&text={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/twitter.png') }}" title="{{ _('Share on') }} twitter" >
+ </a>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/article_pub.html b/newspipe/templates/article_pub.html
new file mode 100644
index 00000000..e810d18f
--- /dev/null
+++ b/newspipe/templates/article_pub.html
@@ -0,0 +1,24 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container" data-article="{{ article.id }}">
+ <div class="well">
+ <h2><a href="{{ article.link }}" target="_blank">{{ article.title|safe }}</a></h2>
+ <h3>{{ _('from') }} <a href="{{ url_for('feed.feed_pub', feed_id=article.source.id) }}">{{ article.source.title }}</a></h3>
+ <h6>{{ article.date | datetime }}</h6>
+ </div>
+ <div class="well">
+ {{ article.content | safe }}
+ </div>
+ <div class="well">
+ <a href="https://api.pinboard.in/v1/posts/add?url={{ article.link }}&description={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/pinboard.png') }}" title="{{ _('Share on') }} Pinboard" />
+ </a>
+ <a href="https://reddit.com/submit?url={{ article.link }}&title={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/reddit.png') }}" title="{{ _('Share on') }} reddit" />
+ </a>
+ <a href="https://twitter.com/intent/tweet?url={{ article.link }}&text={{ article.title }}" rel="noreferrer" target="_blank">
+ <img src="{{ url_for('static', filename='img/twitter.png') }}" title="{{ _('Share on') }} twitter" >
+ </a>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/bookmarks.html b/newspipe/templates/bookmarks.html
new file mode 100644
index 00000000..0f6e02c4
--- /dev/null
+++ b/newspipe/templates/bookmarks.html
@@ -0,0 +1,81 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="row">
+ <div class="col-6">
+ {{ pagination.info }}
+ </div>
+ <div class="col-6 text-right">
+ {% if current_user.is_authenticated %}
+ <a class="text-muted" href="{{ url_for('bookmarks.list_') }}">all</a>&nbsp;⸱&nbsp;
+ <a class="text-muted" href="{{ url_for('bookmarks.list_') + 'private' }}">private</a>&nbsp;⸱&nbsp;
+ <a class="text-muted" href="{{ url_for('bookmarks.list_') + 'public' }}">public</a>&nbsp;⸱&nbsp;
+ <a class="text-muted" href="{{ url_for('bookmarks.list_') + 'unread' }}">unread</a>
+ {% endif %}
+ </div>
+ </div>
+ <br />
+ <div class="row">
+ <div class="col-6">
+ {% if tag %}
+ <i class="fa fa-tag" aria-hidden="true"></i>&nbsp;&nbsp;{{ tag }}
+ {% endif %}
+ {% if query %}
+ {% if tag %}<br />{% endif %}
+ <i class="fa fa-search" aria-hidden="true"></i>&nbsp;&nbsp;{{ query }}
+ {% endif %}
+ </div>
+ <div class="col-6 text-right pull-right">
+ <form method="GET">
+ <div class="form-row align-items-center pull-right">
+ <div class="col-auto">
+ <div class="input-group">
+ <input type="text" name="query" class="form-control" />
+ <div class="input-group-append">
+ <button type="submit" class="btn btn-primary">Search</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ <br />
+ <div class="row">
+ <div class="col-8">
+ {{ pagination.links }}
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col">
+ <ul class="list-group">
+ {% for bookmark in bookmarks %}
+ <li class="list-group-item">
+ <a href="#">
+ <h4 class="list-group-item-heading">
+ <a href="{{ bookmark.href }}">{{ bookmark.title }}</a>
+ </h4>
+ <p class="list-group-item-text">
+ <div class="text-muted">{{ bookmark.description }}</div>
+ <div>{% for tag in bookmark.tags %}<a href="{{ url_for('bookmarks.list_', tag=tag.text) }}">{{ tag.text }}&nbsp;</a>{% endfor %}</div>
+ {{ bookmark.time | datetime }}
+ {% if current_user.is_authenticated %}
+ <a class="text-muted" href="{{ url_for('bookmark.form', bookmark_id=bookmark.id) }}">edit</a>
+ <a class="text-muted" href="{{ url_for('bookmark.delete', bookmark_id=bookmark.id) }}">delete</a>
+ {% endif %}
+ </p>
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+ <br />
+ <div class="row">
+ <div class="col-md-8">
+ {{ pagination.links }}
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/categories.html b/newspipe/templates/categories.html
new file mode 100644
index 00000000..ea5388a3
--- /dev/null
+++ b/newspipe/templates/categories.html
@@ -0,0 +1,36 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ _("You have %(categories)d categories &middot; Add a %(start_link)scategory%(end_link)s", categories=categories|count, start_link=("<a href='%s'>" % url_for("category.form"))|safe, end_link="</a>"|safe) }}</h1>
+ {% if categories|count == 0 %}
+ <h1>{{_("No category")}}</h1>
+ {% else %}
+ <div class="table-responsive">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Name') }}</th>
+ <th>{{ _('Feeds') }}</th>
+ <th>{{ _('Articles') }}</th>
+ <th>{{ _('Actions') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for category in categories %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td>{{ category.name }}</td>
+ <td>{{ feeds_count.get(category.id, 0) }}</td>
+ <td>( {{ unread_article_count.get(category.id, 0) }} ) {{ article_count.get(category.id, 0) }}</td>
+ <td>
+ <a href="{{ url_for("category.form", category_id=category.id) }}"><i class="fa fa-pencil-square-o" aria-hidden="true" title='{{ _("Edit this category") }}'></i></a>
+ <a href="{{ url_for("category.delete", category_id=category.id) }}"><i class="fa fa-times" aria-hidden="true" title='{{ _("Delete this category") }}' onclick="return confirm('{{ _('You are going to delete this category.') }}');"></i></a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+{% endblock %}
diff --git a/newspipe/templates/duplicates.html b/newspipe/templates/duplicates.html
new file mode 100644
index 00000000..38dc52b1
--- /dev/null
+++ b/newspipe/templates/duplicates.html
@@ -0,0 +1,30 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <p><h1>{{ _('Duplicates in the feed') }} <a href="/feed/{{ feed.id }}">{{ feed.title }}</a>.</h1><p>
+ <div class="table-responsive">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th align="center">
+ <span class="delete-all btn btn-primary">{{ _('Delete all in this column') }}</span>
+ </th>
+ <th align="center">
+ <span class="delete-all btn btn-primary">{{ _('Delete all in this column') }}</span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {% 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>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/edit_bookmark.html b/newspipe/templates/edit_bookmark.html
new file mode 100644
index 00000000..ee0e0243
--- /dev/null
+++ b/newspipe/templates/edit_bookmark.html
@@ -0,0 +1,84 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h3>{{ action }}</h3>
+ <form action="" method="post" name="save" class="form-horizontal">
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ <label for="{{ form.href.id }}" class="col-sm-3 control-label">{{ form.href.label }}</label>
+ <div class="col-sm-9">
+ {{ form.href(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.href.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.title.id }}" class="col-sm-3 control-label">{{ form.title.label }}</label>
+ <div class="col-sm-9">
+ {{ form.title(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.title.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.description.id }}" class="col-sm-3 control-label">{{ form.description.label }}</label>
+ <div class="col-sm-9">
+ {{ form.description(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.description.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.tags.id }}" class="col-sm-3 control-label">{{ form.tags.label }}</label>
+ <div class="col-sm-9">
+ {{ form.tags(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.tags.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.shared.id }}" class="col-sm-3 control-label">{{ form.shared.label }}</label>
+ <div class="col-sm-9">
+ <div class="checkbox">
+ {{ form.shared(class_="checkbox", style="margin-left: 0px;") }}
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.to_read.id }}" class="col-sm-3 control-label">{{ form.to_read.label }}</label>
+ <div class="col-sm-9">
+ <div class="checkbox">
+ {{ form.to_read(class_="checkbox", style="margin-left: 0px;") }}
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-9">
+ {{ form.submit(class_="btn btn-primary") }}
+ </div>
+ </div>
+ </form>
+ </div>
+ {% if action == _('Add a new bookmark') %}
+ <div class="row">
+ <div class="col-md-6 pull-right">
+ <p>{{ _('You can add a bookmark with a bookmarklet. Drag the following button to your browser bookmarks.') }}</p>
+ {{ _('<a class="btn btn-primary" href="%(bookmarklet)s" rel="bookmark">Bookmark this page using Newspipe</a>', bookmarklet='javascript:window.location="%s?href="+encodeURIComponent(document.location)+"&title="+document.title' % url_for('bookmark.bookmarklet', _external=True)) }}
+ </div>
+ <div class="col-md-6">
+ <form action="{{ url_for('bookmark.import_pinboard') }}" method="post" id="formImportPinboard" enctype="multipart/form-data">
+ <p>{{ _('Import bookmarks from Pinboard') }} (*.json)</p>
+ <span>
+ <input type="file" name="jsonfile" />
+ <br />
+ <button class="btn btn-primary" type="submit">OK</button>
+ </span>
+ </form>
+ </div>
+ </div>
+ {% endif %}
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/edit_category.html b/newspipe/templates/edit_category.html
new file mode 100644
index 00000000..955d17b9
--- /dev/null
+++ b/newspipe/templates/edit_category.html
@@ -0,0 +1,23 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h3>{{ action }}</h3>
+ <form action="" method="post" name="save" class="form-horizontal">
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ <label for="{{ form.name.id }}" class="col-sm-3 control-label">{{ form.name.label }}</label>
+ <div class="col-sm-9">
+ {{ form.name(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.name.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-9">
+ {{ form.submit(class_="btn btn-primary") }}
+ </div>
+ </div>
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/edit_feed.html b/newspipe/templates/edit_feed.html
new file mode 100644
index 00000000..a439c78d
--- /dev/null
+++ b/newspipe/templates/edit_feed.html
@@ -0,0 +1,98 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h3>{{ action }}</h3>
+ <form action="" method="post" name="save" class="form-horizontal">
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ <label for="{{ form.link.id }}" class="col-sm-3 control-label">{{ form.link.label }}</label>
+ <div class="col-sm-9">
+ {{ form.link(class_="form-control", size="100%") }}
+ </div>
+ {% for error in form.link.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.title.id }}" class="col-sm-3 control-label">{{ form.title.label }}</label>
+ <div class="col-sm-9">
+ {{ form.title(class_="form-control", size="100%", placeholder=_('Optional')) }}
+ </div>
+ {% for error in form.title.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.site_link.id }}" class="col-sm-3 control-label">{{ form.site_link.label }}</label>
+ <div class="col-sm-9">
+ {{ form.site_link(class_="form-control", size="100%", placeholder=_('Optional')) }}
+ </div>
+ {% for error in form.site_link.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.category_id.id }}" class="col-sm-3 control-label">{{ form.category_id.label }}</label>
+ <div class="col-sm-9">
+ {{ form.category_id(class_="form-control", placeholder=_('Optional')) }}
+ </div>
+ {% for error in form.category_id.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.enabled.id }}" class="col-sm-3 control-label">{{ form.enabled.label }}</label>
+ <div class="col-sm-9">
+ <div class="checkbox">
+ {{ form.enabled(class_="checkbox", style="margin-left: 0px;") }}
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="{{ form.private.id }}" class="col-sm-3 control-label">{{ form.private.label }}</label>
+ <div class="col-sm-9">
+ <div class="checkbox">
+ {{ form.private(class_="checkbox", style="margin-left: 0px;") }}
+ </div>
+ <span class="text-muted">{{ _("If checked, articles of this feed won't be available to others and the feed won't be listed on <a href='%(url)s'>your profile page</a>.", url=url_for('user.profile_public', nickname=current_user.nickname) ) }}</span>
+ <span class="text-muted">{{ _("Check this box if there is a private token in the link of the feed.") }}</span>
+ </div>
+
+ </div>
+
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{{ _("Filters") }}</label>
+ <div class="col-sm-1">
+ <input value="+" type="button" class="form-control" id="add-feed-filter-row" />
+ </div>
+ </div>
+ <div class="form-inline col-sm-offset-4 col-sm-8" id="filters-container">
+ {% if feed %}
+ {% for filter_ in feed.filters or [] %}
+ <div class="form-group">
+ <input value="-" type="button" class="form-control del-feed-filter-row" />
+ <select name="type" class="form-control" >
+ <option value="simple match" {% if filter_.get("type") == "simple match" %}selected{% endif %}>{{ _("simple match") }}</option>
+ <option value="regex" {% if filter_.get("type") == "regex" %}selected{% endif %}>{{ _("regex") }}</option>
+ </select>
+ <input type="text" class="form-control" value="{{ filter_.get("pattern") }}" name="pattern" />
+ <select name="action_on" class="form-control">
+ <option value="match" {% if filter_.get("action on") == "match" %}selected{% endif %}>{{ _("match") }}</option>
+ <option value="no match" {% if filter_.get("action on") == "no match" %}selected{% endif %}>{{ _("no match") }}</option>
+ </select>
+ <select name="action" class="form-control">
+ <option value="mark as read" {% if filter_.get("action") == "mark as read" %}selected{% endif %}>{{ _("mark as read") }}</option>
+ <option value="mark as favorite" {% if filter_.get("action") == "mark as favorite" %}selected{% endif %}>{{ _("mark as favorite") }}</option>
+ </select>
+ </div>
+ {% endfor %}
+ {% endif %}
+ </div>
+
+ <div class="form-group">
+ <div class="col-sm-offset-3 col-sm-9">
+ {{ form.submit(class_="btn btn-primary") }}
+ </div>
+ </div>
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/emails/account_activation.txt b/newspipe/templates/emails/account_activation.txt
new file mode 100644
index 00000000..c7d9c52e
--- /dev/null
+++ b/newspipe/templates/emails/account_activation.txt
@@ -0,0 +1,9 @@
+Hello {{ user.nickname }},
+
+Your account has been created.
+Click on the following link in order to confirm it:
+{{ platform_url }}user/confirm_account/{{ token }}
+
+The link expires at {{ expire_time.strftime('%Y-%m-%d %H:%M') }}.
+
+See you,
diff --git a/newspipe/templates/emails/new_password.txt b/newspipe/templates/emails/new_password.txt
new file mode 100644
index 00000000..1a04a36d
--- /dev/null
+++ b/newspipe/templates/emails/new_password.txt
@@ -0,0 +1,8 @@
+Hello {{ user.nickname }},
+
+A new password has been generated at your request:
+{{ password }}
+
+It is advised to replace it as soon as connected to Newspipe.
+
+See you,
diff --git a/newspipe/templates/errors/404.html b/newspipe/templates/errors/404.html
new file mode 100644
index 00000000..c64a2be8
--- /dev/null
+++ b/newspipe/templates/errors/404.html
@@ -0,0 +1,12 @@
+{% extends "layout.html" %}
+{% block head %}
+{{ super() }}
+{% endblock %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h1>Page Not Found</h1>
+ <p>What you were looking for is just not there, go to the <a href="{{ url_for('home') }}">home page</a>.</p>
+ </div>
+</div>
+{% endblock %}
diff --git a/newspipe/templates/errors/500.html b/newspipe/templates/errors/500.html
new file mode 100644
index 00000000..417fc0c7
--- /dev/null
+++ b/newspipe/templates/errors/500.html
@@ -0,0 +1,12 @@
+{% extends "layout.html" %}
+{% block head %}
+{{ super() }}
+{% endblock %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h1>Internal Server Error</h1>
+ <p>Something bad just happened! Go to the <a href="{{ url_for('home') }}">home page</a>.</p>
+ </div>
+</div>
+{% endblock %}
diff --git a/newspipe/templates/feed.html b/newspipe/templates/feed.html
new file mode 100644
index 00000000..4246669b
--- /dev/null
+++ b/newspipe/templates/feed.html
@@ -0,0 +1,76 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h2>{{ feed.title }}</h2>
+ {% if feed.description %} <p>{{ feed.description }}</p> {% endif %}
+ {% if current_user.is_authenticated %}
+ <a href="{{ url_for("feed.delete", feed_id=feed.id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></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>
+ {% endif %}
+ </div>
+ <div class="well">
+ <p>
+ {{ _('This feed contains') }} {{ feed.articles.all()|count }} {{ _('articles') }}.<br />
+ {% if category %}
+ {{ _('This feed is part of category %(category_name)s', category_name=category.name) }}<br />
+ {% endif %}
+ {{ _('Address of the feed') }}: <a href="{{ feed.link }}" target="_blank">{{ feed.link }}</a><br />
+ {% if feed.site_link != "" %}
+ {{ _('Address of the site') }}: <a href="{{ feed.site_link }}" target="_blank">{{ feed.site_link }}</a><br />
+ {% endif %}
+
+ <br />
+
+ {% if feed.last_retrieved %}
+ {{ _("Last download:") }} {{ feed.last_retrieved | datetime }}<br />
+ {% endif %}
+
+ {% if feed.error_count >= conf.DEFAULT_MAX_ERROR %}
+ <b>{{ _("That feed has encountered too much consecutive errors and won't be retrieved anymore.") }}</b><br />
+ {{ _("You can click <a href='%(reset_error_url)s'>here</a> to reset the error count and reactivate the feed.", reset_error_url=url_for("feed.reset_errors", feed_id=feed.id)) }}
+ {% elif feed.error_count > 0 %}
+ {{ _("The download of this feed has encountered some problems. However its error counter will be reinitialized at the next successful retrieving.") }}<br />
+ {% endif %}
+
+ {% if feed.last_error %}
+ {{ _("Here's the last error encountered while retrieving this feed:") }} <pre>{{ feed.last_error }}</pre><br />
+ {% endif %}
+
+ {% if feed.articles.all()|count != 0 %}
+ {{ _('The last article was posted') }} {{ elapsed.days }} {{ _('day(s) ago.') }}<br />
+ {{ _('Daily average') }}: {{ average }}, {{ _('between the') }} {{ first_post_date | datetime }} {{ _('and the') }} {{ end_post_date | datetime }}.
+ {% endif %}
+ </p>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <div class="table-responsive">
+ <table id="table-articles" class="table table-striped">
+ <thead>
+ <tr>
+ <th>{{ _('Article') }}</th>
+ <th>{{ _('Date') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for article in articles %}
+ <tr>
+ <td><a href="{{ url_for("article.article_pub", article_id=article.id) }}">{{ article.title }}</a></td>
+ <td>{{ article.date | datetime }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-8 offset-md-1">
+ {{ pagination.links }}
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/feed_list.html b/newspipe/templates/feed_list.html
new file mode 100644
index 00000000..2ce7841f
--- /dev/null
+++ b/newspipe/templates/feed_list.html
@@ -0,0 +1,55 @@
+{% if feeds.count() != 0 %}
+<div class="table-responsive">
+ <table id="table-feeds" class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Status') }}</th>
+ <th>{{ _('Title') }}</th>
+ <th>{{ _('Site') }}</th>
+ <th>{{ _('Articles') }}</th>
+ <th>{{ _('Actions') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for feed in feeds %}
+ <tr {% if not feed.enabled %}class="warning"{% endif %}>
+ <td>{{ loop.index }}</td>
+ <td>
+ {% if feed.enabled %}
+ <i class="fa fa-eye" aria-hidden="true" title="{{ _('Feed enabled') }}"></i>
+ {% else %}
+ <i class="fa fa-eye-slash" aria-hidden="true" title="{{ _('Feed disabled') }}"></i>
+ {% endif %}
+ {% if feed.error_count >= application.config['DEFAULT_MAX_ERROR'] %}
+ <i class="fa fa-exclamation" aria-hidden="true" title="{{ _('Feed encountered too much errors.') }}"></i>
+ {% endif %}
+ </td>
+ <td>{% if feed.icon_url %}<img src="{{ url_for('icon.icon', url=feed.icon_url) }}" width="16px" />&nbsp;{% endif %}{{ feed.title }}</td>
+ <td><a href="{{ feed.site_link }}">{{ feed.site_link }}</a></td>
+ <td>( {{ unread_article_count.get(feed.id, 0) }} ) {{ article_count.get(feed.id, 0) }}</td>
+ <td>
+ <a href="{{ url_for("feed.feed", feed_id=feed.id) }}"><i class="fa fa-info" aria-hidden="true" title="{{ _('Information') }}"></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("feed.duplicates", feed_id=feed.id) }}"><i class="fa fa-book" aria-hidden="true" title="{{ _('Duplicate articles') }}"></i></a>
+ <a href="{{ url_for("feed.delete", feed_id=feed.id) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+<script>
+$(document).ready(function() {
+ $('#table-feeds').DataTable( {
+ responsive: true,
+ columnDefs: [
+ {
+ bSortable: false,
+ targets: [0, 1, 4, 5]
+ }
+ ]
+ });
+});
+</script>
+{% endif %}
diff --git a/newspipe/templates/feed_list_per_categories.html b/newspipe/templates/feed_list_per_categories.html
new file mode 100644
index 00000000..34d10ddd
--- /dev/null
+++ b/newspipe/templates/feed_list_per_categories.html
@@ -0,0 +1,52 @@
+<div class="row">
+ <div class="col-md-8">
+ <form class="form-inline">
+ <div class="form-group">
+ <label>Filter per category</label>
+ <select class="form-control" id="category-select" name="category_id">
+ <option value="0">All</option>
+ {% for category in user.categories %}
+ <option value="{{category.id}}" {% if category.id==selected_category_id %}selected{% endif %}>{{ category.name }}</option>
+ {% endfor %}
+ </select>
+ <button type="submit" class="btn btn-primary mb-2">OK</button>
+ </div>
+ </form>
+ </div>
+</div>
+
+<br />
+
+<div class="table-responsive">
+ <table id="table-feeds" class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Title') }}</th>
+ <th>{{ _('Site') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for feed in feeds %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td>{% if feed.icon_url %}<img src="{{ url_for('icon.icon', url=feed.icon_url) }}" width="16px" />&nbsp;{% endif %} <a href="{{ url_for('feed.feed_pub', feed_id=feed.id) }}">{{ feed.title }}</a></td>
+ <td><a href="{{ feed.site_link }}">{{ feed.site_link }}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+<script>
+$(document).ready(function() {
+ $('#table-feeds').DataTable( {
+ responsive: true,
+ columnDefs: [
+ {
+ bSortable: false,
+ targets: [0]
+ }
+ ]
+ });
+});
+</script>
diff --git a/newspipe/templates/feed_list_simple.html b/newspipe/templates/feed_list_simple.html
new file mode 100644
index 00000000..5f692a53
--- /dev/null
+++ b/newspipe/templates/feed_list_simple.html
@@ -0,0 +1,35 @@
+{% if feeds | length != 0 %}
+<div class="table-responsive">
+ <table id="table-feeds" class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Title') }}</th>
+ <th>{{ _('Site') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for feed in feeds %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td>{% if feed.icon_url %}<img src="{{ url_for('icon.icon', url=feed.icon_url) }}" width="16px" />&nbsp;{% endif %} <a href="{{ url_for('feed.feed_pub', feed_id=feed.id) }}">{{ feed.title }}</a></td>
+ <td><a href="{{ feed.site_link }}">{{ feed.site_link }}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+<script>
+$(document).ready(function() {
+ $('#table-feeds').DataTable( {
+ responsive: true,
+ columnDefs: [
+ {
+ bSortable: false,
+ targets: [0]
+ }
+ ]
+ });
+});
+</script>
+{% endif %}
diff --git a/newspipe/templates/feeds.html b/newspipe/templates/feeds.html
new file mode 100644
index 00000000..805e1b74
--- /dev/null
+++ b/newspipe/templates/feeds.html
@@ -0,0 +1,7 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ _('You are subscribed to %(feed_count)d feeds.', feed_count=feeds.count()) }} <a href="{{ url_for("feed.form") }}">{{ _('Add') }}</a> {{ _('a feed') }}.</h1>
+ {% include "feed_list.html" %}
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/history.html b/newspipe/templates/history.html
new file mode 100644
index 00000000..ba567106
--- /dev/null
+++ b/newspipe/templates/history.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ _('History') }}</h1>
+ {% if month != None %}
+ <h2><a href="{{ url_for("articles.history", year=year) }}"><span class="fa fa-chevron-left" aria-hidden="true"></span> {{ year }}</a></h2>
+ <h3>{{ month | month_name }}</h3>
+ {% elif year != None %}
+ <h2><a href="{{ url_for("articles.history") }}"><span class="fa fa-chevron-left" aria-hidden="true"></span>&nbsp{{ _('all years') }}</a></h2>
+ <h3>{{ year }}</h3>
+ {% endif %}
+ <ul class="list-group">
+ {% for article in articles_counter | sort(reverse = True) %}
+ {% if year == None %}
+ <li class="list-group-item"><a href="{{ url_for("articles.history", year=article) }}">{{ article }}</a> : {{ articles_counter[article] }} articles</li>
+ {% elif month == None %}
+ <li class="list-group-item"><a href="{{ url_for("articles.history", year=year, month=article) }}">{{ article | month_name }}</a> : {{ articles_counter[article] }} articles</li>
+ {% else %}
+ {% for article in articles %}
+ <li class="list-group-item">{{ article.date | datetime }} - <a href="/article/{{ article.id }}">{{ article.title | safe }}</a></li>
+ {% endfor %}
+ {% endif %}
+ {% endfor %}
+ </ul>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/home.html b/newspipe/templates/home.html
new file mode 100644
index 00000000..8da8dbe1
--- /dev/null
+++ b/newspipe/templates/home.html
@@ -0,0 +1,135 @@
+{% extends "layout.html" %}
+{% block content %}
+<style>
+ li.feed-commands {display: none; text-align: right;}
+ li.feed-commands > span > a {margin-right: 10px;}
+ li.feed-menu:hover + li.feed-commands, li.feed-commands:hover {display: block;}
+</style>
+<div class="container-fluid">
+{% if feeds|count == 0 %}
+ <div class="col-md-4 col-md-offset-4">
+ <h1>{{ _("You don't have any feeds.") }}</h1>
+ <h1><a href="{{ url_for('feed.form') }}">{{ _('Add some') }}</a>, {{ _('or') }} <a href="{{ url_for('user.management') }}">{{ _('upload an OPML file.') }}</a></h1>
+ </div>
+{% else %}
+ <div class="row">
+ <div id="sidebar" class="col-2 d-none d-lg-block">
+ <ul class="nav flex-column" data-offset-top="0" data-offset-bottom="0" style="min-height: 650px;">
+ <li class="nav-item feed-menu"><a class="nav-link" href="{{ gen_url(feed=0) }}">
+ {% if not feed_id %}<b>{% endif %}
+ {{ _('All feeds') }}
+ <span id="total-unread" class="badge pull-right"> {% if nb_unread > 1000 %}>{% endif %}&nbsp;{{ articles.__len__() }}</span>
+ {% if not feed_id %}</b>{% endif %}
+ </a></li>
+ <li class="nav-item feed-commands"><span class="nav-link">
+ <a href="{{ url_for('article.mark_as', new_value='read') }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark all as read') }}"></i></a>
+ </span></li>
+ {% for fid, nbunread in unread|dictsort(by='value')|reverse %}
+ <li class="nav-item feed-menu"><a class="nav-link" href="{{ gen_url(feed=fid) }}">
+ {% if feed_id == fid %}<b>{% endif %}
+ {% if in_error.get(fid, 0) > 0 %}
+ <span style="background-color: {{ "red" if in_error[fid] > 2 else "orange" }} ;" class="badge pull-right" title="Some errors occured while trying to retrieve that feed.">{{ in_error[fid] }}</span>
+ {% endif %}
+ <span id="unread-{{ fid }}" class="badge pull-right">{{ nbunread }}</span>
+ <!-- <img src="{{ url_for('icon.icon', url=feeds[fid].url) }}" width="16px"> -->
+ {{ feeds[fid].title | safe | truncate(25, True) }}
+ {% if feed_id == fid %}</b>{% endif %}
+ </a></li>
+ <li class="nav-item feed-commands"><span class="nav-link">
+ <a href="/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='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></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('feed.delete', feed_id=fid) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ </span></li>
+ {% endfor %}
+
+ {% for fid, feed in feeds.items() if not fid in unread %}
+ <li class="nav-item feed-menu"><a class="nav-link" href="{{ gen_url(feed=fid) }}">
+ {% if in_error.get(fid, 0) > 0 %}
+ <span style="background-color: {{ "red" if in_error[fid] > 2 else "orange" }} ;" class="badge pull-right" title="Some errors occured while trying to retrieve that feed.">{{ in_error[fid] }}</span>
+ {% endif %}
+ {% if feed_id == fid %}<b>{% endif %}
+ <!-- <img src="{{ url_for('icon.icon', url=feeds[fid].url) }}" width="16px"> -->
+ {{ feed.title | safe | truncate(25, True) }}
+ {% if feed_id == fid %}</b>{% endif %}
+ </a></li>
+ <li class="nav-item feed-commands"><span class="nav-link">
+ <a href="/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='read', feed_id=fid) }}"><i class="fa fa-check-square-o" aria-hidden="true" title="{{ _('Mark this feed as read') }}"></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('feed.delete', feed_id=fid) }}"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ </span></li>
+ {% endfor %}
+ </ul>
+ </div>
+ <div class="col-md-12 col-lg-10">
+ <div id="filters" data-filter="{{ filter_ }}">
+ <ul class="nav nav-tabs ml-auto">
+ <li id="tab-all" class="nav-item">
+ <a class="nav-link {% if filter_ == 'all' %}active{% endif %}" href="{{ gen_url(filter_='all') }}">{{ _('All') }}</a>
+ </li>
+ <li id="tab-read" class="nav-item">
+ <a class="nav-link {% if filter_ == 'read' %}active{% endif %}" href="{{ gen_url(filter_='read') }}">{{ _('Read') }}</a>
+ </li>
+ <li id="tab-unread" class="nav-item">
+ <a class="nav-link {% if filter_ == 'unread' %}active{% endif %}" href="{{ gen_url(filter_='unread') }}">{{ _('Unread') }}</a>
+ </li>
+ <li id="tab-unread" class="px-5 nav-item">
+ <a class="nav-link {% if liked %}active{% endif %}" href="{{ gen_url(liked=not liked) }}"><i class="fa fa-heart" aria-hidden="true"></i>&nbsp;{{ _('Liked') }}</a>
+ </li>
+ <li id="tab-nbdisplay" class="px-5 nav-item d-none d-lg-block">
+ <div id="nbdisplay">
+ <a href="{{ gen_url(limit=10) }}" class="badge {% if limit == 10 %}badge-primary{% else %}badge-info{% endif %}">{{ _(10) }}</a>
+ <a href="{{ gen_url(limit=100) }}" class="badge {% if limit == 100 %}badge-primary{% else %}badge-info{% endif %}">{{ _(100) }}</a>
+ <a href="{{ gen_url(limit=1000) }}" class="badge {% if limit == 1000 %}badge-primary{% else %}badge-info{% endif %}">{{ _(1000) }}</a>
+ <a href="{{ gen_url(limit='all') }}" class="badge {% if limit == 'all' %}badge-primary{% else %}badge-info{% endif %}">{{ _('All') }}</a>
+ </div>
+ </li>
+ </ul>
+ </div>
+ {% if articles | count != 0%}
+ <div class="table-responsive">
+ <table class="table table-striped strict-table">
+ <thead>
+ <tr>
+ <th></th>
+ <th>{{ _('Feed') }}</th>
+ <th>{{ _('Article') }}</th>
+ <th>{{ _('Date') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for article in articles %}
+ <tr data-article="{{ article.id }}" data-feed="{{ article.feed_id }}">
+ <td>
+ <a href="#"><i class="fa fa-times" aria-hidden="true" title="{{ _('Delete this article') }}"></i></a>
+ {% if article.like %}
+ <a href="#"><i class="fa fa-star" aria-hidden="true" title="{{ _('One of your favorites') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="fa fa-star-o" aria-hidden="true" title="{{ _('Click if you like this article') }}"></i></a>
+ {% endif %}
+ {% if article.readed %}
+ <a href="#"><i class="fa fa-square-o readed" aria-hidden="true" title="{{ _('Mark this article as unread') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="fa fa-check-square-o readed" aria-hidden="true" title="{{ _('Mark this article as read') }}"></i></a>
+ {% if filter_ == 'all' %}</b>{% endif %}
+ {% endif %}
+ </td>
+ <td><a href="/article/redirect/{{ article.id}}" target="_blank">{{ article.source.title | safe }}</a></td>
+ <td {%if filter_ == 'all' and article.readed == False %}style='font-weight:bold'{% endif %}>
+ <a href="/article/{{ article.id }}">{{ article.title | safe }}</a>
+ </td>
+ <td class="date">{{ article.date | datetime }}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+ </div>
+ </div>
+{% endif %}
+</div>
+{% endblock %}
diff --git a/newspipe/templates/inactives.html b/newspipe/templates/inactives.html
new file mode 100644
index 00000000..e89a5fe1
--- /dev/null
+++ b/newspipe/templates/inactives.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <form method=get action="{{ url_for("feeds.inactives") }}">
+ <p>{{ _('Days of inactivity') }}:</p>
+ <input type="number" name="nb_days" class="form-control" value="{{ nb_days }}" min="0" max="1000000" step="1" size="4" style="text-align: center" />
+ </form>
+ <br />
+ {% if inactives != [] %}
+ <ul class="list-group">
+ {% for feed, delta in inactives %}
+ <li class="list-group-item">
+ <a href="{{ url_for('feed.feed', feed_id=feed.id) }}">
+ {% if feed.icon %}<img src="{{ url_for('feed.icon', feed_id=feed.id) }}" width="16px" />{% endif %}
+ {{ feed.title }}
+ </a> - {{ delta.days }} {{ _('days') }}
+ </li>
+ {% endfor %}
+ </ul>
+ {% else %}
+ <p>{{ _('No inactive feeds.') }}<p>
+ {% endif %}
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/layout.html b/newspipe/templates/layout.html
new file mode 100644
index 00000000..b40b540c
--- /dev/null
+++ b/newspipe/templates/layout.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ {% block head %}
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="description" content="Newspipe is a web news aggregator and reader." />
+ <meta name="author" content="" />
+ <title>Newspipe{% if head_titles %} - {{ ' - '.join(head_titles) }}{% endif %}</title>
+ <link rel="shortcut icon" href="{{ url_for("static", filename="img/favicon.ico") }}" />
+ <!-- CSS -->
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='npm_components/bootstrap/dist/css/bootstrap.min.css') }}" media="screen" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='npm_components/datatables.net-bs4/css/dataTables.bootstrap4.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='npm_components/fork-awesome/css/fork-awesome.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/custom.css') }}" />
+ <!-- JavaScript -->
+ <script type="text/javascript" src="{{ url_for('static', filename = 'npm_components/jquery/dist/jquery.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('static', filename = 'npm_components/bootstrap/dist/js/bootstrap.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('static', filename='npm_components/datatables.net/js/jquery.dataTables.min.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('static', filename='npm_components/datatables.net-bs4/js/dataTables.bootstrap4.min.js') }}"></script>
+ {% endblock %}
+ </head>
+ <body>
+ {% block menu %}
+ <nav class="navbar navbar-expand-lg navbar-dark bg-newspipe-blue">
+ <a class="navbar-brand" href="/">🗞&nbsp;Newspipe</a>
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ {% block menu_links %}
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
+
+ <ul class="navbar-nav mr-auto w-100 justify-content-end">
+ {% if current_user.is_authenticated %}
+ {% if current_user.is_admin %}
+ <li class="nav-item">
+ <a class="nav-link" href="{{ url_for('fetch') }}" title="{{ _('Fetch') }}"><i class="fa fa-download" aria-hidden="true"></i>&nbsp;{{ _('Fetch') }}</a>
+ </li>
+ {% endif %}
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownRSS" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-rss" aria-hidden="true"></i>&nbsp;{{ _('Feeds') }}</a>
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownRSS">
+ <a class="dropdown-item" href="{{ url_for('feeds.feeds') }}">{{ _('Subscribed') }}</a>
+ <a class="dropdown-item" href="{{ url_for('feeds.inactives') }}">{{ _('Inactive') }}</a>
+ <a class="dropdown-item" href="{{ url_for('popular') }}">{{ _('Popular') }}</a>
+ <a class="dropdown-item" href="{{ url_for('articles.history') }}">{{ _('History') }}</a>
+ <div class="dropdown-divider"></div>
+ <a class="dropdown-item" href="{{ url_for('feed.form') }}">{{ _('Add a new feed') }}</a>
+ <form class="navbar-form navbar-left px-4 py-3" action="{{ url_for('feed.bookmarklet') }}">
+ <label class="sr-only" for="inlineFormInputGroupAPIKey">{{ _('Add a new feed') }}</label>
+ <div class="input-group input-group-inline">
+ <div class="input-group-prepend">
+ <input class="form-control" name="url" type="url" placeholder="{{_('Site or feed url')}}" required="required"/>
+ </div>
+ <button type="submit" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i></button>
+ </div>
+ </form>
+ </div>
+ </li>
+
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownCategory" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-tag" aria-hidden="true"></i>&nbsp;{{ _('Categories') }}</a>
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownCategory">
+ <a class="dropdown-item" href="{{ url_for('categories.list_') }}">{{ _('Categories') }}</a>
+ <div class="dropdown-divider"></div>
+ <a class="dropdown-item" href="{{ url_for('category.form') }}">{{ _('Add a new category') }}</a>
+ <form class="navbar-form navbar-left px-4 py-3" action="{{ url_for('category.form') }}" method="POST" name="category">
+ <label class="sr-only" for="inlineFormInputGroupAPIKey">{{ _('Add a new category') }}</label>
+ <div class="input-group input-group-inline">
+ <div class="input-group-prepend">
+ <input class="form-control" name="name" type="text" placeholder="{{_('Category name')}}" required="required"/>
+ </div>
+ <button type="submit" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i></button>
+ </div>
+ </form>
+ </div>
+ </li>
+
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownBookmark" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-bookmark" aria-hidden="true"></i>&nbsp;{{ _('Bookmarks') }}</a>
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownBookmark">
+ <a class="dropdown-item" href="{{ url_for('bookmarks.list_') }}">{{ _('Bookmarks') }}</a>
+ <a class="dropdown-item" href="{{ url_for('bookmark.form') }}">{{ _('Add a new bookmark') }}</a>
+ </div>
+ </li>
+
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownUser" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fa fa-user" aria-hidden="true"></i></a>
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownUser">
+ <a class="dropdown-item" href="{{ url_for('user.profile') }}">{{ _('Profile') }}</a>
+ <a class="dropdown-item" href="{{ url_for('user.management') }}">{{ _('Your data') }}</a>
+ {% if current_user.is_admin %}
+ <div class="dropdown-divider"></div>
+ <a class="dropdown-item" href="{{ url_for('admin.dashboard') }}">{{ _('Dashboard') }}</a>
+ <div class="dropdown-divider"></div>
+ {% endif %}
+ <a class="dropdown-item" href="{{ url_for('about') }}">{{ _('About') }}</a>
+ <a class="dropdown-item" href="{{ url_for('logout') }}" title="{{ _('Logout') }}">Logout</a>
+ </div>
+ </li>
+ {% else %}
+ <li class="nav-item">
+ <a class="nav-link" href="{{ url_for('bookmarks.list_') }}" title="{{ _('Recent bookmarks') }}">{{ _('Recent bookmarks') }}</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ url_for('popular') }}" title="{{ _('Popular feeds') }}">{{ _('Popular feeds') }}</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ url_for('about') }}" title="{{ _('About') }}">{{ _('About') }}</a>
+ </li>
+ {% endif %}
+ </ul>
+ </div>
+ {% endblock %}
+ </nav>
+ {% endblock %}
+ <br />
+
+ <div class="container alert-message not-at-home">
+ {% block messages %}
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+ {% for category, message in messages %}
+ <div class="alert alert-{{category}}">
+ <button type="button" class="close" data-dismiss="alert">&times;</button>
+ {{ message }}
+ </div>
+ {% endfor %}
+ {% endif %}
+ {% endwith %}
+ {% endblock %}
+ </div>
+
+ {% 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/articles.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('static', filename = 'js/feed.js') }}"></script>
+ </body>
+</html>
diff --git a/newspipe/templates/login.html b/newspipe/templates/login.html
new file mode 100644
index 00000000..1253e2d3
--- /dev/null
+++ b/newspipe/templates/login.html
@@ -0,0 +1,32 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="row">
+ <div class="col">
+ <div class="card">
+ <div class="card-body">
+ <h2>{{ _('Log In') }}</h2>
+ <form action="{{ url_for('login') }}" method=post>
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ {{ form.nickmane(class_="form-control", placeholder=_('Your nickname')) }}
+ </div>
+ {% for message in form.nickmane.errors %}
+ <div class="alert alert-warning" role="alert">{{ message }}</div>
+ {% endfor %}
+ <div class="form-group">
+ {{ form.password(class_="form-control", placeholder=_('Your Password')) }}
+ </div>
+ {% for message in form.password.errors %}
+ <div class="alert alert-warning" role="alert">{{ message }}</div>
+ {% endfor %}
+ {{ form.submit(class_="btn btn-primary") }}
+ </form>
+ </div>
+ </div>
+ <br />
+ <a href="/signup" class="btn btn-primary">{{ _('Sign up') }}</a>
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/management.html b/newspipe/templates/management.html
new file mode 100644
index 00000000..22ebde8a
--- /dev/null
+++ b/newspipe/templates/management.html
@@ -0,0 +1,99 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="card">
+ <div class="card-body">
+ <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>{{ 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>
+ </div>
+ <div class="col">
+ <h2>{{ _('Your bookmarks') }}</h2>
+ <p>{{ _('You have') }} {{ nb_bookmarks }} <a href="{{ url_for("bookmarks.list_")}}">{{ _('bookmarks') }}</a>.</p>
+ <a href="{{ url_for("bookmarks.delete_all") }}" class="btn btn-primary" onclick="return confirm('{{ _('You are going to delete all bookmarks.') }}');">{{ _('Delete all bookmarks') }}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <br />
+ <div class="card">
+ <div class="card-body">
+ <div class="row">
+ <div class="col">
+ <h2>{{ _('Your data') }}</h2>
+ <br />
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <h3>{{ _('Articles') }}</h3>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <h5>{{ _('Import') }}</h5>
+ <p>{{ _('Import a Newspipe account (*.json).') }}</p>
+ <form action="" method="post" id="formImportJSON" enctype="multipart/form-data">
+ <input type="file" name="jsonfile" />
+ <button class="btn btn-primary" type="submit">OK</button>
+ </form>
+ </div>
+ <div class="col">
+ <h5>{{ _('Export') }}</h5>
+ <p>{{ _('Export your newspipe account to JSON.') }}</p>
+ <a href="{{ url_for('articles.export') }}" class="btn btn-primary">{{ _('Export') }}</a>
+ </div>
+ </div>
+ <br />
+ <div class="row">
+ <div class="col">
+ <h3 id="import">{{ _('Feeds') }}</h3>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <h5>{{ _('Import') }}</h5>
+ <p>{{ _('Import feeds from OPML (*.xml or *.opml).') }}</p>
+ <form action="" method="post" id="formImportOPML" enctype="multipart/form-data">
+ <input type="file" name="opmlfile" />
+ <button class="btn btn-primary" type="submit">OK</button>
+ </form>
+ </div>
+ <div class="col">
+ <h5>{{ _('Export') }}</h5>
+ <p>{{ _('Export feeds to OPML.') }}</p>
+ <form class="form" action="{{ url_for('feeds.export') }}" method="GET" id="formExportOPML">
+ <div class="form-group">
+ <div class="input-group">
+ <label>Include disabled feeds</label>
+ <input type="checkbox" class="form-control" name="includedisabled" checked />
+ </div>
+ <div class="input-group">
+ <label title="Newspipe encountered too much problems when retrieving these feeds.">Include dead feeds</label>
+ <input type="checkbox" class="form-control" name="includeexceedederrorcount" checked />
+ </div>
+ <div class="input-group">
+ <label>Include private feeds</label>
+ <input type="checkbox" class="form-control" name="includeprivate" checked />
+ </div>
+ </div>
+ <button class="btn btn-primary" type="submit">{{ _('Export') }}</button>
+ </form>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-12">
+ <br />
+ <h2>{{ _('Bookmarks') }}</h2>
+ <a href="{{ url_for('bookmarks.export') }}" class="btn btn-primary">{{ _('Export your bookmarks to JSON') }}</a>
+ </div>
+ </div>
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/opml.xml b/newspipe/templates/opml.xml
new file mode 100644
index 00000000..7159e279
--- /dev/null
+++ b/newspipe/templates/opml.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- OPML generated by Newspipe on {{ now | datetime }} -->
+<opml version="1.1">
+ <head>
+ <title>Feeds of {{ user.nickname }}</title>
+ <dateCreated>{{ now | datetime }}</dateCreated>
+ <dateModified>{{ now | datetime }}</dateModified>
+ <ownerName>{{ user.nickname }}</ownerName>
+ </head>
+ <body>
+ {% for feed in feeds %} <outline title="{{ feed.title|escape }}" text="{{ feed.title|escape }}" description="{{ feed.description|escape }}" {% if feed.category_id != None %}category="/{{ categories[feed.category_id].name }}"{% endif %} xmlUrl="{{ feed.link|escape }}" htmlUrl="{{ feed.site_link|escape }}" />
+ {% endfor %}</body>
+</opml>
diff --git a/newspipe/templates/popular.html b/newspipe/templates/popular.html
new file mode 100644
index 00000000..a80cee57
--- /dev/null
+++ b/newspipe/templates/popular.html
@@ -0,0 +1,27 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <h1>{{ _('Popular feeds') }}</h1>
+ <a href="{{ url_for('popular', nb_days='all') }}">all</a>&nbsp;&#8231;&nbsp;<a href="{{ url_for('popular', nb_days=365) }}">last year</a>&nbsp;&#8231;&nbsp;<a href="{{ url_for('popular', nb_days=31) }}">last month</a>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <ul class="list-group">
+ {% for feed in popular %}
+ <li class="list-group-item d-flex justify-content-between align-items-center">
+ <a href="{{ feed[0] }}">{{ feed[0] }}</a>
+ <a href="{{ url_for('feed.bookmarklet', url=feed[0]) }}" >
+ <span class="fa fa-plus text-muted" aria-hidden="true" title="follow this feed"></span>
+ <span class="text-muted">{{ _('add this feed') }}</span>
+ </a>
+ <span class="badge badge-primary badge-pill">{{ feed[1] }}</span>
+ </li>
+ {% endfor %}
+ </ul>
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/profile.html b/newspipe/templates/profile.html
new file mode 100644
index 00000000..edbae368
--- /dev/null
+++ b/newspipe/templates/profile.html
@@ -0,0 +1,68 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h2>{{ _('Your Profile') }}</h2>
+ <div class="row">
+ <div class="col">
+ <p>{{ _('Member since') }}: {{ user.date_created | datetime }}.</p>
+ <p>{{ _('Last seen') }}: {{ user.last_seen | datetime }}.</p>
+ </div>
+ </div>
+ <div class="card">
+ <div class="card-body">
+ <div class="row">
+ <div class="col">
+ <h3>Edit your profile</h3>
+ </div>
+ </div>
+ <form action="" method="post" name="save">
+ <div class="row">
+ {{ form.hidden_tag() }}
+
+ <div class="col">
+ {{ form.nickname.label }}
+ {{ form.nickname(class_="form-control") }} {% for error in form.nickname.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.password.label }}
+ {{ form.password(class_="form-control") }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.password_conf.label }}
+ {{ form.password_conf(class_="form-control") }} {% for error in form.password_conf.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ </div>
+
+ <div class="col">
+ {{ form.bio.label }}
+ {{ form.bio(class_="form-control") }} {% for error in form.bio.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.webpage.label }}
+ {{ form.webpage(class_="form-control") }} {% for error in form.webpage.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.twitter.label }}
+ {{ form.twitter(class_="form-control") }} {% for error in form.twitter.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.is_public_profile.label }}
+ {{ form.is_public_profile(class_="form-control") }} {% for error in form.is_public_profile.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p>{{ _('Your profile will be available <a href="%(url)s">here</a>.', url=url_for('user.profile_public', nickname=user.nickname) ) }}</p>
+
+ {{ form.automatic_crawling.label }}
+ {{ form.automatic_crawling(class_="form-control") }} {% for error in form.automatic_crawling.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p>{{ _('Uncheck if you are using your own crawler.') }}</p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col">
+ <br />
+ {{ form.submit(class_="btn btn-primary") }}
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ <br />
+ <div class="row">
+ <div class="col">
+ <a href="/delete_account" class="btn btn-warning" onclick="return confirm('{{ _('You are going to delete your account.') }}');">{{ _('Delete your account') }}</a>
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/profile_public.html b/newspipe/templates/profile_public.html
new file mode 100644
index 00000000..9ba3578c
--- /dev/null
+++ b/newspipe/templates/profile_public.html
@@ -0,0 +1,45 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ user.nickname }} / <a href="{{ url_for('user.user_stream', nickname=user.nickname) }}">stream</a></h1>
+ <div class="row">
+ <div class="col-md-12">
+ <p>
+ <span class="fa fa-clock-o" aria-hidden="true"></span>&nbsp;
+ {{ _('Member since') }}: {{ user.date_created | datetime }}
+ </p>
+ <p>
+ <span class="fa fa-clock-o" aria-hidden="true"></span>&nbsp;
+ {{ _('Last seen') }}: {{ user.last_seen | datetime }}
+ </p>
+ {% if user.webpage %}
+ <p>
+ <span class="fa fa-home" aria-hidden="true"></span>&nbsp;
+ {{ _('Webpage') }}: <a href="{{ user.webpage | safe }}">{{ user.webpage | safe }}</a>
+ </p>
+ {% endif %}
+ {% if user.twitter %}
+ <p>
+ <span class="fa fa-twitter" aria-hidden="true"></span>&nbsp;
+ {{ _('Twitter') }}: <a href="{{ user.twitter | safe }}">{{ user.twitter | safe }}</a>
+ </p>
+ {% endif %}
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-5">
+ {% if user.bio %}
+ <p align="justify">{{ user.bio }}</p>
+ {% endif %}
+ </div>
+ <div class="col-md-6 pull-right"></div>
+ </div>
+
+ <h2>{{ _('Feeds') }}</h2>
+ <div class="row">
+ <div class="col-md-12">
+ {% include "feed_list_per_categories.html" %}
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/signup.html b/newspipe/templates/signup.html
new file mode 100644
index 00000000..8d34b3bf
--- /dev/null
+++ b/newspipe/templates/signup.html
@@ -0,0 +1,24 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="form well">
+ <form action="" method="post" name="save">
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ {{ form.nickname(class_="form-control", placeholder=_('Your nickname')) }} {% for error in form.nickname.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p class="help-block">{{ _('Letters, numbers, dots and underscores only.') }}</p>
+ </div>
+ <div class="form-group">
+ {{ form.email(class_="form-control", placeholder=_('Your email')) }} {% for error in form.email.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p class="help-block">{{ _("Only for account activation. Your email won't be stored.") }}</p>
+ </div>
+ <div class="form-group">
+ {{ form.password(class_="form-control", placeholder=_('Your password')) }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p class="help-block">{{ _('Minimum 6 characters.') }}</p>
+ </div>
+ <br />
+ {{ form.submit(class_="btn btn-default") }}
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/newspipe/templates/user_stream.html b/newspipe/templates/user_stream.html
new file mode 100644
index 00000000..b05376a8
--- /dev/null
+++ b/newspipe/templates/user_stream.html
@@ -0,0 +1,70 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="row">
+ <div class="col-md-8">
+ <form class="form-inline">
+ <div class="form-group">
+ <label>Filter per category</label>
+ <select class="form-control" id="category-select" name="category_id">
+ <option value="0">All</option>
+ {% for cur_category in user.categories %}
+ <option value="{{cur_category.id}}" {% if cur_category.id==category.id %}selected{% endif %}>{{ cur_category.name }}</option>
+ {% endfor %}
+ </select>
+ <button type="submit" class="btn btn-primary mb-2">OK</button>
+ </div>
+ </form>
+ </div>
+ </div>
+
+ <br /><br />
+
+ {% if category %}
+ <div class="row">
+ <div class="col-md-8 offset-md-1">
+ <p class="lead">Articles from the category <a href="{{ url_for('user.profile_public', nickname=user.nickname, category_id=category.id) }}">{{ category.name }}</a></p>
+ </div>
+ </div>
+ {% endif %}
+
+ <div class="row">
+ <div class="col-md-8 offset-md-1">
+ {{ pagination.info }}
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-md-8 offset-md-1">
+ {{ pagination.links }}
+ </div>
+ </div>
+
+ <div class="table-responsive">
+ <table id="table-feeds" class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Title') }}</th>
+ <th>{{ _('Published at') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for article in articles %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td><a href="{{ url_for('article.article_pub', article_id=article.id) }}">{{ article.title }}</a></td>
+ <td>{{ article.date }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="row">
+ <div class="col-md-8 offset-md-1">
+ {{ pagination.links }}
+ </div>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
bgstack15