display phash as hex

This commit is contained in:
towards-a-new-leftypol 2023-08-24 18:07:37 -04:00
parent c745ed8901
commit d3f3a9aa0f
2 changed files with 91 additions and 203 deletions

291
script.js
View File

@ -124,13 +124,6 @@ function match(re) {
}
}
/*
var ROUTES = RoutePart([
[match(/^s$/), new RoutePart([], handleSearch)],
[match(/^[a-f0-9]{40}$/), new RoutePart([], handleInfo)]
], loadTop);
*/
var ROUTES = RoutePart(
[
[ match(/^spam_post$/)
@ -147,24 +140,6 @@ var ROUTES = RoutePart(
, handlePageRoot
);
/*
var ROUTES = RoutePart(
[
[ match(/^static$/)
, new RoutePart(
[
[ match(/^index\.html$/)
, new RoutePart([], handlePageRoot)
]
]
, null
)
]
]
, null
);
*/
/**
* Functions
*/
@ -214,48 +189,53 @@ function get(url, xhr_req_follower, headers) {
});
}
var HexArray = "0123456789abcdef";
// Given a BigInt that is packed bytes, unpack the bytes into an ArrayBuffer
function unpackBytes(bigint) {
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
view.setBigInt64(0, bigint);
return buffer;
}
function bytesToHex(uint8arr) {
var hex_encoded = "";
function hexArrayFromBuffer(buffer) {
// Create a Uint8Array view to access the bytes
const uint8Array = new Uint8Array(buffer);
for (var i=0; i < uint8arr.length; i++) {
var j = uint8arr[i] & 0xFF;
hex_encoded += HexArray[j >>> 4];
hex_encoded += HexArray[j & 0x0F];
// Convert each byte to its hexadecimal representation
const hexArray = Array.from(uint8Array, byte => byte.toString(16).padStart(2, '0'));
return uint8Array;
}
function bufferToHex(buffer) {
// Join the hexadecimal values into a single string
return hexArray(buffer).join('');
}
function hammingDistance(buffer1, buffer2) {
if (buffer1.byteLength !== buffer2.byteLength) {
throw new Error("Buffer lengths must be equal");
}
const view1 = new DataView(buffer1);
const view2 = new DataView(buffer2);
let distance = 0;
for (let i = 0; i < buffer1.byteLength; i++) {
const byte1 = view1.getUint8(i);
const byte2 = view2.getUint8(i);
let xor = byte1 ^ byte2;
while (xor !== 0) {
distance++;
xor &= xor - 1;
}
}
return hex_encoded;
return distance;
}
var ESC_STR = '$ESCAPE_PIPE_SYMBOL';
function splitRawRow(raw_row) {
return raw_row
.replace('\\|', ESC_STR)
.split('|')
.map(function(s) {
return s.replace(ESC_STR, '|')
.trim();
})
}
function parseTable(results) {
var raw_rows = results.split('\n').slice(0, -1);
var headers = splitRawRow(raw_rows[0]);
return raw_rows.slice(2, -1)
.map(splitRawRow)
.map(function(row) {
return row.reduce(function(acc, val, i) {
acc[headers[i]] = val;
return acc;
},
{});
})
}
function parseFilePath(s) {
return JSON.parse(s);
}
@ -385,43 +365,16 @@ function keepElements(elem_selectors) {
}
}
function ensureElementExist(selector) {
var document_root = document.querySelector('main');
var elem = document_root.querySelector(selector);
if (!elem) {
document_root.appendChild(global_elements[selector]);
}
}
function loadJwt() {
cancelGlobalEvts();
}
function loadTop() {
//TODO: dispatch changeurl event
cancelGlobalEvts();
ensureElementExist('style.loading');
pageInfoText.innerText = 'Loading Top 100...';
get('/cgi-bin/top_100', cancel)
.then(function(response) {
CurrentScore = currentScore();
console.log("Current score:", CurrentScore);
var document_root = document.querySelector('main');
var t = parseTable(response);
console.log(t);
keepElements(['style', '.info']);
pageInfoText.innerText = 'Top 100';
document_root.appendChild(assembleTable(t));
})
.catch(caught.bind(this, "Failed to load top 100: "));
}
function caught(m, e) {
console.error(m);
console.error(e);
for (var property in e) {
console.error(property + ": " + e[property]);
}
alert(new Error(m + e.message));
};
@ -430,13 +383,13 @@ function mkSpamImgElement(img_description) {
var mime = img_description.mimetype;
var thumb_url;
if (!img_description.thumbnail) {
if (mime == "audio/mpeg") {
thumb_url = `/bin/?path=${GlobalVars.settings.audio_mpeg_thumbnail_path}&mimetype=image/jpeg`
} else {
thumb_url = `/bin/?path=${GlobalVars.settings.content_directory}/${img_description.md5_hash}_thumbnail.jpg&mimetype=image/jpeg`
}
var image_url = `/bin/?path=${GlobalVars.settings.content_directory}/${img_description.md5_hash}&mimetype=${mime}`
var image_url = `/bin/?path=${GlobalVars.settings.content_directory}/${img_description.md5_hash}.attachment&mimetype=${mime}`
img_elem.setAttribute('src', thumb_url);
img_elem.setAttribute('decoding', 'async');
img_elem.setAttribute('loading', 'lazy');
@ -485,9 +438,45 @@ function renderPostElem(post) {
function renderKnownSpamAttachments(attachments) {
var container = div();
container.classList.add('attachment');
attachments.forEach(function(a) {
container.appendChild(mkSpamImgElement(a));
});
return container;
}
function renderThings(things_map) {
var container = div();
for (const [key, value] of Object.entries(things_map)) {
var entry = div();
entry.appendChild(span(bold(text(key + ": "))));
entry.appendChild(span(text(value)));
container.appendChild(entry);
}
return container;
}
function renderAttachmentReason(attachment) {
var container = div();
container.classList.add('attachment-reason');
container.appendChild(mkSpamImgElement(attachment));
var things = {
'mimetype': attachment['mimetype'],
'time stamp': attachment['time_stamp'],
'md5': attachment['md5_hash'],
'phash raw': BigInt(attachment['phash']).toString(2),
'phash (hex)': hexArrayFromBuffer(unpackBytes(BigInt(attachment['phash']))),
//'distance': hammingDistance(unpackBytes(BigInt(attachment['phash'])), unpackBytes(BigInt(attachment['phash']))),
'distance': hammingDistance(unpackBytes(BigInt(attachment['phash'])), unpackBytes(BigInt(0))),
};
container.appendChild(renderThings(things));
return container;
}
@ -501,12 +490,10 @@ function renderReasons(post) {
reasonDetailsContainer.className = 'reason-details';
if (reasonDetails.frequent_attachment_details) {
var attachmentList = ul();
reasonDetails.frequent_attachment_details.forEach(function (attachment) {
attachmentList.appendChild(li(text(attachment.filename)));
});
reasonDetailsContainer.appendChild(h4(text('Previously posted matching attachments:')));
reasonDetailsContainer.appendChild(div(attachmentList));
reasonDetails.frequent_attachment_details.forEach(function (attachment) {
reasonDetailsContainer.appendChild(renderAttachmentReason(attachment));
});
}
if (reasonDetails.frequent_text_details) {
@ -562,14 +549,14 @@ function renderOverviewPost(post) {
var postContainer = renderPostElem(post);
postContainer.appendChild(h3(text('Reasons:')));
postContainer.appendChild(div(renderReasonsUl(post)));
postContainer.classList.add('post--overview');
return postContainer;
}
function loadKnownSpamPosts() {
pageInfoText.innerText = 'Loading known spam post';
pageInfoText.innerText = 'Loading all known spam posts...';
cancelGlobalEvts();
//var url = GlobalVars.settings.postgrest_url + '/known_spam_post?select=*,known_spam_attachments(*)'
var url = GlobalVars.settings.postgrest_url + '/known_spam_post?select=*,known_spam_post_attachment(*)'
var headers = {
'Authorization': 'Bearer ' + GlobalVars.settings.jwt
@ -578,8 +565,7 @@ function loadKnownSpamPosts() {
get(url, cancel, headers)
.then(function(response) {
var json = JSON.parse(response);
console.log("results for", url, json);
//console.log("have known spam images:", json);
console.log("results for", url, response);
pageInfoText.innerText = 'Have these known spam posts:';
var mainElem = document.querySelector('main');
mainElem.innerHTML = '';
@ -597,88 +583,6 @@ function loadKnownSpamPosts() {
.catch(caught.bind(this, "Failed to load known spam posts. Reason:"));
}
function loadInfo(info_hash) {
var preLoad_executed = false;
var page = document.createElement('div');
function preLoad() {
if (preLoad_executed) {
return;
}
preLoad_executed = true;
keepElements(['style', '.info']);
pageInfoText.innerText = info_hash;
document.querySelector('main').appendChild(page);
}
ensureElementExist('style.loading');
pageInfoText.innerText = 'Loading info for ' + info_hash;
cancelGlobalEvts();
get('/cgi-bin/files?i=' + info_hash, cancel)
.then(function(response) {
preLoad();
var files = parseTable(response);
console.log(files);
var h = document.createElement('h2');
h.innerText = 'Contents';
page.appendChild(h);
var t = renderTree(files);
page.appendChild(t);
})
.catch(caught.bind(this, "Failed to info details. Reason:"));
get('/cgi-bin/info?i=' + info_hash, cancel)
.then(function(response) {
preLoad();
var info = parseTable(response)[0];
pageInfoText.innerText = info.name;
var first_seen = new Date(info.added.split('.')[0]+'Z');
var mlink = magnet(info);
mlink.innerText = mlink.href;
var last_seen = new Date(Math.min(
invertScore(Number(info.score)) * 1000,
new Date().getTime())
);
prepend(page, div(text('First Indexed: ' + first_seen)));
prepend(page, div(text('Approximately last seen: ' + last_seen)));
var filecount = div(text('Files: '));
filecount.appendChild(bold(text(info.filecount)))
prepend(page, filecount);
var total_size = div(text('Total Size: '));
total_size.appendChild(bold(text(info.total_size)))
prepend(page, total_size);
prepend(page, div(mlink));
})
.catch(caught.bind(this, "Failed to load file list. Details:"));
}
function loadResults(search_query) {
var encoder = new TextEncoder();
var hex = bytesToHex(encoder.encode(search_query));
console.log(hex);
cancelGlobalEvts();
ensureElementExist('style.loading');
pageInfoText.innerText = 'Loading results for "' + search_query + '"...';
get('/cgi-bin/search?q=' + hex, cancel)
.then(function(response) {
CurrentScore = currentScore();
console.log("Current score:", CurrentScore);
var t = assembleTable(parseTable(response));
var document_root = document.querySelector('main');
keepElements(['style', '.info'])
pageInfoText.innerText = 'Results for "' + search_query + '"';
document_root.appendChild(t);
})
.catch(caught.bind(this, "Failed to results: "));
}
function changeUrl(path, search_query, push_state) {
var event = new CustomEvent(
'urlchange',
@ -694,7 +598,7 @@ function changeUrl(path, search_query, push_state) {
}
function handlePageRoot(_, query_params) {
console.log("handlePageRoot", query_params);
console.log("handlePageRoot", JSON.stringify(query_params));
return loadKnownSpamPosts();
}
@ -759,23 +663,6 @@ function showSpamPost(path_data, _) {
}
function handleSearch(_, query_params) {
var search_query = query_params.q;
if (!search_query) {
console.log("nothing to query");
return;
} else {
console.log(search_query);
loadResults(search_query);
}
}
function handleInfo(parts, query_params) {
console.log('info request', parts, query_params);
loadInfo(parts[0]);
}
function onUrlChange(e) {
var path = e.detail.path.split('/').filter(function(s){ return s.length; });
console.log(e, e.detail, path);

View File

@ -14,7 +14,7 @@ header {
padding: 1em;
}
.post:hover {
.post--overview:hover {
background-color: #FFEEEE;
}
@ -24,6 +24,7 @@ header {
}
.post--body_container,
.attachment-reason,
.attachment {
display: flow-root;
}