2ch statistic page has been fixed and improved.

This commit is contained in:
AB
2018-10-31 01:42:02 +03:00
parent a92daa87ac
commit e6be431049
6 changed files with 272 additions and 231 deletions

View File

@@ -1,7 +1,9 @@
import datetime import datetime
import logging import logging
import os
import requests import requests
import time
from flask import Flask, request, send_from_directory from flask import Flask, request, send_from_directory
from flask import render_template from flask import render_template
@@ -35,7 +37,7 @@ def serve_static(path):
return send_from_directory('static', path) return send_from_directory('static', path)
@app.route('/') @app.route('/', methods=['GET', 'POST'])
def index(): def index():
order = request.args.get('order', default='id', type=str) order = request.args.get('order', default='id', type=str)
sorting = request.args.get('sorting', default='ASC', type=str) sorting = request.args.get('sorting', default='ASC', type=str)
@@ -136,6 +138,7 @@ def stat():
sorting=sorting, sorting=sorting,
posts=posts, posts=posts,
threads=sorted_threads, threads=sorted_threads,
now=datetime.datetime.now().strftime('%s'),
) )
@@ -143,5 +146,46 @@ def main():
app.run(host=flask_host, port=flask_port) app.run(host=flask_host, port=flask_port)
@app.template_filter('datetimeformat')
def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
return datetime.datetime.fromtimestamp(value).strftime(format)
@app.template_filter('readable_delta')
def readable_delta(from_seconds, until_seconds=None):
# Returns a nice readable delta.
def plur(it):
try:
size = len(it)
except TypeError:
size = int(it)
return '' if size == 1 else 's'
if not until_seconds:
until_seconds = time.time()
seconds = int(until_seconds) - int(from_seconds)
delta = datetime.timedelta(seconds=seconds)
delta_minutes = delta.seconds // 60
delta_hours = delta_minutes // 60
if delta.days:
return '%d day%s, %d hour%s' % (
delta.days,
plur(delta.days),
(delta_hours),
plur(delta_hours))
elif delta_hours:
return '%d hour%s, %d minute%s' % (
delta_hours,
plur(delta_hours),
(delta_minutes - delta_hours * 60),
plur(delta_minutes))
elif delta_minutes:
return '%d minute%s' % (delta_minutes, plur(delta_minutes))
else:
return '%d second%s' % (delta.seconds, plur(delta.seconds))
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@@ -1,31 +1,30 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
{% block head %} {% block head %}
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS --> <!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous"> crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="../static/css/style.css"> <link rel="stylesheet" type="text/css" href="../static/css/style.css">
<title>libOpenAnal appliance</title> <title>libOpenAnal appliance</title>
{% endblock %} {% endblock %}
</head> </head>
<body> <body>
<div class="container" id="content">{% block content %} <div class="container" id="content">{% block content %}
<h1>Hexor's conf_bot data extractor tool</h1>{% endblock %}</div> <h1>Hexor's conf_bot data extractor tool</h1>{% endblock %}</div>
{% block scripts %} {% block scripts %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View File

@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ super() }} {{ super() }}
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/">Users</a> <a class="nav-link" href="/">Users</a>
</li> </li>
@@ -17,20 +17,19 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a> <a class="nav-link disabled" href="#">Disabled</a>
</li> </li>
</ul> </ul>
<br> <br>
<div class="row">
<div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<h4>Totals</h4> <h4>Summary</h4>
<b>Users: </b> {{ totals.users[0] }}<br> <b>Users: </b> {{ totals.users[0] }}<br>
<b>Unique words: </b> {{ totals.words[0] }}<br> <b>Unique words: </b> {{ totals.words[0] }}<br>
<b>Words said: </b> {{ totals.relations[0] }}<br> <b>Words said: </b> {{ totals.relations[0] }}<br>
<b>Chats fetched: </b> {{ totals.confs[0] }}<br> <b>Chats fetched: </b> {{ totals.confs[0] }}<br>
</div> </div>
</div> </div>
<table class="table table-hover table-sm"> <table class="table table-hover table-sm">
<thead> <thead>
<tr> <tr>
<th scope="col">#</th> <th scope="col">#</th>
@@ -53,8 +52,8 @@
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}

