From 6e8a6519804c44200332e8ad4a47180d616dc23e Mon Sep 17 00:00:00 2001 From: marcdeb1 Date: Mon, 17 Dec 2018 00:49:26 +0100 Subject: [PATCH 01/43] Tx and index page --- config/app.default.php | 10 +- src/Controller/MainController.php | 75 +++++------- src/Model/Entity/Block.php | 3 + src/Model/Entity/Claim.php | 18 +-- src/Model/Entity/ClaimStream.php | 11 -- src/Model/Entity/Transaction.php | 11 ++ src/Model/Table/AddressesTable.php | 4 +- src/Model/Table/BlocksTable.php | 4 +- src/Model/Table/ClaimStreamsTable.php | 18 --- src/Model/Table/ClaimsTable.php | 20 +-- src/Model/Table/InputsTable.php | 14 +-- src/Model/Table/OutputsTable.php | 20 +-- src/Model/Table/TransactionsTable.php | 4 +- src/Template/Main/blocks.ctp | 58 ++++----- src/Template/Main/index.ctp | 44 +++---- src/Template/Main/tx.ctp | 52 ++++---- webroot/css/bids-chart.css | 8 ++ webroot/js/bids-chart.js | 170 ++++++++++++++++++++++++++ 18 files changed, 341 insertions(+), 203 deletions(-) delete mode 100644 src/Model/Entity/ClaimStream.php delete mode 100644 src/Model/Table/ClaimStreamsTable.php create mode 100644 webroot/css/bids-chart.css create mode 100644 webroot/js/bids-chart.js diff --git a/config/app.default.php b/config/app.default.php index c06599e..7fbc837 100644 --- a/config/app.default.php +++ b/config/app.default.php @@ -222,16 +222,16 @@ return [ 'className' => 'Cake\Database\Connection', 'driver' => 'Cake\Database\Driver\Mysql', 'persistent' => false, - 'host' => 'localhost', + 'host' => 'chainquery.lbry.io:3600', /** * CakePHP will use the default DB port based on the driver selected * MySQL on MAMP uses port 8889, MAMP users will want to uncomment * the following line and set the port accordingly */ //'port' => 'non_standard_port_number', - 'username' => 'my_app', - 'password' => 'secret', - 'database' => 'my_app', + 'username' => 'marcdeb', + 'password' => '3885fc6d0b71befe72a327f47f36c0911057', + 'database' => 'lbry', 'encoding' => 'utf8', 'timezone' => 'UTC', 'flags' => [], @@ -257,7 +257,7 @@ return [ */ //'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'], - 'url' => env('DATABASE_URL', null), + 'url' => env('DATABASE_URL', 'chainquery.lbry.io:3600'), ], /** diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index cc5d715..f144f0c 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -14,6 +14,7 @@ use Endroid\QrCode\ErrorCorrectionLevel; use Endroid\QrCode\LabelAlignment; use Endroid\QrCode\QrCode; + class MainController extends AppController { public static $rpcurl; @@ -92,21 +93,23 @@ class MainController extends AppController { $lbcUsdPrice = $this->_getLatestPrice(); $this->set('lbcUsdPrice', $lbcUsdPrice); - $blocks = $this->Blocks->find()->select(['Chainwork', 'Confirmations', 'Difficulty', 'Hash', 'Height', 'TransactionHashes', 'BlockTime', 'BlockSize'])-> - order(['Height' => 'desc'])->limit(6)->toArray(); + $blocks = $this->Blocks->find()->select(['chainwork', 'confirmations', 'difficulty', 'hash', 'height', 'transaction_hashes', 'block_time', 'block_size'])->order(['height' => 'desc'])->limit(6)->toArray(); for ($i = 0; $i < count($blocks); $i++) { - $tx_hashes = json_decode($blocks[$i]->TransactionHashes); - $blocks[$i]->TransactionCount = count($tx_hashes); + $tx_hashes = json_decode($blocks[$i]->transaction_hashes, true); + $blocks[$i]->transaction_count = count($tx_hashes); } // hash rate $hashRate = $this->_formatHashRate($this->_gethashrate()); // recent claims - $claims = $this->Claims->find()->select(['TransactionHash', 'Name', 'Vout', 'ClaimId', 'ClaimType', 'Author', 'Title', 'Description', 'ContentType', - 'IsNSFW', 'Language', 'ThumbnailUrl', 'Created'])-> - distinct(['Claims.ClaimId'])-> - contain(['Publisher' => ['fields' => ['Name']]])->order(['Claims.Created' => 'DESC'])->limit(5)->toArray(); + $claims = $this->Claims->find()->select(['transaction_hash_id', 'name', 'vout', 'claim_id', 'claim_type', 'author', 'title', 'description', 'content_type', 'is_nsfw', 'language', 'thumbnail_url', 'created_at'])-> + distinct(['Claims.claim_id'])->order(['Claims.created_at' => 'DESC'])->limit(5)->toArray(); + + foreach($claims as $claim) { + $publisher = $this->Claims->find()->select(['name'])->where(['claim_id' => $claim->publisher_id])->first(); + $claim->publisher = $publisher; + } $this->set('recentBlocks', $blocks); $this->set('recentClaims', $claims); @@ -399,10 +402,10 @@ class MainController extends AppController { } $offset = ($page - 1) * $pageLimit; - $currentBlock = $this->Blocks->find()->select(['Height'])->order(['Height' => 'DESC'])->first(); + $currentBlock = $this->Blocks->find()->select(['height'])->order(['height' => 'DESC'])->first(); $blocks = $this->Blocks->find()->select( - ['Height', 'Difficulty', 'TransactionHashes', 'BlockSize', 'Nonce', 'BlockTime'] - )->offset($offset)->limit($pageLimit)->order(['Height' => 'DESC'])->toArray(); + ['height', 'difficulty', 'transaction_hashes', 'block_size', 'nonce', 'block_time'] + )->offset($offset)->limit($pageLimit)->order(['height' => 'DESC'])->toArray(); $this->set('currentBlock', $currentBlock); $this->set('blocks', $blocks); $this->set('pageLimit', $pageLimit); @@ -416,28 +419,13 @@ class MainController extends AppController { return $this->redirect('/'); } - $block = $this->Blocks->find()->where(['Height' => $height])->first(); + $block = $this->Blocks->find()->where(['height' => $height])->first(); if (!$block) { return $this->redirect('/'); } - try { - // update the block confirmations - $req = ['method' => 'getblock', 'params' => [$block->Hash]]; - $response = self::curl_json_post(self::$rpcurl, json_encode($req)); - $json = json_decode($response); - $rpc_block = $json->result; - if (isset($rpc_block->confirmations)) { - $block->Confirmations = $rpc_block->confirmations; - $conn = ConnectionManager::get('default'); - $conn->execute('UPDATE Blocks SET Confirmations = ? WHERE Id = ?', [$rpc_block->confirmations, $block->Id]); - } - } catch (\Exception $e) { - // try again next time - } - // Get the basic block transaction info - $txs = $this->Transactions->find()->select(['InputCount', 'OutputCount', 'Hash', 'Value', 'Version'])->where(['BlockHash' => $block->Hash])->toArray(); + $txs = $this->Transactions->find()->select(['input_count', 'output_count', 'hash', 'version'])->where(['block_hash_id' => $block->hash])->toArray(); $this->set('block', $block); $this->set('blockTxs', $txs); @@ -449,32 +437,27 @@ class MainController extends AppController { $this->loadModel('Transactions'); $this->loadModel('Inputs'); $this->loadModel('Outputs'); + $this->loadModel('Addresses'); $this->loadModel('Claims'); $sourceAddress = $this->request->query('address'); $tx = $this->Transactions->find()->select( - ['Id', 'BlockHash', 'InputCount', 'OutputCount', 'Hash', 'Value', 'TransactionTime', 'TransactionSize', 'Created', 'Version', 'LockTime', 'Raw'])->where(['Hash' => $hash])->first(); + ['id', 'block_hash_id', 'input_count', 'output_count', 'hash', 'transaction_time', 'transaction_size', 'created_at', 'version', 'lock_time', 'raw'])->where(['hash' => $hash])->first(); if (!$tx) { return $this->redirect('/'); } - if ($tx->TransactionSize == 0) { - $tx->TransactionSize = (strlen($tx->Raw) / 2); - $conn = ConnectionManager::get('default'); - $conn->execute('UPDATE Transactions SET TransactionSize = ? WHERE Id = ?', [$tx->TransactionSize, $tx->Id]); - } - - $maxBlock = $this->Blocks->find()->select(['Height'])->order(['Height' => 'desc'])->first(); - $block = $this->Blocks->find()->select(['Confirmations', 'Height'])->where(['Hash' => $tx->BlockHash])->first(); - $confirmations = $block ? (($maxBlock->Height - $block->Height) + 1) : '0'; - $inputs = $this->Inputs->find()->contain(['InputAddresses'])->where(['TransactionId' => $tx->Id])->order(['PrevoutN' => 'asc'])->toArray(); - $outputs = $this->Outputs->find()->contain(['OutputAddresses', 'SpendInput' => ['fields' => ['Id', 'TransactionHash', 'PrevoutN', 'PrevoutHash']]])->where(['Outputs.TransactionId' => $tx->Id])->order(['Vout' => 'asc'])->toArray(); + $block = $this->Blocks->find()->select(['confirmations', 'height'])->where(['hash' => $tx->block_hash_id])->first(); + $confirmations = $block->confirmations; + $inputs = $this->Inputs->find()->where(['transaction_id' => $tx->id])->order(['prevout_n' => 'asc'])->toArray(); + $inputAddresses = $this->Addresses->find()->where(['input_address_id'])->toArray(); + $outputs = $this->Outputs->find()->where(['transaction_id' => $tx->id])->order(['vout' => 'asc'])->toArray(); for ($i = 0; $i < count($outputs); $i++) { - $outputs[$i]->IsClaim = (strpos($outputs[$i]->ScriptPubKeyAsm, 'CLAIM') > -1); - $outputs[$i]->IsSupportClaim = (strpos($outputs[$i]->ScriptPubKeyAsm, 'SUPPORT_CLAIM') > -1); - $outputs[$i]->IsUpdateClaim = (strpos($outputs[$i]->ScriptPubKeyAsm, 'UPDATE_CLAIM') > -1); - $claim = $this->Claims->find()->where(['TransactionHash' => $tx->Hash, 'Vout' => $outputs[$i]->Vout])->first(); + $outputs[$i]->IsClaim = (strpos($outputs[$i]->script_pub_key_asm, 'CLAIM') > -1); + $outputs[$i]->IsSupportClaim = (strpos($outputs[$i]->script_pub_key_asm, 'SUPPORT_CLAIM') > -1); + $outputs[$i]->IsUpdateClaim = (strpos($outputs[$i]->script_pub_key_asm, 'UPDATE_CLAIM') > -1); + $claim = $this->Claims->find()->where(['transaction_hash_id' => $tx->hash, 'vout' => $outputs[$i]->vout])->first(); $outputs[$i]->Claim = $claim; } @@ -482,10 +465,10 @@ class MainController extends AppController { $totalOut = 0; $fee = 0; foreach ($inputs as $in) { - $totalIn = bcadd($totalIn, $in->Value, 8); + $totalIn = bcadd($totalIn, $in->value, 8); } foreach ($outputs as $out) { - $totalOut = bcadd($totalOut, $out->Value, 8); + $totalOut = bcadd($totalOut, $out->value, 8); } $fee = bcsub($totalIn, $totalOut, 8); diff --git a/src/Model/Entity/Block.php b/src/Model/Entity/Block.php index 7858813..8f66eac 100644 --- a/src/Model/Entity/Block.php +++ b/src/Model/Entity/Block.php @@ -5,6 +5,9 @@ namespace App\Model\Entity; use Cake\ORM\Entity; class Block extends Entity { + public function target() { + + } } diff --git a/src/Model/Entity/Claim.php b/src/Model/Entity/Claim.php index 18a5734..d12c480 100644 --- a/src/Model/Entity/Claim.php +++ b/src/Model/Entity/Claim.php @@ -6,7 +6,7 @@ use Cake\ORM\Entity; class Claim extends Entity { function getLbryLink() { - $link = $this->Name; + $link = $this->name; if (isset($this->Publisher->Name)) { $link = $this->Publisher->Name . '/' . $link; } @@ -15,21 +15,21 @@ class Claim extends Entity { } function getExplorerLink() { - $link = '/claims/' . $this->ClaimId; + $link = '/claims/' . $this->claim_id; return $link; } function getContentTag() { $ctTag = null; - if (substr($this->ContentType, 0, 5) === 'audio') { + if (substr($this->content_type, 0, 5) === 'audio') { $ctTag = 'audio'; - } else if (substr($this->ContentType, 0, 5) === 'video') { + } else if (substr($this->content_type, 0, 5) === 'video') { $ctTag = 'video'; - } else if (substr($this->ContentType, 0, 5) === 'image') { + } else if (substr($this->content_type, 0, 5) === 'image') { $ctTag = 'image'; } - if (!$ctTag && $this->ClaimType == 1) { + if (!$ctTag && $this->claim_type == 1) { $ctTag = 'identity'; } return $ctTag; @@ -37,10 +37,10 @@ class Claim extends Entity { function getAutoThumbText() { $autoThumbText = ''; - if ($this->ClaimType == 1) { - $autoThumbText = strtoupper(substr($this->Name, 1, min( strlen($this->Name), 3 ))); + if ($this->claim_type == 1) { + $autoThumbText = strtoupper(substr($this->name, 1, min( strlen($this->name), 3 ))); } else { - $str = (strlen(trim($this->Title)) > 0) ? $this->Title : $this->Name; + $str = (strlen(trim($this->title)) > 0) ? $this->title : $this->name; $autoThumbText = strtoupper(substr($str, 0, min (strlen($str), 2 ))); } return $autoThumbText; diff --git a/src/Model/Entity/ClaimStream.php b/src/Model/Entity/ClaimStream.php deleted file mode 100644 index 6a51882..0000000 --- a/src/Model/Entity/ClaimStream.php +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/src/Model/Entity/Transaction.php b/src/Model/Entity/Transaction.php index 631f08c..b491ed7 100644 --- a/src/Model/Entity/Transaction.php +++ b/src/Model/Entity/Transaction.php @@ -3,8 +3,19 @@ namespace App\Model\Entity; use Cake\ORM\Entity; +use Cake\ORM\TableRegistry; + class Transaction extends Entity { + public function value() { + $OutputModel = TableRegistry::get('Outputs'); + $outputs = $OutputModel->find()->select(['value'])->where(['transaction_id' => $this->id])->toArray(); + $value = 0; + foreach($outputs as $o) { + $value += $o->value; + } + return $value; + } } diff --git a/src/Model/Table/AddressesTable.php b/src/Model/Table/AddressesTable.php index 1876136..daa47f2 100644 --- a/src/Model/Table/AddressesTable.php +++ b/src/Model/Table/AddressesTable.php @@ -8,8 +8,8 @@ class AddressesTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Addresses'); + $this->primaryKey('id'); + $this->table('address'); $this->addBehavior('SimpleAudit'); } diff --git a/src/Model/Table/BlocksTable.php b/src/Model/Table/BlocksTable.php index 0b2a8ed..bc58288 100644 --- a/src/Model/Table/BlocksTable.php +++ b/src/Model/Table/BlocksTable.php @@ -8,8 +8,8 @@ class BlocksTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Blocks'); + $this->primaryKey('id'); + $this->table('block'); $this->addBehavior('SimpleAudit'); } diff --git a/src/Model/Table/ClaimStreamsTable.php b/src/Model/Table/ClaimStreamsTable.php deleted file mode 100644 index eb77edf..0000000 --- a/src/Model/Table/ClaimStreamsTable.php +++ /dev/null @@ -1,18 +0,0 @@ -primaryKey('Id'); - $this->table('ClaimStreams'); - - //$this->addBehavior('SimpleAudit'); - } -} - -?> \ No newline at end of file diff --git a/src/Model/Table/ClaimsTable.php b/src/Model/Table/ClaimsTable.php index 4177faa..9f826da 100644 --- a/src/Model/Table/ClaimsTable.php +++ b/src/Model/Table/ClaimsTable.php @@ -8,25 +8,17 @@ class ClaimsTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Claims'); + $this->primaryKey('id'); + $this->table('claim'); //$this->addBehavior('SimpleAudit'); $this->addAssociations([ 'belongsTo' => [ - 'Publisher' => [ + 'publisher' => [ 'className' => 'App\Model\Table\ClaimsTable', - 'foreignKey' => 'PublisherId', - 'bindingKey' => 'ClaimId', - 'propertyName' => 'Publisher' - ] - ], - 'hasOne' => [ - 'Stream' => [ - 'className' => 'App\Model\Table\ClaimStreamsTable', - 'foreignKey' => 'Id', - 'bindingKey' => 'Id', - 'propertyName' => 'Stream' + 'foreignKey' => 'publisher_id', + 'bindingKey' => 'claim_id', + 'propertyName' => 'publisher' ] ] ]); diff --git a/src/Model/Table/InputsTable.php b/src/Model/Table/InputsTable.php index c1c06e7..58776b6 100644 --- a/src/Model/Table/InputsTable.php +++ b/src/Model/Table/InputsTable.php @@ -8,19 +8,19 @@ class InputsTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Inputs'); + $this->primaryKey('id'); + $this->table('input'); $this->addBehavior('SimpleAudit'); $this->addAssociations([ 'belongsToMany' => [ - 'InputAddresses' => [ + 'input_addresses' => [ 'className' => 'App\Model\Table\AddressesTable', - 'joinTable' => 'InputsAddresses', - 'foreignKey' => 'InputId', - 'targetForeignKey' => 'AddressId', - 'propertyName' => 'InputAddresses' + 'joinTable' => 'input_addresses', + 'foreignKey' => 'input_id', + 'targetForeignKey' => 'address_id', + 'propertyName' => 'input_addresses' ] ] ]); diff --git a/src/Model/Table/OutputsTable.php b/src/Model/Table/OutputsTable.php index 1840aa7..dbb58fc 100644 --- a/src/Model/Table/OutputsTable.php +++ b/src/Model/Table/OutputsTable.php @@ -8,26 +8,26 @@ class OutputsTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Outputs'); + $this->primaryKey('id'); + $this->table('output'); $this->addBehavior('SimpleAudit'); $this->addAssociations([ 'belongsTo' => [ - 'SpendInput' => [ + 'spend_input' => [ 'className' => 'App\Model\Table\InputsTable', - 'foreignKey' => 'SpentByInputId', - 'propertyName' => 'SpendInput' + 'foreignKey' => 'spent_by_input_id', + 'propertyName' => 'spend_input' ] ], 'belongsToMany' => [ - 'OutputAddresses' => [ + 'output_addresses' => [ 'className' => 'App\Model\Table\AddressesTable', - 'joinTable' => 'OutputsAddresses', - 'foreignKey' => 'OutputId', - 'targetForeignKey' => 'AddressId', - 'propertyName' => 'OutputAddresses' + 'joinTable' => 'output_addresses', + 'foreignKey' => 'output_id', + 'targetForeignKey' => 'address_id', + 'propertyName' => 'output_addresses' ] ] ]); diff --git a/src/Model/Table/TransactionsTable.php b/src/Model/Table/TransactionsTable.php index 613512d..7d1a180 100644 --- a/src/Model/Table/TransactionsTable.php +++ b/src/Model/Table/TransactionsTable.php @@ -8,8 +8,8 @@ class TransactionsTable extends Table { public function initialize(array $config) { parent::initialize($config); - $this->primaryKey('Id'); - $this->table('Transactions'); + $this->primaryKey('id'); + $this->table('transaction'); $this->addBehavior('SimpleAudit'); } diff --git a/src/Template/Main/blocks.ctp b/src/Template/Main/blocks.ctp index 38b8543..3c1512f 100644 --- a/src/Template/Main/blocks.ctp +++ b/src/Template/Main/blocks.ctp @@ -21,20 +21,20 @@ end(); ?> - assign('title', 'Block Height ' . $block->Height) ?> + assign('title', 'Block Height ' . $block->height) ?>
-

LBRY Block Height ?>

-

Hash ?>

+

LBRY Block height ?>

+

hash ?>

- PreviousBlockHash)) > 0): ?> - « Previous Block + previous_block_hash)) > 0): ?> + « Previous Block - NextBlockHash)) > 0): ?> - Next Block » + next_block_hash)) > 0): ?> + Next Block »
@@ -47,44 +47,44 @@
Block Size (bytes)
Block Time
-
BlockSize, 0, '', ',') ?>
-
BlockTime)->format('j M Y H:i:s') . ' UTC' ?>
+
block_size, 0, '', ',') ?>
+
block_time)->format('j M Y H:i:s') . ' UTC' ?>
Bits
Confirmations
-
Bits ?>
-
Confirmations, 0, '', ',') ?>
+
bits ?>
+
confirmations, 0, '', ',') ?>
Difficulty
Nonce
-
Amount->format($block->Difficulty, '') ?>
-
Nonce ?>
+
Amount->format($block->difficulty, '') ?>
+
nonce ?>
-
Chainwork
Chainwork ?>
+
Chainwork
chainwork ?>
-
MerkleRoot
MerkleRoot ?>
+
MerkleRoot
merkle_root ?>
-
NameClaimRoot
NameClaimRoot ?>
+
NameClaimRoot
name_claim_root ?>
-
Target
Target ?>
+
Target
Target' ?>
-
Version
Version ?>
+
Version
version ?>
@@ -109,10 +109,10 @@ -
Hash ?>
- InputCount ?> - OutputCount ?> -
Amount->formatCurrency($tx->Value) ?> LBC
+
hash ?>
+ input_count ?> + output_count ?> +
Amount->formatCurrency($tx->value()) ?> LBC
@@ -181,13 +181,13 @@ - Height ?> - Difficulty, 8, '.', '') ?> - Height - $block->Height) + 1), 0, '', ',') ?> - TransactionHashes)) ?> - BlockSize / 1024, 2) . 'KB' ?> - Nonce ?> - BlockTime)->format('d M Y H:i:s') ?> UTC + Height ?> + d0ifficulty, 8, '.', '') ?> + height - $block->height) + 1), 0, '', ',') ?> + transaction_hashes)) ?> + block_size / 1024, 2) . 'KB' ?> + nonce ?> + block_time)->format('d M Y H:i:s') ?> UTC diff --git a/src/Template/Main/index.ctp b/src/Template/Main/index.ctp index 8b0ecf3..5866da6 100644 --- a/src/Template/Main/index.ctp +++ b/src/Template/Main/index.ctp @@ -129,12 +129,12 @@
Block Height
-
Height ?>
+
height ?>
Difficulty
-
Difficulty, 2, '.', '') ?>
+
difficulty, 2, '.', '') ?>
@@ -167,13 +167,13 @@ - - Height ?> - BlockTime)->diffForHumans(); ?> - BlockSize / 1024, 2) . 'KB' ?> - TransactionCount ?> - Difficulty, 2, '.', '') ?> - BlockTime)->format('d M Y H:i:s') . ' UTC' ?> + + height ?> + block_time)->diffForHumans(); ?> + block_size / 1024, 2) . 'KB' ?> + transaction_count ?> + difficulty, 2, '.', '') ?> + block_time)->format('d M Y H:i:s') . ' UTC' ?> @@ -186,11 +186,11 @@ getAutoThumbText(); - $link = $claim->Name; - $rawLink = $claim->Name; - if (isset($claim->Publisher->Name)) { - $link = urlencode($claim->Publisher->Name) . '/' . $link; - $rawLink = $claim->Publisher->Name . '/' . $link; + $link = $claim->name; + $rawLink = $claim->name; + if (isset($claim->publisher->name)) { + $link = urlencode($claim->publisher->name) . '/' . $link; + $rawLink = $claim->publisher->name . '/' . $link; } $link = 'lbry://' . $link; $rawLink = 'lbry://' . $rawLink; @@ -198,35 +198,35 @@ // content type $ctTag = $claim->getContentTag(); ?> -
+
- IsNSFW): ?> + is_nsfw): ?>
NSFW
- IsNSFW && strlen(trim($claim->ThumbnailUrl)) > 0): ?> - + is_nsfw && strlen(trim($claim->thumbnail_url)) > 0): ?> +
- Transaction + Transaction
diff --git a/src/Template/Main/tx.ctp b/src/Template/Main/tx.ctp index f4f4523..7372812 100644 --- a/src/Template/Main/tx.ctp +++ b/src/Template/Main/tx.ctp @@ -14,22 +14,22 @@

