From 0e9d29675f390d7da0f7ed196c22467b6f28d23a Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 9 May 2023 01:29:32 +0300 Subject: [PATCH] implement host page description history crawling --- config/sphinx.conf.txt | 21 ++++++--- crontab/cleaner.php | 4 ++ crontab/crawler.php | 26 ++++++++--- database/yggo.mwb | Bin 19726 -> 20740 bytes library/mysql.php | 97 +++++++++++++++++++++++++++-------------- public/search.php | 12 +++-- 6 files changed, 110 insertions(+), 50 deletions(-) diff --git a/config/sphinx.conf.txt b/config/sphinx.conf.txt index 498b0e7..3ff4121 100644 --- a/config/sphinx.conf.txt +++ b/config/sphinx.conf.txt @@ -12,7 +12,17 @@ source common source hostPage : common { sql_query = \ - SELECT hostPage.hostPageId, hostPage.rank, hostPage.metaTitle, hostPage.metaDescription, hostPage.metaKeywords, hostPage.data, hostPage.uri, host.name \ + SELECT hostPage.hostPageId, \ + hostPage.rank, \ + hostPage.uri, \ + host.name, \ + (SELECT CONCAT_WS(' ', hostPageDescription.metaTitle, \ + hostPageDescription.metaDescription, \ + hostPageDescription.metaKeywords) \ + FROM hostPageDescription \ + WHERE hostPageDescription.hostPageId = hostPage.hostPageId \ + ORDER BY hostPageDescription.timeAdded DESC \ + LIMIT 1) AS pageDescription \ FROM hostPage \ JOIN host ON (host.hostId = hostPage.hostId) \ WHERE host.status = '1' AND hostPage.httpCode = 200 AND hostPage.timeBanned IS NULL @@ -24,15 +34,12 @@ source hostImage : common { sql_query = \ SELECT hostImage.hostImageId, hostImage.rank, hostImage.uri, host.name, \ - (SELECT GROUP_CONCAT(CONCAT_WS(' ', hostImageDescription.alt, hostImageDescription.title)) \ + (SELECT CONCAT_WS(' ', hostImageDescription.alt, hostImageDescription.title) \ FROM hostImageDescription \ - WHERE hostImageDescription.hostImageId = hostImage.hostImageId) AS imageDescription, \ - (SELECT GROUP_CONCAT(CONCAT_WS(' ', hostPage.metaTitle, hostPage.metaDescription, hostPage.metaKeywords)) \ - FROM hostPage \ - WHERE hostPage.hostPageId IN (SELECT hostImageToHostPage.hostPageId FROM hostImageToHostPage WHERE hostImageToHostPage.hostImageId = hostImage.hostImageId)) AS pageDescription \ + WHERE hostImageDescription.hostImageId = hostImage.hostImageId ORDER BY hostImageDescription.timeAdded DESC LIMIT 1) AS imageDescription \ FROM hostImage \ JOIN host ON (host.hostId = hostImage.hostId) \ - WHERE host.status = '1' AND hostImage.httpCode = 200 AND hostImage.timeBanned IS NULL + WHERE host.status = '1' AND hostImage.httpCode = 200 AND hostImage.timeBanned IS NULL \ sql_attr_uint = rank } diff --git a/crontab/cleaner.php b/crontab/cleaner.php index 300498b..1168c61 100644 --- a/crontab/cleaner.php +++ b/crontab/cleaner.php @@ -94,6 +94,8 @@ try { $db->deleteHostPageToHostImage($hostPage->hostPageId); // Delete host page + $db->deleteHostPageDescriptions($hostPage->hostPageId); + $hostPagesDeleted += $db->deleteHostPage($hostPage->hostPageId); } } @@ -122,6 +124,8 @@ try { $db->deleteHostPageToHostImage($hostPage->hostPageId); // Delete host page + $db->deleteHostPageDescriptions($hostPage->hostPageId); + $hostPagesDeleted += $db->deleteHostPage($hostPage->hostPageId); } } diff --git a/crontab/crawler.php b/crontab/crawler.php index 42268f2..bb6d603 100644 --- a/crontab/crawler.php +++ b/crontab/crawler.php @@ -293,7 +293,7 @@ try { if ($hostImageBanned) { - $db->updateHostImageMime($queueHostImage->hostImageId, $hostImageContentType, time()); + $db->updateHostImageMime($queueHostImage->hostImageId, Filter::mime($hostImageContentType), time()); $hostImagesBanned += $db->updateHostImageTimeBanned($queueHostImage->hostImageId, time()); @@ -387,7 +387,7 @@ try { if ($hostPageBanned) { - $db->updateHostPageMime($queueHostPage->hostPageId, $contentType, time()); + $db->updateHostPageMime($queueHostPage->hostPageId, Filter::mime($contentType), time()); $hostPagesBanned += $db->updateHostPageTimeBanned($queueHostPage->hostPageId, time()); @@ -456,15 +456,27 @@ try { continue; } - // Update queued page data + // Update queued page $hostPagesIndexed += $db->updateHostPage($queueHostPage->hostPageId, - Filter::pageTitle($title->item(0)->nodeValue), - Filter::pageDescription($metaDescription), - Filter::pageKeywords($metaKeywords), Filter::mime($contentType), - CRAWL_HOST_DEFAULT_META_ONLY ? null : Filter::pageData($content), time()); + // Format page content + $content = Filter::pageData($content); + + // Add queued page description if not exists + $crc32data = crc32($content); + + if (!$db->getHostPageDescription($queueHostPage->hostPageId, $crc32data)) { + $db->addHostPageDescription($queueHostPage->hostPageId, + $crc32data, + Filter::pageTitle($title->item(0)->nodeValue), + Filter::pageDescription($metaDescription), + Filter::pageKeywords($metaKeywords), + CRAWL_HOST_DEFAULT_META_ONLY ? null : $content, + time()); + } + // Update manifest registry if (CRAWL_MANIFEST && !empty($metaYggoManifest) && filter_var($metaYggoManifest, FILTER_VALIDATE_URL) && preg_match(CRAWL_URL_REGEXP, $metaYggoManifest)) { diff --git a/database/yggo.mwb b/database/yggo.mwb index e807ec4e7c6dfcf5de7e2e479cfbe5fab7f6e1e8..bd4fccd6afef1792da4640cb85f1f851005b1662 100644 GIT binary patch literal 20740 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 literal 19726 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

dOuwS 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 diff --git a/library/mysql.php b/library/mysql.php index 76d5d34..92fd0b1 100644 --- a/library/mysql.php +++ b/library/mysql.php @@ -384,19 +384,34 @@ class MySQL { public function getHostPagesByLimit(int $hostId, int $limit) { - $query = $this->_db->prepare('SELECT * FROM `hostPage` WHERE `hostId` = ? ORDER BY hostPageId DESC LIMIT ' . (int) $limit); + $query = $this->_db->prepare('SELECT * FROM `hostPage` WHERE `hostId` = ? ORDER BY `hostPageId` DESC LIMIT ' . (int) $limit); $query->execute([$hostId]); return $query->fetchAll(); } + public function getHostPageDescription(int $hostPageId, int $crc32data) { + + $query = $this->_db->prepare('SELECT * FROM `hostPageDescription` WHERE `hostPageId` = ? AND `crc32data` = ? LIMIT 1'); + + $query->execute([$hostPageId, $crc32data]); + + return $query->fetch(); + } + + public function getLastPageDescription(int $hostPageId) { + + $query = $this->_db->prepare('SELECT * FROM `hostPageDescription` WHERE `hostPageId` = ? ORDER BY `timeAdded` DESC LIMIT 1'); + + $query->execute([$hostPageId]); + + return $query->fetch(); + } + public function getFoundHostPage(int $hostPageId) { - $query = $this->_db->prepare('SELECT `hostPage`.`metaTitle`, - `hostPage`.`metaDescription`, - `hostPage`.`data`, - `hostPage`.`uri`, + $query = $this->_db->prepare('SELECT `hostPage`.`uri`, `hostPage`.`rank`, `host`.`scheme`, `host`.`name`, @@ -449,11 +464,7 @@ class MySQL { mixed $timeBanned = null, mixed $httpCode = null, mixed $mime = null, - mixed $rank = null, - mixed $metaTitle = null, - mixed $metaDescription = null, - mixed $metaKeywords = null, - mixed $data = null) { + mixed $rank = null) { $query = $this->_db->prepare('INSERT INTO `hostPage` (`hostId`, `crc32uri`, @@ -463,35 +474,18 @@ class MySQL { `timeBanned`, `httpCode`, `mime`, - `rank`, - `metaTitle`, - `metaDescription`, - `metaKeywords`, - `data`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + `rank`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $query->execute([$hostId, $crc32uri, $uri, $timeAdded, $timeUpdated, $timeBanned, $httpCode, $mime, $rank, $metaTitle, $metaDescription, $metaKeywords, $data]); + $query->execute([$hostId, $crc32uri, $uri, $timeAdded, $timeUpdated, $timeBanned, $httpCode, $mime, $rank]); return $this->_db->lastInsertId(); } - public function updateHostPage( int $hostPageId, - mixed $metaTitle, - mixed $metaDescription, - mixed $metaKeywords, - string $mime, - mixed $data, - int $timeUpdated, - mixed $timeBanned = null) { + public function updateHostPage(int $hostPageId, string $mime, int $timeUpdated) { - $query = $this->_db->prepare('UPDATE `hostPage` SET `metaTitle` = ?, - `metaDescription` = ?, - `metaKeywords` = ?, - `mime` = ?, - `data` = ?, - `timeUpdated` = ?, - `timeBanned` = ? WHERE `hostPageId` = ? LIMIT 1'); + $query = $this->_db->prepare('UPDATE `hostPage` SET `timeUpdated` = ?, `mime` = ? WHERE `hostPageId` = ? LIMIT 1'); - $query->execute([$metaTitle, $metaDescription, $metaKeywords, $mime, $data, $timeUpdated, $timeBanned, $hostPageId]); + $query->execute([$timeUpdated, $mime, $hostPageId]); return $query->rowCount(); } @@ -548,6 +542,15 @@ class MySQL { return $query->rowCount(); } + public function deleteHostPageDescriptions(int $hostPageId) { + + $query = $this->_db->prepare('DELETE FROM `hostPageDescription` WHERE `hostPageId` = ?'); + + $query->execute([$hostPageId]); + + return $query->rowCount(); + } + public function deleteHostPageToHostImage(int $hostPageId) { $query = $this->_db->prepare('DELETE FROM `hostImageToHostPage` WHERE `hostPageId` = ?'); @@ -557,6 +560,36 @@ class MySQL { return $query->rowCount(); } + public function addHostPageDescription(int $hostPageId, + int $crc32data, + mixed $metaTitle, + mixed $metaDescription, + mixed $metaKeywords, + mixed $data, + int $timeAdded) { + + $query = $this->_db->prepare('INSERT INTO `hostPageDescription` ( `hostPageId`, + `crc32data`, + `metaTitle`, + `metaDescription`, + `metaKeywords`, + `data`, + `timeAdded` + ) VALUES (?, ?, ?, ?, ?, ?, ?)'); + + $query->execute([ + $hostPageId, + $crc32data, + $metaTitle, + $metaDescription, + $metaKeywords, + $data, + $timeAdded + ]); + + return $query->rowCount(); + } + // Cleaner tools public function getCleanerQueue(int $limit, int $timeFrom) { diff --git a/public/search.php b/public/search.php index aa2d1bf..477b328 100644 --- a/public/search.php +++ b/public/search.php @@ -436,7 +436,9 @@ if (!empty($q)) { getHostImageHostPages($result->id, WEBSITE_SEARCH_IMAGE_RELATED_PAGE_RESULTS_LIMIT) as $hostPage) { ?> getFoundHostPage($hostPage->hostPageId)) { ?> scheme . '://' . $hostPage->name . ($hostPage->port ? ':' . $hostPage->port : false) . $hostPage->uri ?> -

metaTitle ?>

+ getLastPageDescription($result->id)) { ?> +

metaTitle ?>

+ description)) { ?> description ?> @@ -469,9 +471,11 @@ if (!empty($q)) { ?>
-

metaTitle ?>

- metaDescription)) { ?> - metaDescription ?> + getLastPageDescription($result->id)) { ?> +

metaTitle ?>

+ metaDescription)) { ?> + metaDescription ?> + favicon