rss-bridge/bridges/GoodreadsBridge.php

96 lines
3.5 KiB
PHP
Raw Normal View History

<?php
class GoodreadsBridge extends BridgeAbstract
{
const MAINTAINER = 'captn3m0';
const NAME = 'Goodreads Bridge';
const URI = 'https://www.goodreads.com/';
const CACHE_TIMEOUT = 0; // 30min
const DESCRIPTION = 'Various RSS feeds from Goodreads';
const CONTEXT_AUTHOR_BOOKS = 'Books by Author';
// Using a specific context because I plan to expand this soon
const PARAMETERS = [
'Books by Author' => [
'author_url' => [
'name' => 'Link to author\'s page on Goodreads',
'type' => 'text',
'required' => true,
'title' => 'Should look somewhat like goodreads.com/author/show/',
'pattern' => '^(https:\/\/)?(www.)?goodreads\.com\/author\/show\/\d+\..*$',
'exampleValue' => 'https://www.goodreads.com/author/show/38550.Brandon_Sanderson'
],
'published_only' => [
'name' => 'Show published books only',
'type' => 'checkbox',
'required' => false,
'title' => 'If left unchecked, this will return unpublished books as well',
'defaultValue' => 'checked',
],
],
];
private function collectAuthorBooks($url)
{
$regex = '/goodreads\.com\/author\/show\/(\d+)/';
preg_match($regex, $url, $matches);
$authorId = $matches[1];
$authorListUrl = "https://www.goodreads.com/author/list/$authorId?sort=original_publication_year";
$html = getSimpleHTMLDOMCached($authorListUrl, self::CACHE_TIMEOUT);
foreach ($html->find('tr[itemtype="http://schema.org/Book"]') as $row) {
$dateSpan = $row->find('.uitext', 0)->plaintext;
$date = null;
// If book is not yet published, ignore for now
if (preg_match('/published\s+(\d{4})/', $dateSpan, $matches) === 1) {
// Goodreads doesn't give us exact publication date here, only a year
// We are skipping future dates anyway, so this is def published
// but we can't pick a dynamic date either to keep clients from getting
// confused. So we pick a guaranteed date of 1st-Jan instead.
$date = $matches[1] . '-01-01';
} elseif ($this->getInput('published_only') !== 'checked') {
// We can return unpublished books as well
$date = date('Y-01-01');
} else {
continue;
}
$row = defaultLinkTo($row, $this->getURI());
$item['title'] = $row->find('.bookTitle', 0)->plaintext;
$item['uri'] = $row->find('.bookTitle', 0)->getAttribute('href');
$item['author'] = $row->find('.authorName', 0)->plaintext;
$item['content'] = '<a href="'
. $row->find('.bookTitle', 0)->getAttribute('href')
. '"><img src="'
. $row->find('.bookCover', 0)->getAttribute('src')
. '"></a>';
$item['timestamp'] = $date;
$item['enclosures'] = [
$row->find('.bookCover', 0)->getAttribute('src')
];
$this->items[] = $item; // Add item to the list
}
}
public function collectData()
{
switch ($this->queriedContext) {
case self::CONTEXT_AUTHOR_BOOKS:
$this->collectAuthorBooks($this->getInput('author_url'));
break;
default:
throw new Exception('Invalid context', 1);
break;
}
}
}