mirror of https://github.com/CIRCL/lookyloo
Merge branch 'main' into restx
commit
1a9d409d90
|
@ -26,7 +26,16 @@ jobs:
|
|||
sudo apt install libfuzzy-dev
|
||||
python -m pip install --upgrade pip poetry
|
||||
poetry install
|
||||
echo LOOKYLOO_HOME="`pwd`" >> .env
|
||||
poetry run tools/3rdparty.py
|
||||
|
||||
- name: Make sure SRIs are up-to-date
|
||||
run: |
|
||||
poetry run tools/generate_sri.py
|
||||
git diff website/web/sri.txt
|
||||
git diff --quiet website/web/sri.txt
|
||||
|
||||
- name: Test with nosetests
|
||||
run: |
|
||||
poetry run mypy .
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from lookyloo.helpers import get_homedir
|
||||
|
||||
if __name__ == '__main__':
|
||||
dest_dir = get_homedir() / 'website' / 'web'
|
||||
|
||||
to_save: Dict = {'static': {}}
|
||||
|
||||
for resource in (dest_dir / 'static').glob('*'):
|
||||
with resource.open('rb') as f:
|
||||
to_save['static'][resource.name] = base64.b64encode(hashlib.sha512(f.read()).digest()).decode('utf-8')
|
||||
|
||||
with (dest_dir / 'sri.txt').open('w') as fw:
|
||||
json.dump(to_save, fw, indent=2, sort_keys=True)
|
|
@ -27,7 +27,7 @@ from lookyloo.lookyloo import Lookyloo, Indexing
|
|||
from lookyloo.exceptions import NoValidHarFile, MissingUUID
|
||||
|
||||
from .proxied import ReverseProxied
|
||||
from .helpers import src_request_ip, User, load_user_from_request, build_users_table, get_secret_key
|
||||
from .helpers import src_request_ip, User, load_user_from_request, build_users_table, get_secret_key, sri_load
|
||||
|
||||
app: Flask = Flask(__name__)
|
||||
app.wsgi_app = ReverseProxied(app.wsgi_app) # type: ignore
|
||||
|
@ -145,6 +145,14 @@ def month_name(month: int):
|
|||
app.jinja_env.globals.update(month_name=month_name)
|
||||
|
||||
|
||||
def get_sri(directory: str, filename: str) -> str:
|
||||
sha512 = sri_load()[directory][filename]
|
||||
return f'sha512-{sha512}'
|
||||
|
||||
|
||||
app.jinja_env.globals.update(get_sri=get_sri)
|
||||
|
||||
|
||||
# ##### Generic/configuration methods #####
|
||||
|
||||
@app.after_request
|
||||
|
@ -710,7 +718,7 @@ def rebuild_cache():
|
|||
lookyloo.rebuild_cache()
|
||||
return redirect(url_for('index'))
|
||||
|
||||
|
||||
|
||||
@app.route('/search', methods=['GET', 'POST'])
|
||||
def search():
|
||||
if request.form.get('url'):
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
|
||||
from functools import lru_cache
|
||||
|
@ -89,3 +90,9 @@ def get_secret_key() -> bytes:
|
|||
f.write(os.urandom(64))
|
||||
with secret_file_path.open('rb') as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
@lru_cache(64)
|
||||
def sri_load() -> Dict[str, Dict[str, str]]:
|
||||
with (get_homedir() / 'website' / 'web' / 'sri.txt').open() as f:
|
||||
return json.load(f)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"static": {
|
||||
"bomb.svg": "Tro3+kCLzfBNBve2gPnsmXsl+tHUQVrFz77zfrWwnAuTraehZaoAfVJgGOYdG8zceXdGLEKzXVi3GdtEXw0sYQ==",
|
||||
"capture.js": "XhWkFmPwm29Iyf034SS/OXZo+ulN2xo6S6AzdHh+hCBnmygO8dUzX1gsrW91utgxgsmHKjTzXPJCXsylNLw4uQ==",
|
||||
"check.svg": "CRqUAM/yXxgJwpfg3TeoKD+CIqQj62lxqS3zeCmdPaV3dKftk4jk5Mqc1TGxL7i61X1sgV0/f+KJLEOKTw01ww==",
|
||||
"cookie_in_url.png": "hs/oNPnrR2DkDX9Yp6Daug/QqpWJHemJE6lXpxNafjgOYooezp3DpbqKqADT7QcfcTxxUfe1iPDZJlHOrNMAcw==",
|
||||
"cookie_read.png": "mdXCeuNFPvshSwIXAJLoR1xFjXb+K2Mgu47Q1fnUAO8j1N2c/uJuE8sGuBHHbS8HOyr/CbOC6Uf3zsm9KvAs8Q==",
|
||||
"cookie_received.png": "EqL5fRFwjjXkSp242nacVFy7N8f1QAGJv4OIVDKQkDJQvq2MphwUnfLZUQvN3NMayHS/VTGQbgdQVjcOSQ2blA==",
|
||||
"css.png": "XDfV8fW5XRQlHT20rZn3d6LdIp2Dzk+mnZlicBv61iJGFMENLSM4SDgRcGb+x927AlI3lb6qv2C6tJAR2nDl5g==",
|
||||
"d3.v6.min.js": "cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==",
|
||||
"datatables.min.css": "dOYeiy2DhF4m2T2kMXLZ90rwM8un/fAremwgfJO0Uvu7QPUSGOj0cYBDxLEqiVTpnqn2SNYvrhcxJFNnaGkQiw==",
|
||||
"datatables.min.js": "rk4slbQTq1rjbhE2imWdwAHK8N02au6UehXt1QyFMU8WAhxl280ibqn5o3raZ9eoqx+HbmOJ/MVMjbv5s9UFxg==",
|
||||
"down.jpg": "LHRHJ5yCaSjNcDfEoChGIfh7K5HrMYbaGn7EOlxgZ8GoLIwb0nFBkpoOMG9gMHA/pBX2skkXMukvKJC6P6FBGg==",
|
||||
"down_left.jpg": "UwHkJaZGayY1LewuFM3bJHQCUPG1vYyrVeiGG5mCM9MD9FtAhdbD4hBY3JZNDWv93CXeEAbxL1kqEeHTKnyquQ==",
|
||||
"empty.svg": "6tfMLNzDFV9P6t1rC2tDRQtOGzrxi/VtIBc8aV0jo4i3u+dn1fIe3/fySBFA6z13n+XjISF5bTRUNBsN3LWinQ==",
|
||||
"error_screenshot.png": "IkUKnQ47PYYreukA7Byvx+5ACkcCvqk+jYD0GZoQznsD9qDPWrKAMZxlIku7G3Re19vehIlYawep/THcV/ruTA==",
|
||||
"exe.png": "pWwo9nBLtEss/UJ173zHa6/RpySUyz/XMdNhWc6aRIvwwHMO6a+fLmu2K6TbvO3Jbg4VYL2Af4yhHPyhH3ZeTw==",
|
||||
"favicon.ico": "KOmrfwRbOQqhhwSeBkNpMRAxSVMmmLg+2kRMg9iSv7OWjE9spJc7x4MKB4AE/hi0knaV7UBVctAU6XZ7AC72ZA==",
|
||||
"font.png": "RwoQkj9dT9SLUL2F7cAA16Nat9t2hDb58eQlHF9ThUar829p0INUXG+5XuDaFOC8SsmCZK5vw2f+YAQ6mLC1Qw==",
|
||||
"generic.css": "y5crC022oxKIDs2Z2l3HSIwzmPtXNYd6N8ofJYgu1OsSAADO3qoZ1OZVrsdwn1e9wHK4Mvh6GpKoe+GcDzOmSQ==",
|
||||
"generic.js": "c/p+6Dk2kcwd9T9kf/IfoCX/ZU+VbtlUGYBo3qNSzwoUYC1soWwdIwM5rFxwxz9a1tORc/Wu0EFCPRw4ZwbqkQ==",
|
||||
"html.png": "T7pZrb8MMDsA/JV/51hu+TOglTqlxySuEVY0rpDjTuAEyhzk2v+W4kYrj7vX+Tp3n2d2lvVD08PwhCG62Yfbzg==",
|
||||
"ifr.png": "rI5YJypmz1QcULRf9UaOYSqV4tPUSxUdLAycoYzCwywt4Pw4eWzBg9SUr769VyIimoiIyJR+aNuoIA4p5WO2fQ==",
|
||||
"img.png": "bknBlmIfSb9qv9/lSaJ2idn2a8bDyvJ2pATj4oOpehRlCdXlWYOyb2jN3wV1QGHFoqyxNqOv5MfCpI0tbqkicg==",
|
||||
"index.css": "2hAsQwCClHQ7b6VthbKYIkUPam4Ef6wbSxa3+nK0UuqCHezvPMr3aqpz16gD0lyYop55VEd/dhzZJLA4WMAplQ==",
|
||||
"insecure.svg": "iyoot+eMuRI7SITBdjslYS2WWFntz9VGi0doPoZBi/ZGPGDhm/Sd8SaJPiNCSKht/6dYPqgb90LQJ6a4YrhcFA==",
|
||||
"javascript.png": "sQcLDBrB+fEEt3PPoOwFh0g/RVkhDNrhuBMo0WMzf9IKNnZusYx+J59k8HGkAHFGDbytDwe6Tq6LIVgg/B6nqw==",
|
||||
"json.png": "nE6ROpXE5iovHyd5oh8cnA4ozTa5bZjn1A6b+10b1Hb59O1NcMdcrv8Rqge3CAtSqJDKnrYbMChCT1j48yMwQw==",
|
||||
"loader.gif": "ZZKD5vLSKBWKeUpa2KI9qheUJ49iTI/UULmVU/AX28fBfH00K3lLc2v5pVJZ4qXG1BbB13LTXzRKKU35H2XfNg==",
|
||||
"lookyloo.jpeg": "i6wBj8CsIM5YAQLEMQfhs3CNOSKkErF8AMqqM6ZygSwCyQgv9CU8xt94veMZhM/ufBWoz7kAXmR+yywmxsTxug==",
|
||||
"redirect.png": "PAjzlPV97rEFvH55mG1ZC9wRl98be3yMeX/nENuFkJcds6/AXgSR2ig/QyPULgobSnNgiYieLVWY/oqsgeywrQ==",
|
||||
"secure.svg": "H8ni7t0d60nCJDVGuZpuxC+RBy/ipAjWT627D12HlZGg6LUmjSwPTQTUekm3UJupEP7TUkhXyq6WHc5gy7QBjg==",
|
||||
"stats.css": "/kY943FwWBTne4IIyf7iBROSfbGd82TeBicEXqKkRwawMVRIvM/Pk5MRa7okUyGIxaDjFQGmV/U1vy+PhN6Jbw==",
|
||||
"stats_graph.js": "0OEouA6NAxLG2wMd7D2vtGoMrXKna7My98Euc6ecyfdO4/6mIJS87vzISOS4zSZ8u4ehpa+p7E0nWhsXXE7H/Q==",
|
||||
"tree.css": "ma+WfBfjVZpKH9KDg+LayyBac2r95VgqG4jll75Xc1e0zwBXe2/ZxI6Y9AeGCNK5YvtcFNd6oH3c+2KxV8iT0A==",
|
||||
"tree.js": "JeCMrFdQDrSYAXaJZE/tCOnfusbQI68rzFhyo0ojBCHt2FAs/DDBdYwCpkFNZ7J+n05NpfbegrrKVqd06PCNXA==",
|
||||
"up.jpg": "d1ljZJ9f5JekyM6RLFFH2Ua44j6neiQBdUIXOenRTjGppQr3JaeglpQIH6BjPCJL177+TH52U3UIRNS5YAyKIg==",
|
||||
"up_right.jpg": "OMmz+n+MxR34P8/fn5t4DkqKqdJRzQbXQ7fAi2lhkZIJGhVs2vIyY1f2hpYoBxDAX1OcYsSE2lqIR2vXNDGZsA==",
|
||||
"video.png": "gJtmkfr8I1Kw43pYEKjg6CAjgmhl1vIBKBQ3ZkxCu3wvxQm+6kf93iLrrFiY2WuiXzxEn2Leu52GJzmVN5id0g==",
|
||||
"wtf.png": "5iUj4m5G3tJN3wQvR1jD/hF4OKFrboVeuFejd+6ZUvdll3zjkLeewJQ+zptO9ckzktsMPC2+bKM3zM3CXXWoCw=="
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 1, "desc" ]],
|
||||
|
@ -24,12 +23,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
<h4>{{ body_hash }}</h4>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 0, "desc" ]],
|
||||
|
@ -17,11 +16,6 @@
|
|||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
|
|
|
@ -150,5 +150,7 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='capture.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='capture.js') }}'
|
||||
integrity="{{get_sri('static', 'capture.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 1, "desc" ]],
|
||||
|
@ -16,12 +15,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table" style="width:96%">
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 1, "desc" ]],
|
||||
|
@ -22,12 +21,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
<h2>{{ cookie_name }}</h2>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 1, "desc" ]],
|
||||
|
@ -16,12 +15,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table" style="width:96%">
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 0, "desc" ]],
|
||||
|
@ -26,15 +25,8 @@
|
|||
window.opener.openTreeInNewTab(treeUUID);
|
||||
};
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
<h4>{{ url }}</h4>
|
||||
|
|
|
@ -11,15 +11,11 @@
|
|||
|
||||
{% block title %}Details for {{ hostnode.name }} {% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='generic.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='generic.js') }}'
|
||||
integrity="{{get_sri('static', 'generic.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(() => {
|
||||
$('table.table').DataTable( {
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('#table').DataTable( {
|
||||
|
@ -51,8 +50,9 @@ $(document).ready(function () {
|
|||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}"
|
||||
integrity="{{get_sri('static', 'index.css')}}"
|
||||
crossorigin="anonymous">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
|
|
@ -5,12 +5,19 @@
|
|||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"
|
||||
integrity="{{get_sri('static', 'favicon.ico')}}"
|
||||
crossorigin="anonymous">
|
||||
|
||||
{% block styles %}
|
||||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='generic.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='generic.css') }}"
|
||||
integrity="{{get_sri('static', 'generic.css')}}"
|
||||
crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}"
|
||||
integrity="{{get_sri('static', 'datatables.min.css')}}"
|
||||
crossorigin="anonymous">
|
||||
{% endblock %}
|
||||
|
||||
<title>{% block title %}{% endblock%}</title>
|
||||
|
@ -28,6 +35,9 @@
|
|||
{% block scripts %}
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'
|
||||
integrity="{{get_sri('static', 'datatables.min.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 2, "desc" ]],
|
||||
|
@ -26,12 +25,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<table id="table" class="table" style="width:96%">
|
||||
|
|
|
@ -61,5 +61,7 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='capture.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='capture.js') }}'
|
||||
integrity="{{get_sri('static', 'capture.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -79,5 +79,7 @@
|
|||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='stats.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='stats.css') }}"
|
||||
integrity="{{get_sri('static', 'stats.css')}}"
|
||||
crossorigin="anonymous">
|
||||
{% endblock %}
|
||||
|
|
|
@ -27,8 +27,12 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='d3.v6.min.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='tree.js') }}'></script>
|
||||
<script src='{{ url_for('static', filename='d3.v6.min.js') }}'
|
||||
integrity="{{get_sri('static', 'd3.v6.min.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src='{{ url_for('static', filename='tree.js') }}'
|
||||
integrity="{{get_sri('static', 'tree.js')}}"
|
||||
crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
$('#modulesModal').on('show.bs.modal', function(e) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='datatables.min.js') }}'></script>
|
||||
<script type="text/javascript">
|
||||
$('#table').DataTable( {
|
||||
"order": [[ 0, "desc" ]],
|
||||
|
@ -29,12 +28,6 @@
|
|||
|
||||
{% endblock %}
|
||||
|
||||
{% block styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='datatables.min.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
<h4>{{ url }}</h4>
|
||||
|
|
Loading…
Reference in New Issue