diff options
-rw-r--r-- | src/js/app.js | 4 | ||||
-rw-r--r-- | src/js/arching-kaos-fetch.js | 28 | ||||
-rw-r--r-- | src/js/arching-kaos-file-system.js | 237 | ||||
-rw-r--r-- | src/js/url-generators.js | 14 |
4 files changed, 283 insertions, 0 deletions
diff --git a/src/js/app.js b/src/js/app.js index 066d598..53c3077 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -11,6 +11,7 @@ import { mainLayoutSpawn } from "./ui/mainLayout.js"; import { scanStellarNetworkForPeers } from "./arching-kaos-stellar-network.js"; import { checkLocalNodeInfo, checkLocalPeers, checkLocalSchain, seekPeer, seekZblock, showResult } from "./arching-kaos-tools.js"; import { refreshChat, refreshRadio, setDebug } from "./utils.js"; +import { akfsGetMap } from "./arching-kaos-file-system.js"; window.menusel = menusel; window.locationHashOnChange = locationHashOnChange; @@ -133,5 +134,8 @@ menuinit(); locationHashOnChange(); window.isMobile ? doubleFloorMenu().style.display = 'none': doubleFloorMenu().style.display = 'flex'; +// TESTS BELOW +window.akfsGetMap = akfsGetMap; +//akfsGetMap('48965fddebc826632a4bc1bbe1ed6c1909541e1c03023c3cdb481fc3a5b53cfad1b6d92fd4cb77a4f75b6891e4dd005fa26d108b29ba203b732c92e4ce3d5e0c'); // vim: tabstop=4 shiftwidth=4 expandtab softtabstop=4 // @license-end diff --git a/src/js/arching-kaos-fetch.js b/src/js/arching-kaos-fetch.js index 5f27728..6cf1b76 100644 --- a/src/js/arching-kaos-fetch.js +++ b/src/js/arching-kaos-fetch.js @@ -65,4 +65,32 @@ export async function archingKaosFetchText( url, callback, params ){ request.open("GET", url); request.send(); } + +export function archingKaosFetchBlob( url, callback, params ){ + const request = new XMLHttpRequest(); + request.addEventListener("load", ()=>{ + var blob = request.response; + if(request.status !== 404){ + callback(blob, params); + } else { + archingKaosLog(`ERROR ${request.status} while loading ${url}`); + } + }); + request.addEventListener("error", ()=>{ + debugLog("An error occured."); + }); + request.addEventListener("progress", (event)=>{ + if (event.lengthComputable && progressPlaceholder()){ + httpProgressPlaceholder().value = (event.loaded / event.total) * 100; + } else { + httpProgressPlaceholder.value = 0; + debugLog("Supposingly zeroed progressPlaceholder"); + } + }); + request.addEventListener("abort", ()=>{ + debugLog("Request aborted."); + }); + request.open("GET", url); + request.send(); +} // @license-end diff --git a/src/js/arching-kaos-file-system.js b/src/js/arching-kaos-file-system.js new file mode 100644 index 0000000..c629ce4 --- /dev/null +++ b/src/js/arching-kaos-file-system.js @@ -0,0 +1,237 @@ +// Arching Kaos Fetch +// +// Kaotisk Hund - 2024 +// +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL v3.0 +// + +import { akfsGetChunkURL, akfsGetLeafURL, akfsGetMapURL } from "./url-generators.js"; +import { archingKaosFetchBlob } from "./arching-kaos-fetch.js"; +import { offerDownloadableData } from "./utils.js"; + +var thingy = {}; +var leafs_counter = 0; +var leafs_head_counter = 0; +var first_chunk_spotted = 0; +var first_chunk_size = 0; +var final_array_seq = []; +var output = ""; + +function akfsReset() +{ + thingy = null; + thingy = {}; + leafs_counter = 0; + leafs_head_counter = 0; + first_chunk_spotted = 0; + first_chunk_size = 0; + final_array_seq = null; + final_array_seq = []; + output = ""; +} + +export function akfsGetMap(hash) +{ + akfsReset(); + archingKaosFetchBlob(akfsGetMapURL(hash), akfsFromMapGetLevelOneMapHash, [hash]) + return hash; +} + +function akfsFromMapGetOriginalHash(reply, params) +{ + const [ hash ] = params; + if(typeof(reply) === "string") + { + console.log(reply.split('\n')[0].split(' ')[0]); + } +} + +function akfsFromMapGetOriginalFilename(reply, params) +{ + const [ hash ] = params; + if(typeof(reply) === "string") + { + console.log(reply.split('\n')[0].split(' ')[1]); + } +} + +function akfsFromMapGetLevelOneMapHash(reply, params) +{ + const [ hash ] = params; + var hashregexp = /^[0-9a-f]{128}$/; + const level_1_map = reply.split('\n')[1].split(' ')[0]; + if(typeof(reply) === "string" && hashregexp.test(level_1_map)) + { + archingKaosFetchBlob(akfsGetLeafURL(level_1_map), akfsChunkOrLeaf, [level_1_map, hash]); + thingy = { + leafs: [], + chunks: [], + root_hash: level_1_map, + map_hash: hash + }; + thingy[`${level_1_map}`] = []; + } +} + +function akfsSerializeChunks(hash) +{ + if ( thingy.chunks[hash] !== undefined ) + { + final_array_seq.push(hash); + } + else + { + if ( thingy.leafs[hash] !== undefined ) + { + console.log(`The following hash is failing: ${hash}`) + if ( thingy.leafs[hash].head !== undefined ) + { + akfsSerializeChunks(thingy.leafs[hash].head); + } + } + if ( thingy.leafs[hash].head !== thingy.leafs[hash].tail ) + { + akfsSerializeChunks(thingy.leafs[hash].tail); + } + } +} + +function makeUpData() +{ + let response = ""; + for ( var i = 0; i < final_array_seq.length; i++ ) + { + // console.log(`${i} ${final_array_seq[i]}`); + response += thingy.chunks[final_array_seq[i]].data; + } + return Uint8Array.fromBase64(response.replaceAll('\n', '')); +} + +function akfsWorkOnChunks() +{ + akfsSerializeChunks(thingy.root_hash); + var data = makeUpData(); + offerDownloadableData(data); +} + +function akfsChunkOrLeaf(reply, params) +{ + const [ hash, previous ] = params; + var hashregexp = /^[0-9a-f]{128}$/; + var base64regexp = /^[-A-Za-z0-9+/]*={0,3}$/; + if(typeof(reply) === "string") + { + if ( hashregexp.test(reply.split('\n')[0]) && hashregexp.test(reply.split('\n')[1]) ) + { + if ( leafs_counter === 0 ) + { + leafs_counter++; + } + leafs_head_counter++; + if ( previous === thingy.map_hash ) + { + console.log("Previous is a map_hash"); + } + else if ( previous === thingy.root_hash ) + { + console.log("Previous is a root_hash"); + } + if ( hash === thingy.map_hash ) + { + console.log("Current is a map_hash"); + } + else if ( hash === thingy.root_hash ) + { + console.log("Current is a root_hash"); + } + if ( thingy[hash] !== undefined ) + { + thingy[hash][reply.split('\n')[0]] = []; + thingy[hash][reply.split('\n')[1]] = []; + } + var leaf = { + hash: hash, + head: reply.split('\n')[0], + tail: reply.split('\n')[1] + }; + thingy.leafs[leaf.hash] = leaf; + archingKaosFetchBlob(akfsGetLeafURL(leaf.head), akfsChunkOrLeaf, [leaf.head, hash]); + archingKaosFetchBlob(akfsGetChunkURL(leaf.head), akfsChunkOrLeaf, [leaf.head, hash]); + if ( leaf.head !== leaf.tail ) + { + archingKaosFetchBlob(akfsGetLeafURL(leaf.tail), akfsChunkOrLeaf, [leaf.tail, hash]); + archingKaosFetchBlob(akfsGetChunkURL(leaf.tail), akfsChunkOrLeaf, [leaf.tail, hash]); + } + } + else if ( base64regexp.test(reply.split('\n')[0]) ) + { + if ( first_chunk_spotted === 0 ) + { + first_chunk_spotted = leafs_head_counter; + console.log("first_chunk_spotted : "+ first_chunk_spotted); + first_chunk_size = reply.length; + } + var chunk = { + hash: hash, + data: reply + }; + thingy.chunks[chunk.hash] = chunk; + if ( first_chunk_size > chunk.data.length || chunk.data.length < 1024 || ( chunk.data.length < 4096 && first_chunk_size >= 4096 ) ) + { + akfsWorkOnChunks(); + } + } + else + { + console.log("Unreachable"); + } + } + else if (JSON.parse(reply)) + { + const obj = JSON.parse(reply); + if ( obj.error !== undefined ) console.log( obj.error ); + } + else if (typeof(reply) === "object") + { + console.log("Unreachable"); + } + else + { + console.log("Unreachable"); + } +} + +function akfsStoreChunk(chunk, params) +{ + const [ hash, previous ] = params; + var base64regexp = /^[-A-Za-z0-9+/]*={0,3}$/ + if ( base64regexp.test(chunk) ) + { + thingy.chunks[hash] = { + data: chunk + }; + } +} + +function akfsGetChunk(chunk, params) +{ + const [ hash, previous ] = params; + akfsStoreChunk(chunk, [hash, previous]); +} + +function akfsGetLeaf(leaf, params) +{ + const [hash, previous] = params; + if(typeof(leaf) === "object") + { + archingKaosFetchBlob(akfsGetLeafURL(leaf.head), akfsChunkOrLeaf, [hash, previous]); + archingKaosFetchBlob(akfsGetChunkURL(leaf.head), akfsChunkOrLeaf, [hash, previous]); + if ( leaf.head !== leaf.tail ) + { + archingKaosFetchBlob(akfsGetLeafURL(leaf.tail), akfsChunkOrLeaf, [hash, previous]); + archingKaosFetchBlob(akfsGetChunkURL(leaf.tail), akfsChunkOrLeaf, [hash, previous]); + } + } +} + +// @license-end diff --git a/src/js/url-generators.js b/src/js/url-generators.js index 1bfe881..465de59 100644 --- a/src/js/url-generators.js +++ b/src/js/url-generators.js @@ -56,5 +56,19 @@ export function getTrustlinesURL(code=null, issuer=null) '&asset_issuer='+issuer; } +export function akfsGetMapURL(hash=null) +{ + return settings.ak.connect.list[settings.ak.connect.active]+'/v0/map/'+hash; +} + +export function akfsGetLeafURL(hash=null) +{ + return settings.ak.connect.list[settings.ak.connect.active]+'/v0/leaf/'+hash; +} + +export function akfsGetChunkURL(hash=null) +{ + return settings.ak.connect.list[settings.ak.connect.active]+'/v0/chunk/'+hash; +} // vim: tabstop=4 shiftwidth=4 expandtab softtabstop=4 // @license-end |