added metadata to claims

This commit is contained in:
Niko Storni 2017-06-12 02:03:31 +02:00
parent 5894b1a0c8
commit 16a777ad33

View file

@ -5,6 +5,7 @@ var mongo;
var slackbot; var slackbot;
var channel; var channel;
var moment = require('moment'); var moment = require('moment');
const request = require("request");
module.exports = { module.exports = {
init: init, init: init,
@ -12,24 +13,21 @@ module.exports = {
function init(slackbot_, channel_, rpcuser, rpcpassword, mongodburl) { function init(slackbot_, channel_, rpcuser, rpcpassword, mongodburl) {
if (lbry) if (lbry) {
{
throw new Error('init was already called once'); throw new Error('init was already called once');
} }
slackbot = slackbot_; slackbot = slackbot_;
channel = channel_; channel = channel_;
if (!channel_) if (!channel_) {
{
console.log('No claims channel, disabling claimbot'); console.log('No claims channel, disabling claimbot');
return; return;
} }
const MongoClient = require('mongodb').MongoClient; const MongoClient = require('mongodb').MongoClient;
MongoClient.connect(mongodburl, function (err, db) { MongoClient.connect(mongodburl, function (err, db) {
if (err) if (err) {
{
throw err; throw err;
} }
mongo = db; mongo = db;
@ -51,18 +49,15 @@ function init(slackbot_, channel_, rpcuser, rpcpassword, mongodburl) {
}); });
} }
function announceNewClaims() { function announceNewClaims() {
if (!mongo) if (!mongo) {
{ slackPost('Failed to connect to mongo', { icon_emoji: ':exclamation:' });
slackPost('Failed to connect to mongo', {icon_emoji: ':exclamation:'});
return; return;
} }
if (!lbry) if (!lbry) {
{ slackPost('Failed to connect to lbrycrd', { icon_emoji: ':exclamation:' });
slackPost('Failed to connect to lbrycrd', {icon_emoji: ':exclamation:'});
return; return;
} }
@ -72,16 +67,14 @@ function announceNewClaims() {
// console.log('Checking for new blocks'); // console.log('Checking for new blocks');
if (lastProcessedBlock === null) if (lastProcessedBlock === null) {
{
console.log('First run. Setting last processed block to ' + currentHeight + ' and exiting.'); console.log('First run. Setting last processed block to ' + currentHeight + ' and exiting.');
return setLastBlock(currentHeight); return setLastBlock(currentHeight);
} }
const testBlock = false; const testBlock = false;
if (testBlock || lastProcessedBlock < currentHeight) if (testBlock || lastProcessedBlock < currentHeight) {
{
const firstBlockToProcess = testBlock || lastProcessedBlock + 1, const firstBlockToProcess = testBlock || lastProcessedBlock + 1,
lastBlockToProcess = testBlock || currentHeight; lastBlockToProcess = testBlock || currentHeight;
@ -91,7 +84,7 @@ function announceNewClaims() {
} }
}) })
.catch(function (err) { .catch(function (err) {
slackPost(err.stack, {icon_emoji: ':exclamation:'}); slackPost(err.stack, { icon_emoji: ':exclamation:' });
}); });
} }
@ -118,108 +111,115 @@ function announceClaimsLoop(block, lastBlock, currentHeight) {
}) })
.then(function () { .then(function () {
const nextBlock = block + 1; const nextBlock = block + 1;
if (nextBlock <= lastBlock) if (nextBlock <= lastBlock) {
{
return announceClaimsLoop(nextBlock, lastBlock, currentHeight); return announceClaimsLoop(nextBlock, lastBlock, currentHeight);
} }
}); });
} }
function announceClaim(claim, claimBlockHeight, currentHeight) { function announceClaim(claim, claimBlockHeight, currentHeight) {
//console.log(claim);
console.log('' + claimBlockHeight + ': New claim for ' + claim['name']); console.log('' + claimBlockHeight + ': New claim for ' + claim['name']);
return Promise.all([ var options = {
lbryCall('getvalueforname', claim['name']), method: 'GET',
lbryCall('getclaimsforname', claim['name']), url: 'https://explorer.lbry.io/api/getclaimbyid/' + claim['claimId']
]) //url: 'http://127.0.0.1:5000/claim_decode/' + claim['name']
.then(function ([currentWinningClaim, claimsForName]) { };
let value;
try
{
value = JSON.parse(claim['value']);
}
catch (e)
{
}
const text = []; request(options, function (error, response, body) {
if (error) throw new Error(error);
body = JSON.parse(body);
try {
let claimData = body.value.stream.metadata;
let channelName = (body.hasOwnProperty('channel_name') ? body['channel_name'] : null);
//claimData = JSON.parse(body).stream.metadata;
//console.log(JSON.stringify(claimData));
return Promise.all([
lbryCall('getvalueforname', claim['name']),
lbryCall('getclaimsforname', claim['name']),
])
.then(function ([currentWinningClaim, claimsForName]) {
//console.log(JSON.stringify(claimData));
let value = claimData;
if (value) const text = [];
{
if (value['author']) if (value) {
{ if (channelName) {
text.push(value['author']); text.push("Channel: lbry://" + channelName);
} }
if (value['description']) else if (value['author']) {
{ text.push("author: " + value['author']);
text.push(value['description']); }
} if (value['description']) {
// if (value['content_type']) text.push(value['description']);
// { }
// text.push("*Content Type:* " + value['content_type']); // if (value['content_type'])
// } // {
if (value['nsfw']) // text.push("*Content Type:* " + value['content_type']);
{ // }
text.push("*Warning: Adult Content*"); if (value['nsfw']) {
} text.push("*Warning: Adult Content*");
if (value['fee']) }
{ if (value['fee']) {
const fees = []; const fees = [];
for (var key in value['fee']) for (var key in value['fee']) {
{ fees.push(value['fee'][key]['amount'] + ' ' + key);
fees.push(value['fee'][key]['amount'] + ' ' + key); }
text.push(fees.join(', '));
}
} }
text.push(fees.join(', '));
}
}
if (!claim['is controlling']) if (!claim['is controlling']) {
{ // the following is based on https://lbry.io/faq/claimtrie-implementation
// the following is based on https://lbry.io/faq/claimtrie-implementation const lastTakeoverHeight = claimsForName['nLastTakeoverHeight'],
const lastTakeoverHeight = claimsForName['nLastTakeoverHeight'], maxDelay = 4032, // 7 days of blocks at 2.5min per block
maxDelay = 4032, // 7 days of blocks at 2.5min per block activationDelay = Math.min(maxDelay, Math.floor((claimBlockHeight - lastTakeoverHeight) / 32)),
activationDelay = Math.min(maxDelay, Math.floor((claimBlockHeight - lastTakeoverHeight) / 32)), takeoverHeight = claimBlockHeight + activationDelay,
takeoverHeight = claimBlockHeight + activationDelay, secondsPerBlock = 161, // in theory this should be 150, but in practice its closer to 161
secondsPerBlock = 161, // in theory this should be 150, but in practice its closer to 161 takeoverTime = Date.now() + ((takeoverHeight - currentHeight) * secondsPerBlock * 1000);
takeoverTime = Date.now() + ((takeoverHeight - currentHeight) * secondsPerBlock * 1000);
text.push('Takes effect on approx. *' + moment(takeoverTime, 'x').format('MMMM Do [at] HH:mm [UTC]') + '* (block ' + takeoverHeight + ')'); text.push('Takes effect on approx. *' + moment(takeoverTime, 'x').format('MMMM Do [at] HH:mm [UTC]') + '* (block ' + takeoverHeight + ')');
} }
const attachment = { const attachment = {
"fallback": "New claim for lbry://" + claim['name'], "fallback": "New claim for lbry://" + claim['name'],
"color": "#155b4a", "color": "#155b4a",
// "pretext": "New claim in block " + claimBlockHeight, // "pretext": "New claim in block " + claimBlockHeight,
// "author_name": 'lbry://' + claim['name'], // "author_name": 'lbry://' + claim['name'],
// "author_link": 'lbry://' + claim['name'], // "author_link": 'lbry://' + claim['name'],
// "author_icon": "http://flickr.com/icons/bobby.jpg", // "author_icon": "http://flickr.com/icons/bobby.jpg",
"title": "lbry://" + claim['name'], //escapeSlackHtml(value['title']), "title": "lbry://" + (channelName ? channelName + '/' : '') + claim['name'], //escapeSlackHtml(value['title']),
"title_link": "lbry://" + claim['name'], "title_link": "lbry://" + (channelName ? channelName + '/' : '') + claim['name'],
"text": escapeSlackHtml(text.join("\n")), "text": escapeSlackHtml(text.join("\n")),
// "fields": [], // "fields": [],
// "image_url": value['nsfw'] ? null : value['thumbnail'], // "image_url": value['nsfw'] ? null : value['thumbnail'],
// "thumb_url": (!value || value['nsfw']) ? null : value['thumbnail'], // "thumb_url": (!value || value['nsfw']) ? null : value['thumbnail'],
"unfurl_links": false, "unfurl_links": false,
"unfurl_media": false, "unfurl_media": false,
"link_names": false, "link_names": false,
"parse": "none", "parse": "none",
"footer": "Block " + claimBlockHeight + " • Claim ID " + claim['claimId'], "footer": "Block " + claimBlockHeight + " • Claim ID " + claim['claimId'],
"mrkdwn_in": ['text'], "mrkdwn_in": ['text'],
}; };
if (value) if (value) {
{ attachment['fallback'] += (': "' + value['title'] + '" by ' + value['author']);
attachment['fallback'] += (': "' + value['title'] + '" by ' + value['author']); attachment['author_name'] = 'lbry://' + (channelName ? channelName + '/' : '') + claim['name'];
attachment['author_name'] = 'lbry://' + claim['name']; attachment['author_link'] = 'lbry://' + (channelName ? channelName + '/' : '') + claim['name'];
attachment['author_link'] = 'lbry://' + claim['name']; attachment['title'] = escapeSlackHtml(value['title']);
attachment['title'] = escapeSlackHtml(value['title']); if (!value['nsfw']) {
if (!value['nsfw']) attachment['thumb_url'] = value['thumbnail'];
{ }
attachment['thumb_url'] = value['thumbnail']; }
}
}
slackPost('', {icon_emoji: ':bellhop_bell:', attachments: [attachment]}); slackPost('', { icon_emoji: ':bellhop_bell:', attachments: [attachment] });
}); });
}
catch (e) {
console.error(e);
}
});
} }
function escapeSlackHtml(txt) { function escapeSlackHtml(txt) {
@ -238,17 +238,14 @@ function getClaimsForTxid(txid) {
function getLastBlock() { function getLastBlock() {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
mongo.collection('claimbot').findOne({}, function (err, obj) { mongo.collection('claimbot').findOne({}, function (err, obj) {
if (err) if (err) {
{
reject(err); reject(err);
} }
else if (!obj) else if (!obj) {
{ mongo.collection('claimbot').createIndex({ 'last_block': 1 }, { unique: true });
mongo.collection('claimbot').createIndex({'last_block': 1}, {unique: true});
resolve(null); resolve(null);
} }
else else {
{
resolve(obj.last_block); resolve(obj.last_block);
} }
}); });
@ -258,16 +255,14 @@ function getLastBlock() {
function setLastBlock(block) { function setLastBlock(block) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
mongo.collection('claimbot').findOneAndUpdate( mongo.collection('claimbot').findOneAndUpdate(
{'last_block': {'$exists': true}}, { 'last_block': { '$exists': true } },
{'last_block': block}, { 'last_block': block },
{'upsert': true, 'returnOriginal': false}, { 'upsert': true, 'returnOriginal': false },
function (err, obj) { function (err, obj) {
if (!err && obj && obj.value.last_block != block) if (!err && obj && obj.value.last_block != block) {
{
reject('Last value should be ' + block + ', but it is ' + obj.value.last_block); reject('Last value should be ' + block + ', but it is ' + obj.value.last_block);
} }
else else {
{
resolve(); resolve();
} }
} }
@ -284,12 +279,10 @@ function slackPost(text, params) {
function lbryCall(...args) { function lbryCall(...args) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
lbry.cmd(...args, function (err, ...response) { lbry.cmd(...args, function (err, ...response) {
if (err) if (err) {
{
reject(new Error('JSONRPC call failed. Args: [' + args.join(', ') + ']')); reject(new Error('JSONRPC call failed. Args: [' + args.join(', ') + ']'));
} }
else else {
{
resolve(...response); resolve(...response);
} }
}); });