View File

@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ super() }} {{ super() }}
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" href="/">Users</a> <a class="nav-link active" href="/">Users</a>
</li> </li>
@@ -17,41 +17,35 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a> <a class="nav-link disabled" href="#">Disabled</a>
</li> </li>
</ul> </ul>
<br> <br>
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<h4>Totals</h4> <h4>Summary</h4>
<b>Users: </b> {{ totals.users[0] }}<br> <b>Users: </b> {{ totals.users[0] }}<br>
<b>Unique words: </b> {{ totals.words[0] }}<br> <b>Unique words: </b> {{ totals.words[0] }}<br>
<b>Words said: </b> {{ totals.relations[0] }}<br> <b>Words said: </b> {{ totals.relations[0] }}<br>
<b>Chats fetched: </b> {{ totals.confs[0] }}<br> <b>Chats fetched: </b> {{ totals.confs[0] }}<br>
</div> </div>
</div> </div>
<br> <br>
<table class="table table-hover table-sm"> <table class="table table-hover table-sm">
<thead> <thead>
<tr> <tr>
<th scope="col">#</th> <th scope="col">#</th>
<th scope="col"><a <th scope="col"><a href="./?order=first_name&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">First
href="./?order=first_name&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">First
name</a></th> name</a></th>
<th scope="col"><a <th scope="col"><a href="./?order=last_name&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Last
href="./?order=last_name&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Last
name</a></th> name</a></th>
<th scope="col"><a <th scope="col"><a href="./?order=username&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Username</a>
href="./?order=username&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Username</a>
</th> </th>
<th scope="col"><a href="./?order=id&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">User <th scope="col"><a href="./?order=id&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">User
ID</a></th> ID</a></th>
<th scope="col"><a <th scope="col"><a href="./?order=firstly_seen&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Firstly
href="./?order=firstly_seen&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Firstly
seen</a></th> seen</a></th>
<th scope="col"><a <th scope="col"><a href="./?order=last_activity&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Last
href="./?order=last_activity&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Last
activity</a></th> activity</a></th>
<th scope="col"><a <th scope="col"><a href="./?order=count&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Word
href="./?order=count&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Word
count</a></th> count</a></th>
</tr> </tr>
</thead> </thead>
@@ -71,8 +65,8 @@
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}

View File

