commit
c4c329b600
544
BaseSearcher.py
544
BaseSearcher.py
File diff suppressed because it is too large
Load Diff
|
@ -80,7 +80,7 @@ class BibrecPage (Page.Page):
|
|||
))
|
||||
|
||||
|
||||
if os.format in ('html', 'mobile'):
|
||||
if os.format == 'html':
|
||||
cat = BaseSearcher.Cat ()
|
||||
cat.header = _('Similar Books')
|
||||
cat.title = _('Readers also downloaded…')
|
||||
|
@ -101,30 +101,9 @@ class BibrecPage (Page.Page):
|
|||
cat.order = 33
|
||||
os.entries.append (cat)
|
||||
|
||||
if os.format in ('mobile', ):
|
||||
for author in dc.authors:
|
||||
cat = BaseSearcher.Cat ()
|
||||
cat.title = _('By {author}').format (author = author.name_and_dates)
|
||||
cat.rel = 'related'
|
||||
cat.url = os.url ('author', id = author.id)
|
||||
cat.class_ += 'navlink grayed'
|
||||
cat.icon = 'author'
|
||||
cat.order = 31
|
||||
os.entries.append (cat)
|
||||
|
||||
for subject in dc.subjects:
|
||||
cat = BaseSearcher.Cat ()
|
||||
cat.title = _('On {subject}').format (subject = subject.subject)
|
||||
cat.rel = 'related'
|
||||
cat.url = os.url ('subject', id = subject.id)
|
||||
cat.class_ += 'navlink grayed'
|
||||
cat.icon = 'subject'
|
||||
cat.order = 32
|
||||
os.entries.append (cat)
|
||||
|
||||
os.total_results = 1
|
||||
|
||||
os.template = 'results' if os.format == 'mobile' else 'bibrec'
|
||||
os.template = 'bibrec'
|
||||
os.page = 'bibrec'
|
||||
os.og_type = 'book'
|
||||
os.finalize ()
|
||||
|
|
|
@ -19,7 +19,6 @@ pgdatabase: 'gutenberg'
|
|||
pguser: 'postgres'
|
||||
|
||||
host: 'www.gutenberg.org'
|
||||
host_mobile: 'm.gutenberg.org'
|
||||
host_https: 1
|
||||
file_host: 'www.gutenberg.org'
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ def main():
|
|||
'daemonize': False,
|
||||
'pidfile': None,
|
||||
'host': 'localhost',
|
||||
'host_mobile': 'localhost',
|
||||
'file_host': 'localhost',
|
||||
})
|
||||
|
||||
|
@ -165,7 +164,7 @@ def main():
|
|||
cherrypy.config['js_mtime'] = t
|
||||
|
||||
cherrypy.config['all_hosts'] = (
|
||||
cherrypy.config['host'], cherrypy.config['host_mobile'], cherrypy.config['file_host'])
|
||||
cherrypy.config['host'], cherrypy.config['file_host'])
|
||||
|
||||
cherrypy.config.update({'error_page.404': error_page_404})
|
||||
|
||||
|
|
|
@ -13,19 +13,21 @@ Serve cover images of most popular and latest ebooks.
|
|||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
|
||||
import cherrypy
|
||||
import six
|
||||
import textwrap
|
||||
|
||||
from libgutenberg import GutenbergGlobals as gg
|
||||
|
||||
import BaseSearcher
|
||||
|
||||
class CoverPages (object):
|
||||
class CoverPages(object):
|
||||
""" Output a gallery of cover pages. """
|
||||
|
||||
orders = { 'latest': 'release_date',
|
||||
'popular': 'downloads' }
|
||||
orders = {'latest': 'release_date',
|
||||
'popular': 'downloads'}
|
||||
|
||||
@staticmethod
|
||||
def serve (rows, size):
|
||||
|
@ -33,72 +35,65 @@ class CoverPages (object):
|
|||
|
||||
cherrypy.response.headers['Content-Type'] = 'text/html; charset=utf-8'
|
||||
cherrypy.response.headers['Content-Language'] = 'en'
|
||||
|
||||
s = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" xml:base="http://www.gutenberg.org">
|
||||
<head>
|
||||
<title>Cover Flow</title>
|
||||
<!--<style>
|
||||
.cover-thumb {
|
||||
display: inline-block;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.cover-thumb-small {
|
||||
width: 76px;
|
||||
height: 110px;
|
||||
}
|
||||
.cover-thumb-medium {
|
||||
width: 210px;
|
||||
height: 310px;
|
||||
}
|
||||
</style>-->
|
||||
</head>
|
||||
<body><div>"""
|
||||
|
||||
s = ''
|
||||
for row in rows:
|
||||
url = '/' + row.filename
|
||||
href = '/ebooks/%d' % row.pk
|
||||
title = gg.xmlspecialchars (row.title)
|
||||
title = title.replace ('"', '"')
|
||||
if row.title:
|
||||
title = gg.xmlspecialchars (row.title) # handles <,>,&
|
||||
#Shortening long titles for latest covers
|
||||
title = title.replace('"', '"')
|
||||
title = title.replace("'", ''')
|
||||
else:
|
||||
title = '!! missing title !!'
|
||||
short_title = title
|
||||
title_len = len(title)
|
||||
short_title = re.sub(r"\-+", " ", short_title)
|
||||
short_title = short_title.splitlines()[0]
|
||||
if(title_len > 80):
|
||||
short_title = textwrap.wrap(short_title, 80)[0]
|
||||
s += """
|
||||
<a href="{href}" title="{title}" target="_top">
|
||||
<div class="cover_image">
|
||||
<div class="cover_img">
|
||||
<img src="{url}" alt="{title}" title="{title}" draggable="false">
|
||||
</div>
|
||||
<div class="cover_title">
|
||||
<h5>{short_title}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
""".format(url=url, href=href, title=title, short_title=short_title, size=size)
|
||||
|
||||
s += """<a href="{href}"
|
||||
title="{title}"
|
||||
class="cover-thumb cover-thumb-{size}" target="_top"
|
||||
style="background-image: url({url})"> </a>\n""".format (
|
||||
url = url, href = href, title = title, size = size)
|
||||
return s.encode('utf-8')
|
||||
|
||||
|
||||
return (s + '</div></body></html>\n').encode ('utf-8')
|
||||
|
||||
def index (self, count, size, order, **kwargs):
|
||||
def index(self, count, size, order, **kwargs):
|
||||
""" Internal help function. """
|
||||
|
||||
try:
|
||||
count = int (count)
|
||||
count = int(count)
|
||||
if count < 1:
|
||||
raise ValueError ('count < 0')
|
||||
raise ValueError('count < 0')
|
||||
if size not in ('small', 'medium'):
|
||||
raise ValueError ('bogus size')
|
||||
raise ValueError('bogus size')
|
||||
order = 'books.%s' % self.orders[order]
|
||||
|
||||
rows = BaseSearcher.SQLSearcher.execute (
|
||||
rows = BaseSearcher.SQLSearcher.execute(
|
||||
"""SELECT files.filename, books.pk, books.title FROM files, books
|
||||
WHERE files.fk_books = books.pk
|
||||
AND files.diskstatus = 0
|
||||
AND files.fk_filetypes = %%(size)s
|
||||
ORDER BY %s DESC
|
||||
OFFSET 1 LIMIT %%(count)s -- %s""" % (order, cherrypy.request.remote.ip),
|
||||
{ 'count': count,
|
||||
'size': 'cover.%s' % size,
|
||||
})
|
||||
{'count': count, 'size': 'cover.%s' % size,}
|
||||
)
|
||||
|
||||
if rows:
|
||||
return self.serve (rows, size)
|
||||
return self.serve(rows, size)
|
||||
|
||||
except (ValueError, KeyError) as what:
|
||||
raise cherrypy.HTTPError (400, 'Bad Request. %s' % six.text_type (what))
|
||||
raise cherrypy.HTTPError (400, 'Bad Request. %s' % six.text_type(what))
|
||||
except IOError:
|
||||
pass
|
||||
raise cherrypy.HTTPError (500, 'Internal Server Error.')
|
||||
|
|
|
@ -37,7 +37,6 @@ def format (format_, page, os_):
|
|||
formatters = {}
|
||||
formatters['opds'] = OPDSFormatter.OPDSFormatter ()
|
||||
formatters['stanza'] = formatters['opds']
|
||||
formatters['mobile'] = HTMLFormatter.MobileFormatter ()
|
||||
formatters['html'] = HTMLFormatter.HTMLFormatter ()
|
||||
formatters['json'] = JSONFormatter.JSONFormatter ()
|
||||
# FIXME: only needed to load sitemap.xml templates
|
||||
|
|
|
@ -31,9 +31,6 @@ from i18n_tool import ugettext as _
|
|||
# filetypes ignored on desktop site
|
||||
NO_DESKTOP_FILETYPES = 'plucker qioo rdf rst rst.gen rst.master tei cover.medium cover.small'.split ()
|
||||
|
||||
# filetypes shown on mobile site
|
||||
MOBILE_TYPES = (mt.epub, mt.mobi, mt.pdf, 'text/html', mt.html)
|
||||
|
||||
# filetypes which are usually handed over to a separate app on mobile devices
|
||||
HANDOVER_TYPES = (mt.epub, mt.mobi, mt.pdf)
|
||||
|
||||
|
@ -187,44 +184,3 @@ class HTMLFormatter (XMLishFormatter):
|
|||
if showncount == 0:
|
||||
for file_ in dc.files + dc.generated_files:
|
||||
file_.hidden = False
|
||||
|
||||
|
||||
class MobileFormatter (XMLishFormatter):
|
||||
""" Produce HTML output suitable for mobile devices. """
|
||||
|
||||
CONTENT_TYPE = mt.xhtml + '; charset=UTF-8'
|
||||
DOCTYPE = 'html5'
|
||||
|
||||
def __init__ (self):
|
||||
super (MobileFormatter, self).__init__ ()
|
||||
|
||||
|
||||
def get_serializer (self):
|
||||
return genshi.output.HTMLSerializer (doctype = self.DOCTYPE, strip_whitespace = False)
|
||||
|
||||
|
||||
def fix_dc (self, dc, os):
|
||||
""" Add some info to dc for easier templating.
|
||||
|
||||
Also make sure that dc `walks like a cat´. """
|
||||
|
||||
super (MobileFormatter, self).fix_dc (dc, os)
|
||||
|
||||
for file_ in dc.files + dc.generated_files:
|
||||
if len (file_.mediatypes) == 1:
|
||||
type_ = six.text_type (file_.mediatypes[0])
|
||||
m = type_.partition (';')[0]
|
||||
if m in MOBILE_TYPES:
|
||||
cat = BaseSearcher.Cat ()
|
||||
cat.type = file_.mediatypes[0]
|
||||
cat.header = _('Download')
|
||||
cat.title = file_.hr_filetype
|
||||
cat.extra = file_.hr_extent
|
||||
|
||||
cat.charset = file_.encoding
|
||||
cat.url = '/' + file_.filename
|
||||
cat.icon = dc.icon
|
||||
cat.icon2 = 'download'
|
||||
cat.class_ += 'filelink'
|
||||
cat.order = 20
|
||||
os.entries.append (cat)
|
||||
|
|
|
@ -35,12 +35,7 @@ class BookSearchPage (SearchPage):
|
|||
os.f_format_icon = os.format_icon_titles
|
||||
|
||||
if os.sort_order == 'random':
|
||||
sql.where.append ("""
|
||||
pk in (select floor (random () * maxbook)::integer
|
||||
from generate_series (1, 30), (select max (pk) as maxbook
|
||||
from books) xbks1)
|
||||
""")
|
||||
|
||||
sql.where.append ("pk in (select pk from books order by random() limit 20)")
|
||||
if len (os.query):
|
||||
sql.fulltext ('books.tsvec', os.query)
|
||||
os.title = _("Books: {title}").format (title = os.query)
|
||||
|
@ -270,7 +265,7 @@ class AuthorPage (SearchPage):
|
|||
os.entries.insert (0, cat)
|
||||
|
||||
# author aliases
|
||||
if os.format in ('html', 'mobile'):
|
||||
if os.format == 'html':
|
||||
rows = BaseSearcher.SQLSearcher.execute (
|
||||
"""SELECT alias AS title FROM aliases
|
||||
WHERE fk_authors = %(fk_authors)s AND alias_heading = 1""",
|
||||
|
|
|
@ -30,7 +30,6 @@ class Start (Page.Page):
|
|||
|
||||
os.search_terms = ''
|
||||
os.title = {
|
||||
'mobile': _('PG Mobile'),
|
||||
'opds': _('Project Gutenberg'),
|
||||
'stanza': _('Project Gutenberg')
|
||||
}.get (os.format, _('Search Project Gutenberg'))
|
||||
|
|
|
@ -86,17 +86,27 @@ sudo systemctl status autocat3.service
|
|||
# we are having problems with monit trying to restart. It might be necessary to also stop
|
||||
# monit. Further diagnosis is forthcoming.
|
||||
|
||||
## Development
|
||||
create a "feature" branch on on the git repo, using either master or development as base.
|
||||
when your code is working, submit a pull request to master or development as appropriate.
|
||||
|
||||
## updates
|
||||
# currently gutenberg1 is production deployment, gutenberg2 is dev deployment
|
||||
# to do a new deployment, first pull from the master or dev as appropriate
|
||||
# into gutenberg1 or gutenberg2.
|
||||
# DONT edit files on the deployment servers, they should always be updated from the git remote.
|
||||
|
||||
su - autocat
|
||||
# or sudo su - autocat if you can sudo
|
||||
|
||||
cd autocat3
|
||||
git pull
|
||||
git checkout remotes/origin/master
|
||||
|
||||
git fetch origin
|
||||
|
||||
#for gutenberg1
|
||||
git checkout remotes/origin/gutenberg1
|
||||
# for gutenberg2
|
||||
# git checkout remotes/origin/gutenberg2
|
||||
git checkout remotes/origin/gutenberg2
|
||||
|
||||
pipenv install --ignore-pipfile
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
DON'T USE THIS PAGE FOR SCRAPING.
|
||||
|
||||
Seriously. You'll only get your IP blocked.
|
||||
|
||||
Read http://www.gutenberg.org/feeds/ to learn how to download Project
|
||||
Gutenberg metadata much faster than by scraping.
|
||||
|
||||
-->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
|
@ -55,7 +51,7 @@ Gutenberg metadata much faster than by scraping.
|
|||
|
||||
<head xmlns:og="http://opengraphprotocol.org/schema/">
|
||||
|
||||
${site_head ()}
|
||||
${site_head()}
|
||||
|
||||
<title>${os.title} - Free Ebook</title>
|
||||
|
||||
|
@ -69,9 +65,10 @@ Gutenberg metadata much faster than by scraping.
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mw-head-dummy" class="noprint" />
|
||||
<div class="container">
|
||||
${site_top()}
|
||||
|
||||
<div id="content" itemscope="itemscope" itemtype="http://schema.org/Book" i18n:comment="On the 'bibrec' page.">
|
||||
<div class="page_content" id="content" itemscope="itemscope" itemtype="http://schema.org/Book" i18n:comment="On the 'bibrec' page.">
|
||||
|
||||
<div class="breadcrumbs noprint">
|
||||
<ul>
|
||||
|
@ -84,12 +81,10 @@ Gutenberg metadata much faster than by scraping.
|
|||
</py:for>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="header">
|
||||
<h1 itemprop="name">${os.title}</h1>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
|
||||
<div class="page-body">
|
||||
<div property="dcterms:publisher" itemprop="publisher" content="Project Gutenberg" />
|
||||
<div itemprop="bookFormat" content="EBook" />
|
||||
|
||||
|
@ -110,183 +105,30 @@ Gutenberg metadata much faster than by scraping.
|
|||
|
||||
<div id="social" class="noprint">
|
||||
<ul>
|
||||
<!--! Broken. Dialog opens and closes immediately. Disabled for now.
|
||||
<li>
|
||||
${fb_share (os.canonical_url, os.title.encode ('utf-8'),
|
||||
os.description.encode ('utf-8'), os.cover_thumb_url)}
|
||||
</li>
|
||||
-->
|
||||
<li>
|
||||
${tw_share (os.canonical_url, os.twit)}
|
||||
${tw_share(os.canonical_url, os.twit)}
|
||||
</li>
|
||||
<li>
|
||||
<a onclick="printpage ()" title="Print this page"><span class="icon icon_print" /></a>
|
||||
${fb_share(os.canonical_url)}
|
||||
</li>
|
||||
<li>
|
||||
<a onclick="printpage()" title="Print this page"><span class="icon icon_print" /></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="qr">
|
||||
<!--! qr code of mobile page for screen -->
|
||||
<span class="qrcode qrcode-desktop" title="Scan QR Code for this page." />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tabs-wrapper">
|
||||
<div id="tabs">
|
||||
<ul class="noprint">
|
||||
<li><a href="#download">Download</a></li>
|
||||
<li><a href="#bibrec">Bibrec</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="bibrec" i18n:comment="On the 'bibrec' tab of the 'bibrec' page.">
|
||||
<py:for each="e in os.entries">
|
||||
<py:if test="isinstance (e, bs.DC)">
|
||||
|
||||
<div typeof="pgterms:ebook" about="[ebook:$e.project_gutenberg_id]">
|
||||
|
||||
<h2>Bibliographic Record <span>${help (_('Table: Bibliographic Record'))}</span></h2>
|
||||
|
||||
<table class="bibrec" >
|
||||
<colgroup>
|
||||
<col class="narrow" />
|
||||
<col />
|
||||
</colgroup>
|
||||
|
||||
<tr py:for="author in e.authors">
|
||||
<th>${author.role}</th>
|
||||
<td>
|
||||
<a href="${os.url ('author', id = author.id)}"
|
||||
rel="marcrel:${author.marcrel}" about="/authors/${author.id}" typeof="pgterms:agent"
|
||||
itemprop="creator">${author.name_and_dates}</a></td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="marc in e.marcs">
|
||||
<th>${marc.caption}</th>
|
||||
<py:choose test="">
|
||||
<td py:when="marc.code == '010'">
|
||||
<a class="external"
|
||||
href="http://lccn.loc.gov/${marc.text}"
|
||||
title="Look up this book in the Library of Congress catalog.">${marc.text} <span class="icon icon_external_link"/></a>
|
||||
</td>
|
||||
<td py:when="marc.code[0]=='5'">
|
||||
<?python
|
||||
text = gg.xmlspecialchars (marc.text)
|
||||
text = re.sub (r'(//\S+)', r'<a href="\1">\1</a>', text)
|
||||
text = re.sub (r'#(\d+)', r'<a href="/ebooks/\1">#\1</a>', text)
|
||||
?>
|
||||
${ Markup (gg.insert_breaks (text)) }
|
||||
</td>
|
||||
<td py:when="marc.code=='245'" itemprop="headline">
|
||||
${ Markup (gg.insert_breaks (gg.xmlspecialchars (marc.text))) }
|
||||
</td>
|
||||
<td py:when="marc.code=='240'" itemprop="alternativeHeadline">
|
||||
${ Markup (gg.insert_breaks (gg.xmlspecialchars (marc.text))) }
|
||||
</td>
|
||||
<td py:when="marc.code=='246'" itemprop="alternativeHeadline">
|
||||
${ Markup (gg.insert_breaks (gg.xmlspecialchars (marc.text))) }
|
||||
</td>
|
||||
<td py:otherwise="">
|
||||
${ Markup (gg.insert_breaks (gg.xmlspecialchars (marc.text))) }
|
||||
</td>
|
||||
</py:choose>
|
||||
</tr>
|
||||
|
||||
<tr py:for="language in e.languages"
|
||||
property="dcterms:language" datatype="dcterms:RFC4646" itemprop="inLanguage" content="${language.id}">
|
||||
<th>Language</th>
|
||||
<td py:if="language.id != 'en'"><a href="/browse/languages/${language.id}">${language.language}</a></td>
|
||||
<td py:if="language.id == 'en'">${language.language}</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="locc in e.loccs"
|
||||
property="dcterms:subject" datatype="dcterms:LCC" content="${locc.id}">
|
||||
<th>LoC Class</th>
|
||||
<td>
|
||||
<a href="/browse/loccs/${locc.id.lower ()}">${locc.id}: ${locc.locc}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="subject in e.subjects">
|
||||
<th>Subject</th>
|
||||
<td property="dcterms:subject" datatype="dcterms:LCSH">
|
||||
<a class="block" href="${os.url ('subject', id = subject.id)}">
|
||||
${subject.subject}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="dcmitype in e.dcmitypes">
|
||||
<th>Category</th>
|
||||
<td property="dcterms:type" datatype="dcterms:DCMIType">${dcmitype.description}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>EBook-No.</th>
|
||||
<td>${e.project_gutenberg_id}</td>
|
||||
</tr>
|
||||
|
||||
<tr property="dcterms:issued" datatype="xsd:date" content="${e.xsd_release_date_time}">
|
||||
<th>Release Date</th>
|
||||
<td itemprop="datePublished">${e.hr_release_date}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Copyright Status</th>
|
||||
<td property="dcterms:rights">${e.rights}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Downloads</th>
|
||||
<td itemprop="interactionCount" i18n:msg="count">${e.downloads} downloads in the last 30 days.</td>
|
||||
</tr>
|
||||
|
||||
<tr itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer">
|
||||
<th>Price</th>
|
||||
<td><span itemprop="priceCurrency" content="USD" /><span itemprop="price">$0.00</span><span itemprop="availability" content="In Stock" ><a href="http://schema.org/InStock"></a></span></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</py:if>
|
||||
</py:for>
|
||||
|
||||
<div id="more_stuff">
|
||||
<py:for each="n, e in enumerate (os.entries)">
|
||||
<py:if test="isinstance (e, bs.Cat) and e.rel not in ('start', )">
|
||||
<py:if test="e.header and old_header != e.header">
|
||||
<h2 class="header">${e.header}</h2>
|
||||
</py:if>
|
||||
<?python old_header = e.header ?>
|
||||
|
||||
<div class="${e.class_}">
|
||||
<a rel="nofollow"
|
||||
href="${e.url}"
|
||||
type="${e.type}"
|
||||
charset="${e.charset}"
|
||||
accesskey="${str (n % 10)}">
|
||||
<span class="cell leftcell">
|
||||
<span class="icon icon_${e.icon}" />
|
||||
</span>
|
||||
<span class="cell content">
|
||||
<span class="title">${e.title}</span>
|
||||
<span py:if="e.subtitle" class="subtitle">${e.subtitle}</span>
|
||||
<span py:if="e.extra" class="extra">${e.extra}</span>
|
||||
</span>
|
||||
<span class="hstrut" />
|
||||
</a>
|
||||
</div>
|
||||
</py:if>
|
||||
</py:for>
|
||||
</div> <!-- more stuff -->
|
||||
|
||||
</div> <!--! bibrec -->
|
||||
|
||||
<div id="download" i18n:comment="On the 'Download' tab of the 'bibrec' page.">
|
||||
|
||||
<py:for each="e in os.entries">
|
||||
<py:if test="isinstance (e, bs.DC)">
|
||||
<div about="[ebook:$e.project_gutenberg_id]" rel="dcterms:hasFormat" ><!--! rev="dcterms:isFormatOf" -->
|
||||
<py:if test="isinstance(e, bs.DC)">
|
||||
<div about="[ebook:$e.project_gutenberg_id]" rel="dcterms:hasFormat" >
|
||||
|
||||
<h2>Download This eBook</h2>
|
||||
|
||||
|
@ -311,7 +153,7 @@ Gutenberg metadata much faster than by scraping.
|
|||
<th class="noprint"><span>${help ('OneDrive')}</span></th>
|
||||
</tr>
|
||||
|
||||
<tr py:for="i, file_ in enumerate (e.files)"
|
||||
<tr py:for="i, file_ in enumerate(e.files)"
|
||||
py:if="not file_.hidden"
|
||||
class="${i%2 and 'odd' or 'even'}"
|
||||
about="${file_.url}" typeof="pgterms:file">
|
||||
|
@ -363,10 +205,154 @@ Gutenberg metadata much faster than by scraping.
|
|||
|
||||
</div> <!-- download -->
|
||||
|
||||
<div id="more_stuff">
|
||||
<py:for each="n, e in enumerate (os.entries)">
|
||||
<py:if test="isinstance (e, bs.Cat) and e.rel not in ('start', )">
|
||||
<py:if test="e.header and old_header != e.header">
|
||||
<h2 class="header">${e.header}</h2>
|
||||
</py:if>
|
||||
<?python old_header = e.header ?>
|
||||
|
||||
<div class="${e.class_}">
|
||||
<a rel="nofollow"
|
||||
href="${e.url}"
|
||||
type="${e.type}"
|
||||
charset="${e.charset}"
|
||||
accesskey="${str (n % 10)}">
|
||||
<span class="cell leftcell">
|
||||
<span class="icon icon_${e.icon}" />
|
||||
</span>
|
||||
<span class="cell content">
|
||||
<span class="title">${e.title}</span>
|
||||
<span py:if="e.subtitle" class="subtitle">${e.subtitle}</span>
|
||||
<span py:if="e.extra" class="extra">${e.extra}</span>
|
||||
</span>
|
||||
<span class="hstrut" />
|
||||
</a>
|
||||
</div>
|
||||
</py:if>
|
||||
</py:for>
|
||||
</div> <!-- more stuff -->
|
||||
<div id="bibrec" i18n:comment="On the 'bibrec' tab of the 'bibrec' page.">
|
||||
<py:for each="e in os.entries">
|
||||
<py:if test="isinstance (e, bs.DC)">
|
||||
|
||||
<div typeof="pgterms:ebook" about="[ebook:$e.project_gutenberg_id]">
|
||||
|
||||
<h2>Bibliographic Record <span>${help (_('Table: Bibliographic Record'))}</span></h2>
|
||||
|
||||
<table class="bibrec" >
|
||||
<colgroup>
|
||||
<col class="narrow" />
|
||||
<col />
|
||||
</colgroup>
|
||||
|
||||
<tr py:for="author in e.authors">
|
||||
<th>${author.role}</th>
|
||||
<td>
|
||||
<a href="${os.url ('author', id = author.id)}"
|
||||
rel="marcrel:${author.marcrel}" about="/authors/${author.id}" typeof="pgterms:agent"
|
||||
itemprop="creator">${author.name_and_dates}</a></td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="marc in e.marcs">
|
||||
<th>${marc.caption}</th>
|
||||
<py:choose test="">
|
||||
<td py:when="marc.code == '010'">
|
||||
<a class="external"
|
||||
href="http://lccn.loc.gov/${marc.text}"
|
||||
title="Look up this book in the Library of Congress catalog.">${marc.text} <span class="icon icon_external_link"/></a>
|
||||
</td>
|
||||
<td py:when="marc.code[0]=='5'">
|
||||
<?python
|
||||
text = gg.xmlspecialchars(marc.text)
|
||||
text = re.sub(r'(//\S+)', r'<a href="\1">\1</a>', text)
|
||||
text = re.sub(r'#(\d+)', r'<a href="/ebooks/\1">#\1</a>', text)
|
||||
?>
|
||||
${ Markup (gg.insert_breaks (text)) }
|
||||
</td>
|
||||
<td py:when="marc.code=='245'" itemprop="headline">
|
||||
${ Markup (gg.insert_breaks(gg.xmlspecialchars(marc.text))) }
|
||||
</td>
|
||||
<td py:when="marc.code=='240'" itemprop="alternativeHeadline">
|
||||
${ Markup (gg.insert_breaks(gg.xmlspecialchars(marc.text))) }
|
||||
</td>
|
||||
<td py:when="marc.code=='246'" itemprop="alternativeHeadline">
|
||||
${ Markup (gg.insert_breaks(gg.xmlspecialchars(marc.text))) }
|
||||
</td>
|
||||
<td py:otherwise="">
|
||||
${ Markup (gg.insert_breaks(gg.xmlspecialchars(marc.text))) }
|
||||
</td>
|
||||
</py:choose>
|
||||
</tr>
|
||||
|
||||
<tr py:for="language in e.languages"
|
||||
property="dcterms:language" datatype="dcterms:RFC4646" itemprop="inLanguage" content="${language.id}">
|
||||
<th>Language</th>
|
||||
<td py:if="language.id != 'en'"><a href="/browse/languages/${language.id}">${language.language}</a></td>
|
||||
<td py:if="language.id == 'en'">${language.language}</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="locc in e.loccs"
|
||||
property="dcterms:subject" datatype="dcterms:LCC" content="${locc.id}">
|
||||
<th>LoC Class</th>
|
||||
<td>
|
||||
<a href="/browse/loccs/${locc.id.lower ()}">${locc.id}: ${locc.locc}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="subject in e.subjects">
|
||||
<th>Subject</th>
|
||||
<td property="dcterms:subject" datatype="dcterms:LCSH">
|
||||
<a class="block" href="${os.url ('subject', id = subject.id)}">
|
||||
${subject.subject}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr py:for="dcmitype in e.dcmitypes">
|
||||
<th>Category</th>
|
||||
<td property="dcterms:type" datatype="dcterms:DCMIType">${dcmitype.description}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>EBook-No.</th>
|
||||
<td>${e.project_gutenberg_id}</td>
|
||||
</tr>
|
||||
|
||||
<tr property="dcterms:issued" datatype="xsd:date" content="${e.xsd_release_date_time}">
|
||||
<th>Release Date</th>
|
||||
<td itemprop="datePublished">${e.hr_release_date}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Copyright Status</th>
|
||||
<td property="dcterms:rights">${e.rights}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Downloads</th>
|
||||
<td itemprop="interactionCount" i18n:msg="count">${e.downloads} downloads in the last 30 days.</td>
|
||||
</tr>
|
||||
|
||||
<tr itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/Offer">
|
||||
<th>Price</th>
|
||||
<td><span itemprop="priceCurrency" content="USD" /><span itemprop="price">$0.00</span><span itemprop="availability" content="In Stock" ><a href="http://schema.org/InStock"></a></span></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</py:if>
|
||||
</py:for>
|
||||
|
||||
</div> <!--! bibrec -->
|
||||
|
||||
|
||||
</div> <!--! tabs -->
|
||||
</div> <!--! tabs-wrapper -->
|
||||
</div> <!--! body -->
|
||||
|
||||
</div>
|
||||
<div id="dialog" class="hidden">
|
||||
</div>
|
||||
|
||||
|
@ -380,7 +366,6 @@ Gutenberg metadata much faster than by scraping.
|
|||
about=""
|
||||
rel="dcterms:conformsTo"
|
||||
resource="http://www.w3.org/TR/rdfa-syntax" /></a>
|
||||
|
||||
<a href="${os.url_carry ('bibrec', format='rdf')}"
|
||||
title="Download RDF/XML Metadata for this ebook."><img
|
||||
src="http://www.w3.org/RDF/icons/rdf_metadata_button.32"
|
||||
|
@ -389,11 +374,9 @@ Gutenberg metadata much faster than by scraping.
|
|||
alt="RDF/XML Metadata" /></a>
|
||||
-->
|
||||
|
||||
${site_footer ()}
|
||||
${site_footer()}
|
||||
|
||||
</div>
|
||||
|
||||
${site_top ()}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,16 +7,24 @@
|
|||
xmlns:og="http://opengraphprotocol.org/schema/"
|
||||
xmlns:fb="http://www.facebook.com/2008/fbml"
|
||||
py:strip="">
|
||||
<xi:include href="site-layout.html" />
|
||||
<xi:include href="social-functions.html" />
|
||||
|
||||
|
||||
<head>
|
||||
<style>
|
||||
.icon { background: transparent url(/pics/sprite.png?${cherrypy.config['css_mtime']}) 0 0 no-repeat; }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/css/pg-desktop-one.css?${cherrypy.config['css_mtime']}" />
|
||||
href="/gutenberg/pg-desktop-one.css?${cherrypy.config['css_mtime']}" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/gutenberg/new_nav.css?${cherrypy.config['css_mtime']}"/>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/gutenberg/style.css?${cherrypy.config['css_mtime']}"/>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
//<![CDATA[
|
||||
var json_search = "/ebooks/suggest/";
|
||||
var mobile_url = "//m.gutenberg.org/ebooks.mobile/";
|
||||
var canonical_url = "https://www.gutenberg.org/ebooks/";
|
||||
var lang = "en";
|
||||
var fb_lang = "en_US"; /* FB accepts only xx_XX */
|
||||
|
@ -27,7 +35,7 @@
|
|||
//]]></script>
|
||||
<script type="text/javascript"
|
||||
src="/js/pg-desktop-one.js?${cherrypy.config['js_mtime']}" />
|
||||
<link rel="shortcut icon" href="/pics/favicon" />
|
||||
<link rel="shortcut icon" href="/gutenberg/favicon" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||
|
||||
|
@ -36,99 +44,22 @@
|
|||
<title>${os.message}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mw-head-dummy" class="noprint" />
|
||||
<div class="container">
|
||||
${site_top()}
|
||||
<div id="page_content" i18n:comment="error page." style="margin-top: 4em">
|
||||
|
||||
<div id="content" i18n:comment="On the page of results of a search.">
|
||||
<div class="header">
|
||||
<h1>${os.message}</h1>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
|
||||
<div class="page-body">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="fb-root" />
|
||||
|
||||
<div id="print-head" class="noscreen">
|
||||
<div class="center">Project Gutenberg offers thousands of free ebooks to download.</div>
|
||||
</div>
|
||||
|
||||
<div id="screen-head" class="noprint">
|
||||
<table>
|
||||
<tr i18n:comment="The logo, tagline and badges at the very top of every page.">
|
||||
|
||||
<td rowspan="2" id="logo" i18n:comment="The PG logo at the top left of every page.">
|
||||
<a href="/wiki/Main_Page" title="Go to the Main Page.">
|
||||
<span class="icon icon_logo" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td id="tagline-badges" colspan="2">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td id="tagline">Project Gutenberg offers thousands of free ebooks to download.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="menubar-search">
|
||||
<td id="menubar" i18n:comment="The menu bar at the top of every page.">
|
||||
<a id="menubar-first"
|
||||
tabindex="11" accesskey="1"
|
||||
title="Start a new search."
|
||||
href="/ebooks/">Search</a>
|
||||
|
||||
<a tabindex="22"
|
||||
title="Our latest releases."
|
||||
href="/ebooks/search/?sort_order=release_date">Latest</a>
|
||||
|
||||
<a tabindex="31"
|
||||
title="Read the Project Gutenberg terms of use."
|
||||
href="/terms_of_use/">Terms of Use</a>
|
||||
|
||||
<a tabindex="32"
|
||||
href="/wiki/Gutenberg:Project_Gutenberg_Needs_Your_Donation"
|
||||
title="Learn why we need some money.">Donate?</a>
|
||||
|
||||
</td>
|
||||
|
||||
<td id="search" i18n:comment="The search box at the top right of every page.">
|
||||
<form method="get" action="/ebooks/search/"
|
||||
enctype="multipart/form-data">
|
||||
<table class="borderless">
|
||||
<tr>
|
||||
<td id="search-button-cell">
|
||||
<button id="search-button" type="submit" title="Execute the search. <enter>">
|
||||
<span class="icon icon_smsearch" />
|
||||
</button>
|
||||
</td>
|
||||
<td id="search-input-cell">
|
||||
<input id="search-input" name="query" type="text" title="Search Project Gutenberg. <s>"
|
||||
accesskey="s" value="" />
|
||||
</td>
|
||||
<td id="help-button-cell">
|
||||
<button id="help-button" type="button" title="Open the help menu. <h>"
|
||||
accesskey="h">Help</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="helpbox" class="hide">
|
||||
<xi:include href="help.html" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -66,7 +66,7 @@ which contains *all* Project Gutenberg metadata in one RDF/XML file.
|
|||
<body>
|
||||
<div id="mw-head-dummy" class="noprint" />
|
||||
|
||||
<div id="content" i18n:comment="On the page of results of a search.">
|
||||
<div id="content" class="page_content" i18n:comment="On the page of results of a search.">
|
||||
<div class="header">
|
||||
<h1><span class="icon icon_${os.title_icon}" />${os.title}</h1>
|
||||
</div>
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
DON'T USE THIS PAGE FOR SCRAPING.
|
||||
|
||||
Seriously. You'll only get your IP blocked.
|
||||
|
||||
Download https://www.gutenberg.org/feeds/catalog.rdf.bz2 instead,
|
||||
which contains *all* Project Gutenberg metadata in one RDF/XML file.
|
||||
|
||||
-->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:py="http://genshi.edgewall.org/"
|
||||
xmlns:i18n="http://genshi.edgewall.org/i18n"
|
||||
xml:lang="${os.lang}">
|
||||
|
||||
<?python
|
||||
import re
|
||||
|
||||
from libgutenberg import GutenbergGlobals as gg
|
||||
old_header = ''
|
||||
|
||||
def help_page (s = ''):
|
||||
s = s.replace (' ', '_')
|
||||
return '%s#%s' % ('/wiki/Gutenberg:Help_on_Bibliographic_Record_Page', s)
|
||||
?>
|
||||
|
||||
<xi:include href="site-layout.mobile" />
|
||||
|
||||
<head profile="http://a9.com/-/spec/opensearch/1.1/">
|
||||
${site_head ()}
|
||||
|
||||
<title>${os.title}</title>
|
||||
|
||||
<meta name="totalResults" content="${os.total_results}" />
|
||||
<meta name="startIndex" content="${os.start_index}" />
|
||||
<meta name="itemsPerPage" content="${os.items_per_page}" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="content" i18n:comment="On the page of results of a search.">
|
||||
<ol class="results">
|
||||
|
||||
${search_box ()}
|
||||
|
||||
<py:for each="n, e in enumerate (os.entries)">
|
||||
<py:if test="e.header and old_header != e.header">
|
||||
<li class="header">${e.header}</li>
|
||||
</py:if>
|
||||
<?python old_header = e.header ?>
|
||||
|
||||
<py:if test="isinstance (e, bs.DC)">
|
||||
<li class="bibrec">
|
||||
<div class="table">
|
||||
<div class="row">
|
||||
<div class="cell leftcell">
|
||||
<div class="icon icon_${e.icon}" />
|
||||
</div>
|
||||
<div class="cell content">
|
||||
<!--! get coverpage first, it floats to the right -->
|
||||
<img py:if="e.cover_image" class="coverpage"
|
||||
src="${e.cover_image.url}" alt="[Coverpage]" />
|
||||
<p py:for="author in e.authors">${author.role}: ${author.name_and_dates}</p>
|
||||
<py:for each="marc in e.marcs">
|
||||
<py:choose test="">
|
||||
<p py:when="marc.code[0]=='5'">
|
||||
<?python
|
||||
text = gg.xmlspecialchars (marc.text)
|
||||
text = re.sub (r'(//\S+)', r'<a href="\1">\1</a>', text)
|
||||
text = re.sub (r'#(\d+)',
|
||||
r'<a href="/ebooks/\1.mobile">#\1</a>', text)
|
||||
?>
|
||||
${marc.caption}:
|
||||
${ Markup (gg.insert_breaks (text)) }
|
||||
</p>
|
||||
<p py:otherwise="">
|
||||
${marc.caption}:
|
||||
${ Markup (gg.insert_breaks (gg.xmlspecialchars (marc.text))) }
|
||||
</p>
|
||||
</py:choose>
|
||||
</py:for>
|
||||
<p>Ebook No.: ${e.project_gutenberg_id}</p>
|
||||
<p>Published: ${e.hr_release_date}</p>
|
||||
<p>Downloads: ${e.downloads}</p>
|
||||
<p py:for="language in e.languages">Language: ${language.language}</p>
|
||||
<p py:for="subject in e.subjects">Subject: ${subject.subject}</p>
|
||||
<p py:for="locc in e.loccs">LoCC: ${locc.locc}</p>
|
||||
<p py:for="category in e.categories">Category: ${category}</p>
|
||||
<p>Rights: ${e.rights}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</py:if>
|
||||
|
||||
<py:if test="isinstance (e, bs.Cat)">
|
||||
<py:choose test="">
|
||||
<py:when test="e.rel == '__statusline__'" />
|
||||
|
||||
<py:otherwise>
|
||||
<li class="${e.class_}">
|
||||
<a class="table link" href="${e.url}" accesskey="${str (n % 10)}">
|
||||
<span class="row">
|
||||
<span class="cell leftcell">
|
||||
<span class="icon icon_${e.icon}" />
|
||||
</span>
|
||||
<span class="cell content">
|
||||
<span py:if="e.title" class="title">${e.title}</span>
|
||||
<span py:if="e.subtitle" class="subtitle">${e.subtitle}</span>
|
||||
<span py:if="e.extra" class="extra">${e.extra}</span>
|
||||
</span>
|
||||
<span py:if="e.icon2" class="cell rightcell">
|
||||
<span class="icon icon_${e.icon2}" />
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</py:otherwise>
|
||||
</py:choose>
|
||||
</py:if>
|
||||
</py:for>
|
||||
|
||||
<py:if test="os.show_next_page_link">
|
||||
<li class="navlink more grayed">
|
||||
<a class="table link"
|
||||
href="${os.url_carry (start_index = os.next_page_index)}">
|
||||
<span class="row">
|
||||
<span class="cell leftcell">
|
||||
<span class="icon icon_more" />
|
||||
</span>
|
||||
<span class="cell content">
|
||||
<span class="title"><span>Next Page</span>…</span>
|
||||
</span>
|
||||
<span class="cell rightcell">
|
||||
<span class="icon spinner" />
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</py:if>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
${site_footer ()}
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -16,12 +16,15 @@
|
|||
</style>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/css/pg-desktop-one.css?${cherrypy.config['css_mtime']}" />
|
||||
href="/gutenberg/pg-desktop-one.css?${cherrypy.config['css_mtime']}" />
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/gutenberg/new_nav.css?${cherrypy.config['css_mtime']}"/>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/gutenberg/style.css?${cherrypy.config['css_mtime']}"/>
|
||||
|
||||
<!--! IE8 does not recognize application/javascript -->
|
||||
<script>//<![CDATA[
|
||||
var json_search = "${os.json_search}";
|
||||
var mobile_url = "${os.mobile_url}";
|
||||
var canonical_url = "${os.canonical_url}";
|
||||
var lang = "${os.lang}";
|
||||
var fb_lang = "${os.fb_lang}"; /* FB accepts only xx_XX */
|
||||
|
@ -34,7 +37,7 @@
|
|||
<script
|
||||
src="/js/pg-desktop-one.js?${cherrypy.config['js_mtime']}" />
|
||||
|
||||
<link rel="shortcut icon" href="/pics/favicon" />
|
||||
<link rel="shortcut icon" href="/gutenberg/favicon" />
|
||||
<link rel="canonical" href="${os.canonical_url}" />
|
||||
|
||||
<link rel="search"
|
||||
|
@ -110,99 +113,12 @@
|
|||
|
||||
<py:def function="copyright">
|
||||
<div class="copyright" i18n:comment="The copyright notice on the footer of every page.">
|
||||
© 2003–2019 Project Gutenberg Literary Archive Foundation — All Rights Reserved.
|
||||
© 2020 Project Gutenberg Literary Archive Foundation — All Rights Reserved.
|
||||
</div>
|
||||
</py:def>
|
||||
|
||||
<py:def function="site_top">
|
||||
<div id="fb-root" />
|
||||
|
||||
<div id="print-head" class="noscreen">
|
||||
<div class="center">${os.desktop_url}<br/><br/>${os.tagline}</div>
|
||||
</div>
|
||||
|
||||
<div id="screen-head" class="noprint">
|
||||
<table>
|
||||
<tr i18n:comment="The logo, tagline and badges at the very top of every page.">
|
||||
|
||||
<td rowspan="2" id="logo" i18n:comment="The PG logo at the top left of every page.">
|
||||
<a href="/wiki/Main_Page" title="Go to the Main Page.">
|
||||
<span class="icon icon_logo" />
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td id="tagline-badges" colspan="2">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td id="tagline">${os.tagline}</td>
|
||||
<td id="paypal-badge" class="badge">${paypal ()}</td>
|
||||
<td id="flattr-badge" class="badge">${flattr ()}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id="menubar-search">
|
||||
<td id="menubar" i18n:comment="The menu bar at the top of every page.">
|
||||
<a py:if="os.page != 'start'"
|
||||
id="menubar-first"
|
||||
tabindex="11" accesskey="1"
|
||||
title="Start a new search."
|
||||
href="${os.url ('start')}">Search</a>
|
||||
<span py:if="os.page == 'start'"
|
||||
id="menubar-first" class="grayed">Search</span>
|
||||
|
||||
<a tabindex="22"
|
||||
title="Our latest releases."
|
||||
href="/ebooks/search/?sort_order=release_date">Latest</a>
|
||||
|
||||
<a tabindex="31"
|
||||
title="Read the Project Gutenberg terms of use."
|
||||
href="/terms_of_use/">Terms of Use</a>
|
||||
|
||||
<a tabindex="32"
|
||||
href="/wiki/Gutenberg:Project_Gutenberg_Needs_Your_Donation"
|
||||
title="Learn why we need some money.">Donate?</a>
|
||||
|
||||
<a tabindex="33" accesskey="m" href="${os.mobile_url}"
|
||||
title="Go to our mobile site.">Mobile</a>
|
||||
|
||||
</td>
|
||||
|
||||
<td id="search" i18n:comment="The search box at the top right of every page.">
|
||||
<form method="get" action="${os.desktop_search}"
|
||||
enctype="multipart/form-data">
|
||||
<table class="borderless">
|
||||
<tr>
|
||||
<td id="search-button-cell">
|
||||
<button id="search-button" type="submit" title="Execute the search. <enter>">
|
||||
<span class="icon icon_smsearch" />
|
||||
</button>
|
||||
</td>
|
||||
<td id="search-input-cell">
|
||||
<input id="search-input" name="query" type="text" title="${os.placeholder} <s>"
|
||||
accesskey="s" value="${os.search_terms}" />
|
||||
</td>
|
||||
<td id="help-button-cell">
|
||||
<button id="help-button" type="button" title="Open the help menu. <h>"
|
||||
accesskey="h">Help</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div id="helpbox" class="hide">
|
||||
<xi:include href="help.html" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<xi:include href="../../menu.html" />
|
||||
</py:def>
|
||||
|
||||
<py:def function="site_footer">
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:py="http://genshi.edgewall.org/"
|
||||
xmlns:i18n="http://genshi.edgewall.org/i18n"
|
||||
py:strip="">
|
||||
<?python
|
||||
from i18n_tool import ugettext as _
|
||||
?>
|
||||
|
||||
<py:def function="site_head">
|
||||
<style >
|
||||
.icon { background: transparent url(/pics/sprite.png?${cherrypy.config['css_mtime']}) 0 0 no-repeat; }
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/css/pg-mobile-one.css?${cherrypy.config['css_mtime']}" />
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var mobile_search = "${os.add_amp (os.mobile_search)}query=";
|
||||
var json_search = "${os.json_search}";
|
||||
var msg_load_more = "${_('Load More Results…')}";
|
||||
var do_animations = ${'true' if os.do_animations else 'false'};
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="/js/pg-mobile-one.js?${cherrypy.config['js_mtime']}" />
|
||||
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||
<meta http-equiv="Content-Language" content="${os.lang}" />
|
||||
|
||||
<meta name="description" content="The Project Gutenberg ebook catalog for mobile devices." />
|
||||
<meta name="keywords" content="free ebooks, free books, free audio books" />
|
||||
<meta name="classification" content="public" />
|
||||
|
||||
<link rel="icon" href="/pics/favicon" />
|
||||
|
||||
<link rel="canonical" href="${os.canonical_url}" />
|
||||
|
||||
<link rel="search"
|
||||
type="application/opensearchdescription+xml"
|
||||
title="Search Project Gutenberg"
|
||||
href="${os.osd_url}" />
|
||||
|
||||
<link rel="alternate nofollow"
|
||||
type="${os.type_opds}"
|
||||
title="OPDS feed"
|
||||
href="${os.url_carry (format = 'opds')}" />
|
||||
|
||||
<link py:if="os.touch_icon" rel="apple-touch-icon" href="${os.touch_icon}" />
|
||||
<link py:if="os.touch_icon_precomposed" rel="apple-touch-icon-precomposed" href="${os.touch_icon_precomposed}" />
|
||||
<meta py:if="os.viewport" name="viewport" content="${os.viewport}" />
|
||||
</py:def>
|
||||
|
||||
<py:def function="search_box">
|
||||
<li class="grayed" id="searchlist">
|
||||
<div class="table link">
|
||||
<div class="row">
|
||||
<div class="cell leftcell">
|
||||
<div class="icon icon_search" />
|
||||
</div>
|
||||
<div class="cell content">
|
||||
<form id="search" method="get" action="${os.mobile_search}"
|
||||
enctype="multipart/form-data">
|
||||
<div id="query-clear-wrapper">
|
||||
<div id="query-wrapper">
|
||||
<input id="query" name="query"
|
||||
type="text"
|
||||
inputmode="latin"
|
||||
value="${os.search_terms}"
|
||||
title="${os.placeholder}" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--! <div class="cell cancelcell">
|
||||
<button type="reset" id="clear" class="icon icon_cancel"
|
||||
title="Clear" i18n:comment="Reset Form Button" />
|
||||
</div> -->
|
||||
<div class="cell rightcell">
|
||||
<button type="button" id="help"
|
||||
title="Help" onclick="toggle_help ()" i18n:comment="Help about search button">
|
||||
<div class="icon icon_help" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grayed" id="helpbox"
|
||||
style="display: none" onclick="clear_help ()">
|
||||
<div class="helpbox">
|
||||
<xi:include href="help.html" />
|
||||
</div>
|
||||
</li>
|
||||
<py:if test="os.page != 'start' and os.start_index == 1">
|
||||
<li class="navlink grayed">
|
||||
<a class="table link" href="${os.url ('start')}" accesskey="h">
|
||||
<span class="row">
|
||||
<span class="cell leftcell">
|
||||
<span class="icon icon_internal" />
|
||||
</span>
|
||||
<span class="cell content">
|
||||
<span class="title">Search Start Page</span>
|
||||
</span>
|
||||
<span class="cell rightcell">
|
||||
<span class="icon icon_next" />
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</py:if>
|
||||
</py:def>
|
||||
|
||||
<py:def function="site_footer">
|
||||
<div class="footer">
|
||||
<div class="copyright">
|
||||
© 2003–2012 Project Gutenberg Literary Archive Foundation — All Rights Reserved.
|
||||
</div>
|
||||
</div>
|
||||
</py:def>
|
||||
|
||||
</html>
|
|
@ -10,48 +10,40 @@
|
|||
<?python
|
||||
from six.moves import urllib
|
||||
|
||||
def p (params):
|
||||
return urllib.parse.urlencode (params).replace ('+', '%20')
|
||||
def p(params):
|
||||
return urllib.parse.urlencode(params).replace('+', '%20')
|
||||
?>
|
||||
|
||||
|
||||
<py:def function="fb_share(url, title, description, picture)">
|
||||
<py:def function="fb_share(url)">
|
||||
<?python
|
||||
params = {
|
||||
'link': url,
|
||||
'app_id': cherrypy.config['facebook_app_id'],
|
||||
'name': title,
|
||||
'description': description,
|
||||
'redirect_uri': 'https://www.gutenberg.org/fb_redirect.html',
|
||||
'u': url,
|
||||
}
|
||||
if picture is not None:
|
||||
params['picture'] = picture
|
||||
?>
|
||||
<div class="social-button fb-share-button" i18n:comment="Share on Facebook.">
|
||||
<a href="https://www.facebook.com/dialog/feed?${p (params)}"
|
||||
<div class="social-button fb-share-button">
|
||||
<a href="https://www.facebook.com/sharer.php?${p(params)}"
|
||||
title="Share on Facebook"
|
||||
onclick="open_share_popup(this.href, this.target, 1024, 560)" target="_fb_share_popup">
|
||||
onclick="open_share_popup(this.href, this.target, 640, 320)"
|
||||
target="_top">
|
||||
<span class="icon icon_facebook" />
|
||||
</a>
|
||||
</div>
|
||||
</py:def>
|
||||
|
||||
|
||||
|
||||
<py:def function="tw_share(url, text)">
|
||||
<!-- tweet without javascript -->
|
||||
<?python
|
||||
params = {
|
||||
'url': url,
|
||||
'text': text.encode ('utf-8'),
|
||||
'text': text.encode('utf-8'),
|
||||
'count': 'none',
|
||||
'lang': os.twitter_lang,
|
||||
'related': "gutenberg_new:Project Gutenberg New Books"
|
||||
}
|
||||
?>
|
||||
<div class="social-button twitter-share-button">
|
||||
<!--! https://dev.twitter.com/docs/tweet-button -->
|
||||
<a href="https://twitter.com/share?${p (params)}"
|
||||
<a href="https://twitter.com/share?${p(params)}"
|
||||
title="Share on Twitter"
|
||||
onclick="open_share_popup(this.href, this.target, 640, 320)"
|
||||
target="_top">
|
||||
|
|
Loading…
Reference in New Issue