diff --git a/data.sample.db b/data.sample.db index 7e0cc5f..7bd6845 100644 Binary files a/data.sample.db and b/data.sample.db differ diff --git a/packt.php b/packt.php index fcd492e..8101474 100644 --- a/packt.php +++ b/packt.php @@ -15,6 +15,284 @@ $loginData = [ ]; +class Packt +{ + + + private $credentials = []; + const BASE_URL = 'https://www.packtpub.com/'; + + private $database = null; + + public function __construct($credentials) + { + $this->credentials = $credentials; + } + + /** + * @return null|SQLite3 + */ + public function getDatabase() + { + if (!$this->database) { + $this->database = new SQLite3('data.db'); + } + return $this->database; + } + + public function resolveBookUrl($bookUrl) + { + return self::BASE_URL . trim(str_replace(self::BASE_URL, '', $bookUrl), '/'); + } + + public function truncateBookUrl($bookUrl) + { + return str_replace('https://www.packtpub.com', '', $bookUrl); + } + + public function getBookInfo($bookUrl) + { + + $bookUrl = resolveBookUrl($bookUrl); + $bookData = []; + $bookPage = new Document($bookUrl, true); + $bookData['datepublished'] = $bookPage->first('.book-top-block-info-authors time[itemprop="datePublished"]::attr(datetime)'); + $bookData['numberofpages'] = $bookPage->first('span[itemprop="numberOfPages"]::text'); + $bookData['isbn'] = $bookPage->first('span[itemprop="isbn"]::text'); + $bookData['reviewCount'] = $bookPage->first('meta[itemprop="reviewCount"]::attr(content)'); + $bookData['ratingValue'] = $bookPage->first('meta[itemprop="ratingValue"]::attr(content)'); + + $bookData['toc'] = []; + foreach ($bookPage->find('#book-info-toc.onlyDesktop .book-toc-chapter') as $chapter) { + if (!is_null($chapter->first('div[class*="book-toc-chapter-title"]'))) { + $tocSection = []; + $tocSection['title'] = trim($chapter->first('div[class*="book-toc-chapter-title"]')->text()); + $tocSection['subchapters'] = $chapter->find('div[class*="book-toc-section-text"]::text'); + $bookData['toc'][] = $tocSection; + } + } + + $bookData['description'] = $bookPage->find('div.book-info-bottom-indetail-text[itemprop="description"] p::text'); + $bookData['willLearn'] = $bookPage->find('div.book-info-will-learn-text li::text'); + + $bookData['category'] = $bookPage->first('div[data-product-id="' . $bookData['isbn'] . '"]::attr(data-product-category)'); + + $bookData['authors'] = []; + foreach ($bookPage->find('[itemprop="author"]') as $author) { + + $authorData = []; + $authorData['name'] = trim($author->first('.book-info-bottom-author-title')->text()); + $authorData['bio'] = preg_replace('#\s{2,}#', ' ', trim($author->first('.book-info-bottom-author-body')->text())); + $bookData['authors'][] = $authorData; + } + return $bookData; + } + + public function saveBookChapters($data, $bookId) + { + $db = $this->getDatabase(); + foreach ($data['toc'] as $chapterNumber => $chapter) { + + $stmt = $db->prepare('REPLACE INTO chapter (book_id, chapter_number, parent_id, name) + VALUES (:book_id, :chapter_number, :parent_id, :name)'); + $stmt->bindValue(':book_id', $bookId, SQLITE3_INTEGER); + $stmt->bindValue(':chapter_number', $chapterNumber + 1, SQLITE3_INTEGER); + $stmt->bindValue(':parent_id', null, SQLITE3_INTEGER); + $stmt->bindValue(':name', $chapter['title'], SQLITE3_TEXT); + $result = $stmt->execute(); + + $stmt = $db->prepare('select seq from sqlite_sequence where name="chapter"'); + $result = $stmt->execute(); + $lastInsertedId = $result->fetchArray(SQLITE3_ASSOC); + $lastInsertedId['seq']; + + if (isset($chapter['subchapters'])) { + foreach ($chapter['subchapters'] as $subChapterNumber => $subChapterName) { + + $stmt = $db->prepare('REPLACE INTO chapter (book_id, chapter_number, parent_id, name) + VALUES (:book_id, :chapter_number, :parent_id, :name)'); + $stmt->bindValue(':book_id', $bookId, SQLITE3_INTEGER); + $stmt->bindValue(':chapter_number', $subChapterNumber + 1, SQLITE3_INTEGER); + $stmt->bindValue(':parent_id', $lastInsertedId['seq'], SQLITE3_INTEGER); + $stmt->bindValue(':name', $subChapterName, SQLITE3_TEXT); + $result = $stmt->execute(); + } + } + } + + } + + public function directoryNameFromPath($filePath) + { + $filePathParts = explode('/', trim($filePath, '/')); + return 'books' . DIRECTORY_SEPARATOR . $filePathParts[1] . DIRECTORY_SEPARATOR; + } + + public function downloadBook($url) + { + + if (strlen($url) && !file_exists(fileNameFromPath($url))) { + $localPath = $this->fileNameFromPath($url); + $directory = $this->directoryNameFromPath($url); + $fullUrl = $this->resolveBookUrl($url); + + if (!is_dir($directory)) { + mkdir($directory, 0777, true); + } + c($fullUrl, [], $localPath); + return 1; + } + return 0; + } + + public function fileNameFromPath($filePath) + { + $filePathParts = explode('/', trim($filePath, '/')); + return 'books' . DIRECTORY_SEPARATOR . $filePathParts[1] . DIRECTORY_SEPARATOR . $filePathParts[1] . '.' . (isset($filePathParts[2]) ? $filePathParts[2] : 'zip'); + } + + public function getBooks() + { + //logowanie + c('https://www.packtpub.com/', $this->credentials); + //pobieranie listy ksiÄ…zek + $return = c('https://www.packtpub.com/account/my-ebooks'); + $document = new Document($return); + + $books = $document->find('.product-line.unseen'); + foreach ($books as $book) { + $bookData = []; + $bookData['nid'] = (int)$book->attr('nid'); + $bookData['title'] = str_replace(["\r\n"], '', trim($book->first('.title::text'))); + $bookData['ebook_isbn'] = $book->first('div[isbn]::attr(isbn)'); + $bookData['img'] = $book->first('img[class*=imagecache]::attr(src)'); + $bookData['url'] = $this->truncateBookUrl($book->first('div[class*=product-thumbnail]')->first('a::attr(href)')); + $bookData['pdf'] = $this->truncateBookUrl($book->first('a[href$=pdf]::attr(href)')); + $bookData['epub'] = $this->truncateBookUrl($book->first('a[href$=epub]::attr(href)')); + $bookData['mobi'] = $this->truncateBookUrl($book->first('a[href$=mobi]::attr(href)')); + $bookData['code'] = $this->truncateBookUrl($book->first('a[href*=code_download]::attr(href)')); + yield $bookData; + } + } + + /** + * @param int $nid + * @return bool + */ + public function isBookByNid(int $nid) + { + $stmt = $this->getDatabase()->prepare('SELECT nid FROM book WHERE nid = :nid'); + $stmt->bindValue(':nid', $nid, SQLITE3_INTEGER); + $result = $stmt->execute(); + return $result->fetchArray(SQLITE3_ASSOC) === false ? false : true; + } + + public function saveBooks() + { + foreach ($this->getBooks() as $basicBookInfo) { + if ($this->isBookByNid($basicBookInfo['nid'])) { + $stmt = $this->getDatabase()->prepare('UPDATE book SET nid = :nid, title = :title, ebook_isbn = :ebook_isbn, img = :img, url = :url, pdf = :pdf, epub = :epub, mobi = :mobi, code = :code, upd_dt = (DATETIME(\'now\')) WHERE nid = :nid'); + } else { + $stmt = $this->getDatabase()->prepare('INSERT INTO book (nid, title, isbn, img, url, pdf, epub, mobi, code) +VALUES (:nid, :title, :ebook_isbn, :img, :url, :pdf, :epub, :mobi, :code)'); + } + $stmt->bindValue(':nid', $basicBookInfo['nid'], SQLITE3_INTEGER); + $stmt->bindValue(':title', $basicBookInfo['title'], SQLITE3_TEXT); + $stmt->bindValue(':ebook_isbn', $basicBookInfo['ebook_isbn'], SQLITE3_TEXT); + $stmt->bindValue(':img', $basicBookInfo['img'], SQLITE3_TEXT); + $stmt->bindValue(':url', $basicBookInfo['url'], SQLITE3_TEXT); + $stmt->bindValue(':pdf', $basicBookInfo['pdf'], SQLITE3_TEXT); + $stmt->bindValue(':epub', $basicBookInfo['epub'], SQLITE3_TEXT); + $stmt->bindValue(':mobi', $basicBookInfo['mobi'], SQLITE3_TEXT); + $stmt->bindValue(':code', $basicBookInfo['code'], SQLITE3_TEXT); + $stmt->execute(); + } + } + + public function saveBookDetails($bookDetails) + { + print_r($bookDetails['nid']); + if ($this->isBookByNid($bookDetails['nid'])) { + print_r($bookDetails); + + echo 'xxx'; + + $stmt = $this->getDatabase()->prepare('UPDATE book SET datepublished = :datepublished, reviewCount = :reviewCount, ratingValue = :ratingValue, numberofpages = :numberofpages, upd_dt = (DATETIME(\'now\')) WHERE nid = :nid'); + $stmt->bindValue(':datepublished', $bookDetails['datepublished'], SQLITE3_TEXT); + $stmt->bindValue(':reviewCount', $bookDetails['reviewCount'], SQLITE3_INTEGER); + $stmt->bindValue(':ratingValue', $bookDetails['ratingValue'], SQLITE3_FLOAT); + $stmt->bindValue(':numberofpages', $bookDetails['numberofpages'], SQLITE3_INTEGER); + $stmt->bindValue(':nid', $bookDetails['nid'], SQLITE3_INTEGER); + print_r($stmt->execute()); + } + + + } + + public function getBookDetails($bookUrl) + { + $bookUrl = $this->resolveBookUrl($bookUrl); + $bookData = []; + $bookPage = new Document($bookUrl, true); + $bookData['datepublished'] = $bookPage->first('.book-top-block-info-authors time[itemprop="datePublished"]::attr(datetime)'); + $bookData['numberofpages'] = $bookPage->first('span[itemprop="numberOfPages"]::text'); + $bookData['paper_isbn'] = $bookPage->first('.book-info-details span[itemprop="isbn"]::text'); + $bookData['ebook_isbn'] = $bookPage->first('div.digital-product[data-product-type="ebooks"]::attr(data-product-id)'); + $bookData['ebook_price'] = $bookPage->first('div.digital-product[data-product-type="ebooks"]::attr(data-product-price)'); + $bookData['paper_price'] = $bookPage->first('div.physical-product[data-product-type="books"]::attr(data-product-price)'); + $bookData['reviewCount'] = $bookPage->first('meta[itemprop="reviewCount"]::attr(content)'); + $bookData['ratingValue'] = $bookPage->first('meta[itemprop="ratingValue"]::attr(content)'); + + $bookData['toc'] = []; + foreach ($bookPage->find('#book-info-toc.onlyDesktop .book-toc-chapter') as $chapter) { + if (!is_null($chapter->first('div[class*="book-toc-chapter-title"]'))) { + $tocSection = []; + $tocSection['title'] = trim($chapter->first('div[class*="book-toc-chapter-title"]')->text()); + $tocSection['subchapters'] = $chapter->find('div[class*="book-toc-section-text"]::text'); + $bookData['toc'][] = $tocSection; + } + } + + $bookData['title'] = $bookPage->first('h1[itemprop="name"]::text'); + $bookData['description'] = $bookPage->find('div.book-info-bottom-indetail-text[itemprop="description"] p::text'); + $bookData['willLearn'] = $bookPage->find('div.book-info-will-learn-text li::text'); + + $bookData['category'] = $bookPage->first('div[data-product-id="' . $bookData['paper_isbn'] . '"]::attr(data-product-category)'); +// $bookData['price'] = $bookPage->first('div[data-product-id="' . $bookData['isbn'] . '"]::attr(data-product-price)'); +// $bookData['price'] = $bookPage->first('div[data-product-id="' . $bookData['paper_isbn'] . '"][data-product-type="ebooks"]'); +// $bookData['nid'] = $bookPage->first('div[data-product-id="' . $bookData['paper_isbn'] . '"]::attr(data-product-nid)'); + $bookData['nid'] = $bookPage->first('div.digital-product[data-product-type="ebooks"]::attr(data-product-nid)'); + + $bookData['authors'] = []; + foreach ($bookPage->find('[itemprop="author"]') as $author) { + + $authorData = []; + $authorData['name'] = trim($author->first('.book-info-bottom-author-title')->text()); + $authorData['bio'] = preg_replace('#\s{2,}#', ' ', trim($author->first('.book-info-bottom-author-body')->text())); + $bookData['authors'][] = $authorData; + } + return $bookData; + } + +} + +echo '
';
+
+$packt = new Packt($loginData);
+
+
+//$books = $packt->saveBooks();
+//print_r($books);
+
+
+echo '
';
+$bookDetails = $packt->getBookDetails('/web-development/dependency-injection-angularjs');
+print_r($bookDetails);
+//$packt->saveBookDetails($bookDetails);
+
+
+die();
+
 function c($url, $post = [], $localFilePath = null)
 {
     $cookie = "cookie.txt";
@@ -127,7 +405,6 @@ function saveBookChapters($data, $bookId)
             }
         }
     }
-
 }
 
 
@@ -176,7 +453,6 @@ while ($book = $booksResult->fetchArray(SQLITE3_ASSOC)) {
     }
 
 
-
 }
 
 //$data = json_decode(file_get_contents('data.txt'), 1);
@@ -304,13 +580,11 @@ VALUES  (:nid, :title, :isbn, :img, :url, :datepublished, :numberofpages, :revie
 function downloadBook($url)
 {
 
-    if (strlen($url) && !fileExists(fileNameFromPath($url))) {
+    if (strlen($url) && !file_exists(fileNameFromPath($url))) {
         $localPath = fileNameFromPath($url);
         $directory = directoryNameFromPath($url);
         $fullUrl = resolveBookUrl($url);
 
-        echo ($fullUrl) . "\n";
-//        var_dump($localPath);
         if (!is_dir($directory)) {
             mkdir($directory, 0777, true);
         }
@@ -332,8 +606,4 @@ function directoryNameFromPath($filePath)
     return 'books' . DIRECTORY_SEPARATOR . $filePathParts[1] . DIRECTORY_SEPARATOR;
 }
 
-function fileExists($filePath)
-{
-    return file_exists($filePath);
-}