Spaces:
Running
Running
export-only: merge-compatible filenames, no sync UI
Browse files- review.html +3 -43
review.html
CHANGED
|
@@ -70,9 +70,6 @@ footer .sp { flex: 1; }
|
|
| 70 |
<footer>
|
| 71 |
<span><kbd>←</kbd><kbd>→</kbd> prev/next mention · <kbd>k</kbd> keep · <kbd>d</kbd> drop · <kbd>space</kbd> skip · <kbd>[</kbd><kbd>]</kbd> slide · <kbd>-</kbd><kbd>+</kbd> size · <kbd>e</kbd> export</span>
|
| 72 |
<span class="sp"></span><span id="count"></span>
|
| 73 |
-
<input id="hubtok" type="password" placeholder="HF token" title="write token for data-use-annotations; only needed on static hosting without the bundled server"
|
| 74 |
-
style="font:inherit;color:var(--fg);background:var(--bg);border:1px solid var(--line);border-radius:8px;padding:8px 10px;max-width:130px">
|
| 75 |
-
<button id="hfBtn" onclick="hfLogin()" title="log in to push rulings to the Hub as yourself">log in with HF</button>
|
| 76 |
<button id="hubBtn" onclick="exp()">export</button>
|
| 77 |
</footer>
|
| 78 |
<script>
|
|
@@ -333,49 +330,12 @@ async function hubCommit(entry) {
|
|
| 333 |
return 'Hub';
|
| 334 |
} catch (e) { return 'this browser only (Hub sync failed)'; }
|
| 335 |
}
|
| 336 |
-
async function pushAll() {
|
| 337 |
-
// one read, merge every local ruling, one commit to your own file.
|
| 338 |
-
// use after pasting your token, or to retry anything saved locally only.
|
| 339 |
-
if (needName()) return;
|
| 340 |
-
const tok = ($('hubtok').value || '').trim() || SHAREDTOK || '';
|
| 341 |
-
if (!tok) { $('mine').textContent = 'push unavailable — no shared token configured'; return; }
|
| 342 |
-
const btn = $('pushBtn');
|
| 343 |
-
btn.disabled = true;
|
| 344 |
-
try {
|
| 345 |
-
const repo = 'rafmacalaba/data-use-annotations';
|
| 346 |
-
const me = who().replace(/[^a-zA-Z0-9-_]/g, '_');
|
| 347 |
-
const path = `rulings/${me}.jsonl`;
|
| 348 |
-
let rows = [];
|
| 349 |
-
try {
|
| 350 |
-
const r = await fetch(`https://huggingface.co/datasets/${repo}/resolve/main/${path}`);
|
| 351 |
-
if (r.ok) rows = (await r.text()).split('\n').filter(Boolean).map(JSON.parse);
|
| 352 |
-
} catch (e) {}
|
| 353 |
-
const seen = new Set(rows.map(x => x.queue + '|' + x.key));
|
| 354 |
-
let added = 0;
|
| 355 |
-
for (const [key, ruling] of Object.entries(R)) {
|
| 356 |
-
const q = RQ[key] || $('ds').value;
|
| 357 |
-
if (seen.has(q + '|' + key)) continue;
|
| 358 |
-
rows.push({key, ruling, queue: q, annotator: who(),
|
| 359 |
-
ts: new Date().toISOString().replace(/\.\d+Z$/, '+00:00')});
|
| 360 |
-
added++;
|
| 361 |
-
}
|
| 362 |
-
if (!added) { lastSaved = 'Hub (already in sync)'; lightMeta(); btn.disabled = false; return; }
|
| 363 |
-
const content = btoa(unescape(encodeURIComponent(rows.map(x => JSON.stringify(x)).join('\n') + '\n')));
|
| 364 |
-
const nd = [{key: 'header', value: {summary: `push ${added} rulings (${me}, web)`, description: ''}},
|
| 365 |
-
{key: 'file', value: {content, path, encoding: 'base64'}}].map(o => JSON.stringify(o)).join('\n');
|
| 366 |
-
const res = await fetch(`https://huggingface.co/api/datasets/${repo}/commit/main`, {
|
| 367 |
-
method: 'POST', headers: {Authorization: `Bearer ${tok}`, 'Content-Type': 'application/x-ndjson'}, body: nd});
|
| 368 |
-
if (!res.ok) throw new Error('hub ' + res.status);
|
| 369 |
-
lastSaved = `Hub (${added} pushed)`;
|
| 370 |
-
} catch (e) { lastSaved = 'push failed — still stored in this browser'; }
|
| 371 |
-
btn.disabled = false;
|
| 372 |
-
lightMeta();
|
| 373 |
-
}
|
| 374 |
function exp() {
|
| 375 |
-
const rows = Object.entries(R).map(([key, ruling]) => ({key, ruling, queue: RQ[key] || $('ds').value, annotator: who()
|
|
|
|
| 376 |
const a = document.createElement('a');
|
| 377 |
a.href = URL.createObjectURL(new Blob([rows.map(r => JSON.stringify(r)).join('\n')], {type: 'application/json'}));
|
| 378 |
-
a.download = '
|
| 379 |
}
|
| 380 |
document.addEventListener('keydown', e => {
|
| 381 |
if (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT') return;
|
|
|
|
| 70 |
<footer>
|
| 71 |
<span><kbd>←</kbd><kbd>→</kbd> prev/next mention · <kbd>k</kbd> keep · <kbd>d</kbd> drop · <kbd>space</kbd> skip · <kbd>[</kbd><kbd>]</kbd> slide · <kbd>-</kbd><kbd>+</kbd> size · <kbd>e</kbd> export</span>
|
| 72 |
<span class="sp"></span><span id="count"></span>
|
|
|
|
|
|
|
|
|
|
| 73 |
<button id="hubBtn" onclick="exp()">export</button>
|
| 74 |
</footer>
|
| 75 |
<script>
|
|
|
|
| 330 |
return 'Hub';
|
| 331 |
} catch (e) { return 'this browser only (Hub sync failed)'; }
|
| 332 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
function exp() {
|
| 334 |
+
const rows = Object.entries(R).map(([key, ruling]) => ({key, ruling, queue: RQ[key] || $('ds').value, annotator: who(),
|
| 335 |
+
ts: new Date().toISOString().replace(/\.\d+Z$/, '+00:00')}));
|
| 336 |
const a = document.createElement('a');
|
| 337 |
a.href = URL.createObjectURL(new Blob([rows.map(r => JSON.stringify(r)).join('\n')], {type: 'application/json'}));
|
| 338 |
+
a.download = `rulings-${who() || 'anon'}-${$('ds').value}.jsonl`; a.click();
|
| 339 |
}
|
| 340 |
document.addEventListener('keydown', e => {
|
| 341 |
if (e.target.tagName === 'INPUT' || e.target.tagName === 'SELECT') return;
|