mirror of
https://git.nolog.cz/NoLog.cz/headline.git
synced 2025-01-31 11:53:35 +01:00
Add about page and list of feeds, template parts
This commit is contained in:
parent
1304ef1a83
commit
0157afbf52
9 changed files with 199 additions and 85 deletions
69
view/app.py
69
view/app.py
|
@ -4,9 +4,15 @@ import sqlite3
|
|||
from flask import Flask, request, render_template
|
||||
from flask import g
|
||||
from flask_paginate import Pagination, get_page_parameter
|
||||
import confuse
|
||||
|
||||
|
||||
DATABASE = "../data/diffs.db"
|
||||
CONFIG_FILE = "../data/config.yaml"
|
||||
|
||||
config = confuse.Configuration('headline', __name__)
|
||||
config.set_file(CONFIG_FILE)
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
@ -14,43 +20,60 @@ app = Flask(__name__)
|
|||
|
||||
|
||||
def get_db():
|
||||
db = getattr(g, '_database', None)
|
||||
if db is None:
|
||||
db = g._database = sqlite3.connect(DATABASE)
|
||||
db.row_factory = sqlite3.Row
|
||||
return db
|
||||
db = getattr(g, '_database', None)
|
||||
if db is None:
|
||||
db = g._database = sqlite3.connect(DATABASE)
|
||||
db.row_factory = sqlite3.Row
|
||||
return db
|
||||
|
||||
@app.teardown_appcontext
|
||||
def close_connection(exception):
|
||||
db = getattr(g, '_database', None)
|
||||
if db is not None:
|
||||
db.close()
|
||||
db = getattr(g, '_database', None)
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
db = get_db().cursor()
|
||||
db.execute('SELECT count(diff_id) FROM diffs')
|
||||
diff_count = db.fetchall()[0][0]
|
||||
db = get_db().cursor()
|
||||
db.execute('SELECT count(diff_id) FROM diffs')
|
||||
diff_count = db.fetchall()[0][0]
|
||||
|
||||
|
||||
#flask-paginate
|
||||
page = request.args.get(get_page_parameter(), type=int, default=1)
|
||||
#flask-paginate
|
||||
page = request.args.get(get_page_parameter(), type=int, default=1)
|
||||
|
||||
pagination = Pagination(page=page, total=diff_count, record_name='diffs')
|
||||
pagination = Pagination(page=page, total=diff_count, record_name='diffs', css_framework='bootstrap5')
|
||||
|
||||
|
||||
page_skip = pagination.skip
|
||||
per_page = pagination.per_page
|
||||
db.execute("SELECT * FROM diffs ORDER BY diff_id DESC LIMIT ? OFFSET ?", (per_page,page_skip))
|
||||
diffs = db.fetchall()
|
||||
page_skip = pagination.skip
|
||||
per_page = pagination.per_page
|
||||
db.execute("SELECT * FROM diffs ORDER BY diff_id DESC LIMIT ? OFFSET ?", (per_page,page_skip))
|
||||
diffs = db.fetchall()
|
||||
|
||||
return render_template('./index.html',
|
||||
diffs=diffs,
|
||||
pagination=pagination,
|
||||
)
|
||||
return render_template('./index.html',
|
||||
diffs=diffs,
|
||||
pagination=pagination,
|
||||
diff_count = diff_count
|
||||
)
|
||||
|
||||
|
||||
@app.route('/about')
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
|
||||
|
||||
@app.route('/feeds')
|
||||
def feed_list():
|
||||
feeds = []
|
||||
for conf in config['feeds']:
|
||||
feed = {
|
||||
'rss_source' : str(conf['rss_source']),
|
||||
'unique_tag' : str(conf['unique_tag']),
|
||||
'feed_name' : str(conf['name'])
|
||||
}
|
||||
feeds.append(feed)
|
||||
return render_template('feeds.html', feeds=feeds)
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0")
|
||||
app.run(host="0.0.0.0")
|
|
@ -1,2 +1,3 @@
|
|||
flask
|
||||
flask-paginate
|
||||
confuse
|
BIN
view/static/favicon.ico
Normal file
BIN
view/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
9
view/static/main.css
Normal file
9
view/static/main.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
body {
|
||||
margin-bottom: 60px; /* Margin bottom by footer height */
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
26
view/templates/about.html
Normal file
26
view/templates/about.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" class="h100">
|
||||
|
||||
<head>
|
||||
{% include 'parts/head.html' %}
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column h-100">
|
||||
|
||||
<!-- Begin page content -->
|
||||
<main class="flex-shrink-0">
|
||||
<div class="container">
|
||||
<h1 class="mt-5">Headliner</h1>
|
||||
<p class="lead">Headliner is monitoring rss feeds of czech news websites for changes in article headlines. Just
|
||||
because it might be interesting.</p>
|
||||
<p>See <a href="https://git.nolog.cz/mdivecky/headline">the source code</a>, but be aware that it's not too nice.
|
||||
Feel free to improve it.</p>
|
||||
<p>If you want to access the raw data collected by this tool, write us an e-mail, you can find the contact on our
|
||||
website below.</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{% include 'parts/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
35
view/templates/feeds.html
Normal file
35
view/templates/feeds.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
{% include 'parts/head.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>RSS/Atom URL</th>
|
||||
<th>Unique tag</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for feed in feeds %}
|
||||
<tr>
|
||||
<td>{{ feed.feed_name }}</td>
|
||||
<td>{{ feed.rss_source | urlize(target="_blank") }}</td>
|
||||
<td>{{ feed.unique_tag }}</td>
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'parts/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,66 +1,74 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Headliner</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
<style>
|
||||
|
||||
/* .expanded {
|
||||
width: 100%;
|
||||
} */
|
||||
/* Longer name hidden by default */
|
||||
span.long{
|
||||
display:none;
|
||||
}
|
||||
/* On hover, hide the short name */
|
||||
.expanded:hover span.short{
|
||||
display:none;
|
||||
}
|
||||
/* On hover, display the longer name. */
|
||||
.expanded:hover span.long{
|
||||
display:block;
|
||||
}
|
||||
<head>
|
||||
{% include 'parts/head.html' %}
|
||||
|
||||
</style>
|
||||
<style>
|
||||
/* Longer name hidden by default */
|
||||
span.long {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Detection time</th>
|
||||
<th>Source</th>
|
||||
<th>Diff</th>
|
||||
<th>Original</th>
|
||||
<th>Changed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for diff in diffs %}
|
||||
<tr>
|
||||
<td>{{ diff.diff_id }}</td>
|
||||
<td>{{ diff.diff_time }}</td>
|
||||
<td><a href='{{ diff.article_url }}' target="_blank">{{ diff.feed_name }}</a></td>
|
||||
<td>{{ diff.diff_html|safe }}</td>
|
||||
<td class="expanded">
|
||||
<span class="short">{{ diff.title_orig|truncate(15) }} </span>
|
||||
<span class="long">{{ diff.title_orig }} </span>
|
||||
</td>
|
||||
<td class="expanded">
|
||||
<span class="short">{{ diff.title_new|truncate(15) }} </span>
|
||||
<span class="long">{{ diff.title_new}} </span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ pagination.links }}
|
||||
/* On hover, hide the short name */
|
||||
.expanded:hover span.short {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* On hover, display the longer name. */
|
||||
.expanded:hover span.long {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Detection time</th>
|
||||
<th>Source</th>
|
||||
<th>Diff</th>
|
||||
<th>Original</th>
|
||||
<th>Changed</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for diff in diffs %}
|
||||
<tr>
|
||||
<td>{{ diff.diff_time }}</td>
|
||||
<td><a href='{{ diff.article_url }}' target="_blank">{{ diff.feed_name }}</a></td>
|
||||
<td>{{ diff.diff_html|safe }}</td>
|
||||
<td class="expanded">
|
||||
<span class="short">{{ diff.title_orig|truncate(15) }} </span>
|
||||
<span class="long">{{ diff.title_orig }} </span>
|
||||
</td>
|
||||
<td class="expanded">
|
||||
<span class="short">{{ diff.title_new|truncate(15) }} </span>
|
||||
<span class="long">{{ diff.title_new}} </span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
<div class="container text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{ pagination.links }}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{ pagination.info }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include 'parts/footer.html' %}
|
||||
</body>
|
||||
|
||||
</html>
|
6
view/templates/parts/footer.html
Normal file
6
view/templates/parts/footer.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<footer class="footer mt-auto py-3 bg-light">
|
||||
<div class="container">
|
||||
<span class="text-muted"> <a href="{{ url_for('index') }}">Headliner</a> | <a
|
||||
href="{{ url_for('feed_list') }}">Feed list</a> | <a href="{{ url_for('about') }}">About</a></span>
|
||||
</div>
|
||||
</footer>
|
6
view/templates/parts/head.html
Normal file
6
view/templates/parts/head.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Headliner</title>
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
Loading…
Reference in a new issue