adding web sockets (part 1) #15

Merged
bones7242 merged 6 commits from master into master 2017-05-26 10:37:42 +02:00
4 changed files with 298 additions and 57 deletions
Showing only changes of commit fec251902e - Show all commits

173
helpers/lbryApi-old.js Normal file
View file

@ -0,0 +1,173 @@
// load dependencies
var path = require('path');
var axios = require('axios');
// helper function to filter an array of claims for only free, public claims
function filterForFreePublicClaims(claimsListArray){
//console.log(">> filterForFreePublicClaims, claimsListArray:", claimsListArray);
if (!claimsListArray) {
return null;
};
var freePublicClaims = claimsListArray.filter(function(claim){
return (((claim.value.stream.metadata.license.indexOf('Public Domain') != -1) || (claim.value.stream.metadata.license.indexOf('Creative Commons') != -1)) &&
(!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee === 0));
});
return freePublicClaims;
}
// helper function to decide if a claim is free and public
function isFreePublicClaim(claim){
console.log(">> isFreePublicClaim, claim:", claim);
if ((claim.value.stream.metadata.license === 'Public Domain' || claim.value.stream.metadata.license === 'Creative Commons') &&
(!claim.value.stream.metadata.fee || claim.value.stream.metadata.fee.amount === 0)) {
return true;
} else {
return false;
}
}
// helper function to order a set of claims
function orderTopClaims(claimsListArray){
console.log(">> orderTopClaims, claimsListArray:");
claimsListArray.sort(function(claimA, claimB){
if (claimA.amount === claimB.amount){
return (claimA.height > claimB.height);
} else {
return (claimA.amount < claimB.amount);
}
})
return claimsListArray;
}
module.exports = {
publishClaim: function(publishObject){
axios.post('http://localhost:5279/lbryapi', publishObject)
.then(function (response) {
// receive resonse from LBRY
// if successfull, (1) delete file (2) send response to the client
console.log(">> 'publish' success...");
console.log(">> 'publish' response.data:", response.data);
console.log(" [x] Done");
// return the claim we got
//res.status(200).send(JSON.stringify({msg: "you succsessfully published!", txData: response.data}));
}).catch(function(error){
// receive response from LBRY
// if not successfull, (1) delete file and (2) send response to the client
console.log(">> 'publish' error.response.data:", error.response.data);
console.log(" [x] Done");
//res.status(500).send(JSON.stringify({msg: "your file was not published", err: error.response.data.error.message}));
})
},
serveClaimBasedOnNameOnly: function(claimName, res){
// make a call to the daemon to get the claims list
axios.post('http://localhost:5279/lbryapi', {
method: "claim_list",
params: {
name: claimName
}
}
).then(function (response) {
console.log(">> Claim_list success");
console.log(">> Number of claims:", response.data.result.claims.length)
// return early if no claims were found
if (response.data.result.claims.length === 0){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html'));
return;
}
// filter the claims to return free, public claims
var freePublicClaims = filterForFreePublicClaims(response.data.result.claims);
// return early if no free, public claims were found
if (!freePublicClaims || (freePublicClaims.length === 0)){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html'));
return;
}
// order the claims
var orderedPublcClaims = orderTopClaims(freePublicClaims);
// create the uri for the first (selected) claim
console.log(">> ordered free public claims", orderedPublcClaims);
var freePublicClaimUri = "lbry://" + orderedPublcClaims[0].name + "#" + orderedPublcClaims[0].claim_id;
console.log(">> your free public claim uri:", freePublicClaimUri);
// fetch the image to display
axios.post('http://localhost:5279/lbryapi', {
method: "get",
params: {
uri: freePublicClaimUri
}
}
).then(function (getResponse) {
console.log(">> 'get claim' success...");
console.log(">> response data:", getResponse.data);
console.log(">> dl path =", getResponse.data.result.download_path)
// return the claim we got
res.status(200).sendFile(getResponse.data.result.download_path);
}).catch(function(getError){
console.log(">> /c/ 'get' error:", getError.response.data);
res.status(500).send(JSON.stringify({msg: "An error occurred while fetching the free, public claim by URI.", err: getError.response.data.error.message}));
})
}).catch(function(error){
console.log(">> /c/ error:", error.response.data);
res.status(500).send(JSON.stringify({msg: "An error occurred while getting the claim list.", err: error.response.data.error.message}));
})
},
serveClaimBasedOnUri: function(uri, res){
/*
to do: need to pass the URI through a test (use 'resolve') to see if it is free and public. Right now it is jumping straight to 'get'ing and serving the asset.
*/
console.log(">> your uri:", uri);
// fetch the image to display
axios.post('http://localhost:5279/lbryapi', { // to do: abstract this code to a function that can be shared
method: "get",
params: {
uri: uri
}
}
).then(function (getResponse) {
console.log(">> 'get claim' success...");
console.log(">> response data:", getResponse.data);
console.log(">> dl path =", getResponse.data.result.download_path)
/*
to do: make sure the file has completed downloading before serving back the file
*/
// return the claim we got
res.status(200).sendFile(getResponse.data.result.download_path);
/* delete the file after a certain amount of time? */
}).catch(function(error){
console.log(">> /c/ 'get' error:", error.response.data);
res.status(500).send(JSON.stringify({msg: "an error occurred", err: error.response.data.error.message}));
})
},
serveAllClaims: function(claimName, res){
// make a call to the daemon to get the claims list
axios.post('http://localhost:5279/lbryapi', {
method: "claim_list",
params: {
name: claimName
}
}
).then(function (response) {
console.log(">> Claim_list success");
console.log(">> Number of claims:", response.data.result.claims.length)
// return early if no claims were found
if (response.data.result.claims.length === 0){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html'));
return;
}
// filter the claims to return free, public claims
var freePublicClaims = filterForFreePublicClaims(response.data.result.claims);
// return early if no free, public claims were found
if (!freePublicClaims || (freePublicClaims.length === 0)){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html'));
return;
}
console.log(">> Number of free public claims:", freePublicClaims.length);
// order the claims
var orderedPublicClaims = orderTopClaims(freePublicClaims);
// serve the response
res.status(200).send(orderedPublicClaims); //to do: rather than returning json, serve a page of all these claims
}).catch(function(error){
console.log(">> /c/ error:", error.response.data);
// serve the response
res.status(500).send(JSON.stringify({msg: "An error occurred while finding the claim list.", err: error.response.data.error.message}));
})
}
}

