Blocked claims (#81)
* handle blocked claims * fix chainquery endpoint * channel-level blocking * don't show blocked claims in the result grid * optimisation: break out of foreach loop if match found * add caching for api request * rename cache key
This commit is contained in:
parent
02551e98d7
commit
31d515e992
8 changed files with 713 additions and 453 deletions
1055
composer.lock
generated
1055
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -222,7 +222,7 @@ return [
|
|||
'className' => 'Cake\Database\Connection',
|
||||
'driver' => 'Cake\Database\Driver\Mysql',
|
||||
'persistent' => false,
|
||||
'host' => 'chainquery.lbry.io',
|
||||
'host' => 'chainquery.lbry.com',
|
||||
/**
|
||||
* CakePHP will use the default DB port based on the driver selected
|
||||
* MySQL on MAMP uses port 8889, MAMP users will want to uncomment
|
||||
|
@ -257,9 +257,9 @@ return [
|
|||
*/
|
||||
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
|
||||
|
||||
'url' => env('DATABASE_URL', 'chainquery.lbry.io:3600'),
|
||||
'url' => env('DATABASE_URL', 'chainquery.lbry.com:3600'),
|
||||
],
|
||||
|
||||
|
||||
'localdb' => [ // Local db for price history
|
||||
'className' => 'Cake\Database\Connection',
|
||||
'driver' => 'Cake\Database\Driver\Mysql',
|
||||
|
|
|
@ -7,6 +7,7 @@ use Mdanter\Ecc\Crypto\Signature\Signer;
|
|||
use Mdanter\Ecc\Serializer\PublicKey\PemPublicKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer;
|
||||
use Mdanter\Ecc\Serializer\Signature\DerSignatureSerializer;
|
||||
use Cake\Cache\Cache;
|
||||
use Cake\Core\Configure;
|
||||
use Cake\Datasource\ConnectionManager;
|
||||
use Cake\Log\Log;
|
||||
|
@ -30,6 +31,8 @@ class MainController extends AppController {
|
|||
|
||||
const tagReceiptAddress = 'bLockNgmfvnnnZw7bM6SPz6hk5BVzhevEp';
|
||||
|
||||
const blockedListUrl = 'https://api.lbry.com/file/list_blocked';
|
||||
|
||||
protected $redis;
|
||||
|
||||
public function initialize() {
|
||||
|
@ -154,8 +157,10 @@ class MainController extends AppController {
|
|||
$endLimitId = $maxClaimId;
|
||||
}
|
||||
|
||||
$blockedList = json_decode($this->_getBlockedList());
|
||||
$claims = $this->Claims->find()->select($this->Claims)->
|
||||
select(['publisher' => 'C.name'])->leftJoin(['C' => 'claim'], ['C.claim_id = Claims.publisher_id'])->
|
||||
select(['publisher' => 'C.name', 'publisher_transaction_hash_id' => 'C.transaction_hash_id', 'publisher_vout' => 'C.vout'])->
|
||||
leftJoin(['C' => 'claim'], ['C.claim_id = Claims.publisher_id'])->
|
||||
where(['Claims.id >' => $startLimitId, 'Claims.id <=' => $endLimitId])->
|
||||
order(['Claims.id' => 'DESC'])->toArray();
|
||||
|
||||
|
@ -173,6 +178,17 @@ class MainController extends AppController {
|
|||
$claims[$i]->LicenseUrl = $json->metadata->licenseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
$claimChannel = null;
|
||||
if ($claims[$i]->publisher_transaction_hash_id) {
|
||||
$claimChannel = new \stdClass();
|
||||
$claimChannel->transaction_hash_id = $claims[$i]->publisher_transaction_hash_id;
|
||||
$claimChannel->vout = $claims[$i]->publisher_vout;
|
||||
}
|
||||
|
||||
$blocked = $this->_isClaimBlocked($claims[$i], $claimChannel, $blockedList);
|
||||
$claims[$i]->isBlocked = $blocked;
|
||||
$claims[$i]->thumbnail_url = $blocked ? null : $claims[$i]->thumbnail_url; // don't show the thumbnails too
|
||||
}
|
||||
|
||||
$this->set('pageLimit', $pageLimit);
|
||||
|
@ -220,8 +236,15 @@ class MainController extends AppController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fetch blocked list
|
||||
$blockedList = json_decode($this->_getBlockedList());
|
||||
$claimChannel = $this->Claims->find()->select(['transaction_hash_id', 'vout'])->where(['claim_id' => $claim->publisher_id])->first();
|
||||
$claimIsBlocked = $this->_isClaimBlocked($claim, $claimChannel, $blockedList);
|
||||
|
||||
$this->set('claim', $claim);
|
||||
$this->set('moreClaims', $moreClaims);
|
||||
$this->set('claimIsBlocked', $claimIsBlocked);
|
||||
$this->set('moreClaims', $claimIsBlocked ? [] : $moreClaims);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,4 +980,44 @@ class MainController extends AppController {
|
|||
// Close any open file handle
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function _isClaimBlocked($claim, $claimChannel, $blockedList) {
|
||||
if (!$blockedList || !isset($blockedList->data)) {
|
||||
// invalid blockedList response
|
||||
return false;
|
||||
}
|
||||
|
||||
$blockedOutpoints = $blockedList->data->outpoints;
|
||||
$claimIsBlocked = false;
|
||||
foreach ($blockedOutpoints as $outpoint) {
|
||||
// $parts[0] = txid
|
||||
// $parts[1] = vout
|
||||
$parts = explode(':', $outpoint);
|
||||
if ($claim->transaction_hash_id == $parts[0] && $claim->vout == $parts[1]) {
|
||||
$claimIsBlocked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// check if the publisher (channel) is blocked
|
||||
// block the channel if that's the case
|
||||
if ($claimChannel && $claimChannel->transaction_hash_id == $parts[0] && $claimChannel->vout == $parts[1]) {
|
||||
$claimIsBlocked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $claimIsBlocked;
|
||||
}
|
||||
|
||||
private function _getBlockedList() {
|
||||
$cachedList = Cache::read('list_blocked', 'api_requests');
|
||||
if ($cachedList !== false) {
|
||||
return $cachedList;
|
||||
}
|
||||
|
||||
// get the result from the api
|
||||
$response = self::curl_get(self::blockedListUrl);
|
||||
Cache::write('list_blocked', $response, 'api_requests');
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,14 @@ $ctTag = $claim->getContentTag();
|
|||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($claim->isBlocked): ?>
|
||||
|
||||
<div class="blocked-info">
|
||||
In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications. For more information, please refer to <a href="https://lbry.com/faq/dmca" target="_blank">DMCA takedown requests</a>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="metadata">
|
||||
<div class="title" title="<?php echo $claim->claim_type == 1 ? $claim->name : ((strlen(trim($claim->title)) > 0) ? $claim->title : '') ?>"><?php echo $claim->claim_type == 1 ? $claim->name : ((strlen(trim($claim->title)) > 0) ? $claim->title : '<em>No Title</em>') ?></div>
|
||||
<div class="link" title="<?php echo $claim->getLbryLink() ?>"><a href="<?php echo $claim->getLbryLink() ?>" rel="nofollow"><?php echo $claim->getLbryLink() ?></a></div>
|
||||
|
@ -61,10 +69,10 @@ $ctTag = $claim->getContentTag();
|
|||
|
||||
<!--<div class="label half-width">Author</div>
|
||||
<div class="label half-width">License</div>-->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--<div class="value half-width" title="<?php echo strlen(trim($claim->author)) > 0 ? $claim->author : '<em>Unspecified</em>' ?>"><?php echo strlen(trim($claim->author)) > 0 ? $claim->author : '<em>Unspecified</em>' ?></div>
|
||||
|
||||
|
||||
<div class="value half-width" title="<?php echo strlen(trim($claim->license)) > 0 ? $claim->license : '' ?>">
|
||||
<?php if (strlen(trim($claim->LicenseUrl)) > 0): ?><a href="<?php echo $claim->LicenseUrl ?>" rel="nofollow" target="_blank"><?php endif; ?>
|
||||
<?php echo strlen(trim($claim->License)) > 0 ? $claim->License : '<em>Unspecified</em>' ?>
|
||||
|
@ -73,4 +81,5 @@ $ctTag = $claim->getContentTag();
|
|||
-->
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
|
@ -65,6 +65,15 @@ if (strlen(trim($desc)) == 0) {
|
|||
</div>
|
||||
|
||||
<div class="claims-body">
|
||||
<?php if ($claimIsBlocked): ?>
|
||||
|
||||
<div class="blocked-claim-info">
|
||||
<div class="content">
|
||||
In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications. For more information, please refer to <a href="https://lbry.com/faq/dmca" target="_blank">DMCA takedown requests</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="claim-info">
|
||||
<div data-autothumb="<?php echo $autoThumbText ?>" class="thumbnail <?php echo $a[mt_rand(0, count($a) - 1)] ?>">
|
||||
<?php if (!$claim->is_nsfw && strlen(trim($claim->thumbnail_url)) > 0): ?>
|
||||
|
@ -140,6 +149,7 @@ if (strlen(trim($desc)) == 0) {
|
|||
|
||||
<div class="clear"></div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (count($moreClaims) > 0): ?>
|
||||
|
||||
|
@ -155,7 +165,7 @@ if (strlen(trim($desc)) == 0) {
|
|||
$row++;
|
||||
}
|
||||
echo $this->element('claimbox', array('claim' => $claim, 'idx' => $idx, 'last_row' => $last_row));
|
||||
$idx++;
|
||||
$idx++;
|
||||
endforeach; ?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -83,6 +83,7 @@ border-radius: 0 8px 8px 0 }
|
|||
.claims-grid .claim-grid-item .tags .nsfw { background: #e53935; text-align: center; color: #fff; position: relative; left: 1px }
|
||||
.claims-grid .claim-grid-item .tags .bid-state { background: #551CA1; text-align: center; color: #fff; }
|
||||
.claims-grid .claim-grid-item .tags .content-type { background: #880e4f; text-align: center; color: #fff; }
|
||||
.claims-grid .claim-grid-item .blocked-info { padding: 24px; font-size: 90%; }
|
||||
.claims-grid .claim-grid-item .metadata { padding: 24px; font-size: 90% }
|
||||
.claims-grid .claim-grid-item .title { font-size: 120%; height: 25px; line-height: 25px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
||||
.claims-grid .claim-grid-item .desc { font-size: 90%; font-weight: 300; height: 72px; overflow: hidden; text-overflow: ellipsis; margin: 8px 0 20px 0; line-height: 24px }
|
||||
|
@ -95,6 +96,8 @@ border-radius: 0 8px 8px 0 }
|
|||
.claims-grid .claim-grid-item .spacer { height: 16px }
|
||||
|
||||
.claims-body { width: 1200px; margin: 0 auto 0 auto; cursor: default }
|
||||
.claims-body .blocked-claim-info { border: 1px solid rgba(0,0,0,.15); cursor: default }
|
||||
.claims-body .blocked-claim-info .content { padding: 48px }
|
||||
.claims-body .claim-info { width: 400px; float: left; /*box-shadow: 0 2px 4px rgba(0,0,0,.175);*/ border: 1px solid rgba(0,0,0,.15); cursor: default }
|
||||
.claims-body .claim-info .thumbnail { width: 100%; height: 220px; background: #f0f0f0; display: block; position: relative; overflow: hidden }
|
||||
.claims-body .claim-info .thumbnail img { width: 100% }
|
||||
|
|
|
@ -38,7 +38,7 @@ function buildChartData(claimsData) {
|
|||
}
|
||||
|
||||
function loadChartData() {
|
||||
var api_url = "https://chainquery.lbry.io/api/sql?query=";
|
||||
var api_url = "https://chainquery.lbry.com/api/sql?query=";
|
||||
var query = "SELECT c1.claim_type, c1.bid_state, c1.effective_amount, c1.transaction_time, o.transaction_time AS 'spent_time' FROM claim c1 LEFT JOIN (SELECT output.claim_id, tx.transaction_time FROM output INNER JOIN input ON input.prevout_hash = output.transaction_hash AND input.prevout_n = output.vout INNER JOIN transaction tx ON tx.id = input.transaction_id) o ON o.claim_id=c1.claim_id AND c1.bid_state='Spent' ORDER BY c1.transaction_time ASC";
|
||||
var url = api_url + query;
|
||||
var loadProgress = $('.bids-chart-container .load-progress');
|
||||
|
@ -167,4 +167,4 @@ divId: 'chart-export'
|
|||
}
|
||||
});
|
||||
loadChartData();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -97,7 +97,7 @@ function buildChartData(blockData) {
|
|||
}
|
||||
|
||||
function loadChartData() {
|
||||
var api_url = "https://chainquery.lbry.io/api/sql?query=";
|
||||
var api_url = "https://chainquery.lbry.com/api/sql?query=";
|
||||
var query = "SELECT height, block_time FROM block WHERE confirmations > 0 ORDER BY height";
|
||||
var url = api_url + query;
|
||||
var loadProgress = $('.mining-inflation-chart-container .load-progress');
|
||||
|
@ -261,4 +261,4 @@ divId: 'chart-export'
|
|||
}
|
||||
});
|
||||
loadChartData();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue