d47081
2 years ago
committed by
GitHub
9 changed files with 565 additions and 44 deletions
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
<<<<<<< HEAD |
||||
# kvazar-network webapp |
||||
Web-oriented content exploring platform for Kevacoin Blockchain |
||||
|
||||
### requirements |
||||
``` |
||||
php-8^ |
||||
php-curl |
||||
php-mbstring |
||||
php-sqlite3 |
||||
php-pdo |
||||
php-bcmath |
||||
php-gd |
||||
``` |
||||
#### database |
||||
|
||||
https://github.com/kvazar-network/database |
||||
|
||||
##### MySQL |
||||
|
||||
https://github.com/kvazar-network/webapp/tree/master |
||||
|
||||
##### SQLite |
||||
|
||||
https://github.com/kvazar-network/webapp/tree/sqlite |
||||
|
||||
#### crontab |
||||
|
||||
``` |
||||
0 0 * * * /path-to/php /path-to/crontab/sitemap.php > /dev/null 2>&1 |
||||
``` |
||||
|
||||
### nginx sef_mode example |
||||
|
||||
``` |
||||
location / { |
||||
try_files $uri $uri/ =404 @sef; |
||||
} |
||||
|
||||
location @sef { |
||||
rewrite ^(/.*)$ /?$1 last; |
||||
} |
||||
``` |
||||
|
||||
### examples |
||||
|
||||
#### yggdrasil |
||||
[http://[203:9fd0:95df:54d7:29db:5ee1:fe2d:95c7]](http://[203:9fd0:95df:54d7:29db:5ee1:fe2d:95c7]) |
||||
======= |
||||
>>>>>>> master |
@ -0,0 +1,268 @@
@@ -0,0 +1,268 @@
|
||||
<?php |
||||
|
||||
class SQLite { |
||||
|
||||
private PDO $_db; |
||||
|
||||
public function __construct(string $database, string $username, string $password) { |
||||
|
||||
try { |
||||
|
||||
$this->_db = new PDO('sqlite:' . $database, $username, $password); |
||||
$this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||||
$this->_db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); |
||||
$this->_db->setAttribute(PDO::ATTR_TIMEOUT, 600); |
||||
|
||||
$this->_db->query(' |
||||
CREATE TABLE IF NOT EXISTS "namespace"( |
||||
"nameSpaceId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nameSpaceId">=0), |
||||
"timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0), |
||||
"hash" CHAR(34) NOT NULL, |
||||
CONSTRAINT "hash_UNIQUE" |
||||
UNIQUE("hash") |
||||
) |
||||
'); |
||||
|
||||
$this->_db->query(' |
||||
CREATE TABLE IF NOT EXISTS "block"( |
||||
"blockId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("blockId">=0), |
||||
"timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0), |
||||
"lostTransactions" INTEGER NOT NULL CHECK("lostTransactions">=0) |
||||
) |
||||
'); |
||||
|
||||
$this->_db->query(' |
||||
CREATE TABLE IF NOT EXISTS "data"( |
||||
"dataId" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("dataId">=0), |
||||
"nameSpaceId" INTEGER NOT NULL CHECK("nameSpaceId">=0), |
||||
"blockId" INTEGER NOT NULL CHECK("blockId">=0), |
||||
"time" INTEGER NOT NULL CHECK("time">=0), |
||||
"timeIndexed" INTEGER NOT NULL CHECK("timeIndexed">=0), |
||||
"size" INTEGER NOT NULL, |
||||
"ns" TEXT NOT NULL CHECK("ns" IN(\'0\', \'1\')), |
||||
"deleted" TEXT NOT NULL CHECK("deleted" IN(\'0\', \'1\')), |
||||
"txid" CHAR(64) NOT NULL, |
||||
"key" TEXT NOT NULL, |
||||
"value" TEXT NOT NULL, |
||||
CONSTRAINT "txid_UNIQUE" |
||||
UNIQUE("txid"), |
||||
CONSTRAINT "fk_data_namespace" |
||||
FOREIGN KEY("nameSpaceId") |
||||
REFERENCES "namespace"("nameSpaceId"), |
||||
CONSTRAINT "fk_data_block" |
||||
FOREIGN KEY("blockId") |
||||
REFERENCES "block"("blockId") |
||||
) |
||||
|
||||
'); |
||||
|
||||
$this->_db->query('CREATE INDEX IF NOT EXISTS "data.fk_data_namespase_idx" ON "data" ("nameSpaceId")'); |
||||
$this->_db->query('CREATE INDEX IF NOT EXISTS "data.fk_data_block_idx" ON "data" ("blockId")'); |
||||
$this->_db->query('CREATE INDEX IF NOT EXISTS "data.deleted_INDEX" ON "data" ("deleted")'); |
||||
$this->_db->query('CREATE INDEX IF NOT EXISTS "data.ns_INDEX" ON "data" ("ns")'); |
||||
|
||||
} catch(PDOException $e) { |
||||
trigger_error($e->getMessage()); |
||||
} |
||||
} |
||||
|
||||
public function getNamespaceValueByNS(string $ns) { |
||||
|
||||
try { |
||||
|
||||
$query = $this->_db->prepare('SELECT `data`.`value` AS `value` |
||||
|
||||
FROM `data` |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE `namespace`.`hash` = ? |
||||
AND `data`.`ns` = "1" |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `data`.`blockId` DESC |
||||
|
||||
LIMIT 1'); |
||||
|
||||
$query->execute([$ns]); |
||||
|
||||
$result = $query->fetch(); |
||||
|
||||
return $result ? $result['value'] : ''; |
||||
|
||||
} catch(PDOException $e) { |
||||
|
||||
trigger_error($e->getMessage()); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public function getNamespaceHashByTX(string $txid) { |
||||
|
||||
try { |
||||
|
||||
$query = $this->_db->prepare('SELECT `namespace`.`hash` |
||||
|
||||
FROM `namespace` |
||||
JOIN `data` ON (`data`.`nameSpaceId` = `namespace`.`nameSpaceId`) |
||||
|
||||
WHERE `data`.`txid` = ?'); |
||||
|
||||
$query->execute([$txid]); |
||||
|
||||
return $query->rowCount() ? $query->fetch()['hash'] : ''; |
||||
|
||||
} catch(PDOException $e) { |
||||
|
||||
trigger_error($e->getMessage()); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public function getData(string $namehash = '', string $txid = '', string $search = '', int $start = 0, int $limit = 10) { |
||||
|
||||
try { |
||||
|
||||
if ($txid) { |
||||
|
||||
$query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`, |
||||
`namespace`.`hash` AS `namehash`, |
||||
`data`.`time` AS `time`, |
||||
`data`.`key` AS `key`, |
||||
`data`.`value` AS `value`, |
||||
`data`.`txid` AS `txid` |
||||
|
||||
FROM `data` |
||||
JOIN `block` ON (`block`.`blockId` = `data`.`blockId`) |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE `data`.`txid` = ? |
||||
AND `data`.`ns` = "0" |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `block`.`blockId` DESC |
||||
|
||||
LIMIT ' . (int) $start . ',' . (int) $limit); |
||||
|
||||
$query->execute([$txid]); |
||||
|
||||
} else if ($namehash) { |
||||
|
||||
$query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`, |
||||
`namespace`.`hash` AS `namehash`, |
||||
`data`.`time` AS `time`, |
||||
`data`.`key` AS `key`, |
||||
`data`.`value` AS `value`, |
||||
`data`.`txid` AS `txid` |
||||
|
||||
FROM `data` |
||||
JOIN `block` ON (`block`.`blockId` = `data`.`blockId`) |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE `namespace`.`hash` = ? |
||||
AND `data`.`ns` = "0" |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `block`.`blockId` DESC |
||||
|
||||
LIMIT ' . (int) $start . ',' . (int) $limit); |
||||
|
||||
$query->execute([$namehash]); |
||||
|
||||
} else if ($search) { |
||||
|
||||
$query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`, |
||||
`namespace`.`hash` AS `namehash`, |
||||
`data`.`time` AS `time`, |
||||
`data`.`key` AS `key`, |
||||
`data`.`value` AS `value`, |
||||
`data`.`txid` AS `txid` |
||||
|
||||
FROM `data` |
||||
JOIN `block` ON (`block`.`blockId` = `data`.`blockId`) |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE (`data`.`key` LIKE :search |
||||
OR `data`.`value` LIKE :search |
||||
OR `block`.`blockId` LIKE :search |
||||
OR `namespace`.`hash` LIKE :search |
||||
OR `data`.`txid` LIKE :search) |
||||
|
||||
AND `data`.`ns` = "0" |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `block`.`blockId` DESC |
||||
|
||||
LIMIT ' . (int) $start . ',' . (int) $limit); |
||||
|
||||
$query->bindValue(':search', '%' . $search . '%', PDO::PARAM_STR); |
||||
|
||||
$query->execute(); |
||||
|
||||
} else { |
||||
|
||||
$query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`, |
||||
`namespace`.`hash` AS `namehash`, |
||||
`data`.`time` AS `time`, |
||||
`data`.`key` AS `key`, |
||||
`data`.`value` AS `value`, |
||||
`data`.`txid` AS `txid` |
||||
|
||||
FROM `data` |
||||
JOIN `block` ON (`block`.`blockId` = `data`.`blockId`) |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE `data`.`ns` = "0" |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `block`.`blockId` DESC |
||||
|
||||
LIMIT ' . (int) $start . ',' . (int) $limit); |
||||
|
||||
$query->execute(); |
||||
} |
||||
|
||||
$result = $query->fetchAll(); |
||||
|
||||
return $result ? $result : []; |
||||
|
||||
} catch(PDOException $e) { |
||||
|
||||
trigger_error($e->getMessage()); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public function getTrends(int $offset = 0) { |
||||
|
||||
try { |
||||
|
||||
$query = $this->_db->prepare('SELECT `block`.`blockId` AS `block`, |
||||
`namespace`.`hash` AS `namehash`, |
||||
`data`.`time` AS `time`, |
||||
`data`.`key` AS `key`, |
||||
`data`.`value` AS `value`, |
||||
`data`.`txid` AS `txid` |
||||
|
||||
FROM `data` |
||||
JOIN `block` ON (`block`.`blockId` = `data`.`blockId`) |
||||
JOIN `namespace` ON (`namespace`.`nameSpaceId` = `data`.`nameSpaceId`) |
||||
|
||||
WHERE `data`.`ns` = "0" |
||||
AND `data`.`time` >= ' . (int) $offset . ' |
||||
-- AND `data`.`deleted` = "0" -- |
||||
|
||||
ORDER BY `block`.`blockId` DESC'); |
||||
|
||||
$query->execute(); |
||||
|
||||
$result = $query->fetchAll(); |
||||
|
||||
return $result ? $result : []; |
||||
|
||||
} catch(PDOException $e) { |
||||
|
||||
trigger_error($e->getMessage()); |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,174 @@
@@ -0,0 +1,174 @@
|
||||
<<<<<<< HEAD |
||||
<?php |
||||
|
||||
require_once('../config.php'); |
||||
require_once('../library/icon.php'); |
||||
require_once('../library/sqlite.php'); |
||||
|
||||
$query = isset($_GET['q']) ? preg_replace('/[^\w\s]+/u', '', urldecode($_GET['q'])) : ''; |
||||
$ns = ''; |
||||
$tx = ''; |
||||
$page = 0; |
||||
|
||||
if (isset($_SERVER['REQUEST_URI'])) { |
||||
|
||||
$q = explode('/', $_SERVER['REQUEST_URI']); |
||||
|
||||
if (isset($q[1])) { |
||||
if ($q[1] == 'rss') { |
||||
$rss = true; |
||||
} else if (strlen($q[1]) == 34) { |
||||
$ns = preg_replace('/[^a-zA-Z0-9]+/', '', $q[1]); |
||||
} else if (strlen($q[1]) == 64) { |
||||
$tx = preg_replace('/[^a-zA-Z0-9]+/', '', $q[1]); |
||||
} else if (preg_match('/[0-9]+/', $q[1])) { |
||||
$page = (int) $q[1]; |
||||
} |
||||
} |
||||
|
||||
if (isset($q[2])) { |
||||
if ($q[2] == 'rss') { |
||||
$rss = true; |
||||
} else if (strlen($q[2]) == 34) { |
||||
$ns = preg_replace('/[^a-zA-Z0-9]+/', '', $q[2]); |
||||
} else if (preg_match('/[0-9]+/', $q[2])) { |
||||
$page = (int) $q[2]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ($query) { |
||||
$rss = isset($_GET['rss']) ? true : false; |
||||
} |
||||
|
||||
if ($page > 0) { |
||||
$limit = PAGE_LIMIT * $page - PAGE_LIMIT; |
||||
} else { |
||||
$limit = PAGE_LIMIT * $page; |
||||
} |
||||
|
||||
$db = new SQLite(DB_NAME, DB_USERNAME, DB_PASSWORD); |
||||
|
||||
if ($ns) { |
||||
|
||||
$namespaceHash = $ns; |
||||
$namespaceValue = $db->getNamespaceValueByNS($ns); |
||||
|
||||
} else if ($tx) { |
||||
|
||||
$namespaceHash = $db->getNamespaceHashByTX($tx); |
||||
$namespaceValue = $db->getNamespaceValueByNS($namespaceHash); |
||||
|
||||
} else { |
||||
|
||||
$namespaceHash = false; |
||||
$namespaceValue = false; |
||||
} |
||||
|
||||
$trends = []; |
||||
|
||||
if (TRENDS_ENABLED) { |
||||
|
||||
foreach ($db->getTrends(time() - TRENDS_SECONDS_OFFSET) as $value) { |
||||
|
||||
foreach ((array) explode(' ', strip_tags(html_entity_decode(nl2br(trim($value['key']))))) as $trend) { |
||||
|
||||
if (strlen($trend) >= TRENDS_MIN_LENGHT) { |
||||
|
||||
$trend = strtolower($trend); |
||||
|
||||
if (isset($trends[$trend])) { |
||||
$trends[$trend]++; |
||||
} else { |
||||
$trends[$trend] = 1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
foreach ((array) explode(' ', strip_tags(html_entity_decode(nl2br(trim($value['value']))))) as $trend) { |
||||
|
||||
if (strlen($trend) >= TRENDS_MIN_LENGHT) { |
||||
|
||||
$trend = strtolower($trend); |
||||
|
||||
if (isset($trends[$trend])) { |
||||
$trends[$trend]++; |
||||
} else { |
||||
$trends[$trend] = 1; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
arsort($trends); |
||||
|
||||
$trends = array_slice($trends, 0, TRENDS_LIMIT); |
||||
|
||||
$trends = array_flip($trends); |
||||
} |
||||
|
||||
$data = []; |
||||
foreach ($db->getData($ns, $tx, $query, $limit, PAGE_LIMIT) as $value) { |
||||
$data[] = [ |
||||
'namehash' => $value['namehash'], |
||||
'block' => $value['block'], |
||||
'txid' => $value['txid'], |
||||
'time' => date(($rss ? 'r' : 'd-m-Y H:i'), $value['time']), |
||||
'key' => $rss ? htmlentities(strip_tags(trim($value['key'])), ENT_XML1) : nl2br(trim($value['key'])), |
||||
'value' => $rss ? htmlentities(strip_tags(trim($value['value'])), ENT_XML1): nl2br(trim($value['value'])), |
||||
]; |
||||
} |
||||
|
||||
$older = false; |
||||
$newer = false; |
||||
|
||||
if (!in_array($page, [0, 1])) { |
||||
if ($page == 2) { |
||||
$newer = ($ns ? $ns : ''); |
||||
} else { |
||||
$newer = ($ns ? $ns . '/' . ($page - 1) : ($page - 1)); |
||||
} |
||||
|
||||
if ($query) { |
||||
$newer = $newer . '?q=' . $query; |
||||
} |
||||
} |
||||
|
||||
if ($data) { |
||||
if (in_array($page, [0, 1])) { |
||||
$older = ($ns ? $ns . '/2' : '2'); |
||||
} else { |
||||
$older = ($ns ? $ns . '/' . ($page + 1) : ($page + 1)); |
||||
} |
||||
|
||||
if ($query) { |
||||
$older = $older . '?q=' . $query; |
||||
} |
||||
} |
||||
|
||||
if ($ns) { |
||||
if ($page) { |
||||
$hrefThisPage = $ns . '/' . $page; |
||||
} else { |
||||
$hrefThisPage = $ns; |
||||
} |
||||
} else { |
||||
if ($page) { |
||||
$hrefThisPage = $page; |
||||
} else { |
||||
$hrefThisPage = ''; |
||||
} |
||||
} |
||||
|
||||
if ($rss) { |
||||
|
||||
header('Content-type: application/xml'); |
||||
require_once('rss.phtml'); |
||||
|
||||
} else { |
||||
|
||||
require_once('index.phtml'); |
||||
|
||||
} |
||||
======= |
||||
>>>>>>> master |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?> |
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> |
||||
<channel> |
||||
<atom:link href="<?php echo BASE_URL; ?><?php echo ($ns ? $ns . '/rss' : |
||||
($query ? '?q=' . $query . '&rss' : 'rss')); ?>" rel="self" type="application/rss+xml"></atom:link> |
||||
<title>KVAZAR - <?php echo ($namespaceValue ? $namespaceValue : |
||||
($namespaceHash ? $namespaceHash : |
||||
($query ? 'SEARCH - ' . $query : 'TODAY'))); ?></title> |
||||
<description>Observe Kevacoin Universe</description> |
||||
<link><?php echo BASE_URL; ?><?php echo ($ns ? $ns : ($query ? '?q=' . $query : false)); ?></link> |
||||
<?php foreach ($data as $item) { ?> |
||||
<item> |
||||
<title><?php echo $item['key']; ?></title> |
||||
<guid><?php echo BASE_URL; ?><?php echo $item['txid']; ?></guid> |
||||
<pubDate><?php echo $item['time']; ?></pubDate> |
||||
<description><?php echo $item['value']; ?></description> |
||||
<link><?php echo BASE_URL; ?><?php echo $item['txid']; ?></link> |
||||
</item> |
||||
<?php } ?> |
||||
</channel> |
||||
</rss> |
Loading…
Reference in new issue