descartes load -- possibly all before show
This commit is contained in:
parent
56aab9e545
commit
696378ebe0
8
db/db.py
8
db/db.py
@ -132,9 +132,9 @@ class DB:
|
||||
try:
|
||||
cursor = self.db_con.cursor(buffered=True)
|
||||
if bool:
|
||||
cursor.execute(db.sql.CONTENT_QUERY_BOOLEAN.format(self.archive_name, term))
|
||||
cursor.execute(db.sql.CONTENT_QUERY_BOOLEAN.format(term))
|
||||
else:
|
||||
cursor.execute(db.sql.CONTENT_QUERY.format(self.archive_name, term))
|
||||
cursor.execute(db.sql.CONTENT_QUERY.format(term))
|
||||
|
||||
# nbr_, author_name_, to_, subject_, date_, url_
|
||||
results = []
|
||||
@ -157,9 +157,9 @@ class DB:
|
||||
try:
|
||||
cursor = self.db_con.cursor(buffered=True)
|
||||
if bool:
|
||||
cursor.execute(archive.sql.FROM_QUERY_BOOLEAN.format(self.archive_name, term))
|
||||
cursor.execute(db.sql.FROM_QUERY_BOOLEAN.format(term))
|
||||
else:
|
||||
cursor.execute(archive.sql.FROM_QUERY.format(self.archive_name, term))
|
||||
cursor.execute(db.sql.FROM_QUERY.format(term))
|
||||
|
||||
# print(cursor.rowcount)
|
||||
results = []
|
||||
|
||||
6955
index.html
Normal file
6955
index.html
Normal file
File diff suppressed because it is too large
Load Diff
12862
index/index.all
Normal file
12862
index/index.all
Normal file
File diff suppressed because it is too large
Load Diff
151
www/routes.py
151
www/routes.py
@ -4,6 +4,11 @@ import json, logging, os, glob
|
||||
from lxml import etree as et
|
||||
import config
|
||||
from collections import OrderedDict
|
||||
import db.db as db
|
||||
|
||||
'''
|
||||
UTILS
|
||||
'''
|
||||
|
||||
def list_all(d, ext):
|
||||
|
||||
@ -13,14 +18,6 @@ def list_all(d, ext):
|
||||
|
||||
return [os.path.basename(f) for f in glob.glob(os.path.join(d, "*." + ext))]
|
||||
|
||||
@app.route('/')
|
||||
def top():
|
||||
return render_template("index.html")
|
||||
|
||||
'''
|
||||
INDEX
|
||||
'''
|
||||
|
||||
def read_index(d, fn):
|
||||
fp = os.path.join(d, fn)
|
||||
if not os.path.isfile(fp):
|
||||
@ -31,6 +28,144 @@ def read_index(d, fn):
|
||||
|
||||
return index_data
|
||||
|
||||
'''
|
||||
ROOT
|
||||
'''
|
||||
|
||||
@app.route('/')
|
||||
def top():
|
||||
index = read_index(config.index['path'], config.index['all'])
|
||||
if index is not None:
|
||||
return render_template("index.html", index=index);
|
||||
else:
|
||||
return "Error no index...."
|
||||
|
||||
'''
|
||||
SAVE
|
||||
'''
|
||||
|
||||
@app.route('/save')
|
||||
def save():
|
||||
index = read_index(config.index['path'], config.index['all'])
|
||||
if index is not None:
|
||||
rendered = render_template("index.html", index=index);
|
||||
with open(os.path.join(config.deploy['path'], config.deploy['name']), 'w') as fp:
|
||||
fp.write(rendered)
|
||||
return rendered
|
||||
else:
|
||||
return "Error no index...."
|
||||
|
||||
'''
|
||||
SEARCH
|
||||
'''
|
||||
|
||||
def format_chapter_section(nbr):
|
||||
tok = nbr.split('.')
|
||||
return "Ch." + tok[0] + " §" + tok[1] + "." + tok[2]
|
||||
|
||||
def key_from_chapter_section(str):
|
||||
tok = str.replace("Ch.", "").replace(" §", ".")
|
||||
if '-' in tok:
|
||||
tok = tok.split('-')[0]
|
||||
return tuple([int(j) for j in tok.split('.')])
|
||||
|
||||
def add_term_index(term, refs):
|
||||
|
||||
index = read_index(config.index['path'], config.index['all'])
|
||||
if index is None:
|
||||
logging.error("No index.all...")
|
||||
return False
|
||||
|
||||
if term in index:
|
||||
logging.warning("Term: " + term + " is already indexed... skipping add")
|
||||
return True
|
||||
|
||||
refs = sorted(refs, key=lambda x: key_from_chapter_section(x['nbr']))
|
||||
index[term] = refs
|
||||
|
||||
index = OrderedDict(sorted(index.items(), key=lambda x: x[0].lower()))
|
||||
|
||||
with open(os.path.join(config.index['path'], config.index['all']), 'w') as fout:
|
||||
json.dump(index, fout, indent=4, ensure_ascii=False)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@app.route('/search', methods = ['GET', 'POST'])
|
||||
def search():
|
||||
if request.method == 'GET':
|
||||
|
||||
data = request.values
|
||||
if len(data) == 0:
|
||||
index = read_index(config.index['path'], config.index['all'])
|
||||
if index is not None:
|
||||
return render_template("search.html", index=index);
|
||||
else:
|
||||
return "Error no index...."
|
||||
else:
|
||||
a = data.get('action')
|
||||
if a == "search":
|
||||
k_arg = request.args.get('keyword')
|
||||
f_arg = request.args.get('field')
|
||||
|
||||
print(k_arg)
|
||||
print(f_arg)
|
||||
|
||||
with db.DB(config.list_server_busy_db) as dba:
|
||||
|
||||
if f_arg == 'content':
|
||||
res = dba.content_search(k_arg)
|
||||
else:
|
||||
res = dba.from_search(k_arg)
|
||||
|
||||
print(res)
|
||||
|
||||
# format data to return
|
||||
search_results = { "keyword": k_arg, "field": f_arg, "results": [] }
|
||||
for r in res:
|
||||
# {'nbr': nbr_, 'from': author_name_, 'to': to_, 'subject': subject_, 'date': date_, 'url': url_}
|
||||
search_results['results'].append({'nbr': format_chapter_section(r['nbr']), 'url': r['url'] if r['url'] != 'n/a' else ''})
|
||||
|
||||
# sort?
|
||||
search_results['results'] = sorted(search_results['results'], key=lambda x: key_from_chapter_section(x['nbr']))
|
||||
return jsonify(search_results)
|
||||
else:
|
||||
return "-"
|
||||
|
||||
elif request.method == 'POST':
|
||||
|
||||
data = request.json
|
||||
a = data.get('action')
|
||||
|
||||
if a == "add":
|
||||
term = data['term']
|
||||
refs = data['refs']
|
||||
if add_term_index(term, refs):
|
||||
return 'ok'
|
||||
|
||||
return "-"
|
||||
|
||||
@app.route('/save_to_index', methods = ['POST'])
|
||||
def save_to_index():
|
||||
if request.method == 'POST':
|
||||
k_arg = request.args.get('keyword')
|
||||
f_arg = request.args.get('field')
|
||||
|
||||
with db.DB(config.list_server_busy_db) as dba:
|
||||
|
||||
if f_arg == 'content':
|
||||
res = dba.content_search(k_arg)
|
||||
else:
|
||||
res = dba.from_search(k_arg)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
INDEX
|
||||
'''
|
||||
|
||||
|
||||
def modify_selected_kw_index(d, fn, kw, action="add"):
|
||||
fp = os.path.join(d, fn)
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
font-family: 'Cormorant Garamond';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.eot'); /* IE9 Compat Modes */
|
||||
src: local('Cormorant Garamond Regular'), local('CormorantGaramond-Regular'),
|
||||
url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('http://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.svg#CormorantGaramond') format('svg'); /* Legacy iOS */
|
||||
url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
||||
url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('https://full-digest-rescheduled.info/fonts/cormorant-garamond-v7-latin/cormorant-garamond-v7-latin-regular.svg#CormorantGaramond') format('svg'); /* Legacy iOS */
|
||||
}
|
||||
@ -1,4 +1,47 @@
|
||||
.cor_large {
|
||||
.title {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
font-size: 1500%;
|
||||
font-size: 650%;
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
.cor {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
}
|
||||
|
||||
term {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
padding-right: 0.5em;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
ref {
|
||||
font-family: 'Cormorant Garamond', serif;
|
||||
padding-right: 0.2em;
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
.keyword-index {
|
||||
text-indent: -2em;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
#index {
|
||||
margin-left: 2em;
|
||||
margin-right: 2em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-family: Courier;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#footer br {
|
||||
display: block;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
|
||||
70
www/static/search.js
Normal file
70
www/static/search.js
Normal file
@ -0,0 +1,70 @@
|
||||
$(document).ready(function(){
|
||||
$('#loading').hide()
|
||||
|
||||
$('#info').click( function() {
|
||||
console.log("click");
|
||||
$('#info-search').toggle();
|
||||
});
|
||||
|
||||
$('#search').submit(function(e) {
|
||||
e.preventDefault();
|
||||
args = $(this).serialize();
|
||||
$('#results').empty();
|
||||
// console.log('/search?'+ args)
|
||||
$('#loading').show()
|
||||
$.get('/search?'+ args + '&action=search', function(data) {
|
||||
$('#loading').hide()
|
||||
console.log(data);
|
||||
var term = data.keyword.replace(/['"]+/g, '');
|
||||
var id_str = term.replace(/\s/g, "").replace(/\*/g, "");
|
||||
console.log(id_str)
|
||||
$('<div/>', {
|
||||
id: id_str,
|
||||
class: "keyword-index",
|
||||
}).appendTo('#results');
|
||||
$('#' + id_str).prepend('<term>' + term + '</term>');
|
||||
$.each(data.results, function(i, item) {
|
||||
let end = (i == data.results.length - 1 ? "" : ", ")
|
||||
if (item.url != '') {
|
||||
$('#' + id_str).append('<ref data-url="' + item.url + '" data-nbr="' + item.nbr + '"><a href="' + item.url + '">' + item.nbr + '</a></ref>' + end);
|
||||
} else {
|
||||
$('#' + id_str).append('<ref data-url="' + item.url + '" data-nbr="' + item.nbr + '">' + item.nbr + '</ref>' + end );
|
||||
}
|
||||
});
|
||||
$('#' + id_str).append('<button class="add">+</button>');
|
||||
$('.add').click(function(e) {
|
||||
var indx = $(this).parent(".keyword-index");
|
||||
|
||||
var term = indx.children("term")[0];
|
||||
var term_out = $(term).text();
|
||||
|
||||
var refs_out = []
|
||||
var refs = indx.children("ref").each( function() {
|
||||
let url = $(this).data('url');
|
||||
let nbr = $(this).data('nbr');
|
||||
if (url == "") url = "n/a";
|
||||
refs_out.push({'url': url, 'nbr': nbr});
|
||||
});
|
||||
|
||||
$.ajax ({
|
||||
type: "POST",
|
||||
contentType: 'application/json',
|
||||
url: '/search',
|
||||
data: JSON.stringify({'action': 'add', 'term': term_out, 'refs': refs_out}),
|
||||
success: function (d) {
|
||||
if(d === 'ok') {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// $.post('/search', {'action': 'add', 'term': term_out, 'refs': refs_out}, function(d) {
|
||||
// if(d === 'ok') {
|
||||
// location.reload();
|
||||
// }
|
||||
// });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@ -6,6 +6,31 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static',filename='lestyle.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<div class="cor_large">List server busy.<br>Full digest rescheduled.</div>
|
||||
<div class="title">List server busy.<br>Full digest rescheduled.</div>
|
||||
<hr>
|
||||
<hr>
|
||||
<hr>
|
||||
<div id="index">
|
||||
<h1>Index</h1>
|
||||
<br>
|
||||
{% for term, refs in index.items() %}
|
||||
<div class="keyword-index">
|
||||
<term>{{term}}</term>
|
||||
{% for r in refs %}
|
||||
<ref>{% if r.url != 'n/a' %}<a href="{{r.url}}">{{r.nbr}}</a>{% else %}{{r.nbr}}{% endif %}</ref>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<hr>
|
||||
<hr>
|
||||
<hr>
|
||||
<div id="footer">
|
||||
List server busy. Full digest rescheduled.<br>
|
||||
A compendium of listserv discussions & divagations 1995-2019<br>
|
||||
Assembled by <a href="http://le-club-des-sans-sujets.org">David Gauthier (Le Club des Sans Sujets)</a><br>
|
||||
Produced in collaboration with <a href="http://torquetorque.net">Torque</a>
|
||||
</div>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
@ -3,7 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<title>{{fn}}</title>
|
||||
<script type="text/javascript" src="{{ url_for('static',filename='jquery-3.2.1.min.js') }}" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static',filename='indx.js') }}"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{fn}}</h1>
|
||||
@ -24,5 +24,6 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<script type="text/javascript" src="{{ url_for('static',filename='indx.js') }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
59
www/templates/search.html
Normal file
59
www/templates/search.html
Normal file
@ -0,0 +1,59 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>List server busy. Full digest rescheduled.</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static',filename='fonts.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static',filename='lestyle.css') }}">
|
||||
<script type="text/javascript" src="{{ url_for('static',filename='jquery-3.2.1.min.js') }}" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static',filename='search.js') }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1><div class="cor">List server busy. Full digest rescheduled.</div></h1>
|
||||
<form action="/search" method="get" id="search">
|
||||
<label>keyword: </label><input type="search" name="keyword">
|
||||
<select form="search" name="field">
|
||||
<option value="content">content</option>
|
||||
<option value="from">from</option>
|
||||
</select>
|
||||
<input type="submit" value="search" id="submit">
|
||||
<input type="button" value=" ? " id="info">
|
||||
<div id="loading">Loading...</div>
|
||||
</form>
|
||||
<div id="info-search" style="display: none">
|
||||
<table><tbody><tr><th>Operator</th><th> </th></tr>
|
||||
<tr><td>+</td><td>The word is mandatory in all text returned.</td></tr>
|
||||
<tr><td>-</td><td>The word cannot appear in any text returned.</td></tr>
|
||||
<tr><td><</td><td>The word that follows has a lower relevance than other words, although text containing it will still match</td></tr>
|
||||
<tr><td>></td><td>The word that follows has a higher relevance than other words.</td></tr>
|
||||
<tr><td>()</td><td>Used to group words into subexpressions.</td></tr>
|
||||
<tr><td>~</td><td>The word following contributes negatively to the relevance of the text (which is different to the '-' operator, which specifically excludes the word, or the '<' operator, which still causes the word to contribute positively to the relevance of the text.</td></tr>
|
||||
<tr><td>*</td><td>The wildcard, indicating zero or more characters. It can only appear at the end of a word.</td></tr>
|
||||
<tr><td>"</td><td>Anything enclosed in the double quotes is taken as a whole (so you can match phrases, for example).</td></tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
<div id="results"></div>
|
||||
<hr>
|
||||
<hr>
|
||||
<hr>
|
||||
<div id="index">
|
||||
{% for term, refs in index.items() %}
|
||||
<div class="keyword-index">
|
||||
<term>{{term}}</term>
|
||||
{% for r in refs %}
|
||||
<ref>{% if r.url != 'n/a' %}<a href="{{r.url}}">{{r.nbr}}</a>{% else %}{{r.nbr}}{% endif %}</ref>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<hr>
|
||||
<hr>
|
||||
<hr>
|
||||
<div id="footer">
|
||||
List server busy. Full digest rescheduled.<br>
|
||||
A compendium of listserv discussions & divagations 1995-2019<br>
|
||||
Assembled by <a href="http://le-club-des-sans-sujets.org">David Gauthier (Le Club des Sans Sujets)</a><br>
|
||||
Produced in collaboration with <a href="http://torquetorque.net">Torque</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1212,7 +1212,7 @@ alexei shulgin</content>
|
||||
<subject>RE: nettime: Art on Net</subject>
|
||||
<from>Olia Lialina</from>
|
||||
<to>nettime-l@desk.nl</to>
|
||||
<date>Thu, 13 Mar 1997 16:25:39 +-300</date>
|
||||
<date>Thu, 13 Mar 1997 16:25:39</date>
|
||||
<content>
|
||||
I.
|
||||
David,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user