Skip to content

Commit fa49117

Browse files
committed
synchro
1 parent f216a52 commit fa49117

File tree

3 files changed

+189
-86
lines changed

3 files changed

+189
-86
lines changed

src/documents/templates/documents/base.html

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
{% load static %}
44
{% load documents %}
55
{% load alerts %}
6-
<!DOCTYPE html>
76
<html>
87
<head lang="{{ LANGUAGE_CODE }}">
98
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

src/documents/templates/documents/synchro.html

+133-36
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,144 @@
33

44
{% block content %}
55

6-
<div class="row mb-4">
7-
<div class="col-4">
8-
</div>
9-
<div class="col-8">
10-
{% if not length_ok %}
11-
<div class="alert alert-warning">
12-
Liczba znalezionych części dokumentu nie zgadza się z liczbą części audiobooka.
13-
Konieczna jest korekta za pomocą atrybutów <code>forcesplit</code> i <code>nosplit</code>.
14-
</div>
15-
{% else %}
16-
<form method="post" action="">
17-
{% csrf_token %}
18-
<button class="btn btn-primary">
19-
Zaplanuj synchronizację
20-
</button>
21-
</form>
22-
{% endif %}
23-
24-
</div>
25-
</div>
26-
27-
<table class="table">
6+
<h1>Wskazówki synchronizacji dla: <a href="{{ book.get_absolute_url }}">{{ book.title }}</a></h1>
7+
8+
9+
<table class="table" id="sync-table">
2810
<thead>
2911
<tr>
12+
<th></th>
3013
<th>Nagłówek cięcia</th>
3114
<th>Audiobook</th>
3215
</tr>
3316
</thead>
34-
{% for h, m in table %}
35-
<tr>
36-
<td>
37-
{% if h %}
38-
<a target="_blank" href="{% url 'wiki_editor' book.slug %}#CodeMirrorPerspective">
39-
{{ h.0 }} (linia {{ h.2 }})
40-
</a>
41-
{% else %}
42-
43-
{% endif %}
44-
</td>
45-
<td>{{ m|default_if_none:'—' }}</td>
46-
</tr>
47-
{% endfor %}
17+
<tbody>
18+
</tbody>
4819
</table>
20+
21+
22+
<form method="post" action="">
23+
{% csrf_token %}
24+
<input type="hidden" name="hints" id="hints">
25+
<button class="btn btn-primary">
26+
Zapisz wskazówki
27+
</button>
28+
</form>
29+
30+
{% endblock %}
31+
32+
33+
{% block add_js %}
34+
<script type="text/javascript">
35+
$(function() {
36+
37+
let hints = {{ hints|safe }};
38+
let mp3 = {{ mp3|safe }};
39+
let headers = {{ headers|safe }};
40+
let headers_other = {{ headers_other|safe }};
41+
42+
let table = $("#sync-table tbody");
43+
44+
function showTable() {
45+
$("#hints").val(JSON.stringify(hints));
46+
47+
let mI = 0;
48+
let hI = 0;
49+
let row = 0;
50+
let hint;
51+
table.empty();
52+
while (mI < mp3.length || hI < headers.length) {
53+
let tr = $("<tr>");
54+
55+
if (row < hints.length) {
56+
hint = hints[row];
57+
} else {
58+
hint = [];
59+
}
60+
tr.data('hint', hint);
61+
62+
let td = $("<td>");
63+
if (headers_other.length) {
64+
td.append(
65+
$('<button class="btn btn-primary mr-1">').text('+').click(function() {
66+
hintAdd(tr);
67+
})
68+
);
69+
}
70+
td.append(
71+
$('<button class="btn btn-primary">').text('-').click(function() {
72+
hintRm(tr);
73+
})
74+
);
75+
td.appendTo(tr);
76+
if (hint[0] == '+') {
77+
tr.addClass('hit-add');
78+
// select?
79+
let sel = $("<select>");
80+
sel.append($("<option>").text('wybierz'));
81+
$.each(headers_other, (i, e) => {
82+
let opt = $("<option>").text(
83+
e[1] + ' (' + e[0] + ')'
84+
).val(i);
85+
if (i == hint[1]) {
86+
opt.attr('selected', 'selected')
87+
}
88+
sel.append(opt)
89+
});
90+
sel.change(function() {
91+
tr.data('hint', ['+', $(this).val()]);
92+
refreshTable();
93+
});
94+
95+
$("<td>").append(sel).appendTo(tr);
96+
} else {
97+
let td = $("<td>").text(headers[hI][1]).appendTo(tr);
98+
if (hint[0] == '-') {
99+
tr.addClass('text-muted');
100+
}
101+
hI ++;
102+
}
103+
104+
if (hint[0] == '-') {
105+
$("<td>").appendTo(tr);
106+
} else {
107+
$("<td>").text(mp3[mI]).appendTo(tr);
108+
mI ++;
109+
}
110+
table.append(tr);
111+
row ++;
112+
}
113+
}
114+
115+
showTable();
116+
117+
function refreshTable() {
118+
hints = [];
119+
$("tr", table).each((i, e) => {
120+
hint = $(e).data('hint')
121+
if (hint !== null) {
122+
hints.push(hint)
123+
}
124+
});
125+
showTable();
126+
}
127+
128+
function hintAdd(tr) {
129+
$("<tr>").data('hint', ['+']).insertBefore(tr);
130+
refreshTable();
131+
}
132+
function hintRm(tr) {
133+
let $tr = $(tr);
134+
let hint = $tr.data('hint');
135+
if (hint[0] == '+') {
136+
$tr.data('hint', null)
137+
} else if (hint[0] == '-') {
138+
$tr.data('hint', [])
139+
} else {
140+
$tr.data('hint', ['-'])
141+
}
142+
refreshTable();
143+
}
144+
});
145+
</script>
49146
{% endblock %}

