/src/Lovelybooks/Client.php
PHP | 1426 lines | 1181 code | 232 blank | 13 comment | 59 complexity | 52e329d8564329e3801aeb88475feb23 MD5 | raw file
- <?php
- namespace Lovelybooks;
- class Client {
- protected $curl = null;
- const
- READING_STATE_UNREAD = 'Lese ich gerade nicht',
- READING_STATE_READING = 'Lese ich gerade',
- READING_STATE_READ = 'Schon gelesen';
- protected $user = array(
- 'id' => 0,
- 'name' => '',
- 'isLoggedIn' => false
- );
- protected $ajax = [];
- public function __construct() {
- if(!isset($_SESSION['lb_cookies'])) {
- $_SESSION['lb_cookies'] = [];
- }
- if(!isset($_SESSION['lb_user'])) {
- $_SESSION['lb_user'] = '';
- }
- }
- /**
- * Checks the given header-lines for cookie-information and stores them in the session
- *
- * @param array $headers Array of strings with header-information
- * @return void
- */
- public function getCookies($headers) {
- $cookies = $_SESSION['lb_cookies'];
- foreach($headers as $header) {
- if(strpos($header, 'Set-Cookie: ') === 0) {
- list($cookie, ) = explode('; ', str_replace('Set-Cookie: ', '', $header));
- list($id, $value) = explode('=', $cookie);
- $cookies[$id] = $value;
- }
- }
- $_SESSION['lb_cookies'] = $cookies;
- }
- protected function decode($value) {
- return str_replace(
- array('-'),
- array(' '),
- $value
- );
- }
- protected function curlInstance() {
- $curl = new \Curl\Curl();
- $curl->setUserAgent('');
- $curl->setReferrer('https://www.lovelybooks.de');
- foreach($_SESSION['lb_cookies'] as $id => $value) {
- if ($id === 'LB-Token' && $value === '""') {
- continue;
- }
- $curl->setCookie($id, $value);
- }
- return $curl;
- }
- protected function checkResponse($status) {
- if ($status >= 500) {
- throw new \Exception('Lovelybooks ist nicht erreichbar!');
- }
- }
- protected function parseAjaxLinks($content) {
- $iMax = preg_match_all('/Wicket\.Ajax\.ajax\({[^}]*?"u":"([^"]+)".*?,"c":"(id[^"]+)"/', $content, $matches);
- $this->ajax = [];;
- for ($i = 0; $i < $iMax; $i++) {
- $this->ajax[$matches[2][$i]] = $matches[1][$i];
- }
- }
- protected function fetchAjaxContent($id) {
- if(!isset($this->ajax[$id])) {
- return '';
- }
- $curl = $this->curlInstance();
- $curl->setHeader('Accept', 'application/xml, text/xml, */*; q=0.01');
- $curl->setHeader('Wicket-Ajax', 'true');
- $curl->setHeader('Wicket-Ajax-BaseURL', '.');
- $curl->setHeader('Wicket-FocusedElementId', 'seleniumLogin');
- $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
- $curl->get('https://www.lovelybooks.de' . $this->ajax[$id]);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- return $content;
- }
- public function getUserStatus() {
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/');
- $content = $curl->response;
- $this->getCookies($curl->response_headers);
- $unreadMessages = false;
- if (strpos($content, "'userStatus': ['ausgeloggt']") !== false) {
- $this->user['isLoggedIn'] = false;
- } else {
- $this->user['isLoggedIn'] = true;
- foreach($curl->response_headers as $header) {
- if(strpos($header, 'Location: /eingeloggt/') === 0) {
- $this->user['name'] = str_replace('/', '', str_replace('Location: /eingeloggt/', '', $header));
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/eingeloggt/' . $this->user['name'] . '/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $curl->close();
- $unreadMessages = (strpos($content, 'new-mails') > 0);
- }
- }
- }
- return ['loggedIn' => $this->user['isLoggedIn'], 'name' => $this->user['name'], 'unreadMessages' => $unreadMessages];
- }
- public function login($email, $password) {
- $_SESSION['lb_cookies'] = [];
- $status = 500;
- $counter = 5;
- $curl = $this->curlInstance();
- $curl->setHeader('Cache-Control', 'no-cache');
- $curl->setHeader('Pragma', 'no-cache');
- $curl->setHeader('Connection', 'keep-alive');
- $curl->setHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8');
- while ($counter > 0 && $status > 305) {
- $curl->get('https://www.lovelybooks.de/');
- $status = (int) $curl->http_status_code;
- if ($status > 305) {
- sleep(0.1);
- $counter--;
- }
- }
- foreach($curl->response_headers as $header) {
- if(strpos($header, 'Location: /eingeloggt/') === 0) {
- return true;
- }
- }
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- if (trim($content) === '') {
- throw new \Exception('Login failed '.$status . var_export($curl->response_headers, true));
- }
- preg_match('/Wicket\.Ajax\.ajax\(\{"u":"([^"]+)","e":"click","c":"seleniumLogin"/', $content, $matches);
- if(!isset($matches[1])) {
- throw new \Exception('Login failed 2');
- }
- $curl->close();
-
- $query = $matches[1];
- sleep(1);
- $curl = $this->curlInstance();
- $curl->setHeader('Accept', 'application/xml, text/xml, */*; q=0.01');
- $curl->setHeader('Wicket-Ajax', 'true');
- $curl->setHeader('Wicket-Ajax-BaseURL', '.');
- $curl->setHeader('Wicket-FocusedElementId', 'seleniumLogin');
- $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
- $curl->get('https://www.lovelybooks.de/' . $query .'&_='.round(1000 * microtime(true)));
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- preg_match('/<input\stype="hidden"\sname="([^"]+)/', $content, $matches);
- $id = $matches[1];
- preg_match('/[\d-]+\.IBehaviorListener\.0-dialogContainer-loginForm-submit/', $content, $matches);
- $action = $matches[0];
- preg_match('/p::submit"\sid="([^"]+)"/', $content, $matches);
- $submitId = $matches[1];
- $data = [
- 'email' => $email,
- 'password' => $password,
- 'p::submit' => '1',
- $id => ''
- ];
- sleep(0.1);
- $curl = $this->curlInstance();
- $curl->verbose(true);
- $curl->setHeader('Accept', 'application/xml, text/xml, */*; q=0.01');
- $curl->setHeader('Wicket-Ajax', 'true');
- $curl->setHeader('Wicket-Ajax-BaseURL', '.');
- $curl->setHeader('Wicket-FocusedElementId', $submitId);
- $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
- $curl->post('https://www.lovelybooks.de/?' . $action, $data);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- // check for failed login-data
- if(strpos($content, '>Leider ist Deine E-Mail-Adresse und/oder Dein Passwort nicht korrekt. Bitte versuche es noch einmal.') > 0) {
- throw new \Exception('Login failed 3');
- }
- sleep(1);
- $curl = $this->curlInstance();
- $curl->setHeader('Upgrade-Insecure-Requests', '1');
- $curl->setHeader('Connection', 'keep-alive');
- $curl->setHeader('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8');
- $curl->get('https://www.lovelybooks.de/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- foreach($curl->response_headers as $header) {
- if (strpos($header, 'Location: /eingeloggt/') === 0) {
- $_SESSION['lb_user'] = str_replace('/', '', str_replace('Location: /eingeloggt/', '', $header));
- }
- }
- $curl->close();
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/eingeloggt/' . $_SESSION['lb_user'] . '/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- //$curl->close();
- if (strpos($content, "'userStatus': ['eingeloggt']") > 0) {
- return [
- 'name' => $_SESSION['lb_user'],
- 'loggedIn' => true,
- 'unreadMessages' => (strpos($content, 'new-mails') > 0),
- ];
- }
- return [
- 'loggedIn' => false,
- 'name' => '',
- 'content' => var_export($_SESSION, true)
- ];
- }
- public function getAuthorDetails($name) {
- $author = [];
- $name = urlencode($name);
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/autor/' . $name . '/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $this->parseAjaxLinks($curl->response);
- $author['link'] = '/autor/' . $name . '/';
- $content = $curl->response;
- $curl->close();
- $content = explode('<div id="footer">', explode('itemprop="author">', $content)[1])[0];
- $author['name'] = explode('</h1>', $content)[0];
- preg_match('/Lebenslauf\s*<span>von ([^<]*)<\/span><\/h1>\s*<div class="text">([^<]*)/', $content, $matches);
- $author['biography'] = html_entity_decode(trim($matches[2]));
- preg_match('/autorpicL">\s*<img src="([^"]*)/', $content, $matches);
- $author['image'] = $matches[1];
- $author['books'] = [];
- // infos
- $infos = explode('</li>', explode('</ul>', explode('<ul class="facts">', $content)[2])[0]);
- array_pop($infos);
- $author['facts'] = [];
- foreach($infos as $data) {
- list($id, $value) = explode('</b>', $data);
- $id = str_replace(':', '', $id);
- $id = html_entity_decode(trim(strip_tags($id)));
- $value = html_entity_decode(trim(strip_tags($value, '<a>')));
- if($id == '' || $value == '') {
- continue;
- }
- $author['facts'][$id] = preg_replace('/<a href="#">\s*<a href="([^"]+)">([^<]+)<\/a>\s*<\/a>/', '<a href="$1">$2</a>', $value);
- }
- // videos
- $videos = explode('<iframe width="245" height="200" src="', explode('<div class="hr">', explode('<div class="videos">', $content)[1])[0]);
- array_shift($videos);
- $author['videos'] = [];
- foreach($videos as $data) {
- $author['videos'][] = [
- 'embedd' => '<iframe width="245" height="200" src="' . urldecode(explode('<', $data)[0]) . '</iframe>',
- 'url' => urldecode(explode('"', $data)[0])
- ];
- }
- $id = explode('"', explode('<a href="javascript:;" class="append" id="', $data)[1])[0];
- $videos = $this->fetchAjaxContent($id);
- $videos = explode('<iframe width="245" height="200" src="', $videos);
- array_shift($videos);
- foreach($videos as $data) {
- $author['videos'][] = [
- 'embedd' => '<iframe width="245" height="200" src="' . urldecode(explode('<', $data)[0]) . '</iframe>',
- 'url' => urldecode(explode('"', $data)[0])
- ];
- }
- // tags
- $tags = explode('</li>', '<div ' . explode('</ul>', explode('<div class="tagcloud"', $content)[1])[0]);
- array_pop($tags);
- $author['tags'] = [];
- foreach($tags as $data) {
- $data = trim(strip_tags($data));
- if($data !== '') {
- $author['tags'][] = $data;
- }
- }
- // fetch books of the author
- $page = 0;
- $counter = -1;
- $books = [];
- while($counter !== count($books)) {
- $counter = count($books);
- $books = array_merge($books, $this->getAuthorBooks($name, $page));
- $page++;
- }
- foreach($books as $id => $value) {
- $value['author'] = $author['name'];
- $value['authorlink'] = '/autor/' . $author['name'] . '/';
- $books[$id] = $value;
- }
- $author['books'] = array_keys($books);
- return ['books' => $books, 'author' => $author];
- }
- protected function getAuthorBooks($author, $page = 0) {
- $books = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/autor/' . $author . '/buch/?seite=' . $page);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $content = explode('<div class="controls">', $content)[0];
- $data = explode('dataviewitem', $content);
- array_shift($data);
- $i = 1;
- foreach($data as $bookdata) {
- preg_match('/<img src="([^"]+)/', $bookdata, $matches1);
- preg_match('/<h3><a href="([^"]+)[^<]+>([^<]+)<\/a><\/h3>\s*<div class="ratingstars r(\d+)[^>]+>\s*<div>\s*\(<span>(\d+)/', $bookdata, $matches2);
- preg_match('/<p class="sideinfo">(?:Erscheinungsdatum: (\d+\.\d+\.\d+))?<\/p>\s*<p>([^<]*)/', $bookdata, $matches3);
- $id = html_entity_decode(trim(urldecode($matches2[1])));
- $books[$id] = [
- 'cover' => $matches1[1],
- 'id' => $id,
- 'link' => $id,
- 'title' => html_entity_decode(trim($matches2[2])),
- 'rating' => (int) $matches2[3],
- 'votings' => (int) $matches2[4],
- 'published' => (trim($matches3[1]) !== '' ? strtotime($matches3[1] . ' 00:00:00') : 0),
- 'description' => html_entity_decode(trim($matches3[2])),
- ];
- }
- return $books;
- }
- public function getUserDetails($name) {
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/mitglied/' . $name . '/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $content = explode('<div id="content">', $content)[1];
- $content = explode('<div id="footer">', $content)[0];
- $user = [];
- preg_match('/<h2>\s+([^\s]+)\s+ \s+<small class="tooltipped bottom" id="seleniumUserId">\(userID:([\d]+)\)/', $content, $matches);
- $user['id'] = $matches[2];
- $user['name'] = $matches[1];
- preg_match('/<strong>Mitglied seit ([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d,]+)\D+([\d\.]+)\D+([\d\.]+)/', $content, $matches);
- $user['stats']['since'] = $matches[1];
- $user['stats']['eselsohren'] = $matches[2];
- $user['stats']['books'] = $matches[3];
- $user['stats']['wishlist'] = $matches[4];
- $user['stats']['reviews'] = $matches[5];
- $user['stats']['tags'] = $matches[6];
- $user['stats']['ratings'] = $matches[7];
- $user['stats']['ratingsAverage'] = $matches[8];
- $user['stats']['groups'] = $matches[9];
- $user['stats']['friends'] = $matches[10];
- preg_match('/<div class="imgbox">\s+<img src="([^"]+)"/', $content, $matches);
- $user['image'] = $matches[1];
- $iMax = preg_match_all('/<li><a href="#" data-id="(\d+)">\s+<a href="\/autor\/([^\/]+)\/[^\/]+\/" class="bookImgContainer medium"><img src="([^"]+)" alt="([^"]+)"/', $content, $matches);
- $user['lastadded'] = [];
- for ($i = 0; $i < $iMax; $i++) {
- $user['lastadded'][] = [
- 'bookid' => $matches[1][$i],
- 'author' => $this->decode($matches[2][$i]),
- 'cover' => $matches[3][$i],
- 'title' => $matches[4][$i],
- ];
- }
- $reviews = explode('<div class="review">', $content);
- array_shift($reviews);
- $user['reviews'] = [];
- foreach ($reviews as $review) {
- $data = [];
- preg_match('/<img src="([^"]+)"[^>]+><[^>]+>(?:\s*<[^>]+>){4}([^<]+)(?:\s*<[^>]+>){4}([^<]+)(?:\s*<[^>]+>){2}\s+<div title="(\d+)[^>]+>(?:\s*<[^>]+>){9}Rezension vom ([\d\.]+)(?:\s*<[^>]+>){3}\(<span>(\d+)/', $review, $matches);
- $data['cover'] = $matches[1];
- $data['title'] = $matches[2];
- $data['author'] = $matches[3];
- $data['rating'] = $matches[4];
- $data['helpful'] = $matches[5];
- $data['content'] = str_replace('<div class="">', '', '<div class="' . explode('</div>', explode('seven-lines', $review)[1])[0]);
- preg_match('/<a href="\/autor\/[^\/]+\/[^\/]+\/rezension\/(\d+)\/">(\d+) Kommentare<\/a>/', $review, $matches);
- $data['id'] = $matches[1];
- $data['commentsamount'] = $matches[2];
- $user['reviews'][] = $data;
- }
- $current = explode('<div class="appender"', explode(' <div class="ichlese">', $content)[1])[0];
- $iMax = preg_match_all('/<div class="singlebook">\s+<[^<]+<a href="(\/autor\/([^\/]+)\/[^"]+)[^>]+><img src?="([^"]+)" alt="([^"]+)"[^<]+<\/a>\s+<[^<]+<a href="\/bibliothek\/[^\/]+\/lesestatus\/(\d+)[^<]+<[^<]+<[^<]+<div class="percent" style="width:(\d+)%"><\/div>\s+<\/div>\s+<p class="pages">([^<]+)<\/p>/', $current, $matches);
- $books = [];
- for ($i = 0; $i < $iMax; $i++) {
- $link = urldecode($matches[1][$i]);
- $books[$link] = [
- 'id' => $link,
- 'link' => $link,
- 'author' => html_entity_decode(urldecode($matches[2][$i])),
- 'authorlink' => '/autor/' . urldecode($matches[2][$i]) . '/',
- 'cover' => $matches[3][$i],
- 'title' => html_entity_decode($matches[4][$i]),
- 'lesestatus' => $matches[5][$i],
- 'percent' => $matches[6][$i],
- 'status' => html_entity_decode($matches[7][$i]),
- ];
- }
- $user['current'] = array_keys($books);
- $user['details'] = [];
- $details = explode('<div class="hr">', explode('Steckbrief</h2>', $content)[1])[0];
- $details = explode('</tbody>', explode('<tbody>', $details)[1])[0];
- $details = explode('</tr>', $details);
- array_pop($details);
- foreach($details as $detail) {
- list($id, $value) = explode(':', strip_tags($detail), 2);
- $user['details'][trim($id)] = preg_replace('/\s+/', ' ', str_replace("\n", ' ', trim($value)));
- }
- $user['notes'] = [];
- $notes = explode('<div class="note">', explode('<div id="navigator">', $content)[0]);
- array_shift($notes);
- foreach($notes as $note) {
- preg_match('/<img src="([^"]+)" alt="([^"]+)[^4]+4><[^<]+<[^<]+<[^>]+>([^<]+)<\/span><\/h4>\s+<p>([^<]+)<\/p>/', $note, $matches);
- $user['notes'][] = [
- 'username' => $matches[2],
- 'userimage' => $matches[1],
- 'date' => $matches[3],
- 'content' => $matches[4],
- ];
- }
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/mitglied/' . $name . '/mitglieder/freunde/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $content = explode(' Freunde</h2>', $content)[1];
- $content = explode('<div class="controls">', $content)[0];
- $friendsData = explode('dataviewitem', $content);
- array_shift($friendsData);
- $user['friends'] = [];
- foreach($friendsData as $data) {
- preg_match('/class="userpicL" title="([^"]+)">\s*<a href="([^"]+)">\s*<div class="mask"><\/div>\s*<img src="([^"]+)/', $data, $matches);
- $since = explode('<', explode('seit ', $data)[1])[0];
- $user['friends'][] = [
- 'name' => $matches[1],
- 'link' => $matches[2],
- 'image' => $matches[3],
- 'since' => strtotime($since . ' 00:00:00'),
- ];
- }
- return ['books' => $books, 'user' => $user];
- }
- public function getLibraries() {
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/bibliothek/' . $_SESSION['lb_user'] . '/alle/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $libraries = [];
- $iMax = preg_match_all('/href="(\/bibliothek\/' . urldecode($_SESSION['lb_user']) . '\/[^"]+\/)"[^>]+>[^<]+<\/a>\s*<span[^>]+>\s*<strong>([^<]+)/', $content, $matches);
- for ($i = 0; $i < $iMax; $i++) {
- if(trim($matches[2][$i]) === '') {
- continue;
- }
- if(trim($matches[2][$i]) === '1') {
- continue;
- }
- if(trim($matches[1][$i]) === '') {
- continue;
- }
- if($matches[1][$i] === 'alle') {
- continue;
- }
- $libraries[$matches[1][$i]] = [
- 'id' => $matches[1][$i],
- 'name' => $matches[2][$i],
- 'books' => [],
- ];
- }
- return $libraries;
- }
- public function getLibraryPage($library, $page = 0) {
- if($library{0} !== '/') {
- $library = '/' . $library;
- }
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de' . urldecode($library) . '/?seite=' . urldecode($page));
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $books = explode('<div class="libraryitem">', $content);
- array_shift($books);
- $books[count($books) - 1] = explode('<div id="paging">', $books[count($books) - 1])[0];
- $library = [
- 'id' => $library . '/',
- 'name' => '',
- 'books' => [],
- 'page' => $page,
- 'url' => $url,
- ];
- $bookList = [];
- foreach($books as $book) {
- $data = [];
- preg_match('/<div\sclass="bookcoverXM"\sdata-id="([\d]+)">/', $book, $matches);
- $data['id'] = $matches[1];
- preg_match('/href="(\/autor\/[^"]+)" class="bookImgContainer"><img\ssrc="([^"]+)"\salt="([^"]+)"/', $book, $matches);
- $data['id'] = urldecode($matches[1]);
- $data['link'] = urldecode($matches[1]);
- $data['cover'] = $matches[2];
- $data['title'] = $matches[3];
- preg_match('/.*?href="\/bibliothek\/' . $_SESSION['lb_user'] . '\/lesestatus\/([^"]+)\/"/', $book, $matches);
- $data['lesestatus'] = $matches[1];
- preg_match('/<a\shref="(\/autor\/[^"]+\/)">\s(.*)\s+<\/a>((?:\s.+)+?)\s+<br\s*\/>\s+<span>([^<]+)<\/span><br\s*\/>\s+<span>([^<]+)<\/span><span>,\s([\d.]+)<\/span><br\s*\/>\s*ISBN[^>]+>([\d]+)<\/span><br\s*\/>\s+<span>Genre: ([^<]+)/', $book, $matches);
- $data['authorlink'] = html_entity_decode(urldecode($matches[1]));
- $data['author'] = html_entity_decode(trim($matches[2]));
- $data['coauthor'] = html_entity_decode(join(' ', explode(',', join('', explode(' ', join('', explode("\n", trim(strip_tags($matches[3])))))))));
- $data['edition'] = html_entity_decode($matches[4]);
- $data['company'] = html_entity_decode(str_replace('Erschienen bei ', '', $matches[5]));
- $data['published'] = strtotime($matches[6] . ' ' . '00:00:00');
- $data['isbn'] = $matches[7];
- $data['genre'] = html_entity_decode($matches[8]);
- $data['rating'] = 0;
- preg_match('/<div\stitle="([0-5])\svon\s5\sSternen"/', $book, $matches);
- if (isset($matches[1])) {
- $data['rating'] = $matches[1];
- }
- $iMax = preg_match_all('/<strong class="tooltipped left hand">([A-Za-z\s,.]+):<\/strong>\s+<span class="tooltip" style="width:[\d]+px">([^<]*)<\/span>/', $book, $matches);
- for ($i = 0; $i < $iMax; $i++) {
- $data[$matches[1][$i]] = $matches[2][$i];
- }
- $bookList[$data['link']] = $data;
- $library['books'][] = $data['link'];
- }
- return [ 'books' => $bookList, 'library' => $library];
- }
- public function getTagPage($tag, $page = 0) {
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/stoebern/empfehlung/' . urldecode($tag) . '/?seite=' . urldecode($page));
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $books = explode('dataviewitem', explode('<div id="sidebar"', $content)[0]);
- array_shift($books);
- $tag = [
- 'id' => $tag,
- 'books' => [],
- ];
- $bookList = [];
- foreach($books as $book) {
- $data = [];
- preg_match('/<img src="([^"]+)[^<]+\s*<\/a>\s*<\/div>\s*<div class="bookinfo">\s*<h3><a href="([^"]+)">([^<]+)<\/a><\/h3>\s*<p class="autor">\s*<a href="([^"]+)">\s*([^<]+)/', $book, $matches);
- $data['id'] = $matches[2];
- $data['link'] = urldecode($matches[2]);
- $data['cover'] = urldecode($matches[1]);
- $data['title'] = html_entity_decode(trim($matches[3]));
- $data['authorlink'] = urldecode($matches[4]);
- $data['author'] = html_entity_decode(trim($matches[5]));
- $bookList[$data['link']] = $data;
- $tag['books'][] = $data['link'];
- }
- return [ 'books' => $bookList, 'tag' => $tag];
- }
- public function getBook($author, $title) {
- $book = [];
- $book['link'] = '/autor/' . $author . '/' . $title .'/';
- $book['id'] = $book['link'];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/autor/' . urlencode($author) . '/' . urlencode($title) .'/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $this->parseAjaxLinks($curl->response);
- $content = $curl->response;
- $content = explode('<div class="buchdetails', $content)[1];
- $content = explode('<div id="footer">', $content)[0];
- preg_match('/<h1>\s*<span class="autor"[^>]+>\s*<a href="([^"]+)">\s*([^<]+)<\/a>\s*<\/span>\s*<span[^>]+>([^<]+)/', $content, $matches);
- $book['title'] = html_entity_decode($matches[3]);
- $book['authorlink'] = html_entity_decode($matches[1]);
- $book['author'] = html_entity_decode($matches[2]);
- preg_match('/itemprop="description">([^<]*)/', $content, $matches);
- $book['description'] = html_entity_decode($matches[1]);
- preg_match('/<div class="bookcoverXXL">\s+<div>\s+<img src="([^"]+)/', $content, $matches);
- $book['cover'] = $matches[1];
- $book['actions'] = [];
- $actions = explode('</a>', explode('<ul class="social">', explode('<ul class="buchoptions">', $content)[1])[0]);
- array_pop($actions);
- foreach($actions as $action) {
- $label = array_pop(explode('>', $action));
- if($label === 'Buchversand Stein' || $label === 'Amazon' || $label === 'Lieblingsbuchhandlung') {
- continue;
- }
- $book['actions'][] = strip_tags('<a' . array_pop(explode('<a', $action)));
- }
- $comments = explode('<div class="cellcontent">', explode('<span class="zurueck">', $content)[0]);
- array_shift($comments);
- $book['comments'] = [];
- foreach($comments as $comment) {
- $comment = trim(strip_tags($comment, '<p><img>'));
- $book['comments'][] = [
- 'comment' => html_entity_decode(strip_tags(explode('</p>', $comment)[0])),
- 'username' => html_entity_decode(str_replace('— ', '', trim(explode('<img', explode('</p>', $comment)[1])[0]))),
- 'userimage' => explode('"', explode('<img src="', explode('</p>', $comment)[1])[1])[0]
- ];
- }
- $additions = explode('<div class="article', explode('<li class="display-more"', explode('<ul class="appending-list">', $content)[1])[0]);
- array_shift($additions);
- $book['additions'] = [];
- foreach($additions as $addition) {
- preg_match('/<h3><a href="(\/autor\/[^\/]+\/[^\/]+\/([^\/]+)[^"]*)"><span>([^<]+)/', $addition, $matches);
- $data = [
- 'link' => $matches[1],
- 'type' => trim(explode('"', $addition)[0]),
- 'title' => html_entity_decode($matches[3])
- ];
- preg_match('/<\/div>\s*<img src="([^"]+)" alt="([^"]+)/', $addition, $matches);
- $data['username'] = $matches[2];
- $data['userimage'] = $matches[1];
- $data['rating'] = 0;
- if(strpos($addition, '"ratingstars r') > 0) {
- $data['rating'] = explode('0" id="id', explode('"ratingstars r', $addition)[1])[0];
- }
- preg_match('/"timeago" title="([^"]+)/', $addition, $matches);
- $data['published'] = strtotime($matches[1]);
- preg_match('/<div class="text preview"[^<]+<p id="id[^>]+>([^<]+)</', $addition, $matches);
- $data['content'] = $matches[1];
- preg_match('/id="(id[^"]+)" href=/', $addition, $matches);
- if(isset($matches[1])) {
- $data['content'] = $this->fetchAjaxContent($matches[1]);
- $data['content'] = str_replace(
- ['<strong></strong>', '<em></em>', '"> <p>', '"><p>', '</p></p>'],
- ['', '', '">', '">', '</p>'],
- explode('<a class="mehr"',
- explode('class="text complete"', $data['content'])[1]
- )[0]
- );
- $data['content'] = '<div ' . trim($data['content']) . '</div>';
- $data['content'] = strip_tags($data['content'], '<p><br><em><i><u><strong>');
- }
- $book['additions'][] = $data;
- }
- $tags = explode('</li><li>', explode('</div>', explode('<div class="tagcloud"', $content)[1])[0]);
- $book['tags'] = [];
- $book['tags'][] = trim(html_entity_decode(strip_tags('<br ' . array_shift($tags))));
- foreach($tags as $tag) {
- $book['tags'][] = trim(html_entity_decode(strip_tags($tag)));
- }
- $info = explode('<div class="shops">', explode('<div class="buchinfo">', $content)[1])[0];
- $iMax = preg_match_all('/<li>\s*<b>\s*([^:<]+):*<\/b>\s*([^<]+)/', $info, $matches);
- $book['facts'] = [];
- for ($i = 0; $i < $iMax; $i++) {
- $id = trim($matches[1][$i]);
- $value = preg_replace('/\s+/', ' ', $matches[2][$i]);
- if($id === 'Verlag') {
- $book['company'] = trim(html_entity_decode($value));
- continue;
- }
- if($id === 'Aktuelle Ausgabe') {
- $book['published'] = strtotime($value);
- continue;
- }
- if($id === 'ISBN') {
- $book['isbn'] = $value;
- continue;
- }
- $book['facts'][trim($matches[1][$i])] = $value;
- }
- $iMax = preg_match_all('/<li id="[^"]+">\s*<b>\s*([^<:]+):*\s*<\/b>\s*([^<]+)/', $info, $matches);
- for ($i = 0; $i < $iMax; $i++) {
- $id = trim($matches[1][$i]);
- $value = preg_replace('/\s+/', ' ', $matches[2][$i]);
- $book['facts'][trim($matches[1][$i])] = $value;
- }
- $genre = explode('>', explode('</a>', explode('chlid="genreLink"', $info)[1])[0]);
- $genre = array_pop($genre);
- $book['genre'] = trim($genre);
- $editions = explode('<div class="ausgaben"', $info)[1];
- $iMax = preg_match_all('/<a href="(\/autor\/[^"]+)">\s*<img src="([^"]+)" alt="([^"]+)/', $editions, $matches);
- $book['editions'] = [];
- for ($i = 0; $i < $iMax; $i++) {
- $book['editions'][] = [
- 'link' => urldecode($matches[1][$i]),
- 'cover' => $matches[2][$i],
- 'title' => html_entity_decode($matches[3][$i])
- ];
- }
- return $book;
- }
- public function getBookStatus($book) {
- $status = [];
- $status['id'] = $book;
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/bibliothek/' . $_SESSION['lb_user'] . '/lesestatus/' . $book .'/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- preg_match('/<h1>\s*<span\s+class="autor">\s*<a\s+href="(\/autor\/[^\/]+\/)">\s*(.*)\s*<\/a>\s*<\/span>\s*<span>\s*(.*)\s*<\/span>\s*<\/h1>/', $content, $matches);
- $status['authorlink'] = urldecode($matches[1]);
- $status['author'] = html_entity_decode($matches[2]);
- $status['title'] = html_entity_decode($matches[3]);
- preg_match('/<div\s+class="progress">\s*<span\s+class="user">([^<]+)<\/span>\s*<span[^>]+>[^<]+<span\s+class="page">([\d]+)<\/span>/', $content, $matches);
- $status['user'] = $matches[1];
- $status['page'] = $matches[2];
- preg_match('/<div\s+class="bookcoverXXL"\s+data-id="([\d]+)">\s*<a\s+href="(\/autor\/[^"]+)"[^>]+><img\s+src="([^"]+)/', $content, $matches);
- $status['bookid'] = $matches[1];
- $status['booklink'] = urldecode($matches[2]);
- $status['cover'] = $matches[3];
- $comments = explode('<div class="singleEntry ', explode('<div id="footer">', explode('<div class="entriesBox"', $content)[1])[0]);
- array_shift($comments);
- $status['comments'] = [];
- foreach($comments as $comment) {
- $data = [];
- preg_match('/class="timeago"\s+title="([^"]+)">[^>]+>\s*<div class="progressStatus">\s*(?:<div class="progressbar">\s*<div class="percent" style="width:\s*(\d+)%">[^>]+>\s*[^>]+>\s*)?<p class="pages">(?:Seite (\d+) \/ (\d+)|(Lese gerade nicht|Schon gelesen))<\/p>/', $comment, $matches);
- if(count($matches) < 2) {
- continue;
- }
- $data['created'] = strtotime($matches[1]);
- $data['created_orig'] = $matches[1];
- if($data['created'] == false) {
- $data['created'] = strtotime($matches[1].' 00:00:00');
- }
- $data['percent'] = (int) $matches[2];
- $data['pageCurrent'] = (int) $matches[3];
- $data['pageTotal'] = (int) $matches[4];
- $status['pageTotal'] = (int) $matches[4];
- $data['comment'] = html_entity_decode(trim($matches[5]));
- $data['defaultComment'] = '';
- preg_match('/<div class="plaincomment">\s+<p class="defaultText">([^<]+)<\/p>\s+<div class="contentWrap">([^<]*)<\/div>/', $comment, $matches);
- if(count($matches) > 0) {
- $data['defaultComment'] = html_entity_decode(trim($matches[1]));
- $matches[2] = trim($matches[2]);
- if ($matches[2] !== '') {
- $data['comment'] = html_entity_decode($matches[2]);
- }
- }
- $status['comments'][] = $data;
- }
- preg_match('/<div class="beginEntry">\s+<span class="timeago" title="([^"]+)">/', $comment, $matches);
- $status['comments'][] = [
- 'created' => strtotime($matches[1]),
- 'pageCurrent' => 0,
- 'percent' => 0,
- 'pageTotal' => $status['pageTotal'],
- 'comment' => 'zur Bibliothek hinzugefügt'
- ];
- return $status;
- }
- public function updateBookStatus($book, $page, $comment = '', $status = '') {
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/bibliothek/' . $_SESSION['lb_user'] . '/lesestatus/' . $book .'/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- // fetch the form-popup for updating book-status
- preg_match('/Wicket\.Ajax\.ajax\({"u":"(\/bibliothek\/' . $_SESSION['lb_user'] . '\/lesestatus\/' . $book . '\/\?[\d]+-[\d]+\.IBehaviorListener\.0-updateReadingStateLink)","e":"click","c":"([^"]+)"\}\)/', $content, $matches);
- $curl = $this->curlInstance();
- $curl->setHeader('Accept', 'application/xml, text/xml, */*; q=0.01');
- $curl->setHeader('Wicket-Ajax', 'true');
- $curl->setHeader('Wicket-Ajax-BaseURL', '.');
- $curl->setHeader('Wicket-FocusedElementId', $matches[2]);
- $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
- $curl->get('https://www.lovelybooks.de' . $matches[1]);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- preg_match('/Wicket\.Ajax\.ajax\({"f":"([^"]+)","u":"(\/bibliothek\/' . $_SESSION['lb_user'] . '\/lesestatus\/' . $book . '\/\?[\d]+-[\d]+\.IBehaviorListener\.1-dialogContainer-form-submitButton)","e":"click","c":"([^"]+)",/', $content, $matches);
- $id = $matches[1].'_hf_0';
- $url = $matches[2];
- $submitId = $matches[3];
- $baseUrl = '/bibliothek/' . $_SESSION['lb_user'] . '/lesestatus/' . $book . '/';
- preg_match_all('/<input\s+type="radio"\s+id="[^"]+"\s+name="readingStatePanel:radioGroupContainer:radioGroupReadingState"\s+value="([^"]+)"\s+(checked="checked"\s+)?class="[^"]+">\s*<label for="[^"]+">([^<]+)<\/label>/', $content, $matches);
- $options = [];
- $iMax = count($matches[0]);
- for ($i = 0; $i < $iMax; $i++) {
- $options[$matches[3][$i]] = $matches[1][$i];
- if(trim($matches[2][$i]) !== '') {
- $readingState = $matches[1][$i];
- }
- }
- if (isset($options[$status])) {
- $readingState = $options[$status];
- }
- preg_match('/<input\s+type="text"\s+value="([\d]+)"(?:\s+[^=]+="[^"]+")*\sname="readingStatePanel:containerReading:containerFormat:textField2"/', $content, $matches);
- $pagesTotal = $matches[1];
- $data = [
- $id => '',
- 'readingStatePanel:radioGroupContainer:radioGroupReadingState' => $readingState,
- 'readingStatePanel:containerReading:containerFormat:textField1' => $page,
- 'readingStatePanel:containerReading:containerFormat:textField2' => $pagesTotal,
- 'readingStatePanel:containerReading:textArea' => $comment,
- 'submitButton' => '1'
- ];
- $curl = $this->curlInstance();
- $curl->setHeader('Accept', 'application/xml, text/xml, */*; q=0.01');
- $curl->setHeader('Wicket-Ajax', 'true');
- $curl->setHeader('Wicket-Ajax-BaseURL', $baseUrl);
- $curl->setHeader('Wicket-FocusedElementId', $submitId);
- $curl->setHeader('X-Requested-With', 'XMLHttpRequest');
- $curl->post('https://www.lovelybooks.de' . $url, $data);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- }
- public function getCurrentBooks() {
- return $this->getLibraryPage('wirdgeradegelesen');
- }
- public function getMessagePage($folder = 'inbox', $amount = 20, $page = 0) {
- $messages = [];
- $folders = [
- 'inbox' => 'posteingang',
- 'outbox' => 'postausgang',
- ];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/nachrichten/' . $folders[$folder] . '/?anzahl=' . $amount . '&seite=' . $page);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $this->parseAjaxLinks($curl->response);
- $content = $curl->response;
- $curl->close();
- $content = explode('<div id="content">', $content)[1];
- $content = explode('<div id="footer">', $content)[0];
- $content = explode('<table width="100%">', $content)[1];
- $content = explode('</table>', $content)[0];
- $messagesData = explode('><input type="checkbox" name="group" ', $content);
- array_shift($messagesData);
- foreach($messagesData as $message) {
- preg_match('/src="([^"]+)" alt="([^"]+)/', $message, $matches1);
- preg_match('/>am ([^\s]+) um ([^\s]+) Uhr<[^<]+<[^<]+<[^<]+<a href="[^"]+" id="([^"]+)"( style="[^"]+")?><[^>]+>([^<]+)/', $message, $matches2);
- $data = [
- 'folder' => $folder,
- 'sendername' => html_entity_decode($matches1[2]),
- 'senderimage' => $matches1[1],
- 'date' => strtotime($matches2[1] . ' ' . $matches2[2] . ':00'),
- 'subject' => html_entity_decode(trim($matches2[5])),
- 'read' => trim($matches2[4]) === ''
- ];
- $data['description'] = html_entity_decode($this->fetchAjaxContent($matches2[3]));
- $data['description'] = trim(explode('</p></div>', explode('<div class="wiki2html"><p>', $data['description'])[1])[0]);
- $data['id'] = $data['date'] * 1000;
- $counter = 100;
- while(isset($messages[(string) $data['id']]) && $counter > 0) {
- $counter--;
- $data['id'] = $data['id'] + 1;
- }
- $messages[(string) $data['id']] = $data;
- }
- return $messages;
- }
- public function createMessage($receipients, $subject, $message, $attachments = []) {
- $messages = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/nachrichten/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $this->parseAjaxLinks($curl->response);
- $content = $curl->response;
- $curl->close();
- preg_match('/id="([^"]+)">Nachricht erstellen/', $content, $matches);
- $content = $this->fetchAjaxContent($matches[1]);
- $this->parseAjaxLinks($content);
- preg_match('/<input\s+type="hidden"\s+name="([^"]+)"\s+id="[^"]+"\s*\/>/', $content, $matches);
- $submitId = $matches[1];
- preg_match('/button name="okButton" id="([^"]+)"><span>Nachricht senden/', $content, $matches);
- $action = $this->ajax[$matches[1]];
- $data = [
- 'recipientsInput' => join(',', (array) $receipients),
- 'subjectInput' => $subject,
- 'dialogFormPreview:messageText' => $message,
- 'okButton' => 1,
- $submitId => ''
- ];
- $curl = $this->curlInstance();
- $curl->verbose(true);
- $curl->post('https://www.lovelybooks.de' . $action, $data);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- return [
- 'https://www.lovelybooks.de' . $action, $data
- ];
- }
- public function getRaffles() {
- $raffles = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/leserunden-und-buchverlosungen/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $rafflesData = explode('<div class="slider">', $content)[1];
- $rafflesData = explode('<div class="contentblock">', $rafflesData)[0];
- $rafflesData = explode('<div class="singlebook"', $rafflesData);
- array_shift($rafflesData);
- $books = [];
- foreach($rafflesData as $raffle) {
- if(preg_match('/href="(\/autor\/[^\/]+\/[^\/]+\/leserunde\/(\d+)\/)">\s+<img src="([^"]+)" alt="([^"]+)[^<]+(?:<[^<]+){5}<span>(\d+)(?:<[^<]+){5}<a[^>]+>([^<]+)(?:<[^<]+){3}<a[^>]+>([^<]+)(?:<[^<]+){5}<[^>]+>([^<]+)/', $raffle, $matches)) {
- $book = [
- 'title' => html_entity_decode(trim($matches[4])),
- 'author' => html_entity_decode(trim($matches[6])),
- 'leserunde' => $matches[2],
- 'cover' => urldecode($matches[3]),
- ];
- $linkparts = explode('/', urldecode($matches[1]));
- array_pop($linkparts);
- array_pop($linkparts);
- array_pop($linkparts);
- $book['link'] = join('/', $linkparts) . '/';
- $book['id'] = join('/', $linkparts) . '/';
- array_pop($linkparts);
- $book['authorlink'] = join('/', $linkparts) . '/';
- $books[$book['link']] = $book;
- $date = str_replace([
- ' Januar ', ' Februar ', ' März ', ' April ', ' Mai ', ' Juni ', ' Juli ', ' August ', ' September ', ' Oktober ', ' November ', ' Dezember ', ' um '
- ], [
- '01.', '02.', '03.', '04.', '05.', '06.', '07.', '08.', '09.', '10.', '11.', '12.', ' '
- ],
- html_entity_decode(trim($matches[8]))
- );
- $raffles[] = [
- 'link' => urldecode($matches[1]),
- 'id' => (int) $matches[2],
- 'book' => $book['link'],
- 'amount' => (int) $matches[5],
- 'date' => strtotime($date . ':59'),
- ];
- }
- }
- return [
- 'raffles' => $raffles,
- 'books' => $books
- ];
- }
- public function getGroups() {
- $groups = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/mitglied/' . $_SESSION['lb_user'] . '/gruppen/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $content = explode('<div class="controls">', explode('<div class="tab-box">', $content)[1])[0];
- $content = explode('dataviewitem', $content);
- array_shift($content);
- foreach($content as $part) {
- $group = [];
- preg_match('/<a href="(\/gruppe\/[^"]+)">\s*<img.*?src="([^"]+)" alt="([^"]+)"/', $part, $matches);
- $group['link'] = $matches[1];
- $group['id'] = $matches[1];
- $group['cover'] = $matches[2];
- $group['title'] = html_entity_decode(trim($matches[3]));
- preg_match('/<p>\s*erstellt am ([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d\.]+)\D+([\d:]+)+/', $part, $matches);
- $group['created'] = strtotime($matches[1] . ' 00:00:00');
- $group['members'] = (int) $matches[2];
- $group['posts'] = (int) $matches[3];
- $group['lastupdated'] = strtotime($matches[4] . ' ' . $matches[5]);
- $group['description'] = strip_tags(html_entity_decode(explode('</div>', '<div' . explode('expandable five-lines"', $part)[1])[0]), '<p><br><em><strong>');
- $groups[$group['id']] = $group;
- }
- return $groups;
- }
- public function getGroup($id, $name) {
- $group = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/gruppe/' . $id . '/' . $name . '/');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $group['link'] = '/gruppe/' . $id . '/' . $name . '/';
- $content = explode('<div id="footer">', explode('<div id="content">', $content)[1])[0];
- $parts = explode('<div class="tab-panel">', $content);
- $details = $parts[0];
- $parts = explode('<div id="marginal">', $parts[1]);
- $overview = $parts[0];
- $marginal = $parts[1];
- preg_match('/<img.*?src="([^"]+)[^“]+“([^”]+)[^(]+\(groupID:(\d+)\)(?:<[^>]+>\s*){2}[^<]+(?:<[^>]+>\s*){2,3}(.*?)<\/div>/', $details, $matches);
- $group['cover'] = $matches[1];
- $group['title'] = $matches[2];
- $group['id'] = (int) $matches[3];
- $group['description'] = $matches[4];
- preg_match('/<span>Erstellt von<[^<]+\s*<[^>]+>([^<]+)\s*<[^>]+>\s*am\s*([\d\.]+)(?:\s*<[^<]+){3}<[^>]+>\s*(\d+) Mitglieder<[^>]+>\s*(\d+) Themen<[^>]+>\s*(\d+) Beiträge<[^>]+>/', $marginal, $matches);
- $group['creator'] = $matches[1];
- $group['created'] = strtotime($matches[2] . ' 00:00:00');
- $group['members'] = (int) $matches[3];
- $group['articles'] = (int) $matches[4];
- $group['posts'] = (int) $matches[5];
- $notes = explode('<div class="note">', $marginal);
- array_shift($notes);
- $group['notes'] = [];
- foreach($notes as $note) {
- preg_match('/<img src="([^"]+)" alt="([^"]+)"[^<]+(?:\s*<[^<]+>){2,5}<a href="[^"]+" name="kommentar_([^"]+)">[^<]+<[^>]+>\s*<[^>]+>([^<]+)(?:\s*<[^>]+>){2,3}([^<]*)/', $note, $matches);
- $group['notes'][] = [
- 'userimage' => $matches[1],
- 'username' => $matches[2],
- 'id' => (int) $matches[3],
- 'ago' => $matches[4],
- 'content' => $matches[5],
- ];
- }
- $parts = explode('</h2>', $overview);
- array_shift($parts);
- $group['posts'] = [];
- $group['posts']['newest'] = [];
- $entries = explode('<h3>', $parts[0]);
- array_shift($entries);
- foreach($entries as $entry) {
- preg_match('/<a href="([^"]+)">(?:<strong>)?([^<]+)(?:\s*<[^<]+){2,4}<a[^>]+>([^<]+)<\/a>\s*<span>\s*([\d\.:,\s]+)Uhr/', $entry, $matches);
- $group['posts']['newest'][] = [
- 'link' => $matches[1],
- 'title' => $matches[2],
- 'user' => $matches[3],
- 'updated' => strtotime(str_replace(',', '', $matches[4])),
- ];
- }
- $group['posts']['hottest'] = [];
- $entries = explode('<h3>', $parts[1]);
- array_shift($entries);
- foreach($entries as $entry) {
- preg_match('/<a href="([^"]+)">(?:<strong>)?([^<]+)(?:\s*<[^<]+){2,4}<a[^>]+>([^<]+)<\/a>\s*<span>\s*([\d\.:,\s]+)Uhr/', $entry, $matches);
- $group['posts']['hottest'][] = [
- 'link' => $matches[1],
- 'title' => $matches[2],
- 'user' => $matches[3],
- 'updated' => strtotime(str_replace(',', '', $matches[4])),
- ];
- }
- $group['users'] = [];
- $entries = explode('class="userpicL"', $parts[2]);
- array_shift($entries);
- $group['users'] = [];
- foreach($entries as $entry) {
- preg_match('/<img src="([^"]+)" alt="([^"]+)"[^<]+(?:\s*<[^<]+){1,8}<div>(\d+) Beiträge/', $entry, $matches);
- $group['users'][] = [
- 'username' => $matches[2],
- 'userimage' => $matches[1],
- 'posts' => (int) $matches[3],
- ];
- }
- $books = [];
- $entries = explode('<a href="', $parts[3]);
- array_shift($entries);
- foreach($entries as $entry) {
- $book = [];
- preg_match('/(\/autor\/[^\/]+)(\/[^"])+)"[^<]+<[^<]+<[^\/]+([^"]+)[^<]+(?:<[^<]+){2,5}<strong>([^<]+)(?:<[^<]+){2}<span>([^<]+)(?:<[^<]+){2}<p title="\d von 5 Sternen/', $entry, $matches);
- if(!$matches[1]) {
- continue;
- }
- $book['authorlink'] = $matches[1];
- $book['id'] = $matches[1] . '/' . $matches[2];
- $book['link'] = $matches[1] . '/' . $matches[2];
- $book['cover'] = 'http:' . $matches[3];
- $book['title'] = $matches[4];
- $book['author'] = $matches[5];
- preg_match('/<p>(\d+) Bibliotheken, (\d+) Leser, (\d+) Gruppen, (\d+) Rezension<\/p>\s*<div>\s*([^<]+)/', $entry, $matches);
- $book['stats'] = [
- 'libraries' => $matches[1],
- 'users' => $matches[2],
- 'groups' => $matches[3],
- 'reviews' => $matches[4],
- 'tags' => explode(',', str_replace(' ', '', trim($matches[5])))
- ];
- $books[$book['link']] = $book;
- }
- $group['books'] = array_keys($books);
- return ['group' => $group, 'books' => $books];
- }
- public function getGenres() {
- $genres = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de/buecher//');
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $data = explode('col990 buehne', explode('<div id="footer">', $content)[0]);
- array_shift($data);
- $books = [];
- foreach($data as $content) {
- preg_match('/<h2>\s*<i[^<]+<\/i>\s*<span>([^<]+)<\/span>\s*<a href="([^"]+)">\s*([^<]+)/', $content, $matches);
- $genre = [
- 'title' => $matches[3],
- 'subtitle' => $matches[1],
- 'link' => $matches[2],
- 'books' => [],
- ];
- $bookData = explode('<div class="bookcover', $content);
- foreach($bookData as $entry) {
- if(!preg_match('/<a href="\/autor\/([^\/]+)\/([^\/]+)\/[^<]+<img src="([^"]+)" alt="([^"]+)/', $entry, $matches)) {
- continue;
- }
- $book = [
- 'title' => html_entity_decode(trim($matches[4])),
- 'cover' => urldecode($matches[3]),
- 'id' => '/autor/' . urldecode($matches[1]) . '/' . urldecode($matches[2]) . '/',
- 'link' => '/autor/' . urldecode($matches[1]) . '/' . urldecode($matches[2]) . '/',
- 'author' => html_entity_decode(urldecode($matches[1])),
- 'authorlink' => '/autor/' . urldecode($matches[1]) . '/',
- ];
- $genre['books'][] = $book['link'];
- $books[$book['link']] = $book;
- }
- $genres[$genre['link']] = $genre;
- }
- return [
- 'books' => $books,
- 'genres' => $genres,
- ];
- }
- public function getGenre($link) {
- $genres = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de' . $link);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $data = explode('col990 buehne', explode('<div id="footer">', $content)[0]);
- array_shift($data);
- $books = [];
- foreach($data as $content) {
- preg_match('/<h2>\s*<i[^<]+<\/i>\s*<span>([^<]+)<\/span>\s*<a href="([^"]+)">\s*([^<]+)/', $content, $matches);
- $genre = [
- 'title' => $matches[3],
- 'subtitle' => $matches[1],
- 'link' => $matches[2],
- 'books' => [],
- ];
- $bookData = explode('<div class="bookcoverXM>', $content);
- array_shift($bookData);
- foreach($bookData as $entry) {
- if(!preg_match('/<a href="\/autor\/([^\/]+)\/([^\/]+)\/[^<]+<img src="([^"]+)" alt="([^"]+)/', $entry, $matches));
- $book = [
- 'title' => html_entity_decode(trim($matches[4])),
- 'cover' => urldecode($matches[3]),
- 'id' => '/autor/' . urldecode($matches[1]) . '/' . urldecode($matches[2]) . '/',
- 'link' => '/autor/' . urldecode($matches[1]) . '/' . urldecode($matches[2]) . '/',
- 'author' => html_entity_decode(urldecode($matches[1])),
- 'authorlink' => '/autor/' . urldecode($matches[1]) . '/',
- ];
- $genre['books'][] = $book['link'];
- $books[$book['link']] = $book;
- }
- $genres[$genre['link']] = $genre;
- }
- return [
- 'books' => $books,
- 'genres' => $genres,
- ];
- }
- public function getForum($url) {
- $forum = [];
- $threads = [];
- $books = [];
- $curl = $this->curlInstance();
- $curl->get('https://www.lovelybooks.de' . $url);
- $this->getCookies($curl->response_headers);
- $this->checkResponse($curl->http_status_code);
- $content = $curl->response;
- $curl->close();
- $forum['title'] = html_entity_decode(explode('</h1>', explode('<h1>', $content)[1])[0]);
- $forum['id'] = urldecode($url);
- $forum['link'] = urldecode($url);
- $forum['follower'] = [];
- $threadList = explode('<div class="aktivitaet">', explode('<div class="unterthemen"', $content)[1])[0];
- $threadList = explode(' href="', $threadList);
- array_shift($threadList);
- array_shift($threadList);
- foreach($threadList as $threadData) {
- $thread = [
- 'id' => str_replace('?tag=', '/?tag=', explode('"', $threadData)[0]),
- 'link' => str_replace('?tag=', '/?tag=', explode('"', $threadData)[0]),
- ];
- $parts = explode('(', strip_tags('<a href="' . $threadData .'></a>'));
- $thread['count'] = explode(')', array_pop($parts))[0];
- $thread['title'] = join('(', $parts);
- $thread['posts'] = [];
- $threads[$thread['id']] = $thread;
- }
- $forum['threads'] = array_keys($threads);
- $content = explode('<div id="sidebar"', explode('>Weitere</', $content)[0])[1];
- $follower = explode('followerDataView', $content);
- array_shift($follower);
- foreach($follower as $data) {
- $forum['follower'][] = [
- 'image' => explode('"', explode('src="', $data)[1])[0],
- 'link' => explode('"', explode('href="', $data)[1])[0],
- 'name' => explode('"', explode('alt="', $data)[1])[0],
- ];
- }
- return [
- 'forum' => $forum,
- 'threads' => $threads,
- 'books' => $books,
- ];
- }
- public function getThread($url) {
- $t