View file

@ -56,27 +56,34 @@ module.exports = {
//res.status(500).send(JSON.stringify({msg: "your file was not published", err: error.response.data.error.message})); //res.status(500).send(JSON.stringify({msg: "your file was not published", err: error.response.data.error.message}));
}) })
}, },
kauffj commented 2017-05-31 20:39:59 +02:00 (Migrated from github.com)
Review

If you find yourself accessing the same field repeatedly, like getUriResponse.data, it can be good to just dereference it.

Additionally, assuming you're writing ES6 (which is probably a good idea), you can just write:

.then(({data}) => { if (data.result.error === "Timeout") //etc. })

If you find yourself accessing the same field repeatedly, like getUriResponse.data, it can be good to just dereference it. Additionally, assuming you're writing ES6 (which is probably a good idea), you can just write: `.then(({data}) => { if (data.result.error === "Timeout") //etc. })`
serveClaimBasedOnNameOnly: function(claimName, res){ getClaimBasedOnNameOnly: function(claimName){
// 1. create a promise
var deferred = new Promise(function (resolve, reject){
// 2. code to resolve or reject the promise
// make a call to the daemon to get the claims list // make a call to the daemon to get the claims list
axios.post('http://localhost:5279/lbryapi', { axios.post('http://localhost:5279/lbryapi', {
method: "claim_list", method: "claim_list",
params: { params: { name: claimName }
name: claimName })
} .then(function (response) {
}
).then(function (response) {
console.log(">> Claim_list success"); console.log(">> Claim_list success");
console.log(">> Number of claims:", response.data.result.claims.length) console.log(">> Number of claims:", response.data.result.claims.length)
// return early if no claims were found // return early if no claims were found
if (response.data.result.claims.length === 0){ if (response.data.result.claims.length === 0){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html')); reject({
msg: "no claims",
err: "no claims"
});
return; return;
} }
// filter the claims to return free, public claims // filter the claims to return free, public claims
var freePublicClaims = filterForFreePublicClaims(response.data.result.claims); var freePublicClaims = filterForFreePublicClaims(response.data.result.claims);
// return early if no free, public claims were found // return early if no free, public claims were found
if (!freePublicClaims || (freePublicClaims.length === 0)){ if (!freePublicClaims || (freePublicClaims.length === 0)){
res.status(200).sendFile(path.join(__dirname, '../public', 'noClaims.html')); reject({
msg: "no free, public claims",
err: "no free, public claims"
});
return; return;
} }
// order the claims // order the claims
@ -88,24 +95,44 @@ module.exports = {
// fetch the image to display // fetch the image to display
axios.post('http://localhost:5279/lbryapi', { axios.post('http://localhost:5279/lbryapi', {
method: "get", method: "get",
params: { params: { uri: freePublicClaimUri }
uri: freePublicClaimUri
}
} }
).then(function (getResponse) { ).then(function (getResponse) {
console.log(">> 'get claim' success..."); console.log(">> 'get claim' success...");
console.log(">> response data:", getResponse.data); console.log(">> response data:", getResponse.data);
console.log(">> dl path =", getResponse.data.result.download_path) console.log(">> dl path =", getResponse.data.result.download_path)
// return the claim we got // resolve the promise with the download path for the claim we got
res.status(200).sendFile(getResponse.data.result.download_path); resolve(getResponse.data.result.download_path);
}).catch(function(getError){ }).catch(function(getError){
console.log(">> /c/ 'get' error:", getError.response.data); console.log(">> 'get' error:", getError.response.data);
res.status(500).send(JSON.stringify({msg: "An error occurred while fetching the free, public claim by URI.", err: getError.response.data.error.message})); // reject the promise with an error message
}) reject({
}).catch(function(error){ msg: "An error occurred while fetching the free, public claim by URI.",
console.log(">> /c/ error:", error.response.data); err: getError.response.data.error.message
res.status(500).send(JSON.stringify({msg: "An error occurred while getting the claim list.", err: error.response.data.error.message})); });
});
}) })
.catch(function(error){
console.log(">> error:", error.response.data);
// check to see what kind of error came back from lbry
// reject the promise with an approriate message
if (error.response.data){
reject({
msg: "An error occurred while getting the claim list.",
err: error.response.data.error.message
});
} else {
reject({
msg: "An error occurred while getting the claim list.",
err: error.response
});
}
});
});
// 3. return the promise
return deferred;
kauffj commented 2017-05-31 20:40:55 +02:00 (Migrated from github.com)
Review

This should probably be defined as a constant.

This should probably be defined as a constant.
}, },
serveClaimBasedOnUri: function(uri, res){ serveClaimBasedOnUri: function(uri, res){
/* /*

View file

@ -11,6 +11,7 @@
<p>spee.ch is a single-serving site that reads and publishes images to and from the <a href="https://lbry.io">LBRY</a> blockchain.</p> <p>spee.ch is a single-serving site that reads and publishes images to and from the <a href="https://lbry.io">LBRY</a> blockchain.</p>
<h3>Status:</h3> <h3>Status:</h3>
<p id="status">your image is being retrieved</p> <p id="status">your image is being retrieved</p>
<div id="image"></div>
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
<script> <script>
var socket = io(); var socket = io();
@ -19,9 +20,17 @@
// request the image through the socket // request the image through the socket
socket.emit("image-request", url); socket.emit("image-request", url);
socket.on("image-update", function(data){
console.log("data:", data);
document.getElementById("status").innerHTML = data;
})
// receive the image through the socket // receive the image through the socket
socket.on("image-send", function(data){ socket.on("image-send", function(data){
console.log("data", data); if (data.image) {
var base64Image = 'data:image/jpeg;base64,' + data.buffer;
document.getElementById("image").innerHTML = '<img src="' + base64Image + '"/>';
}
}) })
</script> </script>
</body> </body>

View file

@ -1,20 +1,52 @@
// routes to export // routes to export
module.exports = function(app) { module.exports = function(app) {
var http = require("http").Server(app); var http = require('http').Server(app);
var io = require("socket.io")(http); var io = require('socket.io')(http);
var fs = require('fs');
var path = require('path');
var lbryApi = require('../helpers/lbryApi.js');
function sendTheImage(socket, filePath){
fs.readFile(filePath, function(err, buff){
if (err) {
console.log("fs err", err);
return;
};
//console.log("buff", buff);
socket.emit('image-send', { image: true, buffer: buff.toString('base64') });
console.log('image file has been sent via sockets');
});
}
io.on('connection', function(socket){ io.on('connection', function(socket){
console.log('a user connected'); console.log('a user connected');
// trying to serve an image file from the server // serve an image file from the server
socket.on('image-request', function(data){ socket.on('image-request', function(name){
// 1. retrieve the image from lbry via daemon // 1. retrieve the image from lbry via daemon
console.log("received image request for:", data) console.log("received image request for:", name)
// 2. emit updates as the image is being retrieved var promise = lbryApi.getClaimBasedOnNameOnly(name);
promise.then(function(data){
console.log("socket-routes / image-request - success:", data)
// 3. serve the image back once it is retrieved // 3. serve the image back once it is retrieved
socket.emit("image-send", "test string for: " + data); sendTheImage(socket, data);
})
.catch(function(error){
console.log("socket-routes / image-request - error:", error)
// handle the errors
if (error.msg === "no claims"){
socket.emit("image-update", "no claims were found for " + name);
} else if (error.msg === "no free, public claims"){
socket.emit("image-update", "no free, public claims were found for " + name);
} else {
socket.emit("image-update", "an unknown error occured with fetching claim");
};
return;
});
// 2. emit updates as the image is being retrieved
socket.emit("image-update", "we are getting your image for " + name);
}) })
// handle disconnect // handle disconnect