Skip to content

Commit

Permalink
"Closes #91 - Add way to delete entries from index
Browse files Browse the repository at this point in the history
- and from search"
  • Loading branch information
o0101 committed Dec 30, 2021
1 parent 364edb7 commit 59f5454
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 11 deletions.
36 changes: 29 additions & 7 deletions src/archivist.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
afterPathChanged,
saveIndex,
getIndex,
deleteFromIndexAndSearch,
search,
getDetails,
isReady,
Expand Down Expand Up @@ -673,13 +674,15 @@ export default Archivist;
return await untilHas(Status, 'loaded');
}

async function loadFuzzy() {
const fuzzyDocs = Fs.readFileSync(getFuzzyPath()).toString();
State.Docs = new Map(JSON.parse(fuzzyDocs).map(doc => {
doc.i_url = getURI(doc.url);
doc.contentSignature = getContentSig(doc);
return [doc.url, doc];
}));
async function loadFuzzy({fromMemOnly: fromMemOnly = false} = {}) {
if ( ! fromMemOnly ) {
const fuzzyDocs = Fs.readFileSync(getFuzzyPath()).toString();
State.Docs = new Map(JSON.parse(fuzzyDocs).map(doc => {
doc.i_url = getURI(doc.url);
doc.contentSignature = getContentSig(doc);
return [doc.url, doc];
}));
}
State.Fuzzy = fuzzy = new Fuzzy({source: [...State.Docs.values()], keys: FUZZ_OPTS.keys});
DEBUG && console.log('Fuzzy loaded');
}
Expand Down Expand Up @@ -951,6 +954,25 @@ export default Archivist;
return idx;
}

async function deleteFromIndexAndSearch(url) {
if ( State.Index.has(url) ) {
const {id, ndx_id, title, /*date,*/} = State.Index.get(url);
// delete index entries
State.Index.delete(url);
State.Index.delete(id);
State.Index.delete('ndx'+ndx_id);
// delete FTS entries (where we can)
State.NDX_FTSIndex.remove(ndx_id);
State.Flex.remove(id);
State.Docs.delete(url);
// save it all (to ensure we don't load data from disk that contains delete entries)
saveFiles({forceSave:true});
// and just rebuild the whole FTS index (where we must)
await loadFuzzy({fromMemOnly:true});
return {title};
}
}

async function search(query) {
const flex = (await Flex.searchAsync(query, args.results_per_page))
.map(id=> ({id, url: State.Index.get(id)}));
Expand Down
86 changes: 82 additions & 4 deletions src/libraryServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ function addHandlers() {
res.end(IndexView(index));
});

app.get('/edit_index.html', async (req, res) => {
Archivist.saveIndex();
const index = Archivist.getIndex();
res.end(IndexView(index, {edit:true}));
});

app.post('/edit_index.html', async (req, res) => {
const {url_to_delete} = req.body;
await Archivist.deleteFromIndexAndSearch(url_to_delete);
const index = Archivist.getIndex();
res.end(IndexView(index));
});

app.post('/mode', async (req, res) => {
const {mode} = req.body;
await Archivist.changeMode(mode);
Expand Down Expand Up @@ -134,31 +147,96 @@ async function stop() {
return pr;
}

function IndexView(urls) {
function IndexView(urls, {edit:edit = false} = {}) {
return `
<!DOCTYPE html>
<meta charset=utf-8>
<title>Your HTML Library</title>
<title>
${ edit ? 'Editing ' : ''}
Your HTML Library
</title>
<link rel=stylesheet href=/style.css>
${ edit ? `
<script>
const sleep = ms => new Promise(res => setTimeout(res, ms));
const StrikeThrough = 'line-through';
</script>
` : ''}
<header>
<h1><a href=/>22120</a> &mdash; Archive Index</h1>
</header>
<form method=GET action=/search>
<form method=GET action=/search style="margin-bottom: 1em;">
<fieldset class=search>
<legend>Search your archive</legend>
<input class=search type=search name=query placeholder="search your library">
<button>Search</button>
</fieldset>
</form>
<form style="display:flex; justify-content: end; margin-bottom:0"
method=GET
action=${ edit ? '/archive_index.html' : '/edit_index.html' }>
<details>
<summary style="display:inline-block; cursor: default;">
${ edit ? `
<button
style="
border: 0;
background: 0;
font-size: x-large;
line-height: 0.5;
"
>
&check;
</button>`
:
'&hellip;'
}
</summary>
<div style="position: absolute;">
<button><em style=font-size:x-large;line-height:0.5;>&#9986;</em> edit</button>
</div>
</details>
</form>
<ul>
${
urls.map(([url,{title, id}]) => `
<li>
${DEBUG ? id + ':' : ''} <a target=_blank href=${url}>${(title||url).slice(0, MAX_HEAD)}</a>
${ DEBUG ? id + ':' : ''}
<a target=_blank href=${url}>${(title||url).slice(0, MAX_HEAD)}</a>
${ edit ? `
<form style=display:contents; method=POST action=/edit_index.html>
<input name=url_to_delete type=url hidden value="${url}">
<button
style="font-size: smaller; line-height: 0.618;"
type=button
onclick="double_confirm(event);"
>
X
</button>
</form>
` : ''}
</li>
`).join('\n')
}
</ul>
${ edit ? `
<script>
async function double_confirm(deleteClick) {
const form = deleteClick.target.closest('form');
let {host} = new URL(form.url_to_delete.value);
host = host.replace(/^www\./i, '');
const link = form.previousElementSibling;
const original = link.style.textDecoration;
link.style.textDecoration = StrikeThrough;
await sleep(300);
const reallyDelete = confirm(
\`\n are you sure you want to delete this \n\n \${host} \n\n from the internet?\n\`
);
if ( reallyDelete ) return form.submit();
link.style.textDecoration = original;
}
</script>
` : ''}
`
}

Expand Down

0 comments on commit 59f5454

Please sign in to comment.