diff --git a/backend/api/common/Controller/Coins.php b/backend/api/common/Controller/Coins.php index 66a8ffc..0c9b2ba 100644 --- a/backend/api/common/Controller/Coins.php +++ b/backend/api/common/Controller/Coins.php @@ -63,4 +63,108 @@ class Coins { $output['deleted'] = $status; return $this->withJson($response, $output); } + public function values(Request $request, Response $response, ModelFactory $factory, $coin_id): Response { + $coin = $factory->find(Coin::class)->one($coin_id); + if (!$coin) { + return $this->withJson($response, ['coin' => null, 'values' => []]); + } + $values = $coin->values(); + if ($values === null) { + return $this->withJson($response, [ + 'coin' => $coin->toArray(), + 'values' => [] + ]); + } + usort($values, function($a, $b) { + return $a->dateTime()->timestamp - $b->dateTime()->timestamp; + }); + $values = array_map(function($item) { + $arr = $item->toArray(); + $arr['formatted'] = $item->unit()->format($item->value); + return $arr; + }, $values); + $output = [ + 'coin' => $coin->toArray(), + 'values' => $values + ]; + return $this->withJson($response, $output); + } + public function valuesMonth(Request $request, Response $response, ModelFactory $factory, $coin_id): Response { + $coin = $factory->find(Coin::class)->one($coin_id); + if (!$coin) { + return $this->withJson($response, ['coin' => null, 'values' => []]); + } + $values = $coin->values('month'); + if ($values === null) { + return $this->withJson($response, [ + 'coin' => $coin->toArray(), + 'values' => [] + ]); + } + usort($values, function($a, $b) { + return $a->dateTime()->timestamp - $b->dateTime()->timestamp; + }); + $values = array_map(function($item) { + $arr = $item->toArray(); + $arr['formatted'] = $item->unit()->format($item->value); + return $arr; + }, $values); + $output = [ + 'coin' => $coin->toArray(), + 'values' => $values + ]; + return $this->withJson($response, $output); + } + public function valuesSixMonths(Request $request, Response $response, ModelFactory $factory, $coin_id): Response { + $coin = $factory->find(Coin::class)->one($coin_id); + if (!$coin) { + return $this->withJson($response, ['coin' => null, 'values' => []]); + } + $values = $coin->values('months'); + if ($values === null) { + return $this->withJson($response, [ + 'coin' => $coin->toArray(), + 'values' => [] + ]); + } + usort($values, function($a, $b) { + return $a->dateTime()->timestamp - $b->dateTime()->timestamp; + }); + $values = array_map(function($item) { + $arr = $item->toArray(); + $arr['formatted'] = $item->unit()->format($item->value); + return $arr; + }, $values); + $output = [ + 'coin' => $coin->toArray(), + 'values' => $values + ]; + return $this->withJson($response, $output); + } + public function valuesYear(Request $request, Response $response, ModelFactory $factory, $coin_id): Response { + $coin = $factory->find(Coin::class)->one($coin_id); + if (!$coin) { + return $this->withJson($response, ['coin' => null, 'values' => []]); + } + $values = $coin->values('year'); + if ($values === null) { + return $this->withJson($response, [ + 'coin' => $coin->toArray(), + 'values' => [] + ]); + } + usort($values, function($a, $b) { + return $a->dateTime()->timestamp - $b->dateTime()->timestamp; + }); + $values = array_map(function($item) { + $arr = $item->toArray(); + $arr['formatted'] = $item->unit()->format($item->value); + return $arr; + }, $values); + $output = [ + 'coin' => $coin->toArray(), + 'values' => $values + ]; + return $this->withJson($response, $output); + } } diff --git a/backend/api/common/Service/Update.php b/backend/api/common/Service/Update.php index 3add238..3cb48ad 100644 --- a/backend/api/common/Service/Update.php +++ b/backend/api/common/Service/Update.php @@ -1,16 +1,18 @@ factory = $factory; - $this->execs = $executables; + $this->client = $client; $this->load(); } public function load() { @@ -22,39 +24,154 @@ class Update { } protected $coins; public function register(int $coin_id, int $type = 0) { - /*if (array_search($coin_id, $this->coins[$type]) !== false) { - return; - }*/ + if (array_search($coin_id, $this->coins[$type]) !== false) { + return false; + } $this->coins[$type] []= $coin_id; $this->getHistorical($coin_id, $type); $check = \ORM::for_table('coin_registers')->where('coin_id', $coin_id)->find_one(); if (!$check) { - \ORM::raw_execute("INSERT INTO coin_registers (coin_id, type) VALUES (?, ?)", [$coin_id, $type]); + return \ORM::raw_execute("INSERT INTO coin_registers (coin_id, type, date_Time) VALUES (?, ?, NOW())", [$coin_id, $type]); } return true; } protected function getHistorical(int $coin_id, int $type) { $coin = $this->factory->find(Coin::class)->one($coin_id); $f = Carbon::now(); - $exe = [$this->execs[$type]]; + $url = []; switch ($type) { case 0: - $exe []= '-i ' . $coin->identifier; - $exe []= '-c usd,clp'; - $exe []= 'hist -hi'; - $exe []= '-f ' . $f->copy()->subYears(10)->timestamp; - $exe []= '-t ' . $f->timestamp(); - break; + return $this->getHistoricalCrypto($coin); case 1: - $exe []= '-i ' . $coin->identifier; - $exe []= 'hist -hi'; - $exe []= '-s ' . $f->copy()->subYears(10)->year; - break; + return $this->getHistoricalIndicador($coin); + default: + return false; } - !d(implode(' ', $exe)); - $output = shell_exec(implode(' ', $exe)); - !d($output); + } + protected function getHistoricalCrypto(Coin $coin) { + $f = Carbon::now(); + $url = []; + $url []= 'crypto'; + $url []= 'historical'; + $url []= $coin->identifier; + $url []= $f->copy()->subYears(10)->timestamp; + $url []= $f->timestamp; + $url = implode('/', $url); + $to = $this->factory->find(Coin::class)->where([['code', 'USD']])->one(); + $response = $this->client->get($url); + $results = json_decode($response->getBody()->getContents()); + $created = []; + foreach ($results->prices as $result) { + $d = Carbon::createFromTimestamp(substr($result[0], 0, -3)); + $value = $result[1]; + $data = [ + 'date_time' => $d->format('Y-m-d H:i:s'), + 'coin_id' => $coin->id, + 'value' => $value, + 'unit_id' => $to->id + ]; + $value = Value::add($this->factory, $data); + $status = $value->save(); + $created []= [ + 'value' => $value->toArray(), + 'created' => $status + ]; + } + return $created; + } + protected function getHistoricalIndicador(Coin $coin) { + $f = Carbon::now(); + $urls = []; + for ($i = 10; $i >= 0; $i --) { + $url = []; + $url []= 'indicador'; + $url []= 'historical'; + $url []= $coin->identifier; + $url []= $f->copy()->subYears($i)->year; + $urls []= implode('/', $url); + } + $to = $this->factory->find(Coin::class)->where([['code', 'CLP']])->one(); + $created = []; + foreach ($urls as $url) { + $response = $this->client->get($url); + $results = json_decode($response->getBody()->getContents()); + foreach ($results->serie as $result) { + $d = Carbon::parse($result->fecha); + $value = $result->valor; + $data = [ + 'date_time' => $d->format('Y-m-d H:i:s'), + 'coin_id' => $coin->id, + 'value' => $value, + 'unit_id' => $to->id + ]; + $value = Value::add($this->factory, $data); + $status = $value->save(); + $created []= [ + 'value' => $value->toArray(), + 'created' => $status + ]; + } + } + return $created; } public function run() { + $created = []; + $created = array_merge($created, $this->getCryptos($this->coins[0])); + $created = array_merge($created, $this->getIndicadores($this->coins[1])); + return $created; + } + protected function getCryptos(array $coins) { + $created = []; + foreach ($coins as $coin_id) { + $coin = $this->factory->find(Coin::class)->one($coin_id); + $url = []; + $url []= 'crypto'; + $url []= $coin->identifier; + $url = implode('/', $url); + $to = $this->factory->find(Coin::class)->where([['code', 'USD']])->one(); + $response = $this->client->get($url); + $results = json_decode($response->getBody()->getContents()); + $data = [ + 'date_time' => $results->n->last_updated_at, + 'coin_id' => $coin->id, + 'value' => 1 / $results->n->usd, + 'unit_id' => $to->id + ]; + $value = Value::add($this->factory, $data); + $status = $value->save(); + $created []= [ + 'value' => $value->toArray(), + 'created' => $status + ]; + } + return $created; + } + protected function getIndicadores(array $coins) { + $created = []; + foreach ($coins as $coin_id) { + $coin = $this->factory->find(Coin::class)->one($coin_id); + $f = Carbon::now(); + $url = []; + $url []= 'indicador'; + $url []= $coin->identifier; + $url []= $f->format('d-m-Y'); + $url = implode('/', $url); + $to = $this->factory->find(Coin::class)->where([['code', 'CLP']])->one(); + $response = $this->client->get($url); + $results = json_decode($response->getBody()->getContents()); + $data = [ + 'date_time' => $results->serie[0]->fecha, + 'coin_id' => $coin->id, + 'value' => $results->serie[0]->valor, + 'unit_id' => $to->id + ]; + $value = Value::add($this->factory, $data); + $status = $value->save(); + $created []= [ + 'value' => $value->toArray(), + 'created' => $status + ]; + } + return $created; } } diff --git a/backend/api/composer.json b/backend/api/composer.json index c1d8a3d..3c1c334 100644 --- a/backend/api/composer.json +++ b/backend/api/composer.json @@ -11,7 +11,8 @@ "provm/models": "^1.0-rc", "spatie/crypto": "^2.0", "robmorgan/phinx": "^0.12.5", - "nesbot/carbon": "^2.49" + "nesbot/carbon": "^2.49", + "guzzlehttp/guzzle": "^7.3" }, "require-dev": { "phpunit/phpunit": "^9.5", diff --git a/backend/api/resources/routes/api/coins.php b/backend/api/resources/routes/api/coins.php index 8a0e4b4..e17d801 100644 --- a/backend/api/resources/routes/api/coins.php +++ b/backend/api/resources/routes/api/coins.php @@ -9,5 +9,11 @@ $app->group('/coins', function($app) { $app->group('/coin/{coin_id}', function($app) { $app->put('/edit', [Coins::class, 'edit']); $app->delete('/delete', [Coins::class, 'delete']); + $app->group('/values', function($app) { + $app->get('/month', [Coins::class, 'valuesMonth']); + $app->get('/months', [Coins::class, 'valuesSixMonths']); + $app->get('/year', [Coins::class, 'valuesYear']); + $app->get('[/]', [Coins::class, 'values']); + }); $app->get('[/]', [Coins::class, 'show']); }); diff --git a/backend/api/setup/api/settings.php b/backend/api/setup/api/settings.php index 7a68ef8..b21d358 100644 --- a/backend/api/setup/api/settings.php +++ b/backend/api/setup/api/settings.php @@ -23,16 +23,5 @@ return [ ]); return (object) $arr; }, - 'coingecko' => function(Container $c) { - return implode(DIRECTORY_SEPARATOR, [ - $c->get('locations')->bin, - 'coingecko' - ]); - }, - 'mindicador' => function(Container $c) { - return implode(DIRECTORY_SEPARATOR, [ - $c->get('locations')->bin, - 'mindicador' - ]); - } + 'python_api' => $_ENV['PYTHON_API'] ]; diff --git a/backend/api/setup/api/setups.php b/backend/api/setup/api/setups.php index 98501da..aee0ab4 100644 --- a/backend/api/setup/api/setups.php +++ b/backend/api/setup/api/setups.php @@ -12,13 +12,13 @@ return [ ProVM\Common\Factory\Model::class => function(Container $container) { return new ProVM\Crypto\Common\Factory\Model(); }, + GuzzleHttp\Client::class => function(Container $container) { + return new GuzzleHttp\Client(['base_uri' => $container->get('python_api')]); + }, ProVM\Crypto\Common\Service\Update::class => function(Container $container) { return new ProVM\Crypto\Common\Service\Update( $container->get(ProVM\Crypto\Common\Factory\Model::class), - [ - $container->get('coingecko'), - $container->get('mindicador') - ] + $container->get(GuzzleHttp\Client::class) ); } ]; diff --git a/backend/api/src/Coin.php b/backend/api/src/Coin.php index 1819aa9..9163b5e 100644 --- a/backend/api/src/Coin.php +++ b/backend/api/src/Coin.php @@ -1,6 +1,7 @@ prefix == '') { + if ($this->prefix != '') { $output []= $this->prefix; } $output []= number_format($value, $this->decimals ?? 0, ',', '.'); - if ($this->suffix == '') { + if ($this->suffix != '') { $output []= $this->suffix; } return implode(' ', $output); } + protected $values; + public function values($period = null) { + if ($this->values === null) { + $this->values = $this->parentOf(Value::class, [Model::CHILD_KEY => 'coin_id']); + } + if ($this->values === null) { + return $this->values; + } + if ($period === null) { + return $this->values; + } + $f = Carbon::now(); + switch ($period) { + case 'month': + case 'mes': + $m = $f->copy()->subMonths(1); + return array_filter($this->values, function($item) use ($m) { + return ($item->dateTime()->greaterThanOrEqualTo($m)); + }); + case 'months': + case 'meses': + $m = $f->copy()->subMonths(6); + return array_filter($this->values, function($item) use ($m) { + return ($item->dateTime()->greaterThanOrEqualTo($m)); + }); + case 'year': + case 'año': + $m = $f->copy()->subYears(1); + return array_filter($this->values, function($item) use ($m) { + return ($item->dateTime()->greaterThanOrEqualTo($m)); + }); + } + } public static function find(Factory $factory, $input) { return $factory->find(Coin::class)->where([['code', $input->code]])->one();