LBRY Transaction

-

Hash ?>

+

hash ?>

Time Created

-
Created->format('j M Y H:i:s') . ' UTC '; ?>
+
created_at->format('j M Y H:i:s') . ' UTC '; ?>

Block Time

-
TransactionTime == null || strlen(trim($tx->TransactionTime)) == 0) ? 'Not yet confirmed' : - \DateTime::createFromFormat('U', $tx->TransactionTime)->format('j M Y H:i:s') . ' UTC' ?> +
transaction_time == null || strlen(trim($tx->transaction_time)) == 0) ? 'Not yet confirmed' : + \DateTime::createFromFormat('U', $tx->transaction_time)->format('j M Y H:i:s') . ' UTC' ?> - TransactionTime > $tx->Created->getTimestamp()): - $diffSeconds = $tx->TransactionTime - $tx->Created->getTimestamp(); + transaction_time > $tx->created_at->getTimestamp()): + $diffSeconds = $tx->transaction_time - $tx->created_at->getTimestamp(); if ($diffSeconds <= 60) { echo sprintf(' (+%s second%s)', $diffSeconds, $diffSeconds == 1 ? '' : 's'); } else { @@ -47,15 +47,15 @@
Amount (LBC)
-
Amount->format($tx->Value) ?>
+
Amount->format($tx->value()) ?>
Block Height
- BlockHash) || strlen(trim($tx->BlockHash)) === 0): ?> + block_hash_id) || strlen(trim($tx->block_hash_id)) === 0): ?>
Unconf.
- +
@@ -66,17 +66,17 @@
Size (bytes)
-
TransactionSize, 0, '', ',') ?>
+
transaction_size, 0, '', ',') ?>
Inputs
-
InputCount ?>
+
input_count ?>
Outputs
-
OutputCount ?>
+
output_count ?>
@@ -86,28 +86,28 @@