src/documents/views.py

+56-49
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from copy import deepcopy
66
from datetime import datetime, date, timedelta
77
from itertools import zip_longest
8+
import json
89
import logging
910
import os
1011
from urllib.parse import quote_plus, unquote, urlsplit, urlunsplit
@@ -25,6 +26,7 @@
2526
from django.views.decorators.http import require_POST
2627
from django_cas_ng.decorators import user_passes_test
2728
import requests
29+
from lxml import etree
2830

2931
from librarian import epubcheck
3032
from librarian.html import raw_printable_text
@@ -770,14 +772,29 @@ def mark_final_completed(request):
770772
return render(request, 'documents/mark_final_completed.html')
771773

772774

775+
@login_required
773776
def synchro(request, slug):
774777
book = get_object_or_404(Book, slug=slug)
775778
if not book.accessible(request):
776779
return HttpResponseForbidden("Not authorized.")
777780

778-
document = book.wldocument(librarian2=True)
781+
if request.method == 'POST':
782+
#hints = json.loads(request.POST.get('hints'))
783+
chunk = book[0]
784+
tree = etree.fromstring(chunk.head.materialize())
785+
m = tree.find('.//meta[@id="synchro"]')
786+
if m is None:
787+
rdf = tree.find('.//{http://www.w3.org/1999/02/22-rdf-syntax-ns#}Description')
788+
m = etree.SubElement(rdf, 'meta', id="synchro")
789+
m.tail = '\n'
790+
m.text = request.POST.get('hints')
791+
text = etree.tostring(tree, encoding='unicode')
792+
chunk.commit(text, author=request.user, description='Synchronizacja')
793+
return HttpResponseRedirect('')
794+
795+
document = book.wldocument(librarian2=True, publishable=False)
796+
779797
slug = document.meta.url.slug
780-
print(f'https://audio.wolnelektury.pl/archive/book/{slug}.json')
781798
error = None
782799
try:
783800
items = requests.get(f'https://audio.wolnelektury.pl/archive/book/{slug}.json').json()['items']
@@ -792,59 +809,49 @@ def synchro(request, slug):
792809
split_on = (
793810
'naglowek_rozdzial',
794811
'naglowek_scena',
795-
)
796-
797-
if split_on:
798-
documents = []
799-
headers = [('Początek', 0, 0)]
800-
present = True
801-
n = 0
802-
while present:
803-
present = False
804-
n += 1
805-
newdoc = deepcopy(document)
806-
newdoc.tree.getroot().document = newdoc
807-
808-
master = newdoc.tree.getroot()[-1]
809-
i = 0
810-
for item in list(master):
811-
#chunkno, sourceline = 0, self.sourceline
812-
#if builder.splits:
813-
# chunkno, sourceline = len(builder.splits), sourceline - builder.splits[-1]
814-
815-
if 'forcesplit' in item.attrib or (item.tag in split_on and 'nosplit' not in item.attrib):
816-
# TODO: clear
817-
i += 1
818-
if n > 1 and i == n:
819-
headers.append((
820-
raw_printable_text(item),
821-
0,
822-
item.sourceline,
823-
))
824-
if i != n and not (n == 1 and not i):
825-
master.remove(item)
826-
else:
827-
present = True
828-
if present:
829-
documents.append(newdoc)
830-
else:
831-
documents = [document]
832-
headers = [(
833-
document.meta.title, 0 ,0
834-
)]
835-
836-
length_ok = len(headers) == len(mp3)
837-
table = zip_longest(headers, mp3)
838-
812+
)
813+
split_other = (
814+
'naglowek_czesc',
815+
'naglowek_akt',
816+
'naglowek_podrozdzial',
817+
'srodtytul',
818+
)
819+
820+
headers = []
821+
headers_other = []
822+
master = document.tree.getroot()[-1]
823+
for item in master:
824+
if item.tag in split_on:
825+
headers.append([
826+
item.tag,
827+
raw_printable_text(item),
828+
0,
829+
item.sourceline,
830+
])
831+
if item.tag in split_other:
832+
headers_other.append([
833+
item.tag,
834+
raw_printable_text(item),
835+
0,
836+
item.sourceline,
837+
])
838+
839+
hints = []
840+
m = document.tree.find('.//meta[@id="synchro"]')
841+
if m is not None:
842+
try:
843+
hints = json.loads(m.text)
844+
except:
845+
raise
846+
pass
839847

840848
return render(request, 'documents/synchro.html', {
841849
'book': book,
842-
'documents': documents,
843850
'headers': headers,
851+
'headers_other': headers_other,
844852
'mp3': mp3,
845-
'length_ok': length_ok,
846-
'table': table,
847853
'error': error,
854+
'hints': hints,
848855
})
849856

850857

0 commit comments

Comments
 (0)