@@ -1,10 +1,10 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ super() }} {{ super() }}
<ul class="nav nav-pills"> <ul class="nav nav-pills">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/">Users</a> <a class="nav-link" href="/">Users</a>
</li> </li>
@@ -17,45 +17,47 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a> <a class="nav-link disabled" href="#">Disabled</a>
</li> </li>
</ul> </ul>
<br> <br>
<form action="/" method="get"> <div class="row">
<div class="col-sm-12">
<h4>Summary</h4>
<b>Board: </b> {{ board }}<br>
<b>Threads: </b> {{ threads|length }}<br>
<b>Total posts: </b> {{ posts }}<br>
</div>
</div>
<hr>
<div class="container">
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4 offset-md-4">
<form action="/stat" method="get">
<div class="input-group mb-3"> <div class="input-group mb-3">
<input type="text" class="form-control" placeholder="Board" aria-label="Board" <input type="text" class="form-control" placeholder="Board" aria-label="Board" aria-describedby="button-stat"
aria-describedby="button-stat" name="board"> name="board">
<div class="input-group-append"> <div class="input-group-append">
<button class="btn btn-primary" type="submit" id="button-stat">Get stat</button> <button class="btn btn-primary" type="submit" id="button-stat">Get stat</button>
</div> </div>
</div> </div>
</form> </form>
<div class="row">
<div class="col-sm-12">
<h4>Info</h4>
<b>Board: </b> {{ board }}<br>
<b>Threads: </b> {{ threads|length }}<br>
<b>Total posts: </b> {{ posts }}<br>
</div> </div>
</div> </div>
<br> </div>
<table class="table table-hover table-sm"> <br>
<table class="table table-hover table-sm">
<thead> <thead>
<tr> <tr>
<th scope="col">#</th> <th scope="col">#</th>
<th scope="col">Subject</th> <th scope="col">Subject</th>
<th scope="col"><a <th scope="col"><a href="./stat?board={{ board }}&order=posts&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Posts</a>
href="./stat?board={{ board }}&order=posts&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Posts</a>
</th> </th>
<th scope="col"><a <th scope="col"><a href="./stat?board={{ board }}&order=views&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Views</a>
href="./stat?board={{ board }}&order=views&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Views</a>
</th> </th>
<th scope="col"><a <th scope="col"><a href="./stat?board={{ board }}&order=score&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Score</a>
href="./stat?board={{ board }}&order=score&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Score</a>
</th> </th>
<th scope="col"><a <th scope="col"><a href="./stat?board={{ board }}&order=lasthit&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Lasthit</a>
href="./stat?board={{ board }}&order=timestamp&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Created</a> <th scope="col"><a href="./stat?board={{ board }}&order=timestamp&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Age</a>
</th>
<th scope="col"><a
href="./stat?board={{ board }}&order=lasthit&sorting={%- if sorting == 'ASC' -%}DESC{%- else -%}ASC{%- endif -%}">Lasthit</a>
</th> </th>
</tr> </tr>
</thead> </thead>
@@ -63,17 +65,20 @@
{% for thread in threads %} {% for thread in threads %}
<tr> <tr>
<th scope="row">{{ loop.index }}</th> <th scope="row">{{ loop.index }}</th>
<td><a href="https://2ch.hk/b/res/{{ thread['num'] }}.html">{{ thread['subject'] }}</a></td> <td><a href="https://2ch.hk/{{board}}/res/{{ thread['num'] }}.html">{{ thread['subject'] }}</a></td>
<td>{{ thread['posts_count'] }}</td> <td>{{ thread['posts_count'] }}</td>
<td>{{ thread['views'] }}</td> <td>{{ thread['views'] }}</td>
<td>{{ "%.2f"|format(thread['score']|float) }}</td> <td>{{ "%.2f"|format(thread['score']|float) }}</td>
<td>{{ thread['timestamp'] | time }}</td> <td data-toggle="tooltip" data-placement="right" title="Last hit: {{ thread['lasthit']|time }}">{{thread['lasthit']|readable_delta(now)}}
<td>{{ thread['lasthit'] | time }}</td> ago
</td>
<td data-toggle="tooltip" data-placement="right" title="Created: {{ thread['timestamp']|time }}">{{thread['timestamp']|readable_delta(thread['lasthit'])}}</td>
<td></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}

View File

@@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{{ super() }} {{ super() }}
@@ -73,8 +73,8 @@
<td>{{ word[0] }}</td> <td>{{ word[0] }}</td>
{% if not loop.last %} {% if not loop.last %}
{% if (word[1]/loop.nextitem[1]) > 2 %} {% if (word[1]/loop.nextitem[1]) > 2 %}
<td><span class="badge badge-danger" data-toggle="tooltip" data-placement="right" <td><span class="badge badge-danger" data-toggle="tooltip" data-placement="right" title="Must have been abused">{{
title="Must have been abused">{{ word[1] }} </span></td> word[1] }} </span></td>
{% else %} {% else %}
<td><span class="badge badge-secondary">{{ word[1] }} </span></td> <td><span class="badge badge-secondary">{{ word[1] }} </span></td>
{% endif %} {% endif %}