Staging #1066
13 changed files with 249 additions and 81 deletions
|
@ -2,5 +2,6 @@ client/build
|
||||||
node_modules/
|
node_modules/
|
||||||
public/bundle
|
public/bundle
|
||||||
server/render/build
|
server/render/build
|
||||||
|
server/bundle
|
||||||
test/
|
test/
|
||||||
server/chainquery
|
server/chainquery
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2017-2018 LBRY Inc.
|
Copyright (c) 2017-2019 LBRY Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
|
||||||
"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
"Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
"ipAddress": "",
|
"ipAddress": "",
|
||||||
"host": "https://www.example.com",
|
"host": "https://www.example.com",
|
||||||
"description": "A decentralized hosting platform built on LBRY",
|
"description": "A decentralized hosting platform built on LBRY",
|
||||||
"twitter": false
|
"twitter": false,
|
||||||
|
"blockListEndpoint": "https://api.lbry.io/file/list_blocked"
|
||||||
},
|
},
|
||||||
"publishing": {
|
"publishing": {
|
||||||
"primaryClaimAddress": null,
|
"primaryClaimAddress": null,
|
||||||
|
|
|
@ -2,6 +2,16 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.asset-preview__blocked {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
height: 80%;
|
||||||
|
padding: 5px;
|
||||||
|
//remove margin-bottom after mystery 5px on wrapper is gone.
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.asset-preview__image {
|
.asset-preview__image {
|
||||||
width : 100%;
|
width : 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -2,51 +2,59 @@ import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
const ClaimPending = () => {
|
|
||||||
return (
|
|
||||||
<div className='claim-pending'>PENDING</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const AssetPreview = ({ defaultThumbnail, claimData }) => {
|
const AssetPreview = ({ defaultThumbnail, claimData }) => {
|
||||||
const {name, fileExt, contentType, thumbnail, title, pending} = claimData;
|
const {name, fileExt, contentType, thumbnail, title, blocked} = claimData;
|
||||||
const showUrl = createCanonicalLink({asset: {...claimData}});
|
const showUrl = createCanonicalLink({asset: {...claimData}});
|
||||||
const embedUrl = `${showUrl}.${fileExt}`;
|
const embedUrl = `${showUrl}.${fileExt}`;
|
||||||
switch (contentType) {
|
|
||||||
case 'image/jpeg':
|
/*
|
||||||
case 'image/jpg':
|
This blocked section shouldn't be necessary after pagination is reworked,
|
||||||
case 'image/png':
|
though it might be useful for channel_mine situations.
|
||||||
case 'image/gif':
|
*/
|
||||||
return (
|
|
||||||
<Link to={showUrl} className='asset-preview'>
|
if (blocked) {
|
||||||
<div>
|
return (
|
||||||
|
<div className='asset-preview'>
|
||||||
|
<div className='asset-preview__blocked'>
|
||||||
|
<h3>Error 451</h3>
|
||||||
|
<p>This content is blocked for legal reasons.</p>
|
||||||
|
</div>
|
||||||
|
<h3 className='asset-preview__title'>Blocked Content</h3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
switch (contentType) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/png':
|
||||||
|
case 'image/gif':
|
||||||
|
return (
|
||||||
|
<Link to={showUrl} className='asset-preview'>
|
||||||
<img
|
<img
|
||||||
className={'asset-preview__image'}
|
className={'asset-preview__image'}
|
||||||
src={embedUrl}
|
src={embedUrl}
|
||||||
alt={name}
|
alt={name}
|
||||||
/>
|
/>
|
||||||
<h3 className='asset-preview__title'>{title}</h3>
|
<h3 className='asset-preview__title'>{title}</h3>
|
||||||
</div>
|
</Link>
|
||||||
</Link>
|
);
|
||||||
);
|
case 'video/mp4':
|
||||||
case 'video/mp4':
|
return (
|
||||||
return (
|
<Link to={showUrl} className='asset-preview'>
|
||||||
<Link to={showUrl} className='asset-preview'>
|
|
||||||
<div>
|
|
||||||
<div className='asset-preview__play-wrapper'>
|
<div className='asset-preview__play-wrapper'>
|
||||||
<img
|
<img
|
||||||
className={'asset-preview__video'}
|
className={'asset-preview__video'}
|
||||||
src={thumbnail || defaultThumbnail}
|
src={thumbnail || defaultThumbnail}
|
||||||
alt={name}
|
alt={name}
|
||||||
/>
|
/>
|
||||||
<div className='asset-preview__play-overlay'></div>
|
<div className='asset-preview__play-overlay' />
|
||||||
</div>
|
</div>
|
||||||
<h3 className='asset-preview__title'>{title}</h3>
|
<h3 className='asset-preview__title'>{title}</h3>
|
||||||
</div>
|
</Link>
|
||||||
</Link>
|
);
|
||||||
);
|
default:
|
||||||
default:
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
13
client/src/containers/AssetBlocked/index.js
Normal file
13
client/src/containers/AssetBlocked/index.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import View from './view';
|
||||||
|
import { selectAsset } from '../../selectors/show';
|
||||||
|
|
||||||
|
const mapStateToProps = (props) => {
|
||||||
|
const {show} = props;
|
||||||
|
const asset = selectAsset(show);
|
||||||
|
return {
|
||||||
|
asset,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, null)(View);
|
58
client/src/containers/AssetBlocked/view.jsx
Normal file
58
client/src/containers/AssetBlocked/view.jsx
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import React from 'react';
|
||||||
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
import HorizontalSplit from '@components/HorizontalSplit';
|
||||||
|
/*
|
||||||
|
This component shouldn't be necessary after pagination is reworked,
|
||||||
|
though it might be useful for channel_mine situations.
|
||||||
|
*/
|
||||||
|
class BlockedLeft extends React.PureComponent {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<img className='asset-image' src={'https://upload.wikimedia.org/wikipedia/commons/archive/a/af/20120315000030%21OR_451.svg'} alt={'451 image'} />
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BlockedRight extends React.PureComponent {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<p>In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.</p>
|
||||||
|
<p><a href={'https://lbry.io/faq/dmca'} >Click here</a> for more information.</p>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AssetBlocked extends React.Component {
|
||||||
|
componentDidMount () {
|
||||||
|
/*
|
||||||
|
This function and fetch exists to send the browser the appropriate 451 error.
|
||||||
|
*/
|
||||||
|
const { asset } = this.props;
|
||||||
|
const { claimData: { contentType, outpoint } } = asset;
|
||||||
|
let fileExt;
|
||||||
|
if (typeof contentType === 'string') {
|
||||||
|
fileExt = contentType.split('/')[1] || 'jpg';
|
||||||
|
}
|
||||||
|
const sourceUrl = `${createCanonicalLink({ asset: asset.claimData })}.${fileExt}?${outpoint}`;
|
||||||
|
fetch(sourceUrl)
|
||||||
|
.catch();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<HorizontalSplit
|
||||||
|
collapseOnMobile
|
||||||
|
leftSide={<BlockedLeft />}
|
||||||
|
rightSide={<BlockedRight />}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AssetBlocked;
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import PageLayout from '@components/PageLayout';
|
import PageLayout from '@components/PageLayout';
|
||||||
import * as Icon from 'react-feather';
|
import * as Icon from 'react-feather';
|
||||||
import AssetDisplay from '@containers/AssetDisplay';
|
import AssetDisplay from '@containers/AssetDisplay';
|
||||||
|
import AssetBlocked from '@containers/AssetBlocked';
|
||||||
import AssetInfo from '@containers/AssetInfo';
|
import AssetInfo from '@containers/AssetInfo';
|
||||||
import ErrorPage from '@pages/ErrorPage';
|
import ErrorPage from '@pages/ErrorPage';
|
||||||
import AssetTitle from '@containers/AssetTitle';
|
import AssetTitle from '@containers/AssetTitle';
|
||||||
|
@ -29,23 +30,32 @@ class ShowAssetDetails extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const { asset } = this.props;
|
const { asset } = this.props;
|
||||||
if (asset) {
|
if (asset) {
|
||||||
const { claimData: { name } } = asset;
|
const { claimData: { name, blocked } } = asset;
|
||||||
return (
|
if (!blocked) {
|
||||||
<PageLayout
|
return (
|
||||||
pageTitle={`${name} - details`}
|
<PageLayout
|
||||||
asset={asset}
|
pageTitle={`${name} - details`}
|
||||||
>
|
asset={asset}
|
||||||
<div className="asset-main">
|
>
|
||||||
<AssetDisplay />
|
<div className="asset-main">
|
||||||
<AssetTitle />
|
<AssetDisplay />
|
||||||
|
<AssetTitle />
|
||||||
<button className='collapse-button' onClick={this.collapse}>
|
<button className='collapse-button' onClick={this.collapse}>
|
||||||
{this.state.closed ? <Icon.PlusCircle className='plus-icon' /> : <Icon.MinusCircle />}
|
{this.state.closed ? <Icon.PlusCircle className='plus-icon' /> : <Icon.MinusCircle />}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{!this.state.closed && <AssetInfo />}
|
{!this.state.closed && <AssetInfo />}
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<PageLayout>
|
||||||
|
<div className="asset-main">
|
||||||
|
<AssetBlocked />
|
||||||
|
</div>
|
||||||
|
</PageLayout>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ErrorPage error={'loading asset data...'} />
|
<ErrorPage error={'loading asset data...'} />
|
||||||
|
|
|
@ -5,6 +5,7 @@ const getClaimData = require('server/utils/getClaimData');
|
||||||
const chainquery = require('chainquery').default;
|
const chainquery = require('chainquery').default;
|
||||||
const db = require('../../../../models');
|
const db = require('../../../../models');
|
||||||
const waitOn = require('wait-on');
|
const waitOn = require('wait-on');
|
||||||
|
const logger = require('winston');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -17,32 +18,35 @@ const claimGet = async ({ ip, originalUrl, params }, res) => {
|
||||||
const claimId = params.claimId;
|
const claimId = params.claimId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let claimData = await chainquery.claim.queries.resolveClaim(name, claimId).catch(() => {});
|
let claimInfo = await chainquery.claim.queries.resolveClaim(name, claimId).catch(() => {});
|
||||||
if (!claimData) {
|
if (claimInfo) {
|
||||||
claimData = await db.Claim.resolveClaim(name, claimId);
|
logger.info('claim/get: claim resolved in chainquery');
|
||||||
}
|
}
|
||||||
|
if (!claimInfo) {
|
||||||
if (!claimData) {
|
claimInfo = await db.Claim.resolveClaim(name, claimId);
|
||||||
throw new Error('No matching uri found in Claim table');
|
}
|
||||||
|
if (!claimInfo) {
|
||||||
|
throw new Error('claim/get: resolveClaim: No matching uri found in Claim table');
|
||||||
}
|
}
|
||||||
|
|
||||||
let lbrynetResult = await getClaim(`${name}#${claimId}`);
|
let lbrynetResult = await getClaim(`${name}#${claimId}`);
|
||||||
if (!lbrynetResult) {
|
if (!lbrynetResult) {
|
||||||
throw new Error(`Unable to Get ${name}#${claimId}`);
|
throw new Error(`claim/get: getClaim Unable to Get ${name}#${claimId}`);
|
||||||
|
}
|
||||||
|
const claimData = await getClaimData(claimInfo);
|
||||||
|
if (!claimData) {
|
||||||
|
throw new Error('claim/get: getClaimData failed to get file blobs');
|
||||||
|
}
|
||||||
|
await waitOn({
|
||||||
|
resources: [ lbrynetResult.download_path ],
|
||||||
|
timeout : 10000, // 10 seconds
|
||||||
|
window : 500,
|
||||||
|
});
|
||||||
|
const fileData = await createFileRecordDataAfterGet(claimData, lbrynetResult);
|
||||||
|
if (!fileData) {
|
||||||
|
throw new Error('claim/get: createFileRecordDataAfterGet failed to create file in time');
|
||||||
}
|
}
|
||||||
|
|
||||||
let fileData = await createFileRecordDataAfterGet(await getClaimData(claimData), lbrynetResult);
|
|
||||||
const upsertCriteria = { name, claimId };
|
const upsertCriteria = { name, claimId };
|
||||||
await db.upsert(db.File, fileData, upsertCriteria, 'File');
|
await db.upsert(db.File, fileData, upsertCriteria, 'File');
|
||||||
|
|
||||||
try {
|
|
||||||
await waitOn({
|
|
||||||
resources: [ lbrynetResult.file_name ],
|
|
||||||
delay : 500,
|
|
||||||
timeout : 10000, // 10 seconds
|
|
||||||
});
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
const { message, completed } = lbrynetResult;
|
const { message, completed } = lbrynetResult;
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
success: true,
|
success: true,
|
||||||
|
@ -53,5 +57,4 @@ const claimGet = async ({ ip, originalUrl, params }, res) => {
|
||||||
handleErrorResponse(originalUrl, ip, error, res);
|
handleErrorResponse(originalUrl, ip, error, res);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = claimGet;
|
module.exports = claimGet;
|
||||||
|
|
|
@ -16,6 +16,7 @@ const createDatabaseIfNotExists = require('./models/utils/createDatabaseIfNotExi
|
||||||
const { getWalletBalance } = require('./lbrynet/index');
|
const { getWalletBalance } = require('./lbrynet/index');
|
||||||
const configureLogging = require('./utils/configureLogging');
|
const configureLogging = require('./utils/configureLogging');
|
||||||
const configureSlack = require('./utils/configureSlack');
|
const configureSlack = require('./utils/configureSlack');
|
||||||
|
const { setupBlockList } = require('./utils/blockList');
|
||||||
const speechPassport = require('./speechPassport');
|
const speechPassport = require('./speechPassport');
|
||||||
const processTrending = require('./utils/processTrending');
|
const processTrending = require('./utils/processTrending');
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ const {
|
||||||
} = require('./middleware/logMetricsMiddleware');
|
} = require('./middleware/logMetricsMiddleware');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
details: { port: PORT },
|
details: { port: PORT, blockListEndpoint },
|
||||||
startup: {
|
startup: {
|
||||||
performChecks,
|
performChecks,
|
||||||
performUpdates,
|
performUpdates,
|
||||||
|
@ -34,6 +35,9 @@ const {
|
||||||
|
|
||||||
const { sessionKey } = require('@private/authConfig.json');
|
const { sessionKey } = require('@private/authConfig.json');
|
||||||
|
|
||||||
|
// configure.js doesn't handle new keys in config.json files yet. Make sure it doens't break.
|
||||||
|
let bLE;
|
||||||
|
|
||||||
function Server () {
|
function Server () {
|
||||||
this.initialize = () => {
|
this.initialize = () => {
|
||||||
// configure logging
|
// configure logging
|
||||||
|
@ -166,19 +170,37 @@ function Server () {
|
||||||
logger.info('Starting LBC balance:', walletBalance);
|
logger.info('Starting LBC balance:', walletBalance);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.performUpdates = () => {
|
this.performUpdates = () => {
|
||||||
if (!performUpdates) {
|
if (!performUpdates) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (blockListEndpoint) {
|
||||||
|
bLE = blockListEndpoint;
|
||||||
|
} else if (!blockListEndpoint) {
|
||||||
|
if (typeof (blockListEndpoint) !== 'string') {
|
||||||
|
logger.warn('blockListEndpoint is null due to outdated siteConfig file. \n' +
|
||||||
|
'Continuing with default LBRY blocklist api endpoint. \n ' +
|
||||||
|
'(Specify /"blockListEndpoint" : ""/ to disable.')
|
||||||
|
bLE = 'https://api.lbry.io/file/list_blocked';
|
||||||
|
}
|
||||||
|
}
|
||||||
logger.info(`Peforming updates...`);
|
logger.info(`Peforming updates...`);
|
||||||
return Promise.all([
|
if (!bLE) {
|
||||||
db.Blocked.refreshTable(),
|
logger.info('Configured for no Block List')
|
||||||
db.Tor.refreshTable(),
|
db.Tor.refreshTable().then( (updatedTorList) => {
|
||||||
])
|
|
||||||
.then(([updatedBlockedList, updatedTorList]) => {
|
|
||||||
logger.info('Blocked list updated, length:', updatedBlockedList.length);
|
|
||||||
logger.info('Tor list updated, length:', updatedTorList.length);
|
logger.info('Tor list updated, length:', updatedTorList.length);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return Promise.all([
|
||||||
|
db.Blocked.refreshTable(bLE),
|
||||||
|
db.Tor.refreshTable()])
|
||||||
|
.then(([updatedBlockedList, updatedTorList]) => {
|
||||||
|
logger.info('Blocked list updated, length:', updatedBlockedList.length);
|
||||||
|
logger.info('Tor list updated, length:', updatedTorList.length);
|
||||||
|
})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
this.start = () => {
|
this.start = () => {
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
@ -194,6 +216,9 @@ function Server () {
|
||||||
this.performUpdates(),
|
this.performUpdates(),
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
|
.then(() => {
|
||||||
|
return setupBlockList();
|
||||||
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.info('Spee.ch startup is complete');
|
logger.info('Spee.ch startup is complete');
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
|
|
||||||
const BLOCKED_CLAIM = 'BLOCKED_CLAIM';
|
const BLOCKED_CLAIM = 'BLOCKED_CLAIM';
|
||||||
|
|
||||||
module.exports = (sequelize, { STRING }) => {
|
module.exports = (sequelize, { STRING }) => {
|
||||||
|
@ -16,6 +15,14 @@ module.exports = (sequelize, { STRING }) => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Blocked.getBlockList = function () {
|
||||||
|
logger.debug('returning full block list');
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.findAll()
|
||||||
|
.then(list => { return resolve(list) });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Blocked.isNotBlocked = function (outpoint) {
|
Blocked.isNotBlocked = function (outpoint) {
|
||||||
logger.debug(`checking to see if ${outpoint} is not blocked`);
|
logger.debug(`checking to see if ${outpoint} is not blocked`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -37,9 +44,10 @@ module.exports = (sequelize, { STRING }) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Blocked.refreshTable = function () {
|
Blocked.refreshTable = function (blockEndpoint) {
|
||||||
let blockedList = [];
|
let blockedList = [];
|
||||||
return fetch('https://api.lbry.io/file/list_blocked')
|
|
||||||
|
return fetch(blockEndpoint)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
|
@ -50,9 +58,7 @@ module.exports = (sequelize, { STRING }) => {
|
||||||
if (!jsonResponse.data.outpoints) {
|
if (!jsonResponse.data.outpoints) {
|
||||||
throw new Error('no outpoints in list_blocked response');
|
throw new Error('no outpoints in list_blocked response');
|
||||||
}
|
}
|
||||||
return jsonResponse.data.outpoints;
|
let outpoints = jsonResponse.data.outpoints;
|
||||||
})
|
|
||||||
.then(outpoints => {
|
|
||||||
logger.debug('total outpoints:', outpoints.length);
|
logger.debug('total outpoints:', outpoints.length);
|
||||||
// prep the records
|
// prep the records
|
||||||
for (let i = 0; i < outpoints.length; i++) {
|
for (let i = 0; i < outpoints.length; i++) {
|
||||||
|
|
26
server/utils/blockList.js
Normal file
26
server/utils/blockList.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
const logger = require('winston');
|
||||||
|
const db = require('../models');
|
||||||
|
|
||||||
|
let blockList = new Set();
|
||||||
|
|
||||||
|
const setupBlockList = (intervalInSeconds = 60) => {
|
||||||
|
const fetchList = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
db.Blocked.getBlockList()
|
||||||
|
.then((result) => {
|
||||||
|
blockList.clear();
|
||||||
|
if (result.length > 0) {
|
||||||
|
result.map((item) => { blockList.add(item.dataValues.outpoint) });
|
||||||
|
resolve();
|
||||||
|
} else reject();
|
||||||
|
})
|
||||||
|
.catch(e => { console.error('list was empty', e) });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
setInterval(() => { fetchList() }, intervalInSeconds * 1000);
|
||||||
|
return fetchList();
|
||||||
|
};
|
||||||
|
module.exports = {
|
||||||
|
isBlocked: (outpoint) => { return blockList.has(outpoint) },
|
||||||
|
setupBlockList,
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
const { details: { host } } = require('@config/siteConfig');
|
const { details: { host } } = require('@config/siteConfig');
|
||||||
const chainquery = require('chainquery').default;
|
const chainquery = require('chainquery').default;
|
||||||
const { getClaim } = require('server/lbrynet');
|
const { getClaim } = require('server/lbrynet');
|
||||||
|
const { isBlocked } = require('./blockList');
|
||||||
|
|
||||||
module.exports = async (data, chName = null, chShortId = null) => {
|
module.exports = async (data, chName = null, chShortId = null) => {
|
||||||
// TODO: Refactor getching the channel name out; requires invasive changes.
|
// TODO: Refactor getching the channel name out; requires invasive changes.
|
||||||
|
@ -9,6 +10,11 @@ module.exports = async (data, chName = null, chShortId = null) => {
|
||||||
let lbrynetFileExt = null;
|
let lbrynetFileExt = null;
|
||||||
let channelShortId = chShortId;
|
let channelShortId = chShortId;
|
||||||
let channelName = chName;
|
let channelName = chName;
|
||||||
|
let blocked;
|
||||||
|
const outPoint = `${data.transaction_hash_id}:${data.vout}`;
|
||||||
|
if (isBlocked(outPoint)) {
|
||||||
|
blocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!chName && certificateId && !channelName) {
|
if (!chName && certificateId && !channelName) {
|
||||||
channelName = await chainquery.claim.queries.getClaimChannelName(certificateId).catch(() => {
|
channelName = await chainquery.claim.queries.getClaimChannelName(certificateId).catch(() => {
|
||||||
|
@ -38,8 +44,9 @@ module.exports = async (data, chName = null, chShortId = null) => {
|
||||||
fileExt : data.generated_extension || data.fileExt || lbrynetFileExt,
|
fileExt : data.generated_extension || data.fileExt || lbrynetFileExt,
|
||||||
description: data.description,
|
description: data.description,
|
||||||
thumbnail : data.generated_thumbnail || data.thumbnail_url || data.thumbnail,
|
thumbnail : data.generated_thumbnail || data.thumbnail_url || data.thumbnail,
|
||||||
outpoint : `${data.transaction_hash_id}:${data.vout}` || data.outpoint,
|
outpoint : outPoint || data.outpoint,
|
||||||
host,
|
host,
|
||||||
pending : Boolean(data.height === 0),
|
pending : Boolean(data.height === 0),
|
||||||
|
blocked : blocked,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue