aboutsummaryrefslogtreecommitdiff
path: root/src/web/templates
diff options
context:
space:
mode:
Diffstat (limited to 'src/web/templates')
-rw-r--r--src/web/templates/about.html28
-rw-r--r--src/web/templates/admin/create_user.html29
-rw-r--r--src/web/templates/admin/dashboard.html60
-rw-r--r--src/web/templates/admin/user.html19
-rw-r--r--src/web/templates/article.html45
-rw-r--r--src/web/templates/duplicates.html30
-rw-r--r--src/web/templates/edit_feed.html77
-rw-r--r--src/web/templates/emails/new_account.html9
-rw-r--r--src/web/templates/emails/new_account.txt11
-rw-r--r--src/web/templates/emails/new_article.html1
-rw-r--r--src/web/templates/emails/new_article.txt1
-rw-r--r--src/web/templates/errors/404.html12
-rw-r--r--src/web/templates/errors/500.html12
-rw-r--r--src/web/templates/feed.html47
-rw-r--r--src/web/templates/feed_list.html47
-rw-r--r--src/web/templates/feeds.html7
-rw-r--r--src/web/templates/history.html26
-rw-r--r--src/web/templates/home.html131
-rw-r--r--src/web/templates/inactives.html26
-rw-r--r--src/web/templates/layout.html165
-rw-r--r--src/web/templates/login.html30
-rw-r--r--src/web/templates/management.html31
-rw-r--r--src/web/templates/opml.xml14
-rw-r--r--src/web/templates/profile.html42
-rw-r--r--src/web/templates/recover.html18
-rw-r--r--src/web/templates/signup.html26
26 files changed, 944 insertions, 0 deletions
diff --git a/src/web/templates/about.html b/src/web/templates/about.html
new file mode 100644
index 00000000..8d042077
--- /dev/null
+++ b/src/web/templates/about.html
@@ -0,0 +1,28 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h1>{{ _('About') }}</h1>
+ <p>
+ {{ _('JARR is a news aggregator platform.') }}
+ {{ _('You can easily <a href="https://jarr.readthedocs.org/en/latest/deployment.html">install JARR on your server</a>.') }}
+ {{ _('Alternatively, you can deploy your own copy using this button:') }}</p>
+ <a class="reference external image-reference" href="https://heroku.com/deploy?template=https://github.com/JARR-aggregator/JARR.git"><img alt="https://www.herokucdn.com/deploy/button.png" src="https://www.herokucdn.com/deploy/button.png" /></a></p>
+ <p>{{ _('This software is under AGPLv3 license. You are welcome to copy, modify or
+ redistribute the <a href="https://github.com/JARR-aggregator/JARR">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://github.com/JARR-aggregator/JARR/issues">here</a>.') }}</p>
+ </div>
+ <div class="well">
+ <h1>{{ _('Help') }}</h1>
+ <p>{{ _('If you have any problem, <a href="https://wiki.cedricbonhomme.org/contact">contact</a> the administrator.') }}</p>
+ <p>{{ _('The documentation of the RESTful API is <a href="https://jarr.readthedocs.org/en/latest/web-services.html">here</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-default" href="%(bookmarklet)s" rel="bookmark">Subscribe to this feed using JARR</a>', bookmarklet='javascript:window.location="%s?url="+encodeURIComponent(document.location)' % url_for('feed.bookmarklet', _external=True)) }}
+ </div>
+ <div class="well">
+ <h1>{{ _('Donation') }}</h1>
+ <p>{{ _('If you wish and if you like JARR, you can donate via bitcoin <a href="https://blockexplorer.com/address/1GVmhR9fbBeEh7rP1qNq76jWArDdDQ3otZ">1GVmhR9fbBeEh7rP1qNq76jWArDdDQ3otZ</a>. Thank you!') }}</p>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/admin/create_user.html b/src/web/templates/admin/create_user.html
new file mode 100644
index 00000000..64387dce
--- /dev/null
+++ b/src/web/templates/admin/create_user.html
@@ -0,0 +1,29 @@
+{% 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.email.label }}
+ {{ form.email(class_="form-control") }} {% for error in form.email.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.refresh_rate.label }}
+ {{ form.refresh_rate(class_="form-control") }} {% for error in form.refresh_rate.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ <br />
+ {{ form.submit(class_="btn btn-default") }}
+ </form>
+ </div>
+</div>
+{% endblock %}
diff --git a/src/web/templates/admin/dashboard.html b/src/web/templates/admin/dashboard.html
new file mode 100644
index 00000000..25bd3883
--- /dev/null
+++ b/src/web/templates/admin/dashboard.html
@@ -0,0 +1,60 @@
+{% extends "layout.html" %}
+{% block head%}
+{{super()}}
+{% endblock %}
+{% block content %}
+<div class="container">
+<h1>{{ _('Registered users') }}</h1>
+<table class="table table-striped">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>{{ _('Nickname') }}</th>
+ <th>{{ _('Email') }}</th>
+ <th>{{ _('Last seen') }}</th>
+ <th>{{ _('Actions') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for user in users|sort(attribute="last_seen")|reverse %}
+ <tr {% if user.activation_key != "" %}class="warning"{% endif %}>
+ <td>{{ loop.index }}</td>
+ {% if user.id == current_user.id %}
+ <td><a href="/management">{{ user.nickname }}</a> (It's you!)</td>
+ {% else %}
+ <td><a href="/admin/user/{{ user.id }}">{{ user.nickname }}</a></td>
+ {% endif %}
+ <td><a href="mailto:{{ user.email }}">{{ user.email }}</a></td>
+ <td class="date">{{ user.last_seen }}</td>
+ <td>
+ <a href="/admin/user/{{ user.id }}"><i class="glyphicon glyphicon-user" title="{{ _('View this user') }}"></i></a>
+ <a href="/admin/edit_user/{{ user.id }}"><i class="glyphicon glyphicon-edit" title="{{ _('Edit this user') }}"></i></a>
+ {% if user.id != current_user.id %}
+ {% if user.activation_key == "" %}
+ <a href="/admin/disable_user/{{ user.id }}"><i class="glyphicon glyphicon-ban-circle" title="Disable this account"></i></a>
+ {% else %}
+ <a href="/admin/enable_user/{{ user.id }}"><i class="glyphicon glyphicon-ok-circle" title="Enable this account"></i></a>
+ {% endif %}
+ <a href="/admin/delete_user/{{ user.id }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this user') }}" onclick="return confirm('{{ _('You are going to delete this account.') }}');"></i></a>
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+<a href="/admin/create_user" class="btn btn-default">{{ _('Add a new user') }}</a>
+<h1>{{ _('Send notification messages') }}</h1>
+<form action="" method="post">
+ {{ form.hidden_tag() }}
+
+ {{ form.subject.label }}
+ {{ form.subject(class_="form-control") }} {% for error in form.subject.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ {{ form.message.label }}
+ {{ form.message(class_="form-control", rows=8) }} {% for error in form.message.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+
+ <br />
+ {{ form.submit(class_="btn btn-default") }}
+</form>
+</div>
+{% endblock %}
diff --git a/src/web/templates/admin/user.html b/src/web/templates/admin/user.html
new file mode 100644
index 00000000..d1e08c0d
--- /dev/null
+++ b/src/web/templates/admin/user.html
@@ -0,0 +1,19 @@
+{% extends "layout.html" %}
+{% block head%}
+{{super()}}
+{% endblock %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <a href="/admin/edit_user/{{ user.id }}" class="btn btn-default">{{ _('Edit this user') }}</a>
+ <h2>{{ _('Membership') }}</h2>
+ <div class="row">
+ <div class="col-md-6">
+ <p>{{ _('Member since') }} {{ user.date_created | datetime }}.</p>
+ <p>{{ _('Last seen:') }} {{ user.last_seen | datetime }}.</p>
+ </div>
+ </div>
+ </div>
+ {% include "feed_list.html" %}
+</div>
+{% endblock %}
diff --git a/src/web/templates/article.html b/src/web/templates/article.html
new file mode 100644
index 00000000..b1f950b4
--- /dev/null
+++ b/src/web/templates/article.html
@@ -0,0 +1,45 @@
+{% 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="/delete/{{ article.id }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this article') }}"></i></a>
+ {% if article.like %}
+ <a href="#"><i class="glyphicon glyphicon-star like" title="{{ _('One of your favorites') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="glyphicon glyphicon-star-empty like" title="{{ _('Click if you like this article') }}"></i></a>
+ {% endif %}
+ {% if article.readed %}
+ <a href="#"><i class="glyphicon glyphicon-unchecked readed" title="{{ _('Mark this article as unread') }}"></i></a>
+ {% else %}
+ <a href="#"><i class="glyphicon glyphicon-check readed" 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">
+ <div class="row">
+ <div class="col-md-6">
+ {{ _('Next post:') }} <a href="/article/{{ next_article.id }}">{{ next_article.title }}</a>
+ </div>
+ <div class="col-md-6 text-right">
+ {{ _('Previous post:') }} <a href="/article/{{ previous_article.id }}">{{ previous_article.title }}</a>
+ </div>
+ </div>
+ </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/src/web/templates/duplicates.html b/src/web/templates/duplicates.html
new file mode 100644
index 00000000..32fbdf9a
--- /dev/null
+++ b/src/web/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-default">{{ _('Delete all in this column') }}</span>
+ </th>
+ <th align="center">
+ <span class="delete-all btn btn-default">{{ _('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="/delete/{{ pair[0].id }}"><i class="glyphicon glyphicon-remove" 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="/delete/{{ pair[1].id }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this article') }}"></i></a>&nbsp;<a href="/article/{{ pair[1].id }}">{{ pair[1].title }}</a> ({{ pair[1].retrieved_date }})</td>
+ </tr>
+ {% endfor %}
+ </tobdy>
+ </table>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/edit_feed.html b/src/web/templates/edit_feed.html
new file mode 100644
index 00000000..68da0d48
--- /dev/null
+++ b/src/web/templates/edit_feed.html
@@ -0,0 +1,77 @@
+{% 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.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 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-default") }}
+ </div>
+ </div>
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/emails/new_account.html b/src/web/templates/emails/new_account.html
new file mode 100644
index 00000000..5b173e7e
--- /dev/null
+++ b/src/web/templates/emails/new_account.html
@@ -0,0 +1,9 @@
+<p>Hello {{ user.firstname }} {{ user.lastname }},</p>
+
+<p>An account has been created for you.
+You can now access the <a href="{{ platform_url }}">JARR platform</a>.
+Your login is your e-mail address and your password is:</p>
+
+<p><b>{{ password }}</b></p>
+
+<p>Regards,</p> \ No newline at end of file
diff --git a/src/web/templates/emails/new_account.txt b/src/web/templates/emails/new_account.txt
new file mode 100644
index 00000000..6397f502
--- /dev/null
+++ b/src/web/templates/emails/new_account.txt
@@ -0,0 +1,11 @@
+Hello {{ user.firstname }} {{ user.lastname }},
+
+An account has been created for you.
+You can now access the pyAggr3g470r platform ({{ platform_url }}).
+Your login is your e-mail address and your password is:
+
+---
+{{ password }}
+---
+
+Regards, \ No newline at end of file
diff --git a/src/web/templates/emails/new_article.html b/src/web/templates/emails/new_article.html
new file mode 100644
index 00000000..5a6b7c4a
--- /dev/null
+++ b/src/web/templates/emails/new_article.html
@@ -0,0 +1 @@
+{{ article.content | safe }} \ No newline at end of file
diff --git a/src/web/templates/emails/new_article.txt b/src/web/templates/emails/new_article.txt
new file mode 100644
index 00000000..9b800855
--- /dev/null
+++ b/src/web/templates/emails/new_article.txt
@@ -0,0 +1 @@
+{{ article.content | striptags }} \ No newline at end of file
diff --git a/src/web/templates/errors/404.html b/src/web/templates/errors/404.html
new file mode 100644
index 00000000..c64a2be8
--- /dev/null
+++ b/src/web/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/src/web/templates/errors/500.html b/src/web/templates/errors/500.html
new file mode 100644
index 00000000..417fc0c7
--- /dev/null
+++ b/src/web/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/src/web/templates/feed.html b/src/web/templates/feed.html
new file mode 100644
index 00000000..c421a411
--- /dev/null
+++ b/src/web/templates/feed.html
@@ -0,0 +1,47 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h2>{{ feed.title }}</h2>
+ {% if feed.description %} <p>{{ feed.description }}</p> {% endif %}
+ <a href="{{ url_for("feed.delete", feed_id=feed.id) }}"><i class="glyphicon glyphicon-remove" 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="glyphicon glyphicon-edit" title="{{ _('Edit this feed') }}"></i></a>
+ </div>
+ <div class="well">
+ <p>
+ {{ _('This feed contains') }} {{ feed.articles.all()|count }} <a href= "{{ url_for("home", feed_id=feed.id, filter_="all") }}">{{ _('articles') }}</a>.<br />
+ {{ _('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="well">
+ {% if feed.articles.all()|count != 0 %}
+ <div>{{ tag_cloud|safe }}</div>
+ {% endif %}
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/feed_list.html b/src/web/templates/feed_list.html
new file mode 100644
index 00000000..c5cadab0
--- /dev/null
+++ b/src/web/templates/feed_list.html
@@ -0,0 +1,47 @@
+{% if feeds.all()| count == 0 %}
+ <h1>{{_("No feed")}}</h1>
+{% else %}
+<div class="table-responsive">
+ <table 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|sort(attribute="title") %}
+ <tr {% if not feed.enabled %}class="warning"{% endif %}>
+ <td>{{ loop.index }}</td>
+ <td>
+ {% if feed.enabled %}
+ <i class="glyphicon glyphicon-eye-open" title="{{ _('Feed enabled') }}"></i>
+ {% else %}
+ <i class="glyphicon glyphicon-eye-close" title="{{ _('Feed disabled') }}"></i>
+ {% endif %}
+ {% if feed.error_count >= conf.DEFAULT_MAX_ERROR %}
+ <i class="glyphicon glyphicon-exclamation-sign" title="{{ _('Feed encountered too much errors.') }}"></i>
+ {% endif %}
+ </td>
+ <td><a href="{{ url_for("feed.feed", feed_id=feed.id) }}" {% if feed.description %}title="{{ feed.description }}"{% endif %}>
+ {% if feed.icon_url %}<img src="{{ url_for('icon.icon', url=feed.icon_url) }}" width="16px" />{% endif %}
+ {{ feed.title }}
+ </a></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("home", feed_id=feed.id, filter_="all") }}"><i class="glyphicon glyphicon-th-list" title="{{ _('Articles') }}"></i></a>
+ <a href="{{ url_for("feed.form", feed_id=feed.id) }}"><i class="glyphicon glyphicon-edit" title="{{ _('Edit this feed') }}"></i></a>
+ <a href="/duplicates/{{ feed.id }}"><i class="glyphicon glyphicon-book" title="{{ _('Duplicate articles') }}"></i></a>
+ <a href="{{ url_for("feed.delete", feed_id=feed.id) }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+{% endif %}
diff --git a/src/web/templates/feeds.html b/src/web/templates/feeds.html
new file mode 100644
index 00000000..9ba16359
--- /dev/null
+++ b/src/web/templates/feeds.html
@@ -0,0 +1,7 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ _('You are subscribed to') }} {{ feeds.count() }} {{ _('feeds') }} &middot; {{ _('Add a') }} <a href="{{ url_for("feed.form") }}">{{ _('feed') }}</a></h1>
+ {% include "feed_list.html" %}
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/history.html b/src/web/templates/history.html
new file mode 100644
index 00000000..6be54d71
--- /dev/null
+++ b/src/web/templates/history.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <h1>{{ _('History') }}</h1>
+ {% if month != None %}
+ <h2><a href="/history/{{ year }}"><span class="glyphicon glyphicon-chevron-left"></span> {{ year }}</a></h2>
+ <h3>{{ month | month_name }}</h3>
+ {% elif year != None %}
+ <h2><a href="/history"><span class="glyphicon glyphicon-chevron-left"></span>&nbsp{{ _('all years') }}</a></h2>
+ <h3>{{ year }}</h3>
+ {% endif %}
+ <ul class="list-group">
+ {% for article in articles_counter %}
+ {% if year == None %}
+ <li class="list-group-item"><a href="/history/{{ article }}">{{ article }}</a> : {{ articles_counter[article] }} articles</li>
+ {% elif month == None %}
+ <li class="list-group-item"><a href="/history/{{ year }}/{{ article }}">{{ article | month_name }}</a> : {{ articles_counter[article] }} articles</li>
+ {% else %}
+ {% for article in articles | sort(attribute="date", reverse = True) %}
+ <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/src/web/templates/home.html b/src/web/templates/home.html
new file mode 100644
index 00000000..86d96e94
--- /dev/null
+++ b/src/web/templates/home.html
@@ -0,0 +1,131 @@
+{% extends "layout.html" %}
+{% block content %}
+{% 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="/management">{{ _('upload an OPML file.') }}</a></h1>
+ </div>
+{% else %}
+<div class="container-fluid">
+ <div class="row row-offcanvas row-offcanvas-left">
+ <div class="col-md-2 sidebar sidebar-offcanvas pre-scrollable affix hidden-sm hidden-xs" id="sidebar" role="navigation" data-spy="affix" style="max-height: 100%;">
+ <ul class="nav nav-sidebar" data-offset-top="0" data-offset-bottom="0">
+ <li><a href="{{ gen_url(feed_id=0) }}">
+ {% if not feed_id %}<b>{% endif %}
+ {{ _('All feeds') }} <span id="total-unread" class="badge pull-right">{{ articles.__len__() }}</span>
+ {% if not feed_id %}</b>{% endif %}
+ </a></li>
+ {% for fid, nbunread in unread|dictsort(by='value')|reverse %}
+ <li class="feed-menu"><a href="{{ gen_url(feed_id=fid) }}">
+ {% if feed_id == fid %}<b>{% endif %}
+ {% if in_error.get(fid, 0) > 0 %}
+ <span style="background-color: {{ "red" if in_error[fid] > conf.DEFAULT_MAX_ERROR -1 else "orange" }} ;" class="badge pull-right" title="Some errors occured while trying to retrieve that feed.">{{ in_error[fid] }} {{ _("error") }}{% if in_error[fid] > 1 %}s{% endif %}</span>
+ {% endif %}
+ <span id="unread-{{ fid }}" class="badge pull-right">{{ nbunread }}</span>
+ {{ feeds[fid]|safe }}
+ {% if feed_id == fid %}</b>{% endif %}
+ </a></li>
+ <li class="feed-commands"><span>
+ <a href="/feed/{{ fid }}"><i class="glyphicon glyphicon-info-sign" title="{{ _('Details') }}"></i></a>
+ <a href="{{ url_for("feed.form", feed_id=fid) }}"><i class="glyphicon glyphicon-edit" title="{{ _('Edit this feed') }}"></i></a>
+ <a href="{{ url_for("feed.delete", feed_id=fid) }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ <a href="{{ url_for("feed.update", feed_id=fid, action="read") }}"><i class="glyphicon glyphicon-check" title="{{ _('Mark this feed as read') }}"></i></a>
+ <a href="{{ url_for("feed.update", feed_id=fid, action="unread") }}"><i class="glyphicon glyphicon-unchecked" title="{{ _('Mark this feed as unread') }}"></i></a>
+ </span></li>
+ {% endfor %}
+ {% for fid, ftitle in feeds|dictsort(case_sensitive=False, by='value') if not fid in unread %}
+ <li class="feed-menu"><a href="{{ gen_url(feed_id=fid) }}">
+ {% if in_error.get(fid, 0) > 0 %}
+ <span style="background-color: {{ "red" if in_error[fid] > conf.DEFAULT_MAX_ERROR - 1 else "orange" }} ;" class="badge pull-right" title="Some errors occured while trying to retrieve that feed.">{{ in_error[fid] }} {{ _("error") }}{% if in_error[fid] > 1 %}s{% endif %}</span>
+ {% endif %}
+ {% if feed_id == fid %}<b>{% endif %}
+ {{ ftitle|safe }}
+ {% if feed_id == fid %}</b>{% endif %}
+ </a></li>
+ <li class="feed-commands"><span>
+ <a href="{{ url_for("feed.feed", feed_id=fid) }}"><i class="glyphicon glyphicon-info-sign" title="{{ _('Details') }}"></i></a>
+ <a href="{{ url_for("feed.form", feed_id=fid) }}"><i class="glyphicon glyphicon-edit" title="{{ _('Edit this feed') }}"></i></a>
+ <a href="{{ url_for("feed.delete", feed_id=fid) }}"><i class="glyphicon glyphicon-remove" title="{{ _('Delete this feed') }}" onclick="return confirm('{{ _('You are going to delete this feed.') }}');"></i></a>
+ <a href="{{ url_for("feed.update", feed_id=fid, action="read") }}"><i class="glyphicon glyphicon-check" title="{{ _('Mark this feed as read') }}"></i></a>
+ <a href="{{ url_for("feed.update", feed_id=fid, action="unread") }}"><i class="glyphicon glyphicon-unchecked" title="{{ _('Mark this feed as unread') }}"></i></a>
+ </span></li>
+ {% endfor %}
+ </ul>
+ </div><!-- row -->
+
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {% if messages %}
+ <div class="col-md-offset-2 col-md-10 main">
+ {% block messages %}
+ {{ super() }}
+ {% endblock %}
+ </div>
+ {% endif %}
+ {% endwith %}
+ <div class="col-md-offset-2 col-md-10 main">
+ <div id="filters" data-filter="{{ filter_ }}">
+ <ul id="myTab" class="nav nav-tabs" role="tablist">
+ <li id="tab-all"><a href="{{ gen_url(filter_='all') }}">{{ _('All') }}</a></li>
+ <li id="tab-read"><a href="{{ gen_url(filter_='read') }}">{{ _('Read') }}</a></li>
+ <li id="tab-unread"><a href="{{ gen_url(filter_='unread') }}">{{ _('Unread') }}</a></li>
+ <li id="tab-nbdisplay" class="pull-right">
+ <div id="nbdisplay">
+ <a href="{{ gen_url(limit=10) }}" class="label {% if limit == 10 %}label-primary{% else %}label-info{% endif %}">{{ _(10) }}</a>
+ <a href="{{ gen_url(limit=100) }}" class="label {% if limit == 100 %}label-primary{% else %}label-info{% endif %}">{{ _(100) }}</a>
+ <a href="{{ gen_url(limit=1000) }}" class="label {% if limit == 1000 %}label-primary{% else %}label-info{% endif %}">{{ _(1000) }}</a>
+ <a href="{{ gen_url(limit='all') }}" class="label {% if limit == 'all' %}label-primary{% else %}label-info{% endif %}">{{ _('All') }}</a>
+ </div>
+ </li>
+ </div>
+ {% if articles | count != 0%}
+ <div class="table-responsive">
+ <table class="table table-striped strict-table">
+ <thead>
+ <tr>
+ <th></th>
+ <th><a href="{{ gen_url(sort_='-feed' if sort_ == 'feed' else 'feed') }}">{{ _('Feed') }}</a></th>
+ <th><a href="{{ gen_url(sort_='-article' if sort_ == 'article' else 'article') }}">{{ _('Article') }}</a></th>
+ <th><a href="{{ gen_url(sort_='-date' if sort_ == 'date' else 'date') }}">{{ _('Date') }}</a></th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for article in articles %}
+ <tr data-article="{{ article.id }}" data-feed="{{ article.feed_id }}">
+ <td>
+ <a><i class="glyphicon glyphicon-remove delete" title="{{ _('Delete this article') }}"></i></a>
+ {% if article.like %}
+ <a><i class="glyphicon glyphicon-star like" title="{{ _('One of your favorites') }}"></i></a>
+ {% else %}
+ <a><i class="glyphicon glyphicon-star-empty like" title="{{ _('Click if you like this article') }}"></i></a>
+ {% endif %}
+ {% if article.readed %}
+ <a><i class="glyphicon glyphicon-unchecked readed" title="{{ _('Mark this article as unread') }}"></i></a>
+ {% else %}
+ <a><i class="glyphicon glyphicon-check readed" title="{{ _('Mark this article as read') }}"></i></a>
+ {% if filter_ == 'all' %}</b>{% endif %}
+ {% endif %}
+ </td>
+ <td>
+ <a class="open-article" href="{{ url_for("article.redirect_to_article", article_id=article.id)}}" target="_blank" title="{{article.link}}" alt="{{article.link}}">
+ {% if article.source.icon_url %}
+ <img src="{{ url_for('icon.icon', url=article.source.icon_url) }}" width="16px" />
+ {% else %}
+ <span class="glyphicon glyphicon-ban-circle" title='{{_("No icon found for this feed")}}' alt='{{_("No icon found for this feed")}}'></span>
+ {% endif %}
+ <span class="hidden-xs">{{ article.source.title|safe }}</span></a></td>
+ <td {%if filter_ == 'all' and article.readed == False %}style='font-weight:bold'{% endif %}>
+ <a href="{{ url_for("article.article", article_id=article.id) }}">{{ article.title|safe }}</a>
+ </td>
+ <td class="date">{{ article.date|datetime }}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ {% endif %}
+ </div><!-- row -->
+ </div><!-- main -->
+</div><!-- container-fluid -->
+<style>.not-at-home {display: none};</style>
+{% endif %}
+{% endblock %}
diff --git a/src/web/templates/inactives.html b/src/web/templates/inactives.html
new file mode 100644
index 00000000..eb546eca
--- /dev/null
+++ b/src/web/templates/inactives.html
@@ -0,0 +1,26 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <form method=get action="/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/src/web/templates/layout.html b/src/web/templates/layout.html
new file mode 100644
index 00000000..3a10f2d6
--- /dev/null
+++ b/src/web/templates/layout.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ {% block head %}
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="description" content="JARR is a web-based news aggregator." />
+ <meta name="author" content="" />
+ <title>JARR{% if head_titles %} - {{ ' - '.join(head_titles) }}{% endif %}</title>
+ <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}" />
+ <!-- Bootstrap core CSS -->
+ <link href="{{ url_for('static', filename='css/bootstrap.css') }}" rel="stylesheet" media="screen" />
+ <!-- Add custom CSS here -->
+ <link href="{{ url_for('static', filename='css/customized-bootstrap.css') }}" rel="stylesheet" media="screen" />
+ <link href="{{ url_for('static', filename='css/side-nav.css') }}" rel="stylesheet" media="screen" />
+ {% endblock %}
+ </head>
+ <body>
+ <nav class="navbar navbar-inverse navbar-fixed-top navbar-custom" role="navigation">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="{{ url_for("home") }}">JARR</a>
+ {% if head_titles %}
+ <p class="navbar-text" style="max-height: 20px; overflow: hidden">
+ {{ " - ".join(head_titles) }}
+ </p>
+ {% endif %}
+ </div>
+
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div class="collapse navbar-collapse navbar-ex1-collapse">
+ <ul class="nav navbar-nav navbar-right">
+ {% if g.user.is_authenticated %}
+ <!-- <li><a href="{{ url_for("feed.form") }}"><span class="glyphicon glyphicon-plus-sign"></span> {{ _('Add a feed') }}</a></li> -->
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <div><span class="glyphicon glyphicon-plus-sign"></span>&nbsp;{{ _('Add a feed') }}</div>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <form action="{{ url_for('feed.bookmarklet') }}" class="navbar-form navbar-left" method="GET" name="save">
+ <div class="input-group input-group-inline">
+ <input class="form-control" name="url" type="url" placeholder="{{_("site or feed url")}}" required="required"/>
+ <span class="input-group-btn">
+ <button type="submit" class="btn btn-default" /><span class="glyphicon glyphicon-plus"></span></button>
+ </span>
+ </div><!-- /input-group -->
+ </form>
+ </li>
+ </ul>
+ </li>
+ {% if page_to_render == "favorites" %}
+ <li><a href="{{ url_for("home") }}"><span class="glyphicon glyphicon-home"></span> {{ _('Home') }}</a></li>
+ {% else %}
+ <li><a href="{{ url_for("favorites") }}"><span class="glyphicon glyphicon-star"></span> {{ _('Favorites') }}</a></li>
+ {% endif %}
+ {% if conf.CRAWLING_METHOD == "classic" and (not conf.ON_HEROKU or g.user.is_admin()) %}
+ <li><a href="/fetch"><span class="glyphicon glyphicon-import"></span> {{ _('Fetch') }}</a></li>
+ {% endif %}
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ _('Feed') }} <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="{{ url_for("feeds.update", action="read") }}">{{ _('Mark all as read') }}</a></li>
+ <li><a href="{{ url_for("feeds.update", action="read", nb_days="1") }}">{{ _('Mark all as read older than yesterday') }}</a></li>
+ <li><a href="{{ url_for("feeds.update", action="read", nb_days="10") }}">{{ _('Mark all as read older than 10 days') }}</a></li>
+ <li role="presentation" class="divider"></li>
+ <li><a href="{{ url_for("inactives") }}">{{ _('Inactive') }}</a></li>
+ <li><a href="{{ url_for("history") }}">{{ _('History') }}</a></li>
+ <li><a href="{{ url_for("feeds.feeds") }}">{{ _('All') }}</a></li>
+ </ul>
+ </li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <div><span class="glyphicon glyphicon-user"></span>&nbsp;<b class="caret"></b></div>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href="{{ url_for("profile") }}"><span class="glyphicon glyphicon-user"></span> {{ _('Profile') }}</a></li>
+ <li><a href="{{ url_for("management") }}"><span class="glyphicon glyphicon-cog"></span> {{ _('Your data') }}</a></li>
+ <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span> {{ _('About') }}</a></li>
+ {% if g.user.is_admin() %}
+ <li role="presentation" class="divider"></li>
+ <li><a href="{{ url_for("dashboard") }}"><span class="glyphicon glyphicon-dashboard"></span> {{ _('Dashboard') }}</a></li>
+ <li role="presentation" class="divider"></li>
+ {% endif %}
+ <li><a href="{{ url_for("logout") }}"><span class="glyphicon glyphicon-log-out"></span> {{ _('Logout') }}</a></li>
+ </ul>
+ </li>
+
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <div><span class="glyphicon glyphicon-search"></span>&nbsp;<b class="caret"></b></div>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <form class="navbar-form" method=get action="{{ url_for("search") }}" role="search">
+ <div class="input-group">
+ {% if filter_ %}<input type="hidden" name="filter_" value="{{ filter_ }}" />{% endif %}
+ {% if limit %}<input type="hidden" name="limit" value="{{ limit }}" />{% endif %}
+ {% if feed_id %}<input type="hidden" name="feed_id" value="{{ feed_id }}" />{% endif %}
+ <label for="search_title">{{ _("Title") }}</label>
+ <input type="checkbox" name="search_title" {% if search_title == 'on' or not (search_title == 'on' or search_content == 'on') %}checked{%endif%}/>
+ <br />
+ <label for="search_content">{{ _("Content") }}</label>
+ <input type="checkbox" name="search_content" {% if search_content == 'on' %}checked{%endif%}/>
+ <input type="text" class="form-control" name="query" placeholder="{{ _("Search") }}" {% if search_query %} value="{{ search_query }}"{% endif %} />
+ </div>
+ </form>
+ </li>
+ </ul>
+ </li>
+ {% else %}
+ <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span>&nbsp;{{ _('About') }}</a></li>
+ {% endif %}
+ </ul>
+ </div><!-- /.navbar-collapse -->
+ </div><!-- /.container -->
+ </nav>
+ <br />
+
+ <div class="container 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 %}
+
+ <!-- Bootstrap core JavaScript -->
+ <!-- Placed at the end of the document so the pages load faster -->
+ <script type="text/javascript" src="{{ url_for('static', filename = 'js/jquery.js') }}"></script>
+ <script type="text/javascript" src="{{ url_for('static', filename = 'js/bootstrap.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>
+ <script type="text/javascript" class="source">
+ var filter_ = {% if filter_ %}"{{ filter_ }}"{% else %}undefined{% endif %};
+ if (filter_ == undefined) {
+ if (window.location.href.indexOf("filter_=all") > -1){
+ filter_ = 'all';
+ }
+ else if (window.location.href.indexOf("filter_=unread") > -1) {
+ filter_ = 'unread';
+ }
+ else if (window.location.href.indexOf("filter_=read") > -1) {
+ filter_ = 'read';
+ }
+ }
+ $("#tab-" + filter_).attr('class', "active");
+ </script>
+ </body>
+</html>
diff --git a/src/web/templates/login.html b/src/web/templates/login.html
new file mode 100644
index 00000000..c37d6937
--- /dev/null
+++ b/src/web/templates/login.html
@@ -0,0 +1,30 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h2>{{ _('Log In') }}</h2>
+ <form action="{{ url_for('login') }}" method=post>
+ {{ form.hidden_tag() }}
+
+ <div class="form-group">
+ {{ form.email(class_="form-control", placeholder=_('Your email')) }}
+ </div>
+ {% for message in form.email.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-default") }}
+ </form>
+ </div>
+ <a href="/signup" class="btn btn-default">{{ _('Sign up') }}</a>
+ &nbsp;
+ <a href="/recover" class="btn btn-default">{{ _('Forgot password') }}</a>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/management.html b/src/web/templates/management.html
new file mode 100644
index 00000000..72259551
--- /dev/null
+++ b/src/web/templates/management.html
@@ -0,0 +1,31 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h1>{{ _('Your subscriptions') }}</h1>
+ <p>{{ _('You are subscribed to') }} {{ nb_feeds }} <a href="/feeds">{{ _('feeds') }}</a>. {{ _('Add a') }} <a href="{{ url_for("feed.form") }}">{{ _('feed') }}</a>.</p>
+ <p>{{ nb_articles }} {{ _('articles are stored in the database with') }} {{ nb_unread_articles }} {{ _('unread articles') }}.</p>
+ <a href="/expire_articles?weeks=10" class="btn btn-default" onclick="return confirm('{{ _('You are going to delete old articles.') }}');">{{ _('Delete articles older than 10 weeks') }}</a>
+ </div>
+ <div class="well">
+ <h1 id="import">{{ _('OPML import/export') }}</h1>
+ <form action="" method="post" id="formImportOPML" enctype="multipart/form-data">
+ <span class="btn btn-default btn-file">{{ _('Batch import feeds from OPML') }} (<span class="text-info">*.xml {{ _('or') }} *.opml</span>)<input type="file" name="opmlfile" /></span>
+ <button class="btn btn-default" type="submit">OK</button>
+ </form>
+ <br />
+ <a href="/export_opml" class="btn btn-default">{{ _('Export feeds to OPML') }}</a>
+ <h1>{{ _('Data liberation') }}</h1>
+ <form action="" method="post" id="formImportJSON" enctype="multipart/form-data">
+ <span class="btn btn-default btn-file">{{ _('Import account') }} (<span class="text-info">*.json</span>)<input type="file" name="jsonfile" /></span>
+ <button class="btn btn-default" type="submit">OK</button>
+ </form>
+ <br />
+ <a href="/export?format=JSON" class="btn btn-default">{{ _('Export account to JSON') }}</a>
+ </div>
+ <div class="well">
+ <h1>{{ _('Export articles') }}</h1>
+ <a href="/export?format=HTML" class="btn btn-default">HTML</a>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/opml.xml b/src/web/templates/opml.xml
new file mode 100644
index 00000000..96fe66f5
--- /dev/null
+++ b/src/web/templates/opml.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- OPML generated by pyAggr3g470r 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>
+ <ownerEmail>{{ user.email }}</ownerEmail>
+ </head>
+ <body>
+ {% for feed in user.feeds %} <outline title="{{ feed.title|escape }}" text="{{ feed.title|escape }}" description="{{ feed.description|escape }}" xmlUrl="{{ feed.link|escape }}" htmlUrl="{{ feed.site_link|escape }}" />
+ {% endfor %}</body>
+</opml> \ No newline at end of file
diff --git a/src/web/templates/profile.html b/src/web/templates/profile.html
new file mode 100644
index 00000000..acd593b2
--- /dev/null
+++ b/src/web/templates/profile.html
@@ -0,0 +1,42 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h1>{{ _('Your Profile') }}</h1>
+ <div class="row">
+ <div class="col-md-6">
+ <p>{{ _('Member since') }} {{ user.date_created | datetime }}.</p>
+ <p>{{ _('Last seen:') }} {{ user.last_seen | datetime }}.</p>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <a href="/delete_account" class="btn btn-default" onclick="return confirm('{{ _('You are going to delete your account.') }}');">{{ _('Delete your account') }}</a>
+ </div>
+ </div>
+ </div>
+ <div class="well">
+ <h2>Edit your profile</h2>
+ <form action="" method="post" name="save">
+ {{ 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.email.label }}
+ {{ form.email(class_="form-control") }} {% for error in form.email.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 %}
+
+ {{ form.refresh_rate.label }}
+ {{ form.refresh_rate(class_="form-control") }} {% for error in form.refresh_rate.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <br />
+ {{ form.submit(class_="btn") }}
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/recover.html b/src/web/templates/recover.html
new file mode 100644
index 00000000..c1176d55
--- /dev/null
+++ b/src/web/templates/recover.html
@@ -0,0 +1,18 @@
+{% extends "layout.html" %}
+{% block content %}
+<div class="container">
+ <div class="well">
+ <h2>{{ _('Recover your account') }}</h2>
+ {% for message in form.email.errors %}
+ <div class="flash">{{ message }}</div>
+ {% endfor %}
+ <form action="{{ url_for('recover') }}" method=post>
+ {{ form.hidden_tag() }}
+ <div class="form-group">
+ {{ form.email(class_="form-control", placeholder=_('Your email')) }}
+ </div>
+ {{ form.submit(class_="btn btn-default") }}
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
diff --git a/src/web/templates/signup.html b/src/web/templates/signup.html
new file mode 100644
index 00000000..3962c42a
--- /dev/null
+++ b/src/web/templates/signup.html
@@ -0,0 +1,26 @@
+{% 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.label }}
+ {{ form.nickname(class_="form-control") }} {% 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>
+ {{ form.email.label }}
+ {{ form.email(class_="form-control") }} {% for error in form.email.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <div class="form-group">
+ {{ form.password.label }}
+ {{ form.password(class_="form-control") }} {% for error in form.password.errors %} <span style="color: red;">{{ error }}<br /></span>{% endfor %}
+ <p class="help-block">{{ _('Minimum 6 characters.') }}</p>
+ </div>
+ {{ form.recaptcha.label }}
+ {{ form.recaptcha }} {% for error in form.recaptcha.errors %} <span style="color: red;">{{ error }}<br /></span> {% endfor %}
+ <br />
+ {{ form.submit(class_="btn btn-default") }}
+ </form>
+ </div>
+</div><!-- /.container -->
+{% endblock %}
bgstack15