mirror of
https://github.com/standardebooks/web.git
synced 2025-07-12 01:22:23 -04:00
Move feeds behind Patrons Circle login
This commit is contained in:
parent
0a32b295b0
commit
6c603016bd
20 changed files with 367 additions and 183 deletions
|
@ -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/
|
||||
|
|
|
@ -50,6 +50,23 @@ SSLStaplingReturnResponderErrors off
|
|||
Define domain standardebooks.org
|
||||
Define webroot /standardebooks.org/web
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName standardebooks.com
|
||||
ServerAlias www.standardebooks.com
|
||||
RedirectPermanent / https://${domain}/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
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"
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
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';"
|
||||
|
||||
<Directory ${webroot}/www/>
|
||||
<Directory "${webroot}/www/">
|
||||
# Disable .htaccess files
|
||||
AllowOverride none
|
||||
|
||||
|
@ -88,43 +105,31 @@ Define webroot /standardebooks.org/web
|
|||
|
||||
AddType application/x-mobi8-ebook .azw3
|
||||
|
||||
<Location ~ ^/ebooks/.+?/downloads/.+$>
|
||||
<LocationMatch "^/ebooks/.+?/downloads/.+$">
|
||||
# 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"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# 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
|
||||
<Location ~ ^/vocab/.+$>
|
||||
<LocationMatch "^/vocab/.+$">
|
||||
Header set Content-Type "text/plain"
|
||||
</location>
|
||||
|
||||
<Location ~ ^/feeds/opds>
|
||||
DirectoryIndex index.xml
|
||||
</location>
|
||||
|
||||
# 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.
|
||||
<Directory ~ ${webroot}/www/feeds/>
|
||||
<Files ~ (\.xml|search\.php)$>
|
||||
Header set Content-Type "text/xml; charset=utf-8"
|
||||
</Files>
|
||||
</Directory>
|
||||
</LocationMatch>
|
||||
|
||||
# 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
|
||||
<Location ~ /(ebooks|feeds/opds|fonts)>
|
||||
<LocationMatch "/(ebooks|feeds/opds|fonts)">
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# We use a different CSP policy for single-page files because our default one doesn't allow inline images or CSS
|
||||
<Location ~ /text/single-page$>
|
||||
<LocationMatch "/text/single-page$">
|
||||
Header set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# 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.
|
||||
<FilesMatch \.php$>
|
||||
<FilesMatch "\.php$">
|
||||
SetHandler "proxy:unix:/run/php/${domain}.sock|fcgi://${domain}"
|
||||
Header set Cache-Control "no-store"
|
||||
</FilesMatch>
|
||||
|
||||
# Set some proxy properties.
|
||||
<Proxy fcgi://${domain}>
|
||||
<Proxy "fcgi://${domain}">
|
||||
ProxySet connectiontimeout=5 timeout=240
|
||||
</Proxy>
|
||||
|
||||
|
@ -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]
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName standardebooks.com
|
||||
ServerAlias www.standardebooks.com
|
||||
RedirectPermanent / https://${domain}/
|
||||
</VirtualHost>
|
||||
# Feeds
|
||||
# Rewrite old links to feeds
|
||||
RewriteRule ^/(opds|rss|atom)(.*)$ /feeds/$1$2 [R=301,L]
|
||||
|
||||
<VirtualHost *:443>
|
||||
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"
|
||||
<DirectoryMatch "^${webroot}/www/feeds/(opds|rss|atom).*">
|
||||
# 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 \
|
||||
"
|
||||
|
||||
<FilesMatch "^(style\.php|new-releases\.xml|index\.php|index\.xml)$">
|
||||
# Disable HTTP Basic auth for the feed XSL stylesheet and the new releases feeds
|
||||
Require all granted
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
|
||||
# Emit content-types for OPDS feeds, as some clients require a strictly correct content-type in order to work
|
||||
<DirectoryMatch "^${webroot}/www/feeds/opds">
|
||||
Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"
|
||||
|
||||
<FilesMatch "^index\.xml$">
|
||||
Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
|
||||
# Emit content-types for RSS/Atom feeds
|
||||
<DirectoryMatch "^${webroot}/www/feeds/(?<feedtype>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"
|
||||
|
||||
<FilesMatch "^index\.php$">
|
||||
Header set Content-Type "application/xhtml+xml; charset=utf-8"
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
</VirtualHost>
|
||||
|
|
|
@ -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';"
|
||||
|
||||
<Directory ${webroot}/www/>
|
||||
<Directory "${webroot}/www/">
|
||||
# Disable .htaccess files
|
||||
AllowOverride none
|
||||
|
||||
|
@ -87,43 +87,31 @@ Define webroot /standardebooks.org/web
|
|||
|
||||
AddType application/x-mobi8-ebook .azw3
|
||||
|
||||
<Location ~ ^/ebooks/.+?/downloads/.+$>
|
||||
<LocationMatch "^/ebooks/.+?/downloads/.+$">
|
||||
# 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"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# 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
|
||||
<Location ~ ^/vocab/.+$>
|
||||
<LocationMatch "^/vocab/.+$">
|
||||
Header set Content-Type "text/plain"
|
||||
</location>
|
||||
|
||||
<Location ~ ^/feeds/opds>
|
||||
DirectoryIndex index.xml
|
||||
</location>
|
||||
|
||||
# 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.
|
||||
<Directory ~ ${webroot}/www/feeds/>
|
||||
<Files ~ (\.xml|search\.php)$>
|
||||
Header set Content-Type "text/xml; charset=utf-8"
|
||||
</Files>
|
||||
</Directory>
|
||||
</LocationMatch>
|
||||
|
||||
# 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
|
||||
<Location ~ /(ebooks|feeds/opds|fonts)>
|
||||
<LocationMatch "/(ebooks|feeds/opds|fonts)">
|
||||
Header set Access-Control-Allow-Origin "*"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# We use a different CSP policy for single-page files because our default one doesn't allow inline images or CSS
|
||||
<Location ~ /text/single-page$>
|
||||
<LocationMatch "/text/single-page$">
|
||||
Header set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';"
|
||||
</Location>
|
||||
</LocationMatch>
|
||||
|
||||
# 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.
|
||||
<FilesMatch \.php$>
|
||||
<FilesMatch "\.php$">
|
||||
SetHandler "proxy:unix:/run/php/${domain}.sock|fcgi://${domain}"
|
||||
Header set Cache-Control "no-store"
|
||||
</FilesMatch>
|
||||
|
||||
# Set some proxy properties.
|
||||
<Proxy fcgi://${domain}>
|
||||
<Proxy "fcgi://${domain}">
|
||||
ProxySet connectiontimeout=5 timeout=240
|
||||
</Proxy>
|
||||
|
||||
|
@ -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"
|
||||
<DirectoryMatch "^${webroot}/www/feeds/(opds|rss|atom).*">
|
||||
# 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 \
|
||||
"
|
||||
|
||||
<FilesMatch "^(style\.php|new-releases\.xml|index\.php|index\.xml)$">
|
||||
# Disable HTTP Basic auth for the feed XSL stylesheet and the new releases feeds
|
||||
Require all granted
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
|
||||
# Emit content-types for OPDS feeds, as some clients require a strictly correct content-type in order to work
|
||||
<DirectoryMatch "^${webroot}/www/feeds/opds">
|
||||
Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"
|
||||
|
||||
<FilesMatch "^index\.xml$">
|
||||
Header set Content-Type "application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
|
||||
# Emit content-types for RSS/Atom feeds
|
||||
<DirectoryMatch "^${webroot}/www/feeds/(?<feedtype>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"
|
||||
|
||||
<FilesMatch "^index\.php$">
|
||||
Header set Content-Type "application/xhtml+xml; charset=utf-8"
|
||||
</FilesMatch>
|
||||
</DirectoryMatch>
|
||||
</VirtualHost>
|
||||
|
|
7
config/sql/se/FeedUsers.sql
Normal file
7
config/sql/se/FeedUsers.sql
Normal file
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
19
templates/FeedHowTo.php
Normal file
19
templates/FeedHowTo.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<section id="accessing-the-feeds">
|
||||
<h2>Accessing the feeds</h2>
|
||||
<p>Our New Releases feeds are accessible by the public. Access to our other, more detailed feeds is available to our supporters in the <a href="/donate#patrons-circle">Patrons Circle</a>.</p>
|
||||
<section id="individuals">
|
||||
<h3>Individuals</h3>
|
||||
<ul>
|
||||
<li><p>Join the <a href="/donate#patrons-circle">Patrons Circle</a> by making a donation to get access to all of our ebook feeds for the duration of your gift.</p></li>
|
||||
<li><p><a href="/contribute">Produce an ebook</a> for Standard Ebooks to get lifetime access to our ebook feeds. If you’ve already done that, <a href="/about#editor-in-chief">contact us</a> to enable your access.</p></li>
|
||||
</ul>
|
||||
<p>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.</p>
|
||||
</section>
|
||||
<section id="organizations-and-projects">
|
||||
<h3>Organizations and projects</h3>
|
||||
<ul>
|
||||
<li><p><a href="/donate#corporate-sponsors">Corporate sponsors</a> get access to all of our ebook feeds for the duration of their sponsorship. <a href="/about#editor-in-chief">Contact us</a> to chat about having your organization sponsor our mission.</p></li>
|
||||
<li><p>Software projects that are open-source and not-for-profit may be granted free access to our feeds. <a href="/about#editor-in-chief">Contact us</a> to inquire.</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
|
@ -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('<?xml version="1.0" encoding="utf-8"?>');
|
||||
print("\n");
|
||||
print("<!DOCTYPE html>\n");
|
||||
|
|
|
@ -32,5 +32,5 @@
|
|||
<? if(file_exists(WEB_ROOT . $entry->AdvancedEpubUrl)){ ?><link href="<?= SITE_URL . $entry->AdvancedEpubUrl ?>" length="<?= filesize(WEB_ROOT . $entry->AdvancedEpubUrl) ?>" rel="http://opds-spec.org/acquisition/open-access" title="Advanced epub" type="application/epub+zip" /><? } ?>
|
||||
<? if(file_exists(WEB_ROOT . $entry->KepubUrl)){ ?><link href="<?= SITE_URL . $entry->KepubUrl ?>" length="<?= filesize(WEB_ROOT . $entry->KepubUrl) ?>" rel="http://opds-spec.org/acquisition/open-access" title="Kobo Kepub epub" type="application/kepub+zip" /><? } ?>
|
||||
<? if(file_exists(WEB_ROOT . $entry->Azw3Url)){ ?><link href="<?= SITE_URL . $entry->Azw3Url ?>" length="<?= filesize(WEB_ROOT . $entry->Azw3Url) ?>" rel="http://opds-spec.org/acquisition/open-access" title="Amazon Kindle azw3" type="application/x-mobipocket-ebook" /><? } ?>
|
||||
<? if(file_exists(WEB_ROOT . $entry->TextSinglePageUrl)){ ?><link href="<?= SITE_URL . $entry->TextSinglePageUrl ?>" length="<?= filesize(WEB_ROOT . $entry->TextSinglePageUrl) ?>" rel="http://opds-spec.org/acquisition/open-access" title="XHTML" type="application/xhtml+xml" /><? } ?>
|
||||
<? if(file_exists(WEB_ROOT . $entry->TextSinglePageUrl)){ ?><link href="<?= SITE_URL . $entry->TextSinglePageUrl ?>" length="<?= filesize(WEB_ROOT . $entry->TextSinglePageUrl) ?>" rel="http://opds-spec.org/acquisition/open-access" title="XHTML" type="application/xhtml+xml; charset=utf-8" /><? } ?>
|
||||
</entry>
|
||||
|
|
|
@ -18,11 +18,11 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
|||
?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:schema="http://schema.org/"<? if($isCrawlable){ ?> xmlns:fh="http://purl.org/syndication/history/1.0"<? } ?>>
|
||||
<id><?= SITE_URL . Formatter::ToPlainXmlText($id) ?></id>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($url) ?>" rel="self" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link href="<?= SITE_URL ?><?= Formatter::ToPlainXmlText($parentUrl) ?>" rel="up" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml"/>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($url) ?>" rel="self" type="application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?><?= Formatter::ToPlainXmlText($parentUrl) ?>" rel="up" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml; charset=utf-8"/>
|
||||
<title><?= Formatter::ToPlainXmlText($title) ?></title>
|
||||
<? if($subtitle !== null){ ?><subtitle><?= Formatter::ToPlainXmlText($subtitle) ?></subtitle><? } ?>
|
||||
<icon><?= SITE_URL ?>/images/logo.png</icon>
|
||||
|
|
|
@ -9,11 +9,11 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
|||
?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<id><?= SITE_URL . Formatter::ToPlainXmlText($id) ?></id>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($url) ?>" rel="self" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml"/>
|
||||
<? if($parentUrl !== null){ ?><link href="<?= SITE_URL ?><?= Formatter::ToPlainXmlText($parentUrl) ?>" rel="up" type="application/atom+xml;profile=opds-catalog;kind=navigation"/><? } ?>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($url) ?>" rel="self" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml; charset=utf-8"/>
|
||||
<? if($parentUrl !== null){ ?><link href="<?= SITE_URL ?><?= Formatter::ToPlainXmlText($parentUrl) ?>" rel="up" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/><? } ?>
|
||||
<title><?= Formatter::ToPlainXmlText($title) ?></title>
|
||||
<? if($subtitle !== null){ ?><subtitle><?= Formatter::ToPlainXmlText($subtitle) ?></subtitle><? } ?>
|
||||
<icon><?= SITE_URL ?>/images/logo.png</icon>
|
||||
|
@ -25,7 +25,7 @@ print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
|||
<? foreach($entries as $entry){ ?>
|
||||
<entry>
|
||||
<title><?= Formatter::ToPlainXmlText($entry->Title) ?></title>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($entry->Url) ?>" rel="<?= Formatter::ToPlainXmlText($entry->Rel) ?>" type="application/atom+xml;profile=opds-catalog;kind=<?= $entry->Type ?>"/>
|
||||
<link href="<?= SITE_URL . Formatter::ToPlainXmlText($entry->Url) ?>" rel="<?= Formatter::ToPlainXmlText($entry->Rel) ?>" type="application/atom+xml;profile=opds-catalog;kind=<?= $entry->Type ?>; charset=utf-8"/>
|
||||
<updated><? if($entry->Updated !== null){ ?><?= $entry->Updated->format('Y-m-d\TH:i:s\Z') ?><? } ?></updated>
|
||||
<id><?= Formatter::ToPlainXmlText($entry->Id) ?></id>
|
||||
<content type="text"><?= Formatter::ToPlainXmlText($entry->Description) ?></content>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,15 +27,30 @@ require_once('Core.php');
|
|||
<h2>Join the Patrons Circle</h2>
|
||||
<p>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.</p>
|
||||
<p><i>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.</i></p>
|
||||
<p>During your time as a member of the Patrons Circle, you get:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Patrons Circle members have their name <a href="/about#patrons-circle">listed on our masthead</a> for the duration of their gift.</p>
|
||||
<p>Your name <a href="/about#patrons-circle">listed on our masthead</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Once per quarter, Patrons Circle members may submit a book for inclusion on our <a href="/contribute/wanted-ebooks">Wanted Ebooks list</a>. (Submissions must conform to our <a href="/contribute/collections-policy">collections policy</a> and are subject to approval.)</p>
|
||||
<p>Access to our various <a href="/feeds">ebook feeds</a>:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Browse and download from the entire Standard Ebooks catalog directly in your ereading app using our <a href="/feeds/opds">OPDS feed</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Periodically, members of the Patrons Circle vote on a selection from our <a href="/contribute/wanted-ebooks">Wanted Ebooks list</a> to choose an ebook for immediate production.</strong> The resulting ebook will be a permanent addition to our <a href="/ebooks">online catalog of free digital literature</a>.</p>
|
||||
<p>Get notified of new ebooks in your news client with our <a href="/feeds/atom">Atom</a> or <a href="/feeds/rss">RSS</a> feeds.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Parse and process the feeds to use our ebooks in your personal software projects. (Organizations, see <a href="#corporate-sponsors">corporate sponsorship</a> instead.)</p>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p>The ability to submit a book for inclusion on our <a href="/contribute/wanted-ebooks">Wanted Ebooks list</a>, once per quarter. (Submissions must conform to our <a href="/contribute/collections-policy">collections policy</a> and are subject to approval.)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>The right to periodically vote on a selection from our <a href="/contribute/wanted-ebooks">Wanted Ebooks list</a> to choose an ebook for immediate production.</strong> The resulting ebook will be a permanent addition to our <a href="/ebooks">online catalog of free digital literature</a>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="button-row">
|
||||
|
@ -118,13 +133,13 @@ require_once('Core.php');
|
|||
</section>
|
||||
<section id="corporate-sponsors">
|
||||
<h2>Corporate sponsorships</h2>
|
||||
<p>Sponsorships at the corporate level are a great way to show your organization’s commitment to the support of the literate arts.</p>
|
||||
<p>Sponsorships at the corporate level are a great way to show your organization’s commitment to supporting the literate arts.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Your organization’s logo and a link will be <a href="/about#corporate-sponsors">listed on our masthead</a>, which is prominently linked to on the Standard Ebooks website’s header and footer.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Get customized <abbr class="acronym">ONIX</abbr>, OPDS, or RSS feeds of our ebook catalog for use by your organization for the duration of your sponsorship.</p>
|
||||
<p>Get access to our OPDS, Atom, and RSS <a href="/feeds">ebook feeds</a> for use by your organization for the duration of your sponsorship. We can also produce different kinds of feeds to meet your needs, like <abbr class="acronym">ONIX</abbr> feeds.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>To inquire about sponsorship options, contact the <a href="/about#editor-in-chief">Standard Ebooks Editor-in-Chief</a>.</p>
|
||||
|
|
46
www/feeds/401.php
Normal file
46
www/feeds/401.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
use function Safe\preg_match;
|
||||
|
||||
$type = '';
|
||||
preg_match('/^\/feeds\/(opds|rss|atom)/ius', $_SERVER['REQUEST_URI'], $matches);
|
||||
|
||||
if(sizeof($matches) > 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';
|
||||
}
|
||||
|
||||
?><?= Template::Header(['title' => 'The Standard Ebooks OPDS feed', 'highlight' => '', 'description' => 'Get access to the Standard Ebooks OPDS feed for use in ereading programs in scripting.']) ?>
|
||||
<main>
|
||||
<section class="narrow">
|
||||
<? if($type == 'opds'){ ?>
|
||||
<h1>The Standard Ebooks OPDS Feed</h1>
|
||||
<p><a href="https://en.wikipedia.org/wiki/Open_Publication_Distribution_System">OPDS feeds</a> are designed for use with ereading apps on your phone or tablet, or with ereading systems like <a href="http://koreader.rocks/">KOreader</a>. Add our OPDS feed to your ereading app to search, browse, and download from our entire catalog, directly in your ereader.</p>
|
||||
<p>They’re also perfect for scripting, or for libraries or other organizations who wish to download and process our catalog of ebooks.</p>
|
||||
<? }elseif($type == 'rss'){ ?>
|
||||
<h1>Standard Ebooks RSS Feeds</h1>
|
||||
<p>RSS feeds are an alternative to <a href="/feeds/atom">Atom feeds</a>. They contain less information than Atom feeds, but might be better supported by some RSS readers.</p>
|
||||
<? }elseif($type == 'atom'){ ?>
|
||||
<h1>Standard Ebooks Atom Feeds</h1>
|
||||
<p>Atom feeds can be read by one of the many <a href="https://en.wikipedia.org/wiki/Comparison_of_feed_aggregators">RSS clients</a> available for download, like <a href="https://www.thunderbird.net/en-US/">Thunderbird</a>. They contain more information than regular RSS feeds. Most RSS clients can read both Atom and RSS feeds.</p>
|
||||
<p>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.</p>
|
||||
<? }else{ ?>
|
||||
<h1>Standard Ebooks Ebook Feeds</h1>
|
||||
<? } ?>
|
||||
<?= Template::FeedHowTo() ?>
|
||||
</section>
|
||||
</main>
|
||||
<?= Template::Footer() ?>
|
|
@ -1,17 +1,20 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
?><?= Template::Header(['title' => 'Atom Ebook Feeds', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks.']) ?>
|
||||
?><?= Template::Header(['title' => 'Atom 1.0 Ebook Feeds', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks.']) ?>
|
||||
<main>
|
||||
<article>
|
||||
<h1>Atom 1.0 Feeds</h1>
|
||||
<p>Atom feeds can be read by one of the many <a href="https://en.wikipedia.org/wiki/Comparison_of_feed_aggregators">RSS clients</a> available for download, like <a href="https://www.thunderbird.net/en-US/">Thunderbird</a>. They contain more information than regular RSS feeds. Most RSS clients can read both Atom and RSS feeds.</p>
|
||||
<section class="narrow">
|
||||
<h1>Atom 1.0 Ebook Feeds</h1>
|
||||
<p>Atom feeds can be read by one of the many <a href="https://en.wikipedia.org/wiki/Comparison_of_feed_aggregators">RSS clients</a> available for download, like <a href="https://www.thunderbird.net/en-US/">Thunderbird</a>. They contain more information than regular <a href="/feeds/rss">RSS feeds</a>. Most RSS clients can read both Atom and RSS feeds.</p>
|
||||
<p>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.</p>
|
||||
<?= Template::FeedHowTo() ?>
|
||||
<section id="atom-feeds">
|
||||
<h2>Atom Feeds</h2>
|
||||
<ul class="feed">
|
||||
<li>
|
||||
<p><a href="/feeds/atom/new-releases">New releases</a></p>
|
||||
<p><a href="/feeds/atom/new-releases">New releases</a> (Public)</p>
|
||||
<p class="url"><?= SITE_URL ?>/feeds/atom/new-releases</p>
|
||||
<p>The thirty latest Standard Ebooks, most-recently-released first.</p>
|
||||
<p>The fifteen latest Standard Ebooks, most-recently-released first.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="/feeds/atom/all">All ebooks</a></p>
|
||||
|
@ -30,6 +33,7 @@ require_once('Core.php');
|
|||
<? } ?>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
<?= Template::Footer() ?>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
?><?= Template::Header(['title' => 'Atom Ebook Feeds by Subject', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks by subject.']) ?>
|
||||
?><?= Template::Header(['title' => 'Atom 1.0 Ebook Feeds by Subject', 'description' => 'A list of available Atom 1.0 feeds of Standard Ebooks ebooks by subject.']) ?>
|
||||
<main>
|
||||
<article>
|
||||
<h1>Atom 1.0 Feeds by Subject</h1>
|
||||
<h1>Atom 1.0 Ebook Feeds by Subject</h1>
|
||||
<?= Template::FeedHowTo() ?>
|
||||
<section id="atom-feeds">
|
||||
<h2>Atom Feeds</h2>
|
||||
<ul class="feed">
|
||||
<? foreach(SE_SUBJECTS as $subject){ ?>
|
||||
<li>
|
||||
|
@ -13,6 +16,7 @@ require_once('Core.php');
|
|||
</li>
|
||||
<? } ?>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
<?= Template::Footer() ?>
|
||||
|
|
|
@ -10,19 +10,21 @@ require_once('Core.php');
|
|||
|
||||
?><?= Template::Header(['title' => 'Ebook Feeds', 'description' => 'A list of available feeds of Standard Ebooks ebooks.']) ?>
|
||||
<main>
|
||||
<article>
|
||||
<section class="narrow">
|
||||
<h1>Ebook Feeds</h1>
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
<?= Template::FeedHowTo() ?>
|
||||
<section id="opds-feeds">
|
||||
<h2>OPDS 1.2 feeds</h2>
|
||||
<p><a href="https://en.wikipedia.org/wiki/Open_Publication_Distribution_System">OPDS feeds</a> are designed for use with ereading systems like <a href="http://koreader.rocks/">KOreader</a> or <a href="https://calibre-ebook.com">Calibre</a>, or with ereaders like <a href="https://johnfactotum.github.io/foliate/">Foliate</a>. 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.</p>
|
||||
<p><a href="https://en.wikipedia.org/wiki/Open_Publication_Distribution_System">OPDS feeds</a> are designed for use with ereading apps on your phone or tablet, or with ereading systems like <a href="http://koreader.rocks/">KOreader</a>. Add our OPDS feed to your ereading app to search, browse, and download from our entire catalog, directly in your ereader.</p>
|
||||
<p>They’re also perfect for scripting, or for libraries or other organizations who wish to download and process our catalog of ebooks.</p>
|
||||
<ul class="feed">
|
||||
<li>
|
||||
<p><a href="/feeds/opds">The Standard Ebooks OPDS feed</a></p>
|
||||
<p class="url"><?= SITE_URL ?>/feeds/opds</p>
|
||||
</li>
|
||||
</ul>
|
||||
<section>
|
||||
<section id="opds-how-tos-and-resources">
|
||||
<h3>OPDS how-tos and resources</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
@ -40,9 +42,9 @@ require_once('Core.php');
|
|||
<p>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.</p>
|
||||
<ul class="feed">
|
||||
<li>
|
||||
<p><a href="/feeds/atom/new-releases">New releases</a></p>
|
||||
<p><a href="/feeds/atom/new-releases">New releases</a> (Public)</p>
|
||||
<p class="url"><?= SITE_URL ?>/feeds/atom/new-releases</p>
|
||||
<p>The thirty latest Standard Ebooks, most-recently-released first.</p>
|
||||
<p>The fifteen latest Standard Ebooks, most-recently-released first.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="/feeds/atom/all">All ebooks</a></p>
|
||||
|
@ -67,9 +69,9 @@ require_once('Core.php');
|
|||
<p>RSS feeds are an alternative to Atom feeds. They contain less information than Atom feeds, but might be better supported by some RSS readers.</p>
|
||||
<ul class="feed">
|
||||
<li>
|
||||
<p><a href="/feeds/rss/new-releases">New releases</a></p>
|
||||
<p><a href="/feeds/rss/new-releases">New releases</a> (Public)</p>
|
||||
<p class="url"><?= SITE_URL ?>/feeds/rss/new-releases</p>
|
||||
<p>The thirty latest Standard Ebooks, most-recently-released first.</p>
|
||||
<p>The fifteen latest Standard Ebooks, most-recently-released first.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="/feeds/rss/all">All ebooks</a></p>
|
||||
|
@ -89,6 +91,6 @@ require_once('Core.php');
|
|||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
<?= Template::Footer() ?>
|
||||
|
|
|
@ -13,18 +13,17 @@ try{
|
|||
}
|
||||
catch(\Exception $ex){
|
||||
http_response_code(500);
|
||||
include(WEB_ROOT . '/404.php');
|
||||
exit();
|
||||
}
|
||||
print("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<?xml-stylesheet href=\"/feeds/opds/style\" type=\"text/xsl\"?>\n");
|
||||
?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:schema="http://schema.org/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
|
||||
<id><?= SITE_URL ?>/feeds/opds/all?query=<?= urlencode($query) ?></id>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all?query=<?= urlencode($query) ?>" rel="self" type="application/atom+xml;profile=opds-catalog"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all?query=<?= urlencode($query) ?>" rel="self" type="application/atom+xml;profile=opds-catalog; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/ebooks?query=<?= urlencode($query) ?>" rel="alternate" type="text/html"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds" rel="start" type="application/atom+xml;profile=opds-catalog;kind=navigation; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/feeds/opds/all" rel="http://opds-spec.org/crawlable" type="application/atom+xml;profile=opds-catalog;kind=acquisition; charset=utf-8"/>
|
||||
<link href="<?= SITE_URL ?>/ebooks/opensearch" rel="search" type="application/opensearchdescription+xml; charset=utf-8"/>
|
||||
<title>Search Results</title>
|
||||
<subtitle>Results for “<?= Formatter::ToPlainXmlText($query) ?>”.</subtitle>
|
||||
<icon><?= SITE_URL ?>/images/logo.png</icon>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
?><?= Template::Header(['title' => 'RSS Ebook Feeds', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks.']) ?>
|
||||
?><?= Template::Header(['title' => 'RSS 2.0 Ebook Feeds', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks.']) ?>
|
||||
<main>
|
||||
<article>
|
||||
<h1>RSS 2.0 feeds</h1>
|
||||
<section class="narrow">
|
||||
<h1>RSS 2.0 Ebook Feeds</h1>
|
||||
<p>RSS feeds are an alternative to Atom feeds. They contain less information than Atom feeds, but might be better supported by some RSS readers.</p>
|
||||
<?= Template::FeedHowTo() ?>
|
||||
<section id="rss-feeds">
|
||||
<h2>RSS Feeds</h2>
|
||||
<ul class="feed">
|
||||
<li>
|
||||
<p><a href="/feeds/rss/new-releases">New releases</a></p>
|
||||
<p><a href="/feeds/rss/new-releases">New releases</a> (Public)</p>
|
||||
<p class="url"><?= SITE_URL ?>/feeds/rss/new-releases</p>
|
||||
<p>The thirty latest Standard Ebooks, most-recently-released first.</p>
|
||||
<p>The fifteen latest Standard Ebooks, most-recently-released first.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="/feeds/rss/all">All ebooks</a></p>
|
||||
|
@ -29,6 +32,7 @@ require_once('Core.php');
|
|||
<? } ?>
|
||||
</ul>
|
||||
</section>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
</main>
|
||||
<?= Template::Footer() ?>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?
|
||||
require_once('Core.php');
|
||||
|
||||
?><?= Template::Header(['title' => 'RSS Ebook Feeds by Subject', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks by subject.']) ?>
|
||||
?><?= Template::Header(['title' => 'RSS 2.0 Ebook Feeds by Subject', 'description' => 'A list of available RSS 2.0 feeds of Standard Ebooks ebooks by subject.']) ?>
|
||||
<main>
|
||||
<article>
|
||||
<h1>RSS 2.0 Feeds by Subject</h1>
|
||||
<h1>RSS 2.0 Ebook Feeds by Subject</h1>
|
||||
<ul class="feed">
|
||||
<? foreach(SE_SUBJECTS as $subject){ ?>
|
||||
<li>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue