alexandria-core
Advanced tools
Comparing version 1.0.0 to 1.0.1
373
index.js
@@ -15,102 +15,9 @@ import axios from 'axios'; | ||
// Define application values | ||
Core.artifactsLastUpdate = 0; // timestamp of last ajax call to the artifacts endpoint. | ||
Core.artifacts = []; | ||
Core.supportedArtifacts = []; | ||
Core.artifactsUpdateTimelimit = 30 * 1000; | ||
Core.maxThumbnailSize = 512000; | ||
// Define URLS for things we don't control, these likely will change often | ||
Core.btcTickerURL = "https://blockchain.info/ticker?cors=true"; | ||
Core.getSupportedArtifacts = function(callback){ | ||
// Check to see if we should update again, if not, just return the old data. | ||
if (Core.artifactsLastUpdate < Date.now() - Core.artifactsUpdateTimelimit){ | ||
Core.artifactsLastUpdate = Date.now(); | ||
Core.Artifact = {}; | ||
let _Core = Core; | ||
Core.Artifact.maxThumbnailSize = 512000; | ||
axios | ||
.get(Core.OIPdURL + "/media/get/all") | ||
.then(function(result) { | ||
let jsonResult = result.data; | ||
Core.artifacts = jsonResult; | ||
var supportedArtifacts = []; | ||
for (var x = jsonResult.length -1; x >= 0; x--){ | ||
if (jsonResult[x]['oip-041']){ | ||
if (jsonResult[x]['oip-041'].artifact.type.split('-').length === 2){ | ||
supportedArtifacts.push(jsonResult[x]); | ||
} | ||
} | ||
} | ||
_Core.supportedArtifacts = supportedArtifacts; | ||
callback(_Core.supportedArtifacts); | ||
}); | ||
} else { | ||
callback(Core.supportedArtifacts); | ||
} | ||
} | ||
Core.getIPFS = function(callback){ | ||
Core.ipfs.on('ready', () => { | ||
callback(Core.ipfs); | ||
}) | ||
} | ||
Core.getThumbnailFromIPFS = function(hash, onData){ | ||
// Require a hash to be passed | ||
if (!hash || hash === "") | ||
return; | ||
Core.ipfs.files.cat(hash, function (err, file) { | ||
if (err){ | ||
console.log(err); | ||
return; | ||
} | ||
let stream = file; | ||
let chunks = []; | ||
if (stream){ | ||
stream.on('data', function(chunk) { | ||
chunks.push(chunk); | ||
// Note, this might cause tons of lag depending on how many ongoing IPFS requests we have. | ||
Core.util.chunksToFileURL(chunks, function(data){ | ||
onData(data); | ||
}) | ||
}); | ||
stream.on('end', function(){ | ||
// Core.util.chunksToFileURL(chunks, function(data){ | ||
// onData(data); | ||
// }) | ||
}) | ||
} | ||
}) | ||
} | ||
Core.getFileFromIPFS = function(hash, onComplete){ | ||
// Require a hash to be passed | ||
if (!hash || hash === "") | ||
return; | ||
Core.ipfs.files.cat(hash, function (err, file) { | ||
if (err){ | ||
console.log(err); | ||
return; | ||
} | ||
let stream = file; | ||
let chunks = []; | ||
if (stream){ | ||
stream.on('data', function(chunk) { | ||
chunks.push(chunk); | ||
}); | ||
stream.on('end', function(){ | ||
Core.util.chunksToFileURL(chunks, function(data){ | ||
onComplete(data); | ||
}) | ||
}) | ||
} | ||
}) | ||
} | ||
Core.Artifact = {}; | ||
Core.Artifact.getTXID = function(oip){ | ||
@@ -129,3 +36,3 @@ let txid = ""; | ||
} catch(e) {} | ||
return title; | ||
return Core.util.decodeMakeJSONSafe(title); | ||
} | ||
@@ -153,4 +60,5 @@ | ||
description = oip['oip-041'].artifact.info.description; | ||
} catch(e) {} | ||
return description; | ||
return Core.util.decodeMakeJSONSafe(description); | ||
} | ||
@@ -193,2 +101,66 @@ | ||
Core.Artifact.getScale = function(oip){ | ||
let scale = 1; | ||
try { | ||
let tmpScale = oip['oip-041'].artifact.payment.scale; | ||
if (tmpScale && tmpScale.split(":").length === 2){ | ||
scale = tmpScale.split(":")[0]; | ||
} | ||
} catch (e) {} | ||
return scale | ||
} | ||
Core.Artifact.getMainFile = function(oip, type){ | ||
let mainFile; | ||
let files = Core.Artifact.getFiles(oip); | ||
let location = Core.Artifact.getLocation(oip); | ||
for (let i = 0; i < files.length; i++){ | ||
if (files[i].type === type && !mainFile){ | ||
mainFile = files[i]; | ||
} | ||
} | ||
return mainFile; | ||
} | ||
Core.Artifact.getMainPaidFile = function(oip, type){ | ||
let mainFile; | ||
let files = Core.Artifact.getFiles(oip); | ||
let location = Core.Artifact.getLocation(oip); | ||
for (let i = 0; i < files.length; i++){ | ||
if (files[i].type === type && (files[i].sugPlay !== 0 || files[i].sugBuy !== 0) && !mainFile){ | ||
mainFile = files[i]; | ||
} | ||
} | ||
return mainFile; | ||
} | ||
Core.Artifact.getMainFileSugPlay = function(oip, type){ | ||
let sugPlay = 0; | ||
try { | ||
sugPlay = Core.Artifact.getMainPaidFile(oip, type).sugPlay / Core.Artifact.getScale(oip); | ||
} catch (e) {} | ||
return sugPlay | ||
} | ||
Core.Artifact.getMainFileSugBuy = function(oip, type){ | ||
let sugBuy = 0; | ||
try { | ||
sugBuy = Core.Artifact.getMainPaidFile(oip, type).sugBuy / Core.Artifact.getScale(oip); | ||
} catch (e) {} | ||
return sugBuy | ||
} | ||
Core.Artifact.getThumbnail = function(oip){ | ||
@@ -201,3 +173,3 @@ let thumbnail; | ||
for (let i = 0; i < files.length; i++){ | ||
if (files[i].type === "Image" && files[i].sugPlay === 0 && files[i].fsize < Core.maxThumbnailSize && !thumbnail){ | ||
if (files[i].type === "Image" && files[i].sugPlay === 0 && files[i].fsize < Core.Artifact.maxThumbnailSize && !thumbnail){ | ||
thumbnail = files[i]; | ||
@@ -237,2 +209,46 @@ } | ||
Core.Artifact.getFirstHTML = function(oip){ | ||
let htmlGet; | ||
let files = Core.Artifact.getFiles(oip); | ||
let location = Core.Artifact.getLocation(oip); | ||
for (let i = 0; i < files.length; i++){ | ||
let extension = Core.util.getExtension(files[i].fname); | ||
if ((extension === "html" || extension === "HTML") && !htmlGet){ | ||
htmlGet = files[i]; | ||
} | ||
} | ||
let htmlURL = ""; | ||
if (htmlGet){ | ||
htmlURL = location + "/" + htmlGet.fname; | ||
} | ||
return htmlURL; | ||
} | ||
Core.Artifact.getFirstHTMLURL = function(oip){ | ||
let htmlGet; | ||
let files = Core.Artifact.getFiles(oip); | ||
let location = Core.Artifact.getLocation(oip); | ||
for (let i = 0; i < files.length; i++){ | ||
let extension = Core.util.getExtension(files[i].fname); | ||
if ((extension === "html" || extension === "HTML") && !htmlGet){ | ||
htmlGet = files[i]; | ||
} | ||
} | ||
let htmlURL = ""; | ||
if (htmlGet){ | ||
htmlURL = location + "/" + htmlGet.fname; | ||
} | ||
return Core.util.buildIPFSURL(htmlURL); | ||
} | ||
Core.Artifact.getSongs = function(oip){ | ||
@@ -299,2 +315,134 @@ let files = Core.Artifact.getFiles(oip); | ||
Core.Data = {}; | ||
Core.Data.supportedArtifacts = []; | ||
Core.Data.getSupportedArtifacts = function(callback){ | ||
let _Core = Core; | ||
Core.Network.getArtifactsFromOIPd(function(jsonResult) { | ||
var supportedArtifacts = []; | ||
for (var x = jsonResult.length -1; x >= 0; x--){ | ||
if (jsonResult[x]['oip-041']){ | ||
if (jsonResult[x]['oip-041'].artifact.type.split('-').length === 2){ | ||
supportedArtifacts.push(jsonResult[x]); | ||
} | ||
} | ||
} | ||
_Core.Data.supportedArtifacts = supportedArtifacts; | ||
callback(_Core.Data.supportedArtifacts); | ||
}); | ||
} | ||
Core.Data.getBTCPrice = function(callback){ | ||
// Check to see if we should update again, if not, just return the old data. | ||
Core.Network.getLatestBTCPrice(callback); | ||
} | ||
Core.Network = {}; | ||
Core.Network.cachedArtifacts = []; | ||
Core.Network.artifactsLastUpdate = 0; // timestamp of last ajax call to the artifacts endpoint. | ||
Core.Network.artifactsUpdateTimelimit = 30 * 1000; // 30 seconds | ||
Core.Network.cachedBTCPriceObj = {}; | ||
Core.Network.btcpriceLastUpdate = 0; | ||
Core.Network.btcpriceUpdateTimelimit = 5 * 60 * 1000; // Five minutes | ||
Core.Network.getArtifactsFromOIPd = function(callback){ | ||
// Check to see if we should update again, if not, just return the old data. | ||
if (Core.Network.artifactsLastUpdate < Date.now() - Core.Network.artifactsUpdateTimelimit){ | ||
Core.Network.artifactsLastUpdate = Date.now(); | ||
let _Core = Core; | ||
axios.get(Core.OIPdURL + "/media/get/all").then(function(results){ | ||
_Core.Network.cachedArtifacts = results.data; | ||
callback(_Core.Network.cachedArtifacts); | ||
}); | ||
} else { | ||
callback(Core.Network.cachedArtifacts); | ||
} | ||
} | ||
Core.Network.getLatestBTCPrice = function(callback){ | ||
if (Core.Network.btcpriceLastUpdate < Date.now() - Core.Network.btcpriceUpdateTimelimit || Core.Network.cachedBTCPriceObj === {}){ | ||
Core.Network.btcpriceLastUpdate = Date.now(); | ||
let _Core = Core; | ||
axios.get(Core.btcTickerURL).then(function(result){ | ||
if (result.status === 200){ | ||
_Core.Network.cachedBTCPriceObj = result.data; | ||
} | ||
callback(_Core.Network.cachedBTCPriceObj["USD"].last); | ||
}); | ||
} else { | ||
callback(Core.Network.cachedBTCPriceObj["USD"].last); | ||
} | ||
} | ||
Core.Network.getIPFS = function(callback){ | ||
Core.ipfs.on('ready', () => { | ||
callback(Core.ipfs); | ||
}) | ||
} | ||
Core.Network.getThumbnailFromIPFS = function(hash, onData){ | ||
// Require a hash to be passed | ||
if (!hash || hash === "") | ||
return; | ||
Core.ipfs.files.cat(hash, function (err, file) { | ||
if (err){ | ||
console.log(err); | ||
return; | ||
} | ||
let stream = file; | ||
let chunks = []; | ||
if (stream){ | ||
stream.on('data', function(chunk) { | ||
chunks.push(chunk); | ||
// Note, this might cause tons of lag depending on how many ongoing IPFS requests we have. | ||
Core.util.chunksToFileURL(chunks, function(data){ | ||
onData(data); | ||
}) | ||
}); | ||
stream.on('end', function(){ | ||
// Core.util.chunksToFileURL(chunks, function(data){ | ||
// onData(data); | ||
// }) | ||
}) | ||
} | ||
}) | ||
} | ||
Core.Network.getFileFromIPFS = function(hash, onComplete){ | ||
// Require a hash to be passed | ||
if (!hash || hash === "") | ||
return; | ||
Core.ipfs.files.cat(hash, function (err, file) { | ||
if (err){ | ||
console.log(err); | ||
return; | ||
} | ||
let stream = file; | ||
let chunks = []; | ||
if (stream){ | ||
stream.on('data', function(chunk) { | ||
chunks.push(chunk); | ||
}); | ||
stream.on('end', function(){ | ||
Core.util.chunksToFileURL(chunks, function(data){ | ||
onComplete(data); | ||
}) | ||
}) | ||
} | ||
}) | ||
} | ||
Core.util = {}; | ||
@@ -326,2 +474,27 @@ | ||
Core.util.getExtension = function(filename){ | ||
let splitFilename = filename.split("."); | ||
let indexToGrab = splitFilename.length - 1; | ||
return splitFilename[indexToGrab]; | ||
} | ||
Core.util.decodeMakeJSONSafe = function(stringToCheck){ | ||
let tmpStr = stringToCheck; | ||
if (typeof tmpStr === "string" && tmpStr.substr(0,1) === '"' && tmpStr.substr(tmpStr.length-1,tmpStr.length) === '"') | ||
tmpStr = eval(tmpStr); | ||
return tmpStr; | ||
} | ||
Core.util.calculateBTCCost = function(usd_value, callback){ | ||
Core.Data.getBTCPrice(function(btc_price){ | ||
callback(usd_value / btc_price) | ||
}) | ||
} | ||
Core.util.convertBTCtoBits = function(btc_value){ | ||
return btc_value * Math.pow(10,6); | ||
} | ||
return Core; | ||
@@ -328,0 +501,0 @@ })(); |
{ | ||
"name": "alexandria-core", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "The core module of Alexandria!", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
# alexandria-core | ||
An NPM module containing all of the core functionality to run the Alexandria front end. | ||
## Work in Progress | ||
This section is a work in progress, so more information will be added periotically. Information may be out of data, for latest information, please read the code :) | ||
### Modules | ||
Inside of Alexandria Core there are currently 4 modules. Each of the four modules have specific tasks to try and seperate the logic out. They are seperated as follows: | ||
- Artifact: This contains helper functions for manipulating artifact JSON. | ||
- Data: This contains simple access to application information that was fetched by the network layer. | ||
- Network: Usually called by the Data layer. This module contains all of the server calls & network transfer functions (i.e. IPFS). | ||
- util: Other generally helpful utility functions that we have found helpful. | ||
Currently, we have implemented or planned the following functions: | ||
#### `Core.Artifact` | ||
`Core.Artifact.getTXID(oipArtifact)`: `return`s the txid of the given artifact. | ||
`Core.Artifact.getTitle(oipArtifact)`: `return`s the title of the given artifact. | ||
`Core.Artifact.getType(oipArtifact)`: `return`s the type of the given artifact. | ||
`Core.Artifact.getSubtype(oipArtifact)`: `return`s the subtype of the given artifact. | ||
`Core.Artifact.getDescription(oipArtifact)`: `return`s the description of the given artifact. | ||
`Core.Artifact.getFiles(oipArtifact)`: `return`s the files of the given artifact. | ||
`Core.Artifact.getLocation(oipArtifact)`: `return`s the location of the given artifact (This is usually the IPFS hash, unless the Artifact uses another data storage layer). | ||
`Core.Artifact.getPublisherName(oipArtifact)`: `return`s the Publisher Name of the publisher that published the Artifact. If no Publisher Name is specified, it will display as `Flotoshi`. | ||
`Core.Artifact.getArtist(oipArtifact)`: `return`s the Artist of the given artifact. If an artist is not specified, it will return the Publisher Name. | ||
`Core.Artifact.getThumbnail(oipArtifact)`: `return`s the Thumbnail of the given artifact. This is calculated as the first File with the type "Image" that does not have a price to view it. Returns `""` if no thumbnail can be found. | ||
`Core.Artifact.getFirstImage(oipArtifact)`: `return`s the first image in the given artifact. If none are found, `""` will be returned. | ||
`Core.Artifact.getFirstHTML(oipArtifact)`: `return`s the first html document in the given artifact. This is calculated by grabbing the extension off of files, the first one with an extension of `.html` will be returned. If none are found, `""` will be returned. | ||
`Core.Artifact.getSongs(oipArtifact)`: `return`s the a formatted JSON object of `songs` that were in the given artifact. | ||
`Core.Artifact.getEntypoIconForType(oipArtifact)`: `return`s the css class for the artifact type. This will likely be not very useful for most people. | ||
`Core.Artifact.paid(oipArtifact)`: `return`s `true` if any files have either a suggested buy price or suggested play price. Otherwise it will return false. | ||
#### `Core.Data` | ||
`Core.Data.getSupportedArtifacts(callback(supportedArtifacts))`: Provides an array of supported artifacts to the callback. All artifacts will be formatted based on the highest version supported by `alexandria-core`. Currently this is `oip-041`. | ||
#### `Core.Network` | ||
`Core.Network.getIPFS(callback)`: Passes the IPFS object to the callback after it has been successfully spawned. You are highly discouraged from using this function, but it is here for advanced functionality. | ||
`Core.Network.getThumbnailFromIPFS(hash, onDataCallback)`: Give it either an IPFS file hash or hash + subfile (i.e. `hash/filename.png`). Each time data is downloaded (i.e. on download progress), we call the onDataCallback and pass a base64 encoded version of the file. You can feed this directly into an image source and it will load fine :) | ||
`Core.Network.getFileFromIPFS(hash, onCompleteCallback)`: Give it either an IPFS file hash or hash + subfile (i.e. `hash/filename.png`). When the file download is complete, we call the onDataCallback and pass a base64 encoded version of the file. You can feed this directly into an image source and it will load fine :) | ||
`Core.Network.getArtifactsFromOIPd(callback)`: This will grab a copy of the latest artifacts from OIPd and return them as an array to the callback. | ||
#### `Core.util` | ||
`Core.util.chunksToFileURL(chunks, onLoad)`: This is used by the IPFS network layer to load byte arrays into a file URL reader, then return the fileURL base64 data to the `onLoad` callback. | ||
`Core.util.buildIPFSURL(hash, filename)`: `return`s a built HTTP link to the IPFS resource. Use this if you don't want to download the file, but just get the URL to access it. | ||
`Core.util.getExtension(filename)`: `return`s the file extension as a string. For example, pass this `index.html` and it will return `html`. | ||
`Core.util.decodeMakeJSONSafe(stringToDecode)`: This checks if there are non JSON supported characters that we should re-encode, if there are, then it encodes them and returns a fixed string, if not, it returns the original string. | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18914
388
69
1