Details

-
InputCount ?> inputInputCount === 1 ? '' : 's'; ?>
+
input_count ?> inputinput_count === 1 ? '' : 's'; ?>
-
- +
+ is_coinbase): ?>
Block Reward (New Coins)
- Value)) == 0): ?> + value)) == 0): ?>
Incomplete data
Address])): - $setAddressIds[$addr->Address] = 1; ?> - + if (!isset($setAddressIds[$addr->address])): + $setAddressIds[$addr->address] = 1; ?> + -
Amount->format($in['Value']) ?> LBC from
-
Address ?> - (output) +
Amount->format($in->value) ?> LBC from
+
address ?> + (output) Tag) && strlen(trim($addr->Tag)) > 0): ?>
TagUrl)) > 0): ?>Tag ?>Tag; endif; ?> @@ -125,7 +125,7 @@
-
OutputCount ?> outputOutputCount === 1 ? '' : 's'; ?> +
output_count ?> outputoutput_count === 1 ? '' : 's'; ?> 0): ?> Fee Amount->format($fee) ?> LBC @@ -134,7 +134,7 @@ -
+
Claim && ($out->IsClaim or $out->IsSupportClaim or $out->IsUpdateClaim)): ?>View IsSupportClaim): ?>
SUPPORT
@@ -152,9 +152,9 @@
Amount->format($out['Value']) ?> LBC to
-
Address ?> +
address ?> - IsSpent): ?>(spent)(unspent) + is_spent): ?>(spent)(unspent) Tag) && strlen(trim($addr->Tag)) > 0): ?>
diff --git a/webroot/css/bids-chart.css b/webroot/css/bids-chart.css new file mode 100644 index 0000000..48a41f4 --- /dev/null +++ b/webroot/css/bids-chart.css @@ -0,0 +1,8 @@ +.bids-chart-container { width: 1200px; margin: 0 auto 48px auto; box-shadow: 0 2px 6px rgba(0,0,0,.175); border: 1px solid rgba(0,0,0,.15); padding: 24px 36px; position: relative; overflow: hidden } +.bids-chart-container .load-progress { position: absolute; top: 0; left: 0; width: 100%; height: 3px; background: #1e88e5; animation: indeterminate 4s linear infinite; } +.bids-chart-container .chart { height: 414px } +.bids-chart-container .btn-chart-export { position: absolute; right: 40px; bottom: 36px } +@keyframes indeterminate { + from { left: -70%; } + to { left: 100% } +} \ No newline at end of file diff --git a/webroot/js/bids-chart.js b/webroot/js/bids-chart.js new file mode 100644 index 0000000..d025d04 --- /dev/null +++ b/webroot/js/bids-chart.js @@ -0,0 +1,170 @@ +function buildChartData(claimsData) { + var chartData = []; + var lastDate = 0; + var nbClaimsDay = 0; + var nbClaimsTotal = 0; + var bidClaimsDay = 0; + var bidClaimsTotal = 0; + var nbChannelsDay = 0; + var nbChannelsTotal = 0; + for(var i = 0; i < claimsData.length; i++) { + if(claimsData[i].transaction_time == 0) { + continue; + } + var transactionDate = new Date(claimsData[i].transaction_time * 1000); + transactionDate.setHours(0,0,0,0) + if(lastDate == 0) { + lastDate = transactionDate; + } + if(transactionDate.toString() != lastDate.toString()) { + nbClaimsTotal += nbClaimsDay; + bidClaimsTotal += bidClaimsDay; + var dateData = { + date: lastDate, + NumberClaims: nbClaimsTotal, + BidsClaims: bidClaimsTotal, + }; + chartData.push(dateData); + nbClaimsDay = 0; + bidClaimsDay = 0; + lastDate = transactionDate; + } + if(claimsData[i].claim_type == 1) { + nbClaimsDay += 1; + bidClaimsDay += claimsData[i].effective_amount/100000000; + } + } + return chartData; +} + +function loadChartData() { + var api_url = "https://chainquery.lbry.io/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'); + $.ajax({ + url: url, + type: 'get', + dataType: 'json', + beforeSend: function() { + chartLoadInProgress = true; + loadProgress.css({ display: 'block' }); + }, + success: function(response) { + if(response.success) { + chartData = buildChartData(response.data); + if(chart) { + chart.dataProvider = chartData; + chart.validateNow(); + chart.validateData(); + } + } + else { + console.log("Could not fetch block data."); + } + }, + complete: function() { + chartLoadInProgress = false; + loadProgress.css({ display: 'none' }); + } +}); +} + +var chart; +var chartData = []; +var chartLoadInProgress = false; +AmCharts.ready(function() { +chart = AmCharts.makeChart('bids-chart', { +type: 'serial', +theme: 'light', +mouseWheelZoomEnabled: true, +height: '100%', +categoryField: 'date', +synchronizeGrid: true, +dataProvider: chartData, +responsive: { + enabled: true, +}, +valueAxes: [ +{ + id: 'v-number-claims', + axisColor: '#1e88e5', + axisThickness: 2, + position: 'left', +}, +{ + id: 'v-bids-claims', + axisColor: '#0b7a06', + axisThickness: 2, + position: 'left', + offset: 75, +}, +], +categoryAxis: { +parseDates: true, +autoGridCount: false, +minorGridEnabled: true, +minorGridAlpha: 0.04, +axisColor: '#dadada', +twoLineMode: true +}, +graphs: [ +{ + id: 'g-number-claims', + valueAxis: 'v-number-claims', + title: 'Number of claims', + valueField: 'NumberClaims', + bullet: 'round', + bulletBorderThickness: 1, + bulletBorderAlpha: 1, + bulletColor: '#ffffff', + bulletSize: 5, + useLineColorForBulletBorder: true, + lineColor: '#1e88e5', + hideBulletsCount: 101, + balloonText: '[[NumberClaims]]', +}, +{ + id: 'g-bids-claims', + valueAxis: 'v-bids-claims', + title: 'Bids for claims (LBC)', + valueField: 'BidsClaims', + bullet: 'round', + bulletBorderThickness: 1, + bulletBorderAlpha: 1, + bulletColor: '#ffffff', + bulletSize: 5, + useLineColorForBulletBorder: true, + lineColor: '#0b7a06', + balloonText: '[[BidsClaims]] LBC', + hideBulletsCount: 101 +}, +], +chartCursor: { +cursorAlpha: 0.1, +fullWidth: true, +valueLineBalloonEnabled: true, +categoryBalloonColor: '#333333', +cursorColor: '#1e88e5' +}, +chartScrollbar: { +scrollbarHeight: 36, +color: '#888888', +gridColor: '#bbbbbb' +}, +legend: { +marginLeft: 110, +useGraphSettings: true, +valueText: "", +spacing: 64, + +}, +export: { +enabled: true, +fileName: 'lbry-bids-chart', +position: 'bottom-right', +divId: 'chart-export' +} +}); +loadChartData(); +}); \ No newline at end of file From 94682cc4d428d3dd56933a59604793bcdd5377db Mon Sep 17 00:00:00 2001 From: marcdeb1 Date: Mon, 17 Dec 2018 12:35:54 +0100 Subject: [PATCH 02/43] Fixed transaction value issue --- src/Controller/MainController.php | 7 +++++-- src/Template/Main/blocks.ctp | 4 +--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index f144f0c..fdf30bb 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -381,6 +381,8 @@ class MainController extends AppController { public function blocks($height = null) { $this->loadModel('Blocks'); + $this->loadModel('Outputs'); + $this->loadModel('Transactions'); if ($height === null) { // paginate blocks @@ -413,7 +415,6 @@ class MainController extends AppController { $this->set('numRecords', $numBlocks); $this->set('currentPage', $page); } else { - $this->loadModel('Transactions'); $height = intval($height); if ($height < 0) { return $this->redirect('/'); @@ -425,7 +426,8 @@ class MainController extends AppController { } // Get the basic block transaction info - $txs = $this->Transactions->find()->select(['input_count', 'output_count', 'hash', 'version'])->where(['block_hash_id' => $block->hash])->toArray(); + $txs = $this->Transactions->find()->select(['id', 'input_count', 'output_count', 'hash', 'version'])->where(['block_hash_id' => $block->hash])->toArray(); + $this->set('block', $block); $this->set('blockTxs', $txs); @@ -444,6 +446,7 @@ class MainController extends AppController { $tx = $this->Transactions->find()->select( ['id', 'block_hash_id', 'input_count', 'output_count', 'hash', 'transaction_time', 'transaction_size', 'created_at', 'version', 'lock_time', 'raw'])->where(['hash' => $hash])->first(); + $tx->value = $tx->value(); if (!$tx) { return $this->redirect('/'); } diff --git a/src/Template/Main/blocks.ctp b/src/Template/Main/blocks.ctp index 3c1512f..9c8fb17 100644 --- a/src/Template/Main/blocks.ctp +++ b/src/Template/Main/blocks.ctp @@ -29,13 +29,11 @@
- previous_block_hash)) > 0): ?> + height > 0): ?> « Previous Block - next_block_hash)) > 0): ?> Next Block » -
From 86a1631144e7ad1692284835cb5dcc47e7ee2d10 Mon Sep 17 00:00:00 2001 From: marcdeb1 Date: Mon, 17 Dec 2018 22:36:13 +0100 Subject: [PATCH 03/43] Fix index transaction hash bug --- src/Controller/MainController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index fdf30bb..f6fd254 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -96,9 +96,12 @@ class MainController extends AppController { $blocks = $this->Blocks->find()->select(['chainwork', 'confirmations', 'difficulty', 'hash', 'height', 'transaction_hashes', 'block_time', 'block_size'])->order(['height' => 'desc'])->limit(6)->toArray(); for ($i = 0; $i < count($blocks); $i++) { $tx_hashes = json_decode($blocks[$i]->transaction_hashes, true); - $blocks[$i]->transaction_count = count($tx_hashes); + if(!empty($tx_hashes)) { + $blocks[$i]->transaction_count = count($tx_hashes); + } else { + $blocks[$i]->transaction_count = 0; + } } - // hash rate $hashRate = $this->_formatHashRate($this->_gethashrate()); From b61a1545a77c9a3e42e12005cf435933d8033fe5 Mon Sep 17 00:00:00 2001 From: marcdeb1 Date: Tue, 18 Dec 2018 01:20:54 +0100 Subject: [PATCH 04/43] Realtime action --- src/Controller/MainController.php | 327 +++++++++++++++--------------- src/Model/Entity/Claim.php | 8 +- src/Model/Entity/Transaction.php | 1 - src/Template/Main/claims.ctp | 123 +++++------ src/Template/Main/index.ctp | 5 +- src/Template/Main/realtime.ctp | 14 +- 6 files changed, 250 insertions(+), 228 deletions(-) diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php index f6fd254..afc1d49 100644 --- a/src/Controller/MainController.php +++ b/src/Controller/MainController.php @@ -106,7 +106,7 @@ class MainController extends AppController { $hashRate = $this->_formatHashRate($this->_gethashrate()); // recent claims - $claims = $this->Claims->find()->select(['transaction_hash_id', 'name', 'vout', 'claim_id', 'claim_type', 'author', 'title', 'description', 'content_type', 'is_nsfw', 'language', 'thumbnail_url', 'created_at'])-> + $claims = $this->Claims->find()->select(['transaction_hash_id', 'name', 'vout', 'claim_id', 'claim_type', 'author', 'title', 'description', 'content_type', 'is_nsfw', 'language', 'thumbnail_url', 'created_at', 'publisher_id'])-> distinct(['Claims.claim_id'])->order(['Claims.created_at' => 'DESC'])->limit(5)->toArray(); foreach($claims as $claim) { @@ -124,7 +124,9 @@ class MainController extends AppController { $this->loadModel('Transactions'); $canConvert = false; - $priceInfo = json_decode($this->redis->get(self::lbcPriceKey)); + if(isset($this->redis)) { + $priceInfo = json_decode($this->redis->get(self::lbcPriceKey)); + } if (isset($priceInfo->price)) { $canConvert = true; } @@ -136,7 +138,7 @@ class MainController extends AppController { $page = intval($this->request->query('page')); $conn = ConnectionManager::get('default'); - $stmt = $conn->execute('SELECT COUNT(Id) AS Total FROM Claims'); + $stmt = $conn->execute('SELECT COUNT(Id) AS Total FROM claim'); $count = $stmt->fetch(\PDO::FETCH_OBJ); $numClaims = $count->Total; @@ -149,12 +151,19 @@ class MainController extends AppController { } $offset = ($page - 1) * $pageLimit; - $claims = $this->Claims->find()->distinct(['Claims.ClaimId'])->contain(['Stream', 'Publisher' => ['fields' => ['Name']]])->order(['Claims.Created' => 'DESC'])->offset($offset)->limit($pageLimit)->toArray(); - for ($i = 0; $i < count($claims); $i++) { - if ($canConvert && $claims[$i]->Fee > 0 && $claims[$i]->FeeCurrency == 'USD') { - $claims[$i]->Price = $claims[$i]->Fee / $priceInfo->price; + $claims = $this->Claims->find()->distinct(['claim_id'])->order(['created_at' => 'DESC'])->offset($offset)->limit($pageLimit)->toArray(); + foreach($claims as $claim) { + if(isset($claim->publisher_id)) { + $publisher = $this->Claims->find()->select(['name'])->where(['claim_id' => $claim->publisher_id])->first(); + $claim->publisher = $publisher; } - + } + + for ($i = 0; $i < count($claims); $i++) { + if ($canConvert && $claims[$i]->Fee > 0 && $claims[$i]->fee_currency == 'USD') { + $claims[$i]->price = $claims[$i]->fee / $priceInfo->price; + } + if (isset($claims[$i]->Stream)) { $json = json_decode($claims[$i]->Stream->Stream); if (isset($json->metadata->license)) { @@ -172,13 +181,16 @@ class MainController extends AppController { $this->set('currentPage', $page); $this->set('claims', $claims); } else { - $claim = $this->Claims->find()->contain(['Stream', 'Publisher' => ['fields' => ['ClaimId', 'Name']]])->where(['Claims.ClaimId' => $id])->order(['Claims.Created' => 'DESC'])->first(); + $claim = $this->Claims->find()->where(['claim_id' => $id])->order(['created_at' => 'DESC'])->first(); + $publisher = $this->Claims->find()->select(['name'])->where(['claim_id' => $claim->publisher_id])->first(); + $claim->publisher = $publisher; + if (!$claim) { return $this->redirect('/'); } - if ($canConvert && $claim->Fee > 0 && $claim->FeeCurrency == 'USD') { - $claim->Price = $claim->Fee / $priceInfo->price; + if ($canConvert && $claim->fee > 0 && $claim->fee_currency == 'USD') { + $claim->price = $claim->fee / $priceInfo->price; } if (isset($claim->Stream)) { @@ -192,14 +204,13 @@ class MainController extends AppController { } $moreClaims = []; - if (isset($claim->Publisher) || $claim->ClaimType == 1) { + if (isset($claim->publisher) || $claim->claim_type == 1) { // find more claims for the publisher - $moreClaims = $this->Claims->find()->contain(['Stream', 'Publisher' => ['fields' => ['Name']]])-> - where(['Claims.ClaimType' => 2, 'Claims.Id <>' => $claim->Id, 'Claims.PublisherId' => isset($claim->Publisher) ? $claim->Publisher->ClaimId : $claim->ClaimId])-> - limit(9)->order(['Claims.Fee' => 'DESC', 'RAND()' => 'DESC'])->toArray(); + $moreClaims = $this->Claims->find()->where(['claim_type' => 2, 'id <>' => $claim->id, 'publisher_id' => isset($claim->publisher) ? $claim->publisher_id : $claim->claim_id])-> + limit(9)->order(['fee' => 'DESC', 'RAND()' => 'DESC'])->toArray(); for ($i = 0; $i < count($moreClaims); $i++) { - if ($canConvert && $moreClaims[$i]->Fee > 0 && $moreClaims[$i]->FeeCurrency == 'USD') { - $moreClaims[$i]->Price = $moreClaims[$i]->Fee / $priceInfo->price; + if ($canConvert && $moreClaims[$i]->fee > 0 && $moreClaims[$i]->fee_currency == 'USD') { + $moreClaims[$i]->price = $moreClaims[$i]->fee / $priceInfo->price; } if (isset($moreClaims[$i]->Stream)) { @@ -225,114 +236,20 @@ class MainController extends AppController { // load 10 blocks and transactions $conn = ConnectionManager::get('default'); - $blocks = $this->Blocks->find()->select(['Height', 'BlockTime', 'TransactionHashes'])->order(['Height' => 'desc'])->limit(10)->toArray(); + $blocks = $this->Blocks->find()->select(['height', 'block_time', 'transaction_hashes'])->order(['height' => 'desc'])->limit(10)->toArray(); for ($i = 0; $i < count($blocks); $i++) { - $tx_hashes = json_decode($blocks[$i]->TransactionHashes); - $blocks[$i]->TransactionCount = count($tx_hashes); + $tx_hashes = json_decode($blocks[$i]->transaction_hashes); + $blocks[$i]->transaction_count = count($tx_hashes); } - $stmt = $conn->execute('SELECT T.Hash, T.InputCount, T.OutputCount, T.Value, IFNULL(T.TransactionTime, T.CreatedTime) AS TxTime ' . - 'FROM Transactions T ORDER BY CreatedTime DESC LIMIT 10'); + $stmt = $conn->execute('SELECT T.id, T.hash, T.input_count, T.output_count, IFNULL(T.transaction_time, T.created_at) AS TxTime ' . + 'FROM transaction T ORDER BY created_at DESC LIMIT 10'); $txs = $stmt->fetchAll(\PDO::FETCH_OBJ); $this->set('blocks', $blocks); $this->set('txs', $txs); } - public function apiblocksize($timePeriod = '24h') { - $this->autoRender = false; - - if (!$this->request->is('get')) { - return $this->_jsonError('Invalid HTTP request method.', 400); - } - - $validPeriods = ['24h', '72h', '168h', '30d', '90d', '1y']; - if (!in_array($timePeriod, $validPeriods)) { - return $this->_jsonError('Invalid time period specified.', 400); - } - - $isHourly = (strpos($timePeriod, 'h') !== false); - $now = new \DateTime('now', new \DateTimeZone('UTC')); - $dateFormat = $isHourly ? 'Y-m-d H:00:00' : 'Y-m-d'; - $sqlDateFormat = $isHourly ? '%Y-%m-%d %H:00:00' : '%Y-%m-%d'; - $intervalPrefix = $isHourly ? 'PT' : 'P'; - $start = $now->sub(new \DateInterval($intervalPrefix . strtoupper($timePeriod))); - - $resultSet = []; - - $conn = ConnectionManager::get('default'); - - // get avg block sizes for the time period - $stmt = $conn->execute("SELECT AVG(BlockSize) AS AvgBlockSize, DATE_FORMAT(FROM_UNIXTIME(BlockTime), '$sqlDateFormat') AS TimePeriod " . - "FROM Blocks WHERE DATE_FORMAT(FROM_UNIXTIME(BlockTime), '$sqlDateFormat') >= ? GROUP BY TimePeriod ORDER BY TimePeriod ASC", [$start->format($dateFormat)]); - $avgBlockSizes = $stmt->fetchAll(\PDO::FETCH_OBJ); - foreach ($avgBlockSizes as $size) { - if (!isset($resultSet[$size->TimePeriod])) { - $resultSet[$size->TimePeriod] = []; - } - $resultSet[$size->TimePeriod]['AvgBlockSize'] = (float) $size->AvgBlockSize; - } - - // get avg prices - $stmt = $conn->execute("SELECT AVG(USD) AS AvgUSD, DATE_FORMAT(Created, '$sqlDateFormat') AS TimePeriod " . - "FROM PriceHistory WHERE DATE_FORMAT(Created, '$sqlDateFormat') >= ? GROUP BY TimePeriod ORDER BY TimePeriod ASC", [$start->format($dateFormat)]); - $avgPrices = $stmt->fetchAll(\PDO::FETCH_OBJ); - foreach ($avgPrices as $price) { - if (!isset($resultSet[$price->TimePeriod])) { - $resultSet[$price->TimePeriod] = []; - } - $resultSet[$price->TimePeriod]['AvgUSD'] = (float) $price->AvgUSD; - } - - return $this->_jsonResponse(['success' => true, 'data' => $resultSet]); - } - - public function apirealtimeblocks() { - // load 10 blocks - $this->autoRender = false; - $this->loadModel('Blocks'); - $blocks = $this->Blocks->find()->select(['Height', 'BlockTime', 'TransactionHashes'])->order(['Height' => 'desc'])->limit(10)->toArray(); - for ($i = 0; $i < count($blocks); $i++) { - $tx_hashes = json_decode($blocks[$i]->TransactionHashes); - $blocks[$i]->TransactionCount = count($tx_hashes); - unset($blocks[$i]->TransactionHashes); - } - - $this->_jsonResponse(['success' => true, 'blocks' => $blocks]); - } - - public function apirealtimetx() { - // load 10 transactions - $this->autoRender = false; - $conn = ConnectionManager::get('default'); - $stmt = $conn->execute('SELECT T.Hash, T.InputCount, T.OutputCount, T.Value, IFNULL(T.TransactionTime, T.CreatedTime) AS TxTime ' . - 'FROM Transactions T ORDER BY CreatedTime DESC LIMIT 10'); - $txs = $stmt->fetchAll(\PDO::FETCH_OBJ); - - $this->_jsonResponse(['success' => true, 'txs' => $txs]); - } - - protected function _formatHashRate($value) { - if ($value === 'N/A') { - return $value; - } - - /*if ($value > 1000000000000) { - return number_format( $value / 1000000000000, 2, '.', '' ) . ' TH'; - }*/ - if ($value > 1000000000) { - return number_format( $value / 1000000000, 2, '.', '' ) . ' GH/s'; - } - if ($value > 1000000) { - return number_format( $value / 1000000, 2, '.', '' ) . ' MH/s'; - } - if ($value > 1000) { - return number_format( $value / 1000, 2, '.', '' ) . ' KH/s'; - } - - return number_format($value) . ' H/s'; - } - public function find() { $criteria = $this->request->query('q'); @@ -650,53 +567,78 @@ class MainController extends AppController { echo $qrCode->writeString(); exit(0); } + + public function apiblocksize($timePeriod = '24h') { + $this->autoRender = false; - public static function curl_get($url) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - - $response = curl_exec($ch); - Log::debug('Request execution completed.'); - - if ($response === false) { - $error = curl_error($ch); - $errno = curl_errno($ch); - curl_close($ch); - - throw new \Exception(sprintf('The request failed: %s', $error), $errno); - } else { - curl_close($ch); + if (!$this->request->is('get')) { + return $this->_jsonError('Invalid HTTP request method.', 400); } - return $response; + $validPeriods = ['24h', '72h', '168h', '30d', '90d', '1y']; + if (!in_array($timePeriod, $validPeriods)) { + return $this->_jsonError('Invalid time period specified.', 400); + } + + $isHourly = (strpos($timePeriod, 'h') !== false); + $now = new \DateTime('now', new \DateTimeZone('UTC')); + $dateFormat = $isHourly ? 'Y-m-d H:00:00' : 'Y-m-d'; + $sqlDateFormat = $isHourly ? '%Y-%m-%d %H:00:00' : '%Y-%m-%d'; + $intervalPrefix = $isHourly ? 'PT' : 'P'; + $start = $now->sub(new \DateInterval($intervalPrefix . strtoupper($timePeriod))); + + $resultSet = []; + + $conn = ConnectionManager::get('default'); + + // get avg block sizes for the time period + $stmt = $conn->execute("SELECT AVG(BlockSize) AS AvgBlockSize, DATE_FORMAT(FROM_UNIXTIME(BlockTime), '$sqlDateFormat') AS TimePeriod " . + "FROM Blocks WHERE DATE_FORMAT(FROM_UNIXTIME(BlockTime), '$sqlDateFormat') >= ? GROUP BY TimePeriod ORDER BY TimePeriod ASC", [$start->format($dateFormat)]); + $avgBlockSizes = $stmt->fetchAll(\PDO::FETCH_OBJ); + foreach ($avgBlockSizes as $size) { + if (!isset($resultSet[$size->TimePeriod])) { + $resultSet[$size->TimePeriod] = []; + } + $resultSet[$size->TimePeriod]['AvgBlockSize'] = (float) $size->AvgBlockSize; + } + + // get avg prices + $stmt = $conn->execute("SELECT AVG(USD) AS AvgUSD, DATE_FORMAT(Created, '$sqlDateFormat') AS TimePeriod " . + "FROM PriceHistory WHERE DATE_FORMAT(Created, '$sqlDateFormat') >= ? GROUP BY TimePeriod ORDER BY TimePeriod ASC", [$start->format($dateFormat)]); + $avgPrices = $stmt->fetchAll(\PDO::FETCH_OBJ); + foreach ($avgPrices as $price) { + if (!isset($resultSet[$price->TimePeriod])) { + $resultSet[$price->TimePeriod] = []; + } + $resultSet[$price->TimePeriod]['AvgUSD'] = (float) $price->AvgUSD; + } + + return $this->_jsonResponse(['success' => true, 'data' => $resultSet]); + } + + public function apirealtimeblocks() { + // load 10 blocks + $this->autoRender = false; + $this->loadModel('Blocks'); + $blocks = $this->Blocks->find()->select(['Height', 'BlockTime', 'TransactionHashes'])->order(['Height' => 'desc'])->limit(10)->toArray(); + for ($i = 0; $i < count($blocks); $i++) { + $tx_hashes = json_decode($blocks[$i]->TransactionHashes); + $blocks[$i]->TransactionCount = count($tx_hashes); + unset($blocks[$i]->TransactionHashes); + } + + $this->_jsonResponse(['success' => true, 'blocks' => $blocks]); } - private function _gethashrate() { - $req = ['method' => 'getnetworkhashps', 'params' => []]; - try { - $res = json_decode(self::curl_json_post(self::$rpcurl, json_encode($req))); - if (!isset($res->result)) { - return 0; - } - return $res->result; - } catch (\Exception $e) { - return 'N/A'; - } - } + public function apirealtimetx() { + // load 10 transactions + $this->autoRender = false; + $conn = ConnectionManager::get('default'); + $stmt = $conn->execute('SELECT T.Hash, T.InputCount, T.OutputCount, T.Value, IFNULL(T.TransactionTime, T.CreatedTime) AS TxTime ' . + 'FROM Transactions T ORDER BY CreatedTime DESC LIMIT 10'); + $txs = $stmt->fetchAll(\PDO::FETCH_OBJ); - private function _gettxoutsetinfo() { - $req = ['method' => 'gettxoutsetinfo', 'params' => []]; - try { - $res = json_decode(self::curl_json_post(self::$rpcurl, json_encode($req))); - if (!isset($res->result)) { - return 0; - } - return $res->result; - } catch (\Exception $e) { - return 'N/A'; - } + $this->_jsonResponse(['success' => true, 'txs' => $txs]); } public function apistatus() { @@ -868,7 +810,7 @@ class MainController extends AppController { return $this->_jsonResponse(['success' => true, 'utxo' => $utxo]); } - public function apiutxosupply() { + public function apiutxosupply() { $this->autoRender = false; $this->loadModel('Addresses'); @@ -902,6 +844,75 @@ class MainController extends AppController { return $this->_jsonResponse(['success' => true, 'utxosupply' => ['total' => $txoutsetinfo->total_amount, 'circulating' => $circulating]]); } + + protected function _formatHashRate($value) { + if ($value === 'N/A') { + return $value; + } + + /*if ($value > 1000000000000) { + return number_format( $value / 1000000000000, 2, '.', '' ) . ' TH'; + }*/ + if ($value > 1000000000) { + return number_format( $value / 1000000000, 2, '.', '' ) . ' GH/s'; + } + if ($value > 1000000) { + return number_format( $value / 1000000, 2, '.', '' ) . ' MH/s'; + } + if ($value > 1000) { + return number_format( $value / 1000, 2, '.', '' ) . ' KH/s'; + } + + return number_format($value) . ' H/s'; + } + + public static function curl_get($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + $response = curl_exec($ch); + Log::debug('Request execution completed.'); + + if ($response === false) { + $error = curl_error($ch); + $errno = curl_errno($ch); + curl_close($ch); + + throw new \Exception(sprintf('The request failed: %s', $error), $errno); + } else { + curl_close($ch); + } + + return $response; + } + + private function _gethashrate() { + $req = ['method' => 'getnetworkhashps', 'params' => []]; + try { + $res = json_decode(self::curl_json_post(self::$rpcurl, json_encode($req))); + if (!isset($res->result)) { + return 0; + } + return $res->result; + } catch (\Exception $e) { + return 'N/A'; + } + } + + private function _gettxoutsetinfo() { + $req = ['method' => 'gettxoutsetinfo', 'params' => []]; + try { + $res = json_decode(self::curl_json_post(self::$rpcurl, json_encode($req))); + if (!isset($res->result)) { + return 0; + } + return $res->result; + } catch (\Exception $e) { + return 'N/A'; + } + } private static function curl_json_post($url, $data, $headers = []) { $ch = curl_init(); diff --git a/src/Model/Entity/Claim.php b/src/Model/Entity/Claim.php index d12c480..eab2204 100644 --- a/src/Model/Entity/Claim.php +++ b/src/Model/Entity/Claim.php @@ -3,12 +3,16 @@ namespace App\Model\Entity; use Cake\ORM\Entity; +use Cake\ORM\TableRegistry; class Claim extends Entity { function getLbryLink() { $link = $this->name; - if (isset($this->Publisher->Name)) { - $link = $this->Publisher->Name . '/' . $link; + $ClaimModel = TableRegistry::get('Claims'); + $publisher = $ClaimModel->find()->select(['name'])->where(['claim_id' => $this->publisher_id])->first(); + + if (isset($publisher->name)) { + $link = $publisher->name . '/' . $link; } $link = 'lbry://' . $link; return $link; diff --git a/src/Model/Entity/Transaction.php b/src/Model/Entity/Transaction.php index b491ed7..aa0ed81 100644 --- a/src/Model/Entity/Transaction.php +++ b/src/Model/Entity/Transaction.php @@ -5,7 +5,6 @@ namespace App\Model\Entity; use Cake\ORM\Entity; use Cake\ORM\TableRegistry; - class Transaction extends Entity { public function value() { $OutputModel = TableRegistry::get('Outputs'); diff --git a/src/Template/Main/claims.ctp b/src/Template/Main/claims.ctp index 0d4bfad..963205f 100644 --- a/src/Template/Main/claims.ctp +++ b/src/Template/Main/claims.ctp @@ -41,13 +41,13 @@ $a = ['purple', 'orange', 'blue', 'teal', 'green', 'yellow']; $autoThumbText = $claim->getAutoThumbText(); $cost = 'Free'; -if (isset($claim->Price) && $claim->Price > 0) { - $cost = $this->Amount->formatCurrency($claim->Price) . ' LBC'; -} else if (isset($claim->Fee) && strtolower($claim->FeeCurrency) === 'lbc') { - $cost = $this->Amount->formatCurrency($claim->Fee) . ' LBC'; +if (isset($claim->price) && $claim->price > 0) { + $cost = $this->Amount->formatCurrency($claim->price) . ' LBC'; +} else if (isset($claim->fee) && strtolower($claim->fee_currency) === 'lbc') { + $cost = $this->Amount->formatCurrency($claim->fee) . ' LBC'; } -$desc = $claim->Description; +$desc = $claim->description; if (strlen(trim($desc)) == 0) { $desc = 'No description available.'; } else { @@ -57,29 +57,29 @@ if (strlen(trim($desc)) == 0) { ?> -assign('title', 'Claim • ' . $claim->Name) ?> +assign('title', 'Claim • ' . $claim->name) ?>
-

LBRY ClaimsName ?>

-

ClaimId ?>

+

LBRY Claimsname ?>

+

claim_id ?>

- IsNSFW && strlen(trim($claim->ThumbnailUrl)) > 0): ?> - + is_nsfw && strlen(trim($claim->thumbnail_url)) > 0): ?> +
- ClaimType == 2): ?> + claim_type == 2): ?>
Published By
- Publisher)): ?> - Publisher->Name ?> + publisher)): ?> + publisher->name ?> Anonymous @@ -87,17 +87,17 @@ if (strlen(trim($desc)) == 0) {
Created On
-
TransactionTime > 0 ? $claim->TransactionTime : $claim->Created->format('U'))->format('j M Y H:i:s') ?> UTC
+
transaction_time > 0 ? $claim->transaction_time : $claim->created_at->format('U'))->format('j M Y H:i:s') ?> UTC
Transaction ID
- + - ClaimType == 2): ?> + claim_type == 2): ?>
Cost
Safe for Work
-
IsNSFW ? 'No' : 'Yes' ?>
+
is_nsfw ? 'No' : 'Yes' ?>
@@ -105,11 +105,11 @@ if (strlen(trim($desc)) == 0) {