diff --git a/README.md b/README.md index bee7db2c..efd6aede 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ PHP 7+ is required. ```shell # Install Apache, PHP, PHP-FPM, and various other dependencies. -sudo apt install -y git composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl php-curl php-zip apache2 apache2-utils libfcgi0ldbl task-spooler ipv6calc mariadb-server +sudo apt install -y git composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl php-curl php-zip apache2 apache2-utils libfcgi0ldbl task-spooler ipv6calc mariadb-server libaprutil1-dbd-mysql # Create the site root and logs root and clone this repo into it. sudo mkdir /standardebooks.org/ @@ -26,7 +26,7 @@ echo -e "127.0.0.1\tstandardebooks.test" | sudo tee -a /etc/hosts openssl req -x509 -nodes -days 99999 -newkey rsa:4096 -subj "/CN=standardebooks.test" -keyout /standardebooks.org/web/config/ssl/standardebooks.test.key -sha256 -out /standardebooks.org/web/config/ssl/standardebooks.test.crt # Enable the necessary Apache modules. -sudo a2enmod headers expires ssl rewrite proxy proxy_fcgi +sudo a2enmod headers expires ssl rewrite proxy proxy_fcgi authn_dbd # Link and enable the SE Apache configuration file. sudo ln -s /standardebooks.org/web/config/apache/standardebooks.test.conf /etc/apache2/sites-available/ diff --git a/config/apache/standardebooks.org.conf b/config/apache/standardebooks.org.conf index 847049af..c3c51195 100644 --- a/config/apache/standardebooks.org.conf +++ b/config/apache/standardebooks.org.conf @@ -50,6 +50,23 @@ SSLStaplingReturnResponderErrors off Define domain standardebooks.org Define webroot /standardebooks.org/web + + ServerName standardebooks.com + ServerAlias www.standardebooks.com + RedirectPermanent / https://${domain}/ + + + + ServerName standardebooks.com + ServerAlias www.standardebooks.com + RedirectPermanent / https://${domain}/ + + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/standardebooks.com/fullchain.pem + SSLCertificateKeyFile /etc/letsencrypt/live/standardebooks.com/privkey.pem + Header always set Strict-Transport-Security "max-age=15768000" + + ServerName ${domain} ServerAlias www.${domain} @@ -72,7 +89,7 @@ Define webroot /standardebooks.org/web Header always set Strict-Transport-Security "max-age=15768000" Header set Content-Security-Policy "default-src 'self';" - + # Disable .htaccess files AllowOverride none @@ -88,43 +105,31 @@ Define webroot /standardebooks.org/web AddType application/x-mobi8-ebook .azw3 - + # Serve distributables using the "download" dialog instead of opening in-browser # Note: the trailing e in the Header directive is required # In modern browsers this is handled with the a@download attribute, we keep this here for compatibility SetEnvIf Request_URI ^/ebooks/.+?/downloads/(.+)$ FILENAME=$1 Header set Content-Disposition "attachment; filename=%{FILENAME}e" - + # We explicitly set the content-type for items in the /vocab/ directory, because Apache doesn't set it for us, # and we need a content-type header when using the "nosniff" header. See https://bugzilla.mozilla.org/show_bug.cgi?id=1547076 - + Header set Content-Type "text/plain" - - - - DirectoryIndex index.xml - - - # text/xml allows the page to be displayed in a browser and the encoding to be - # determined from the document and not the HTTP headers. application/rss+xml will cause it to be downloaded. - - - Header set Content-Type "text/xml; charset=utf-8" - - + # Enable HTTP CORS so that browser-based readers like Readium can access opds and ebooks # Allow fonts for newsletter emails # See https://github.com/standardebooks/tools/issues/2 - + Header set Access-Control-Allow-Origin "*" - + # We use a different CSP policy for single-page files because our default one doesn't allow inline images or CSS - + Header set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';" - + # Remove www from requests RewriteCond %{HTTP_HOST} ^www\.(.+) [NC] @@ -137,13 +142,13 @@ Define webroot /standardebooks.org/web SetEnv proxy-sendcl 1 # Forward all PHP requests to the php-fpm pool for this domain. - + SetHandler "proxy:unix:/run/php/${domain}.sock|fcgi://${domain}" Header set Cache-Control "no-store" # Set some proxy properties. - + ProxySet connectiontimeout=5 timeout=240 @@ -190,11 +195,11 @@ Define webroot /standardebooks.org/web # Redirect index pages RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}/index.php -f - RewriteRule (.*) /$1/index.php + RewriteRule (.*) $1/index.php RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}/index.xml -f - RewriteRule (.*) /$1/index.xml + RewriteRule (.*) $1/index.xml # Remove newline characters inserted by accident in some email clients RewriteRule ^(.*)\r\n[\ ]?(.*)$ $1$2 [R=301,N] @@ -248,13 +253,6 @@ Define webroot /standardebooks.org/web RewriteCond %{REQUEST_FILENAME} !^/ebooks/.+?/text.*$ RewriteRule ^/ebooks/([^\.]+?)$ /ebooks/ebook.php?url-path=$1 - # If we ask for /opds/all?query=xyz, rewrite that to the search page. - RewriteCond %{QUERY_STRING} ^query= - RewriteRule ^/feeds/(opds|atom|rss)/all.xml$ /feeds/$1/search.php [QSA] - - # Rewrite old links to feeds - RewriteRule ^/(opds|rss|atom)(.*)$ /feeds/$1$2 [R=301,L] - # Newsletter RewriteRule ^/newsletter$ /newsletter/subscriptions/new.php [L] RewriteRule ^/newsletter/subscriptions/([^/\.]+?)$ /newsletter/subscriptions/get.php?uuid=$1 [L] @@ -270,21 +268,65 @@ Define webroot /standardebooks.org/web RewriteCond expr "tolower(%{REQUEST_METHOD}) =~ /^post$/" RewriteRule ^/patrons-circle/polls/([^/\.]+)/votes$ /patrons-circle/polls/votes/post.php?pollurlname=$1 [L] - - - ServerName standardebooks.com - ServerAlias www.standardebooks.com - RedirectPermanent / https://${domain}/ - + # Feeds + # Rewrite old links to feeds + RewriteRule ^/(opds|rss|atom)(.*)$ /feeds/$1$2 [R=301,L] - - ServerName standardebooks.com - ServerAlias www.standardebooks.com - RedirectPermanent / https://${domain}/ + # If we ask for /opds/all?query=xyz, rewrite that to the search page. + RewriteCond %{QUERY_STRING} \bquery= + RewriteRule ^/feeds/(opds|atom|rss)/all.xml$ /feeds/$1/search.php [QSA] - SSLEngine on - SSLCertificateFile /etc/letsencrypt/live/standardebooks.com/fullchain.pem - SSLCertificateKeyFile /etc/letsencrypt/live/standardebooks.com/privkey.pem - Header always set Strict-Transport-Security "max-age=15768000" + # Enable mod_authn_dbd + DBDriver mysql + DBDParams "dbname=se user=www-data" + + # Enable HTTP Basic auth for feeds + AuthType Basic + AuthName "Enter your Patrons Circle email address or your API key, and a blank password." + Require valid-user + ErrorDocument 401 /feeds/401 + + # Credentials caching to prevent slamming the DB. socache must be ahead of dbd + AuthBasicProvider socache dbd + AuthnCacheProvideFor dbd + AuthnCacheContext ${domain} + + # mod_authn_dbd SQL query to authenticate a user + # The hash is simply the hash of a blank password. We're only interested in the username/API key. + # We have to do this tortured query instead of a cleaner one, because the AuthDBDUserPWQuery + # function will only replace %s EXACTLY ONCE. We cannot have more than one %s in the query string. + AuthDBDUserPWQuery "\ + select '$apr1$13q1pnGf$vQnIj94BXP1EPdL/4ISba.' from \ + ( \ + select Email, Uuid from Patrons p inner join Users u using (UserId) where p.Ended is null \ + union \ + select Email, Uuid from FeedUsers fu inner join Users u using (UserId) where fu.Ended is null \ + ) x where %s in (Email, Uuid) limit 1 \ + " + + + # Disable HTTP Basic auth for the feed XSL stylesheet and the new releases feeds + Require all granted + + + + # Emit content-types for OPDS feeds, as some clients require a strictly correct content-type in order to work + + Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8" + + + Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8" + + + + # Emit content-types for RSS/Atom feeds + rss|atom)/.+"> + # Note the trailing e is required to complete the environmental variable reference + Header set Content-Type "application/%{MATCH_FEEDTYPE}e+xml; charset=utf-8" + + + Header set Content-Type "application/xhtml+xml; charset=utf-8" + + diff --git a/config/apache/standardebooks.test.conf b/config/apache/standardebooks.test.conf index 2bcaf34f..1cb7e7af 100644 --- a/config/apache/standardebooks.test.conf +++ b/config/apache/standardebooks.test.conf @@ -71,7 +71,7 @@ Define webroot /standardebooks.org/web Header always set Strict-Transport-Security "max-age=15768000" Header set Content-Security-Policy "default-src 'self';" - + # Disable .htaccess files AllowOverride none @@ -87,43 +87,31 @@ Define webroot /standardebooks.org/web AddType application/x-mobi8-ebook .azw3 - + # Serve distributables using the "download" dialog instead of opening in-browser # Note: the trailing e in the Header directive is required # In modern browsers this is handled with the a@download attribute, we keep this here for compatibility SetEnvIf Request_URI ^/ebooks/.+?/downloads/(.+)$ FILENAME=$1 Header set Content-Disposition "attachment; filename=%{FILENAME}e" - + # We explicitly set the content-type for items in the /vocab/ directory, because Apache doesn't set it for us, # and we need a content-type header when using the "nosniff" header. See https://bugzilla.mozilla.org/show_bug.cgi?id=1547076 - + Header set Content-Type "text/plain" - - - - DirectoryIndex index.xml - - - # text/xml allows the page to be displayed in a browser and the encoding to be - # determined from the document and not the HTTP headers. application/rss+xml will cause it to be downloaded. - - - Header set Content-Type "text/xml; charset=utf-8" - - + # Enable HTTP CORS so that browser-based readers like Readium can access opds and ebooks # Allow fonts for newsletter emails # See https://github.com/standardebooks/tools/issues/2 - + Header set Access-Control-Allow-Origin "*" - + # We use a different CSP policy for single-page files because our default one doesn't allow inline images or CSS - + Header set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';" - + # Remove www from requests RewriteCond %{HTTP_HOST} ^www\.(.+) [NC] @@ -136,13 +124,13 @@ Define webroot /standardebooks.org/web SetEnv proxy-sendcl 1 # Forward all PHP requests to the php-fpm pool for this domain. - + SetHandler "proxy:unix:/run/php/${domain}.sock|fcgi://${domain}" Header set Cache-Control "no-store" # Set some proxy properties. - + ProxySet connectiontimeout=5 timeout=240 @@ -189,11 +177,11 @@ Define webroot /standardebooks.org/web # Redirect index pages RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}/index.php -f - RewriteRule (.*) /$1/index.php + RewriteRule (.*) $1/index.php RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}/index.xml -f - RewriteRule (.*) /$1/index.xml + RewriteRule (.*) $1/index.xml # Remove newline characters inserted by accident in some email clients RewriteRule ^(.*)\r\n[\ ]?(.*)$ $1$2 [R=301,N] @@ -247,13 +235,6 @@ Define webroot /standardebooks.org/web RewriteCond %{REQUEST_FILENAME} !^/ebooks/.+?/text.*$ RewriteRule ^/ebooks/([^\.]+?)$ /ebooks/ebook.php?url-path=$1 - # If we ask for /opds/all?query=xyz, rewrite that to the search page. - RewriteCond %{QUERY_STRING} ^query= - RewriteRule ^/feeds/(opds|atom|rss)/all.xml$ /feeds/$1/search.php [QSA] - - # Rewrite old links to feeds - RewriteRule ^/(opds|rss|atom)(.*)$ /feeds/$1$2 [R=301,L] - # Newsletter RewriteRule ^/newsletter$ /newsletter/subscriptions/new.php [L] RewriteRule ^/newsletter/subscriptions/([^/\.]+?)$ /newsletter/subscriptions/get.php?uuid=$1 [L] @@ -269,4 +250,65 @@ Define webroot /standardebooks.org/web RewriteCond expr "tolower(%{REQUEST_METHOD}) =~ /^post$/" RewriteRule ^/patrons-circle/polls/([^/\.]+)/votes$ /patrons-circle/polls/votes/post.php?pollurlname=$1 [L] + + # Feeds + # Rewrite old links to feeds + RewriteRule ^/(opds|rss|atom)(.*)$ /feeds/$1$2 [R=301,L] + + # If we ask for /opds/all?query=xyz, rewrite that to the search page. + RewriteCond %{QUERY_STRING} \bquery= + RewriteRule ^/feeds/(opds|atom|rss)/all.xml$ /feeds/$1/search.php [QSA] + + # Enable mod_authn_dbd + DBDriver mysql + DBDParams "dbname=se user=www-data" + + # Enable HTTP Basic auth for feeds + AuthType Basic + AuthName "Enter your Patrons Circle email address or your API key, and a blank password." + Require valid-user + ErrorDocument 401 /feeds/401 + + # Credentials caching to prevent slamming the DB. socache must be ahead of dbd + AuthBasicProvider socache dbd + AuthnCacheProvideFor dbd + AuthnCacheContext ${domain} + + # mod_authn_dbd SQL query to authenticate a user + # The hash is simply the hash of a blank password. We're only interested in the username/API key. + # We have to do this tortured query instead of a cleaner one, because the AuthDBDUserPWQuery + # function will only replace %s EXACTLY ONCE. We cannot have more than one %s in the query string. + AuthDBDUserPWQuery "\ + select '$apr1$13q1pnGf$vQnIj94BXP1EPdL/4ISba.' from \ + ( \ + select Email, Uuid from Patrons p inner join Users u using (UserId) where p.Ended is null \ + union \ + select Email, Uuid from FeedUsers fu inner join Users u using (UserId) where fu.Ended is null \ + ) x where %s in (Email, Uuid) limit 1 \ + " + + + # Disable HTTP Basic auth for the feed XSL stylesheet and the new releases feeds + Require all granted + + + + # Emit content-types for OPDS feeds, as some clients require a strictly correct content-type in order to work + + Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8" + + + Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8" + + + + # Emit content-types for RSS/Atom feeds + rss|atom)/.+"> + # Note the trailing e is required to complete the environmental variable reference + Header set Content-Type "application/%{MATCH_FEEDTYPE}e+xml; charset=utf-8" + + + Header set Content-Type "application/xhtml+xml; charset=utf-8" + + diff --git a/config/sql/se/FeedUsers.sql b/config/sql/se/FeedUsers.sql new file mode 100644 index 00000000..612bfbee --- /dev/null +++ b/config/sql/se/FeedUsers.sql @@ -0,0 +1,7 @@ +CREATE TABLE `FeedUsers` ( + `UserId` int(10) unsigned NOT NULL, + `Created` datetime NOT NULL, + `Ended` datetime DEFAULT NULL, + `Notes` text DEFAULT NULL, + KEY `idxUserId` (`UserId`,`Ended`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/config/sql/se/Patrons.sql b/config/sql/se/Patrons.sql index b13e6e8a..74f8a79f 100644 --- a/config/sql/se/Patrons.sql +++ b/config/sql/se/Patrons.sql @@ -5,6 +5,6 @@ CREATE TABLE `Patrons` ( `IsSubscribedToEmails` tinyint(1) NOT NULL DEFAULT 1, `Created` datetime NOT NULL, `Ended` datetime DEFAULT NULL, - PRIMARY KEY (`UserId`), - KEY `index2` (`IsAnonymous`,`Ended`) + KEY `index2` (`IsAnonymous`,`Ended`), + KEY `index1` (`UserId`,`Ended`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/scripts/generate-feeds b/scripts/generate-feeds index 8dab2ea6..11eae990 100755 --- a/scripts/generate-feeds +++ b/scripts/generate-feeds @@ -107,7 +107,7 @@ $opdsRootEntries = [ 'acquisition') ]; -$opdsRoot = new OpdsNavigationFeed('Standard Ebooks', 'The navigation root for the Standard Ebooks OPDS feed.', '/feeds/opds', WEB_ROOT . '/feeds/opds/index.xml', $opdsRootEntries, null); +$opdsRoot = new OpdsNavigationFeed('Standard Ebooks', 'The Standard Ebooks catalog.', '/feeds/opds', WEB_ROOT . '/feeds/opds/index.xml', $opdsRootEntries, null); SaveFeed($opdsRoot, $force, $now); // Create the subjects navigation document diff --git a/templates/FeedHowTo.php b/templates/FeedHowTo.php new file mode 100644 index 00000000..d2481581 --- /dev/null +++ b/templates/FeedHowTo.php @@ -0,0 +1,19 @@ +
+

Accessing the feeds

+

Our New Releases feeds are accessible by the public. Access to our other, more detailed feeds is available to our supporters in the Patrons Circle.

+
+

Individuals

+
    +
  • Join the Patrons Circle by making a donation to get access to all of our ebook feeds for the duration of your gift.

  • +
  • Produce an ebook for Standard Ebooks to get lifetime access to our ebook feeds. If you’ve already done that, contact us to enable your access.

  • +
+

To access a feed, when prompted enter the email address you used to make your donation or on the S.E. mailing list, and leave the password field blank.

+
+
+

Organizations and projects

+
    +
  • Corporate sponsors get access to all of our ebook feeds for the duration of their sponsorship. Contact us to chat about having your organization sponsor our mission.

  • +
  • Software projects that are open-source and not-for-profit may be granted free access to our feeds. Contact us to inquire.

  • +
+
+
diff --git a/templates/Header.php b/templates/Header.php index 60baf928..beb74302 100644 --- a/templates/Header.php +++ b/templates/Header.php @@ -8,7 +8,7 @@ $colorScheme = $_COOKIE['color-scheme'] ?? 'auto'; $xmlDeclaration = $xmlDeclaration ?? true; if($xmlDeclaration){ - header('content-type: application/xhtml+xml'); + header('content-type: application/xhtml+xml; charset=utf-8'); print(''); print("\n"); print("\n"); diff --git a/templates/OpdsAcquisitionEntry.php b/templates/OpdsAcquisitionEntry.php index 389831ee..ea840318 100644 --- a/templates/OpdsAcquisitionEntry.php +++ b/templates/OpdsAcquisitionEntry.php @@ -32,5 +32,5 @@ AdvancedEpubUrl)){ ?> KepubUrl)){ ?> Azw3Url)){ ?> - TextSinglePageUrl)){ ?> + TextSinglePageUrl)){ ?> diff --git a/templates/OpdsAcquisitionFeed.php b/templates/OpdsAcquisitionFeed.php index abc66a0b..48efa8cb 100644 --- a/templates/OpdsAcquisitionFeed.php +++ b/templates/OpdsAcquisitionFeed.php @@ -18,11 +18,11 @@ print("\n"); ?> xmlns:fh="http://purl.org/syndication/history/1.0"> - - - - - + + + + + <?= Formatter::ToPlainXmlText($title) ?> /images/logo.png diff --git a/templates/OpdsNavigationFeed.php b/templates/OpdsNavigationFeed.php index b28e6787..1ae3b060 100644 --- a/templates/OpdsNavigationFeed.php +++ b/templates/OpdsNavigationFeed.php @@ -9,11 +9,11 @@ print("\n"); ?> - - - - - + + + + + <?= Formatter::ToPlainXmlText($title) ?> /images/logo.png @@ -25,7 +25,7 @@ print("\n"); <?= Formatter::ToPlainXmlText($entry->Title) ?> - + Updated !== null){ ?>Updated->format('Y-m-d\TH:i:s\Z') ?> Id) ?> Description) ?> diff --git a/vms/docker/Dockerfile b/vms/docker/Dockerfile index ce7f79bf..c3c46cc6 100644 --- a/vms/docker/Dockerfile +++ b/vms/docker/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:20.04 RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive apt-get install -y composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl apache2 apache2-utils libfcgi0ldbl task-spooler +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl apache2 apache2-utils libfcgi0ldbl task-spooler libaprutil1-dbd-mysql RUN DEBIAN_FRONTEND=noninteractive apt-get install -y sudo imagemagick openjdk-8-jre python3 pip calibre RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* @@ -14,7 +14,7 @@ RUN sudo usermod -g committers se RUN mkdir -p /standardebooks.org/web RUN mkdir /var/log/local -RUN a2enmod headers expires ssl rewrite proxy proxy_fcgi +RUN a2enmod headers expires ssl rewrite proxy proxy_fcgi authn_dbd # Disable opcaching for dynamic PHP reloading RUN echo "opcache.enable=0" >> /etc/php/7.4/fpm/php.ini diff --git a/www/donate/index.php b/www/donate/index.php index 7c4204ef..4b4a67a8 100644 --- a/www/donate/index.php +++ b/www/donate/index.php @@ -27,15 +27,30 @@ require_once('Core.php');

Join the Patrons Circle

Members of the Patrons Circle are steadfast supporters of free, unrestricted, and beautifully presented digital literature. Besides helping support the creation of free, gorgeous ebooks, they also have a direct voice in shaping the future of the Standard Ebooks catalog.

Join the Patrons Circle with a donation of $10/month or more, or join for one year with a one-time donation of $100 or more.

+

During your time as a member of the Patrons Circle, you get:

@@ -118,13 +133,13 @@ require_once('Core.php');

Corporate sponsorships

-

Sponsorships at the corporate level are a great way to show your organization’s commitment to the support of the literate arts.

+

Sponsorships at the corporate level are a great way to show your organization’s commitment to supporting the literate arts.

  • Your organization’s logo and a link will be listed on our masthead, which is prominently linked to on the Standard Ebooks website’s header and footer.

  • -

    Get customized ONIX, OPDS, or RSS feeds of our ebook catalog for use by your organization for the duration of your sponsorship.

    +

    Get access to our OPDS, Atom, and RSS ebook feeds for use by your organization for the duration of your sponsorship. We can also produce different kinds of feeds to meet your needs, like ONIX feeds.

To inquire about sponsorship options, contact the Standard Ebooks Editor-in-Chief.

diff --git a/www/feeds/401.php b/www/feeds/401.php new file mode 100644 index 00000000..776f69f6 --- /dev/null +++ b/www/feeds/401.php @@ -0,0 +1,46 @@ + 0){ + $type = $matches[1]; +} + +$title = 'Standard Ebooks Ebook Feeds'; +if($type == 'opds'){ + $title = 'The Standard Ebooks OPDS Feed'; +} + +if($type == 'rss'){ + $title = 'Standard Ebooks RSS Feeds'; +} + +if($type == 'atom'){ + $title = 'Standard Ebooks Atom Feeds'; +} + +?> 'The Standard Ebooks OPDS feed', 'highlight' => '', 'description' => 'Get access to the Standard Ebooks OPDS feed for use in ereading programs in scripting.']) ?> +
+
+ +

The Standard Ebooks OPDS Feed

+

OPDS feeds are designed for use with ereading apps on your phone or tablet, or with ereading systems like KOreader. Add our OPDS feed to your ereading app to search, browse, and download from our entire catalog, directly in your ereader.

+

They’re also perfect for scripting, or for libraries or other organizations who wish to download and process our catalog of ebooks.

+ +

Standard Ebooks RSS Feeds

+

RSS feeds are an alternative to Atom feeds. They contain less information than Atom feeds, but might be better supported by some RSS readers.

+ +

Standard Ebooks Atom Feeds

+

Atom feeds can be read by one of the many RSS clients available for download, like Thunderbird. They contain more information than regular RSS feeds. Most RSS clients can read both Atom and RSS feeds.

+

Note that some RSS readers may show these feeds ordered by when an ebook was last updated, even though the feeds are ordered by when an ebook was first released. You should be able to change the sort order in your RSS reader.

+ +

Standard Ebooks Ebook Feeds

+ + +
+
+ diff --git a/www/feeds/atom/index.php b/www/feeds/atom/index.php index fc59b923..080f9680 100644 --- a/www/feeds/atom/index.php +++ b/www/feeds/atom/index.php @@ -1,35 +1,39 @@ 'Atom Ebook Feeds', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks.']) ?> +?> 'Atom 1.0 Ebook Feeds', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks.']) ?>
-
-

Atom 1.0 Feeds

-

Atom feeds can be read by one of the many RSS clients available for download, like Thunderbird. They contain more information than regular RSS feeds. Most RSS clients can read both Atom and RSS feeds.

+
+

Atom 1.0 Ebook Feeds

+

Atom feeds can be read by one of the many RSS clients available for download, like Thunderbird. They contain more information than regular RSS feeds. Most RSS clients can read both Atom and RSS feeds.

Note that some RSS readers may show these feeds ordered by when an ebook was last updated, even though the feeds are ordered by when an ebook was first released. You should be able to change the sort order in your RSS reader.

-
    -
  • -

    New releases

    -

    /feeds/atom/new-releases

    -

    The thirty latest Standard Ebooks, most-recently-released first.

    -
  • -
  • -

    All ebooks

    -

    /feeds/atom/all

    -

    All Standard Ebooks, most-recently-released first.

    -
  • -
-
-

Ebooks by subject

+ +
+

Atom Feeds

    -
  • -

    -

    /feeds/atom/subjects/

    +

    New releases (Public)

    +

    /feeds/atom/new-releases

    +

    The fifteen latest Standard Ebooks, most-recently-released first.

    +
  • +
  • +

    All ebooks

    +

    /feeds/atom/all

    +

    All Standard Ebooks, most-recently-released first.

  • -
+
+

Ebooks by subject

+
    + +
  • +

    +

    /feeds/atom/subjects/

    +
  • + +
+
-
+
diff --git a/www/feeds/atom/subjects/index.php b/www/feeds/atom/subjects/index.php index e0bec2c2..50c2cd8f 100644 --- a/www/feeds/atom/subjects/index.php +++ b/www/feeds/atom/subjects/index.php @@ -1,18 +1,22 @@ 'Atom Ebook Feeds by Subject', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks by subject.']) ?> +?> 'Atom 1.0 Ebook Feeds by Subject', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks by subject.']) ?>
-

Atom 1.0 Feeds by Subject

-
    - -
  • -

    -

    /feeds/atom/subjects/

    -
  • - -
+

Atom 1.0 Ebook Feeds by Subject

+ +
+

Atom Feeds

+
    + +
  • +

    +

    /feeds/atom/subjects/

    +
  • + +
+
diff --git a/www/feeds/index.php b/www/feeds/index.php index 7d085910..708e2464 100644 --- a/www/feeds/index.php +++ b/www/feeds/index.php @@ -10,28 +10,30 @@ require_once('Core.php'); ?> 'Ebook Feeds', 'description' => 'A list of available feeds of Standard Ebooks ebooks.']) ?>
-
+

Ebook Feeds

-

We offers several feeds that you can use to get notified about new ebooks, or to browse and download from our catalog directly in your ereader.

+

We offer several ebook feeds that you can use in your ereading app to browse, search, and download from our catalog. You can also add our feeds to your RSS client to get notified of new ebooks as they’re released.

+

OPDS 1.2 feeds

-

OPDS feeds are designed for use with ereading systems like KOreader or Calibre, or with ereaders like Foliate. They allow you to search, browse, and download from our catalog, directly in your ereader. They’re also perfect for organizations who wish to download and process our catalog efficiently.

+

OPDS feeds are designed for use with ereading apps on your phone or tablet, or with ereading systems like KOreader. Add our OPDS feed to your ereading app to search, browse, and download from our entire catalog, directly in your ereader.

+

They’re also perfect for scripting, or for libraries or other organizations who wish to download and process our catalog of ebooks.

-
-

OPDS how-tos and resources

- +
+

OPDS how-tos and resources

+
@@ -40,9 +42,9 @@ require_once('Core.php');

Note that some RSS readers may show these feeds ordered by when an ebook was last updated, even though the feeds are ordered by when an ebook was first released. You should be able to change the sort order in your RSS reader.

  • -

    New releases

    +

    New releases (Public)

    /feeds/atom/new-releases

    -

    The thirty latest Standard Ebooks, most-recently-released first.

    +

    The fifteen latest Standard Ebooks, most-recently-released first.

  • All ebooks

    @@ -67,9 +69,9 @@ require_once('Core.php');

    RSS feeds are an alternative to Atom feeds. They contain less information than Atom feeds, but might be better supported by some RSS readers.

    • -

      New releases

      +

      New releases (Public)

      /feeds/rss/new-releases

      -

      The thirty latest Standard Ebooks, most-recently-released first.

      +

      The fifteen latest Standard Ebooks, most-recently-released first.

    • All ebooks

      @@ -89,6 +91,6 @@ require_once('Core.php');
-
+
diff --git a/www/feeds/opds/search.php b/www/feeds/opds/search.php index cc42410f..c9c06695 100644 --- a/www/feeds/opds/search.php +++ b/www/feeds/opds/search.php @@ -13,18 +13,17 @@ try{ } catch(\Exception $ex){ http_response_code(500); - include(WEB_ROOT . '/404.php'); exit(); } print("\n\n"); ?> /feeds/opds/all?query= - + - - - + + + Search Results Results for “”. /images/logo.png diff --git a/www/feeds/rss/index.php b/www/feeds/rss/index.php index fd214abd..daea033c 100644 --- a/www/feeds/rss/index.php +++ b/www/feeds/rss/index.php @@ -1,34 +1,38 @@ 'RSS Ebook Feeds', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks.']) ?> +?> 'RSS 2.0 Ebook Feeds', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks.']) ?>
-
-

RSS 2.0 feeds

+
+

RSS 2.0 Ebook Feeds

RSS feeds are an alternative to Atom feeds. They contain less information than Atom feeds, but might be better supported by some RSS readers.

-
    -
  • -

    New releases

    -

    /feeds/rss/new-releases

    -

    The thirty latest Standard Ebooks, most-recently-released first.

    -
  • -
  • -

    All ebooks

    -

    /feeds/rss/all

    -

    All Standard Ebooks, most-recently-released first.

    -
  • -
-
-

Ebooks by subject

+ +
+

RSS Feeds

    -
  • -

    -

    /feeds/rss/subjects/

    +

    New releases (Public)

    +

    /feeds/rss/new-releases

    +

    The fifteen latest Standard Ebooks, most-recently-released first.

    +
  • +
  • +

    All ebooks

    +

    /feeds/rss/all

    +

    All Standard Ebooks, most-recently-released first.

  • -
+
+

Ebooks by subject

+
    + +
  • +

    +

    /feeds/rss/subjects/

    +
  • + +
+
-
+
diff --git a/www/feeds/rss/subjects/index.php b/www/feeds/rss/subjects/index.php index ad36a41a..87b686a2 100644 --- a/www/feeds/rss/subjects/index.php +++ b/www/feeds/rss/subjects/index.php @@ -1,10 +1,10 @@ 'RSS Ebook Feeds by Subject', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks by subject.']) ?> +?> 'RSS 2.0 Ebook Feeds by Subject', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks by subject.']) ?>
-

RSS 2.0 Feeds by Subject

+

RSS 2.0 Ebook Feeds by Subject