aboutsummaryrefslogtreecommitdiffstats
path: root/fatcat_scholar
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@archive.org>2020-05-13 16:02:41 -0700
committerBryan Newbold <bnewbold@archive.org>2020-05-13 16:02:41 -0700
commitaef7b788326313a44e47549af98fc93690b34661 (patch)
tree6909d1a9c2ae5c8abe7145b77cb883d83af12a1e /fatcat_scholar
parent70efe84e5c413dfb8b752faf3b4a5ce31e3d6bf2 (diff)
downloadfatcat-scholar-aef7b788326313a44e47549af98fc93690b34661.tar.gz
fatcat-scholar-aef7b788326313a44e47549af98fc93690b34661.zip
skeleton of basic search, using covid19 index
Diffstat (limited to 'fatcat_scholar')
-rw-r--r--fatcat_scholar/search.py139
-rw-r--r--fatcat_scholar/static/ia-favicon.icobin0 -> 4286 bytes
-rw-r--r--fatcat_scholar/static/ia-logo.svg13
-rw-r--r--fatcat_scholar/static/ia-wordmark.svg1
-rw-r--r--fatcat_scholar/templates/base.html212
-rw-r--r--fatcat_scholar/templates/home.html104
-rw-r--r--fatcat_scholar/templates/search.html74
-rw-r--r--fatcat_scholar/templates/search_macros.html203
-rw-r--r--fatcat_scholar/web.py23
9 files changed, 751 insertions, 18 deletions
diff --git a/fatcat_scholar/search.py b/fatcat_scholar/search.py
new file mode 100644
index 0000000..2373245
--- /dev/null
+++ b/fatcat_scholar/search.py
@@ -0,0 +1,139 @@
+
+"""
+Helpers to make elasticsearch queries.
+"""
+
+import json
+import datetime
+
+import elasticsearch
+from elasticsearch_dsl import Search, Q
+from dynaconf import settings
+
+
+def generic_search_execute(search, limit=25, offset=0, deep_page_limit=2000):
+
+ # Sanity checks
+ if limit > 100:
+ limit = 100
+ if offset < 0:
+ offset = 0
+ if offset > deep_page_limit:
+ # Avoid deep paging problem.
+ offset = deep_page_limit
+
+ search = search[int(offset):int(offset)+int(limit)]
+
+ try:
+ resp = search.execute()
+ except elasticsearch.exceptions.RequestError as e:
+ # this is a "user" error
+ print("elasticsearch 400: " + str(e.info))
+ #flash("Search query failed to parse; you might need to use quotes.<p><code>{}: {}</code>".format(e.error, e.info['error']['root_cause'][0]['reason']))
+ # XXX: abort(e.status_code)
+ raise Exception()
+ except elasticsearch.exceptions.TransportError as e:
+ # all other errors
+ print("elasticsearch non-200 status code: {}".format(e.info))
+ # XXX: abort(e.status_code)
+ raise Exception()
+
+ # convert from objects to python dicts
+ results = []
+ for h in resp:
+ r = h._d_
+ #print(json.dumps(h.meta._d_, indent=2))
+ r['_highlights'] = []
+ if 'highlight' in dir(h.meta):
+ highlights = h.meta.highlight._d_
+ for k in highlights:
+ r['_highlights'] += highlights[k]
+ results.append(r)
+
+ for h in results:
+ # Handle surrogate strings that elasticsearch returns sometimes,
+ # probably due to mangled data processing in some pipeline.
+ # "Crimes against Unicode"; production workaround
+ for key in h:
+ if type(h[key]) is str:
+ h[key] = h[key].encode('utf8', 'ignore').decode('utf8')
+
+ return {
+ "count_returned": len(results),
+ "count_found": int(resp.hits.total),
+ "results": results,
+ "offset": offset,
+ "limit": limit,
+ "deep_page_limit": deep_page_limit,
+ "query_time_ms": int(resp.took),
+ }
+
+def do_fulltext_search(q, limit=25, offset=0, filter_time=None, filter_type=None):
+
+ # Convert raw DOIs to DOI queries
+ if len(q.split()) == 1 and q.startswith("10.") and q.count("/") >= 1:
+ q = 'doi:"{}"'.format(q)
+
+ es_client = elasticsearch.Elasticsearch(settings.ELASTICSEARCH_BACKEND)
+ search = Search(using=es_client, index=settings.ELASTICSEARCH_FULLTEXT_INDEX)
+
+ # type filters
+ if filter_type == "papers":
+ search = search.filter("terms", release_type=[ "article-journal", "paper-conference", "chapter", ])
+ elif filter_type == "reports":
+ search = search.filter("terms", release_type=[ "report", "standard", ])
+ elif filter_type == "datasets":
+ search = search.filter("terms", release_type=[ "dataset", "software", ])
+ elif filter_type == "everything" or filter_type == None:
+ pass
+ else:
+ # XXX: abort(400)
+ raise Exception()
+
+ # time filters
+ if filter_time == "past_week":
+ week_ago_date = str(datetime.date.today() - datetime.timedelta(days=7))
+ search = search.filter("range", release_date=dict(gte=week_ago_date))
+ elif filter_time == "this_year":
+ search = search.filter("term", release_year=datetime.date.today().year)
+ elif filter_time == "since_2000":
+ search = search.filter("range", release_year=dict(gte=2000))
+ elif filter_time == "before_1925":
+ search = search.filter("range", release_year=dict(lte=1924))
+ elif filter_time == "all_time" or filter_time == None:
+ pass
+ else:
+ # XXX: abort(400)
+ raise Exception()
+
+ search = search.query(
+ 'query_string',
+ query=q,
+ default_operator="AND",
+ analyze_wildcard=True,
+ lenient=True,
+ fields=[
+ "everything",
+ "abstract",
+ "fulltext.body",
+ "fulltext.annex",
+ ],
+ )
+ search = search.highlight(
+ "abstract",
+ "fulltext.body",
+ "fulltext.annex",
+ number_of_fragments=3,
+ fragment_size=150,
+ )
+
+ resp = generic_search_execute(search, offset=offset)
+
+ for h in resp['results']:
+ # Ensure 'contrib_names' is a list, not a single string
+ if type(h['contrib_names']) is not list:
+ h['contrib_names'] = [h['contrib_names'], ]
+ h['contrib_names'] = [name.encode('utf8', 'ignore').decode('utf8') for name in h['contrib_names']]
+
+ resp["query"] = { "q": q }
+ return resp
diff --git a/fatcat_scholar/static/ia-favicon.ico b/fatcat_scholar/static/ia-favicon.ico
new file mode 100644
index 0000000..363e30d
--- /dev/null
+++ b/fatcat_scholar/static/ia-favicon.ico
Binary files differ
diff --git a/fatcat_scholar/static/ia-logo.svg b/fatcat_scholar/static/ia-logo.svg
new file mode 100644
index 0000000..2360a9f
--- /dev/null
+++ b/fatcat_scholar/static/ia-logo.svg
@@ -0,0 +1,13 @@
+<svg class="ia-logo style-scope primary-nav" width="27" height="30" viewBox="0 0 27 30" xmlns="http://www.w3.org/2000/svg" aria-labelledby="logoTitleID logoDescID">
+ <title id="logoTitleID" class="style-scope primary-nav">Internet Archive logo</title>
+ <desc id="logoDescID" class="style-scope primary-nav">A line drawing of the Internet Archive headquarters building façade.</desc>
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" class="style-scope primary-nav">
+ <mask id="mask-2" fill="white" class="style-scope primary-nav">
+ <path d="M26.6666667,28.6046512 L26.6666667,30 L0,30 L0.000283687943,28.6046512 L26.6666667,28.6046512 Z M25.6140351,26.5116279 L25.6140351,28.255814 L1.05263158,28.255814 L1.05263158,26.5116279 L25.6140351,26.5116279 Z M3.62469203,7.6744186 L3.91746909,7.82153285 L4.0639977,10.1739544 L4.21052632,13.9963932 L4.21052632,17.6725617 L4.0639977,22.255044 L4.03962296,25.3421929 L3.62469203,25.4651163 L2.16024641,25.4651163 L1.72094074,25.3421929 L1.55031755,22.255044 L1.40350877,17.6970339 L1.40350877,14.0211467 L1.55031755,10.1739544 L1.68423854,7.80887484 L1.98962322,7.6744186 L3.62469203,7.6744186 Z M24.6774869,7.6744186 L24.9706026,7.82153285 L25.1168803,10.1739544 L25.2631579,13.9963932 L25.2631579,17.6725617 L25.1168803,22.255044 L25.0927809,25.3421929 L24.6774869,25.4651163 L23.2130291,25.4651163 L22.7736357,25.3421929 L22.602418,22.255044 L22.4561404,17.6970339 L22.4561404,14.0211467 L22.602418,10.1739544 L22.7369262,7.80887484 L23.0420916,7.6744186 L24.6774869,7.6744186 Z M9.94042303,7.6744186 L10.2332293,7.82153285 L10.3797725,10.1739544 L10.5263158,13.9963932 L10.5263158,17.6725617 L10.3797725,22.255044 L10.3556756,25.3421929 L9.94042303,25.4651163 L8.47583122,25.4651163 L8.0362015,25.3421929 L7.86556129,22.255044 L7.71929825,17.6970339 L7.71929825,14.0211467 L7.86556129,10.1739544 L8.00005604,7.80887484 L8.30491081,7.6744186 L9.94042303,7.6744186 Z M18.0105985,7.6744186 L18.3034047,7.82153285 L18.449948,10.1739544 L18.5964912,13.9963932 L18.5964912,17.6725617 L18.449948,22.255044 L18.425851,25.3421929 L18.0105985,25.4651163 L16.5460067,25.4651163 L16.1066571,25.3421929 L15.9357367,22.255044 L15.7894737,17.6970339 L15.7894737,14.0211467 L15.9357367,10.1739544 L16.0702315,7.80887484 L16.3753664,7.6744186 L18.0105985,7.6744186 Z M25.6140351,4.53488372 L25.6140351,6.97674419 L1.05263158,6.97674419 L1.05263158,4.53488372 L25.6140351,4.53488372 Z M13.0806755,0 L25.9649123,2.93331338 L25.4484139,3.8372093 L0.771925248,3.8372093 L0,3.1041615 L13.0806755,0 Z" id="path-1" class="style-scope primary-nav"></path>
+ </mask>
+ <use fill="#FFFFFF" class="style-scope primary-nav"></use>
+ <g mask="url(#mask-2)" fill="#FFFFFF" class="style-scope primary-nav">
+ <path d="M0,0 L26.6666667,0 L26.6666667,30 L0,30 L0,0 Z" id="swatch" class="style-scope primary-nav"></path>
+ </g>
+ </g>
+</svg>
diff --git a/fatcat_scholar/static/ia-wordmark.svg b/fatcat_scholar/static/ia-wordmark.svg
new file mode 100644
index 0000000..ae09db7
--- /dev/null
+++ b/fatcat_scholar/static/ia-wordmark.svg
@@ -0,0 +1 @@
+<svg class="ia-wordmark style-scope primary-nav" height="14" viewBox="0 0 183 14" width="183" xmlns="http://www.w3.org/2000/svg"><g fill="#fff" fill-rule="evenodd" class="style-scope primary-nav"><g transform="translate(107.24177)" class="style-scope primary-nav"><path d="m3.46567087 2.73592273c.09358964-.31350476.26547063-.95793121.26547063-1.08718317 0-.73655285-.57818604-.75488647-1.20271694-.86488814v-.40471447h2.93682509l3.81107838 12.38893815h-1.62387035l-1.17212033-3.82897484h-3.98340931l-1.17167038 3.82897484h-.96784292zm-.7032722 5.33783106h3.4520181l-1.78045302-5.37541496z" class="style-scope primary-nav"></path><path d="m13.7607138 2.88304997c0-1.82281935-.0319465-1.82281935-1.4843858-2.09919855v-.40471447h3.8425749c1.1721204 0 4.4050127 0 4.4050127 3.2954667 0 2.09828187-1.1554722 2.79816749-2.3896856 3.03696279l2.874282 6.05650866h-1.7957513l-2.7649442-5.72512863h-.9687428v5.72512863h-1.7183599zm1.7183599 3.29500836h.8909015c1.0146377 0 2.4364804-.33092169 2.4364804-2.39299467 0-1.98873853-.9687428-2.54103858-2.2812476-2.54103858-1.0461343 0-1.0461343.33138003-1.0461343 1.6573585z" class="style-scope primary-nav"></path><path d="m31.6158204 12.2524422c-.5304913.2768376-1.3903462.6998857-2.9989182.6998857-3.389925 0-4.6083902-2.4113283-4.6083902-6.55334954 0-3.35000921.8742533-6.07530059 4.3582178-6.07530059 1.3903462 0 2.4058839.27592086 3.1240044.55230005l.0940396 3.07500503h-.4530999c-.062543-.9395976-.921948-2.743625-2.6088113-2.743625-2.296096 0-2.6713545 2.88983555-2.6713545 5.19162051 0 2.90816916.8598549 5.52254214 3.0304147 5.52254214 1.4843858 0 2.2497511-.5523 2.7338976-.9386809z" class="style-scope primary-nav"></path><path d="m36.1784975 2.80971552c0-1.45568877-.0935896-1.62114962-1.5626771-1.80448573v-.40563116l3.2805871-.42258975v5.70633665h4.2484299v-5.50420858h1.7183599v12.38893815h-1.7183599v-6.01984144h-4.2484299v6.01984144h-1.71791z" class="style-scope primary-nav"></path><path d="m46.8631973 12.3083598c1.1086774 0 1.3273532-.2759209 1.3273532-1.711901v-7.91645358c0-1.43598014-.2186758-1.71144266-1.3273532-1.71144266v-.46109033h4.3735162v.46109033c-1.093829 0-1.3273532.27546252-1.3273532 1.71144266v7.91645358c0 1.4359801.2335242 1.711901 1.3273532 1.711901v.4597153h-4.3735162z" class="style-scope primary-nav"></path><path d="m56.1269544 2.73592273c-.4998947-1.67569211-.6407291-1.67569211-1.8902409-1.95207131v-.40471447h3.0304147l3.0614614 10.08806985h.0310465l2.9840699-10.08806985h1.0146377l-3.8106284 12.38893815h-1.3588497z" class="style-scope primary-nav"></path><path d="m68.8422796 2.88304997c0-1.82281935-.0467948-1.82281935-1.4839359-2.09919855v-.40471447h7.4826722l.0467949 2.7243747h-.4378016c0-1.47264736-.6555775-1.85948657-1.6868634-1.85948657h-1.2184652c-.7806636 0-.9835912.07333445-.9835912.95747287v3.66351396h1.8902409c1.0767309 0 1.1865187-.80942895 1.2805583-1.41672984h.4369017v3.86518369h-.4369017c0-.9941401-.3437619-1.58356571-1.2805583-1.58356571h-1.8902409v4.10535405c0 1.0308073.2029276 1.0679328.9835912 1.0679328h1.7345581c.8895516 0 1.311155-.3685056 1.4051946-1.8040274h.4378015l-.0476947 2.6689156h-6.2322605z" class="style-scope primary-nav"></path></g><g transform="translate(.24177 .277385)" class="style-scope primary-nav"><path d="m1.57302598 10.3699491v-8.03470531c0-1.45706379-.25962128-1.73802639-1.57302598-1.73802639v-.46659042h5.18252665v.46659042c-1.29540668 0-1.57302597.2809626-1.57302597 1.73802639v8.03470531c0 1.4575222.27761929 1.7366514 1.57302597 1.7366514v.4675071h-5.18252665v-.4675071c1.3134047 0 1.57302598-.2791292 1.57302598-1.7366514z" class="style-scope primary-nav"></path><path d="m10.0331719 2.39116131c0-1.73756805-.25872136-1.66240024-1.85064525-1.98003007v-.41113124h3.90556795l5.830455 10.1641543h.0368959v-10.1641543h1.1662709v12.5741076h-1.7773033l-6.1076243-10.63028642h-.0373459v10.63028642h-1.166271z" class="style-scope primary-nav"></path><path d="m25.9161467.87818h-1.2774087c-1.4618883 0-1.8875412.46704876-1.9991288 1.83198615h-.5178928l.0737919-2.71016615h9.4768516l.0742417 2.76562533h-.5183426c0-1.43873018-.5925845-1.88744533-2.0175768-1.88744533h-1.2580608v11.6959276h-2.0364747z" class="style-scope primary-nav"></path><path d="m36.505907 2.54103859c0-1.84986143-.0562438-1.84986143-1.7593054-2.12990735v-.41113124h8.8658192l.0557938 2.76562533h-.5183426c0-1.49510604-.777064-1.88744533-1.9982289-1.88744533h-1.4443403c-.9255476 0-1.1662709.07516781-1.1662709.97213976v3.71805646h2.2398522c1.2769587 0 1.4060944-.82272082 1.5176821-1.43964686h.5187926v3.92430959h-.5187926c0-1.00880698-.406755-1.60648273-1.5176821-1.60648273h-2.2398522v4.16631328c0 1.0463909.2407233 1.0830581 1.1662709 1.0830581h2.0544728c1.0555832 0 1.554578-.3735473 1.6652657-1.83061113h.5192426l-.0557938 2.70879113h-7.3845831z" class="style-scope primary-nav"></path><path d="m48.7037894 2.54103859c0-1.84986143-.0368959-1.84986143-1.7575055-2.12990735v-.41113124h4.5525963c1.3885464 0 5.2194226 0 5.2194226 3.34450912 0 2.13036568-1.3687486 2.8403348-2.8315368 3.08325515l3.4056733 6.14634333h-2.1287145l-3.2756376-5.81083823h-1.1478231v5.81083823h-2.0364747zm2.0364747 3.34405077h1.0555833c1.202267 0 2.8873305-.33550509 2.8873305-2.42782853 0-2.01898899-1.147823-2.57908083-2.7028509-2.57908083-1.2400629 0-1.2400629.33596344-1.2400629 1.68256722z" class="style-scope primary-nav"></path><path d="m62.1435345 2.39116131c0-1.73756805-.2596213-1.66240024-1.8510952-1.98003007v-.41113124h3.905118l5.830005 10.1641543h.0373458v-10.1641543h1.166271v12.5741076h-1.7764035l-6.1085242-10.63028642h-.0368959v10.63028642h-1.165821z" class="style-scope primary-nav"></path><path d="m75.9895846 2.54103859c0-1.84986143-.0553439-1.84986143-1.7584055-2.12990735v-.41113124h8.8658192l.0557938 2.76562533h-.5183426c0-1.49510604-.777964-1.88744533-1.9991289-1.88744533h-1.4438902c-.9250977 0-1.1658211.07516781-1.1658211.97213976v3.71805646h2.2394023c1.2774087 0 1.4060944-.82272082 1.5176821-1.43964686h.5187926v3.92430959h-.5187926c0-1.00880698-.406755-1.60648273-1.5176821-1.60648273h-2.2394023v4.16631328c0 1.0463909.2407234 1.0830581 1.1658211 1.0830581h2.0544727c1.0555832 0 1.5550279-.3735473 1.6661657-1.83061113h.5183426l-.0557938 2.70879113h-7.385033z" class="style-scope primary-nav"></path><path d="m90.2243917.87818h-1.2765088c-1.4623382 0-1.8879911.46704876-1.9995788 1.83198615h-.5178927l.0742418-2.71016615h9.4759517l.0742418 2.76562533h-.5178928c0-1.43873018-.5921344-1.88744533-2.0180267-1.88744533h-1.2585108v11.6959276h-2.0360247z" class="style-scope primary-nav"></path></g></g></svg>
diff --git a/fatcat_scholar/templates/base.html b/fatcat_scholar/templates/base.html
new file mode 100644
index 0000000..d47003b
--- /dev/null
+++ b/fatcat_scholar/templates/base.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html lang="en" style="position: relative; min-height: 100%; height: auto;">
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="referrer" content="origin-when-cross-origin">
+ <script>
+ {# TODO: audit this license statement #}
+ /*
+ @licstart The following is the entire license notice for the JavaScript code in this page.
+
+ Copyright (C) 2020 Internet Archive
+
+ The JavaScript code in this page is free software: you can
+ redistribute it and/or modify it under the terms of the GNU Affero
+ General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option)
+ any later version. The code is distributed WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
+
+ As additional permission under GNU AGPL version 3 section 7, you
+ may distribute non-source (e.g., minimized or compacted) forms of
+ that code without the copy of the GNU AGPL normally required by
+ section 4, provided you include this license notice and a URL
+ through which recipients can access the Corresponding Source.
+
+ @licend The above is the entire license notice for the JavaScript code in this page.
+ */
+ </script>
+ <style>
+ {# bnewbold: fix light grey bars in header #}
+ .ui.inverted.menu .item:before { background: none; }
+
+ @media only screen and (max-width: 479px) {
+ .mobile-hide{ display: none !important; }
+ }
+ {# for fulltext search result highlighting #}
+ .search_highlights em {
+ background-color: #FFFFBB; {# yellow #}
+ }
+
+ footer p a {
+ color: rgba(255, 255, 255, 0.5);
+ }
+ footer p a:hover {
+ color: rgba(255, 255, 255, 1.0);
+ opacity: 1.0;
+ }
+ </style>
+ <title>{%- block title -%}scholar.archive.org{%- endblock %}</title>
+ <link rel="stylesheet"
+ href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.css"
+ crossorigin="anonymous">
+ <link rel="icon"
+ type="image/x-icon"
+ href="{{ url_for('static', path='/ia-favicon.ico') }}">
+ {% block extra_head %}{% endblock %}
+</head>
+
+<body>
+<header class="ui inverted menu" style="margin: 0;">
+ <div class="ui container">
+ {% if True %}
+ <div class="ui left corner pink small label">
+ <div data-tooltip="[DEV] environment (data not preserved)" data-position="bottom left">
+ <i class="ui cogs icon"></i>
+ </div>
+ </div>
+ {% endif %}
+ <a href="https://archive.org/" class="header item">
+ <img class="logo" src="{{ url_for('static', path='/ia-logo.svg') }}" style="width: 20px;">
+ <img class="mobile-hide" src="{{ url_for('static', path='/ia-wordmark.svg') }}" style="margin-left: 10px; width: 180px;">
+ </a>
+
+ <div class="right menu">
+ <div class="ui simple dropdown item">
+ <!-- language/translate SVG icon -->
+ <img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB3aWR0aD0iMTc5MiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNzgyIDEwNzhxLTEgMy0xMi41LS41dC0zMS41LTExLjVsLTIwLTlxLTQ0LTIwLTg3LTQ5LTctNS00MS0zMS41dC0zOC0yOC41cS02NyAxMDMtMTM0IDE4MS04MSA5NS0xMDUgMTEwLTQgMi0xOS41IDR0LTE4LjUgMHE2LTQgODItOTIgMjEtMjQgODUuNS0xMTV0NzguNS0xMThxMTctMzAgNTEtOTguNXQzNi03Ny41cS04LTEtMTEwIDMzLTggMi0yNy41IDcuNXQtMzQuNSA5LjUtMTcgNXEtMiAyLTIgMTAuNXQtMSA5LjVxLTUgMTAtMzEgMTUtMjMgNy00NyAwLTE4LTQtMjgtMjEtNC02LTUtMjMgNi0yIDI0LjUtNXQyOS41LTZxNTgtMTYgMTA1LTMyIDEwMC0zNSAxMDItMzUgMTAtMiA0My0xOS41dDQ0LTIxLjVxOS0zIDIxLjUtOHQxNC41LTUuNSA2IC41cTIgMTItMSAzMyAwIDItMTIuNSAyN3QtMjYuNSA1My41LTE3IDMzLjVxLTI1IDUwLTc3IDEzMWw2NCAyOHExMiA2IDc0LjUgMzJ0NjcuNSAyOHE0IDEgMTAuNSAyNS41dDQuNSAzMC41em0tMjA1LTQ4NnEzIDE1LTQgMjgtMTIgMjMtNTAgMzgtMzAgMTItNjAgMTItMjYtMy00OS0yNi0xNC0xNS0xOC00MWwxLTNxMyAzIDE5LjUgNXQyNi41IDAgNTgtMTZxMzYtMTIgNTUtMTQgMTcgMCAyMSAxN3ptNjk4IDEyOWw2MyAyMjctMTM5LTQyem0tMTEwOCA4MDBsNjk0LTIzMnYtMTAzMmwtNjk0IDIzM3YxMDMxem0xMjQxLTMxN2wxMDIgMzEtMTgxLTY1Ny0xMDAtMzEtMjE2IDUzNiAxMDIgMzEgNDUtMTEwIDIxMSA2NXptLTUwMy05NjJsNTczIDE4NHYtMzgwem0zMTEgMTMyM2wxNTggMTMtNTQgMTYwLTQwLTY2cS0xMzAgODMtMjc2IDEwOC01OCAxMi05MSAxMmgtODRxLTc5IDAtMTk5LjUtMzl0LTE4My41LTg1cS04LTctOC0xNiAwLTggNS0xMy41dDEzLTUuNXE0IDAgMTggNy41dDMwLjUgMTYuNSAyMC41IDExcTczIDM3IDE1OS41IDYxLjV0MTU3LjUgMjQuNXE5NSAwIDE2Ny0xNC41dDE1Ny01MC41cTE1LTcgMzAuNS0xNS41dDM0LTE5IDI4LjUtMTYuNXptNDQ4LTEwNzl2MTA3OWwtNzc0LTI0NnEtMTQgNi0zNzUgMTI3LjV0LTM2OCAxMjEuNXEtMTMgMC0xOC0xMyAwLTEtMS0zdi0xMDc4cTMtOSA0LTEwIDUtNiAyMC0xMSAxMDYtMzUgMTQ5LTUwdi0zODRsNTU4IDE5OHEyIDAgMTYwLjUtNTV0MzE2LTEwOC41IDE2MS41LTUzLjVxMjAgMCAyMCAyMXY0MTh6Ii8+PC9zdmc+"
+ alt="select language" style="height: 1.5em; filter: invert(100%);">
+ <i class="dropdown icon" style="margin-left: 0.2em;"></i>
+ <div class="menu">
+ {# TODO: as a dynamic array #}
+ {# TODO: do url_for() here, with current endpoint (from request?) #}
+ <a class="item" href="/">English</a>
+ <a class="item" href="/de/">Deutsch</a>
+ <a class="item" href="/zh/">中文</a>
+ </div>
+ </div>
+ </div>
+ </div>
+</header>
+
+{% block fullmain %}
+<div class="ui vertical stripe segment" style="background-color: #dedede;">
+ <div class="ui container" style="padding: 1em; padding-bottom: 0.0em;">
+ <div class="ui equal height grid">
+ <div class="ui four wide column">
+ <div style="display: flex; justify-content: center; align-items: center; height:100%; width: 100%;">
+ <a href="{{ lang_prefix }}/">
+ <span style="font-size: 1.5rem; font-weight: bold;">[scholar.archive.org]</span>
+ {# hack to align vertically with search box #}
+ <br>&nbsp;
+ </a>
+ </div>
+ </div>
+ <div class="ui twelve wide column">
+ <form class="" id="fulltext_query" action="{{ lang_prefix }}/search") }}" method="get" role="search" aria-label="papers" itemprop="potentialAction" itemscope itemtype="https://schema.org/SearchAction">
+ <meta itemprop="target" content="https://{{ settings.FATCAT_DOMAIN }}/fulltext/search?q={q}"/>
+ <div class="ui form">
+ <div class="ui action input large fluid">
+ <input type="text" placeholder="{{ _("by title, authors, identifiers...") }}" name="q" aria-label="search metadata" required itemprop="query-input" style="border-radius: 0; border: 1px #999 solid;">
+ <button class="ui green button" style="border-radius: 0; background-color: #44a25a; font-size: 1.2rem;">{{ _("Search") }}</button>
+ </div>
+ </div>
+ <div style="float: right; padding-top: 0.5em;">
+ <a href="#">User Guide</a>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+</div>
+<main class="ui main container">
+{% block fullbody %}
+ <div class="ui container text">
+ {% block body %}Nothing to see here.{% endblock %}
+ </div>
+{% endblock %}
+</main>
+{% endblock %}
+
+{#
+<footer class="ui inverted vertical footer segment" style="margin-top: 2em; padding-top: 1em; padding-bottom:2em; position: absolute; bottom: 0px; width: 100%;">
+ <div class="ui center aligned container">
+ <div class="ui horizontal inverted small link list">
+ <a class="item" href="/">fatcat!</a>
+ <a class="item" href="/about">About</a>
+ <a class="item" href="https://guide.{{ settings.FATCAT_DOMAIN }}/sources.html">Sources</a>
+ <a class="item" href="{% if settings.FATCAT_DOMAIN == "fatcat.wiki" %}https://stats.uptimerobot.com/GM9YNSrB0{% elif settings.FATCAT_DOMAIN =="qa.fatcat.wiki" %}https://stats.uptimerobot.com/WQ8wAUREA{% else %}#{% endif %}">Status</a>
+ <a class="item" href="https://guide.{{ settings.FATCAT_DOMAIN }}/bulk_exports.html">Bulk Exports</a>
+ <a class="item" href="https://github.com/internetarchive/fatcat-scholar/">Code</a>
+ <a class="item" href="https://github.com/internetarchive/fatcat-scholar/commit/{{ settings.GIT_REVISION }}"><code>{{ settings.GIT_REVISION }}</code></a>
+ {% if settings.FATCAT_DOMAIN.startswith('qa.') %}
+ <a class="item"><b style="color: orange;">[QA]</b></a>
+ {% elif settings.FATCAT_DOMAIN.startswith('dev.') %}
+ <a class="item"><b style="color: magenta;">[DEV]</b></a>
+ {% endif %}
+ </div>
+ </div>
+</footer>
+#}
+
+<div style="height: 24em;">
+</div>
+<footer class="ui inverted vertical footer segment" style="padding: 5em 0em; position: absolute; bottom: 0px; width: 100%;">
+ <div class="ui container">
+ <div class="ui stackable inverted divided equal height grid">
+ <div class="nine wide column">
+ <div class="ui grid">
+ <div class="three wide column" style="padding-top: 4em;">
+ <img class="logo" src="{{ url_for('static', path='/ia-logo.svg') }}" style="width: 4em; opacity: 0.5;">
+ </div>
+ <div class="twelve wide column">
+ <h3>Internet Archive</h3>
+ <p style="color: rgba(255, 255, 255, 0.5);">We are a 501(c)(3) non-profit, building a digital library of Internet sites and other cultural artifacts in digital form. Other projects include the <a href="https://web.archive.org">Wayback Machine</a>, <a href="https://archive.org">archive.org</a> <a href="https://openlibrary.org">openlibrary.org</a> and <a href="https://archive-it.org">archive-it.org</a>
+ <div class="ui horizontal inverted link list">
+ <a class="item" href="https://archive.org/about/">About Us</a>
+ <a class="item" href="https://archive.org/about/contact.php">Contact Us</a>
+ <a class="item" href="https://archive.org/about/terms.php">Policies</a>
+ <a class="item" href="https://archive.org/donate">Donate</a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="three wide column">
+ <h4 class="ui inverted header">scholar.archive.org</h4>
+ <div class="ui inverted link list">
+ <a href="#" class="item">How It Works</a>
+ <a href="#" class="item">Content Sources</a>
+ <a href="#" class="item">Text and Data Mining</a>
+ <a href="#" class="item">Discussion Forum</a>
+ <a href="#" class="item">Statistics</a>
+ <a href="#" class="item">Help</a>
+ </div>
+ </div>
+ <div class="three wide column">
+ <h4 class="ui inverted header">Open Infrastructure</h4>
+ <div class="ui inverted link list">
+ <a href="https://fatcat.wiki" class="item">Editable Catalog (Fatcat)</a>
+ <a href="https://guide.fatcat.wiki" class="item">Contribute</a>
+ <a href="/api/redoc" class="item">Search API</a>
+ <a href="https://status.fatcat.wiki" class="item">Service Status</a>
+ <a href="https://github.com/internetarchive/fatcat-scholar" class="item">Source Code</a>
+ </div>
+ </div>
+ </div>
+ </div>
+</footer>
+
+<script
+ src="https://code.jquery.com/jquery-3.1.1.min.js"
+ integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
+ crossorigin="anonymous">
+</script>
+<script
+ src="https://cdn.jsdelivr.net/npm/semantic-ui@2.3.2/dist/semantic.min.js"
+ crossorigin="anonymous">
+</script>
+{% block postscript %}{% endblock %}
+</body>
+</html>
diff --git a/fatcat_scholar/templates/home.html b/fatcat_scholar/templates/home.html
index e6e09b5..bb387f7 100644
--- a/fatcat_scholar/templates/home.html
+++ b/fatcat_scholar/templates/home.html
@@ -1,12 +1,92 @@
-<html>
-<head>
- <title>hello</title>
-</head>
-<body>
-<h1>The Start</h1>
-
-<p>{% trans %}This is a longer paragraph, all of which should be translated.{% endtrans %}
-
-<p>and {{ _("this is a quick") }} thing to translate.
-</body>
-</html>
+{% extends "base.html" %}
+
+{% block fullmain %}
+
+<div class="ui vertical stripe segment" style="background-color: #dedede;">
+ <div class="ui container" style="padding: 3em;">
+ <div class="ui centered grid">
+ <div class="ui fourteen wide column">
+ <div style="width: 100%; text-align: center;">
+ <h1>Search Inside Millions of Research Papers</h1>
+ <br>
+ <form class="" id="fulltext_query" action="{{ lang_prefix }}/search") }}" method="get" role="search" aria-label="papers" itemprop="potentialAction" itemscope itemtype="https://schema.org/SearchAction">
+ <meta itemprop="target" content="https://{{ settings.FATCAT_DOMAIN }}/fulltext/search?q={q}"/>
+ <div class="ui form">
+ <div class="ui action input big fluid">
+ <input type="text" placeholder="{{ _("by title, authors, identifiers...") }}" name="q" aria-label="search metadata" required itemprop="query-input" style="border-radius: 0; border: 1px #999 solid;">
+ <button class="ui green button" style="border-radius: 0; background-color: #44a25a; font-size: 1.2rem;">{{ _("Search") }}</button>
+ </div>
+ </div>
+ </form>
+ </div>
+ <br>
+ <br>
+ <p style="font-size: 1.1rem;">This fulltext search index includes over 25 million research articles and other documents preserved in the Internet Archive.
+ <p style="font-size: 1.1rem;">The collection spans from digitized copies of eighteenth century journals though the latest Open Access conference proceedings and pre-prints crawled from the World Wide Web.
+ </div>
+ </div>
+ </div>
+</div>
+
+<div class="ui container" style="padding: 1em; margin-top: 2em;">
+ <div class="ui four cards">
+
+ <div class="ui card">
+ <a class="image" href="https://web.archive.org/web/20171006225602/https://burnstrauma.biomedcentral.com/track/pdf/10.1186/s41038-017-0090-z?site=burnstrauma.biomedcentral.com">
+ <img src="https://covid19.fatcat.wiki/fulltext_web//thumbnail/c9/c9e87f843b3cf7dc47881fa3d3ccb4693d7d9521.png">
+ </a>
+ <div class="content">
+ <a class="header" style="font-size: 1.1em;">Children are not little adults: blood transfusion in children with burn injury</a>
+ Tina L. Palmieri
+ <div class="meta">
+ <span>2017</span>
+ <span>Burns &amp; Trauma</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="ui card">
+ <a class="image" href="https://web.archive.org/web/20200328205104/http://europepmc.org/backend/ptpmcrender.fcgi?accid=PMC5180799&blobtype=pdf">
+ <img src="https://covid19.fatcat.wiki/fulltext_web//thumbnail/1e/1e13eaf1d0fe6682b7759d40c49f9bf35b6eef68.png">
+ </a>
+ <div class="content">
+ <a class="header" style="font-size: 1.1em;">Epidemic Influenza in and around the City of Calcutta</a>
+ Koilas Chandra Bose
+ <div class="meta">
+ <span>1920</span>
+ <span>The Indian Medical Gazette</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="ui card mobile-hide">
+ <a class="image" href="https://web.archive.org/web/2017/http://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0032486&type=printable">
+ <img src="https://covid19.fatcat.wiki/fulltext_web//thumbnail/6e/6ea1978890ab099e90e61ddf078b6d983e60b07f.png">
+ </a>
+ <div class="content">
+ <a class="header" style="font-size: 1.1em;">Repertoire of Intensive Care Unit Pneumonia Microbiota</a>
+ Sabri Bousbia, et al
+ <div class="meta">
+ <span>2012</span>
+ <span>PLoS ONE</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="ui card mobile-hide">
+ <a class="image" href="https://web.archive.org/web/2017/http://journals.plos.org/plosone/article/file?id=10.1371/journal.pone.0010071&type=printable">
+ <img src="https://covid19.fatcat.wiki/fulltext_web//thumbnail/60/60cd26dae93a4048b5aceb66c68bec325392fdf0.png">
+ </a>
+ <div class="content">
+ <a class="header" style="font-size: 1.1em;">BioTorrents: A File Sharing Service for Scientific Data</a>
+ Morgan Langille, et al
+ <div class="meta">
+ <span>2012</span>
+ <span>PLoS ONE</span>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+{% endblock %}
diff --git a/fatcat_scholar/templates/search.html b/fatcat_scholar/templates/search.html
index 783cb47..fcb19c3 100644
--- a/fatcat_scholar/templates/search.html
+++ b/fatcat_scholar/templates/search.html
@@ -1 +1,73 @@
-<h1>Search template will go here</h2>
+{% import "search_macros.html" as search_macros %}
+{% extends "base.html" %}
+
+{% block fullbody %}
+<div class="ui equal height divided grid" style="margin-top: 1em;">
+ <div class="ui two wide column">
+
+ {% if found %}
+ <div class="ui tiny statistic" style="width: 100%; text-align: center;">
+ <div class="value">
+ {{ "{:,}".format(found.count_found) }}
+ </div>
+ <div class="label">
+ Hits
+ </div>
+ </div>
+ {% else %}
+ Maybe some filters, facets, counts over here?
+ {% endif %}
+
+ <div style="text-align: right;">
+ <br>
+ <span style="color: rgba(0,0,0,0.4);">Release Date</span>
+ <div class="ui link list" style="margin-top: 0.3em;">
+ <a class="active item"><b>All Time</b></a>
+ <a class="item" style="color: rgba(0,0,0);">Past Week</a>
+ <a class="item" style="color: rgba(0,0,0);">Past Year</a>
+ <a class="item" style="color: rgba(0,0,0);">Since 2000</a>
+ <a class="item" style="color: rgba(0,0,0);">Before 1925</a>
+ </div>
+
+ <br>
+ <span style="color: rgba(0,0,0,0.4);">Resource Type</span>
+ <div class="ui link list" style="margin-top: 0.3em;">
+ <a class="active item"><b>Papers</b></a>
+ <a class="item" style="color: rgba(0,0,0);">Reports</a>
+ <a class="item" style="color: rgba(0,0,0);">Datasets</a>
+ <a class="item" style="color: rgba(0,0,0);">Everything</a>
+ </div>
+
+ <br>
+ <span style="color: rgba(0,0,0,0.4);">Availability</span>
+ <div class="ui link list" style="margin-top: 0.3em;">
+ <a class="active item"><b>Everything</b></a>
+ <a class="item" style="color: rgba(0,0,0);">Open Access</a>
+ <a class="item" style="color: rgba(0,0,0);">Lending</a>
+ <a class="item" style="color: rgba(0,0,0);">Paywall</a>
+ </div>
+
+ <br>
+ <span style="color: rgba(0,0,0,0.4);">Sort Order</span>
+ <div class="ui link list" style="margin-top: 0.3em;">
+ <a class="active item"><b>Relevancy</b></a>
+ <a class="item" style="color: rgba(0,0,0);">Recent First</a>
+ <a class="item" style="color: rgba(0,0,0);">Oldest First</a>
+ </div>
+ </div>
+
+ </div>
+ <div class="ui thirteen wide column">
+ {% if found %}
+ {% if found.results %}
+ {% for paper in found.results %}
+ {{ search_macros.fulltext_search_result_row(paper) }}
+ {% endfor %}
+ {% endif %}
+ {% else %}
+ Some other message here when there is no search? Like a bunch of examples?
+ Or does that ever happen... we can just run query on "*".
+ {% endif %}
+ </div>
+</div>
+{% endblock %}
diff --git a/fatcat_scholar/templates/search_macros.html b/fatcat_scholar/templates/search_macros.html
new file mode 100644
index 0000000..b600cb4
--- /dev/null
+++ b/fatcat_scholar/templates/search_macros.html
@@ -0,0 +1,203 @@
+
+{% macro fulltext_search_result_row(paper) -%}
+{% set lang_code = "en" %}
+<div class="ui grid">
+<div class="thirteen wide column">
+ {# ### TITLE ROW #}
+ <h4 style="margin-bottom: 0px; font-size: 1.2em;">
+
+ {# "best URL" calculation #}
+ {% if paper.pmcid %}
+ <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/{{ paper.pmcid }}/"
+ {% elif paper.pmid %}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{ paper.pmid }}/"
+ {% elif paper.arxiv_id %}
+ <a href="https://arxiv.org/abs/{{ paper.arxiv_id }}/"
+ {% elif paper.doi %}
+ <a href="https://doi.org/{{ paper.doi }}"
+ {% else %}
+ <a href="https://fatcat.wiki/release/{{ paper.fatcat_ident }}"
+ {% endif %}
+ style="color: #2224c7;">
+ {% if lang_code != 'en' and lang_code == paper.lang and paper.original_title %}
+ {# show original title first instead of title if UI is in that language #}
+ {{ paper.original_title[:512] }}
+ {% if paper.original_title|length > 512 %}...{% endif %}
+ {% elif paper.title %}
+ {{ paper.title[:512] }}
+ {% if paper.title|length > 512 %}...{% endif %}
+ {% else %}
+ [blank]
+ {% endif %}
+ </a>
+
+ {# release type suffix #}
+ {% if paper.release_type in ("article-journal", "paper-conference") %}
+ {# pass #}
+ {% elif paper.release_type in ("book", "chapter", "dataset") %}
+ <b style="text-transform: uppercase;">[{{ _(paper.release_type) }}]</b>
+ {% elif not paper.release_type %}
+ <b style="text-transform: uppercase; color: red;">[media?]</b>
+ {% else %}
+ <b style="text-transform: uppercase;">[{{ _(paper.release_type) }}]</b>
+ {% endif %}
+
+ {# show inverse of title/original_title above #}
+ {% if lang_code != 'en' and lang_code == paper.lang and paper.title and paper.title != paper.original_title %}
+ <br>
+ <i style="font-weight: normal;">
+ {{ paper.title[:512] }} {% if paper.title|length > 512 %}...{% endif %}
+ </i>
+ {% elif paper.original_title and paper.title != paper.original_title %}
+ <br>
+ <i style="font-weight: normal;">
+ {{ paper.original_title[:512] }} {% if paper.original_title|length > 512 %}...{% endif %}
+ </i>
+ {% endif %}
+
+ </h4>
+
+ {# ### AUTHOR ROW #}
+ {% if paper.contrib_names %}
+ <div style="margin-top: 0.1em; margin-bottom: 0.2em; font-size: 1.1em;">
+ <b>
+ {{ ", ".join(paper.contrib_names[:12]) }}
+ {% if paper.contrib_names|length > 12 %}<i>(+{{ paper.contrib_names|length - 12 }} others)</i>{% endif %}
+ </b>
+ </div>
+ {% endif %}
+
+
+ {# ### JOURNAL ROW #}
+ {% if paper.release_year %}
+ {{ paper.release_year }}
+ {% endif %}
+ {% if paper.release_year and paper.container_name %}
+ |
+ {% endif %}
+ {% if paper.container_name %}
+ {% if paper.container_id %}
+ <a href="https://fatcat.wiki/container/{{ paper.container_id }}" style="color: black;">{{ paper.container_name }}</a>
+ {% else %}
+ {{ paper.container_name }}
+ {% endif %}
+ {% if paper.container_is_oa %}<i class="icon unlock orange small"></i>{% endif %}
+ {% endif %}
+ {% if paper.withdrawn_status %}
+ <b style="color: red;"><code>[{{ paper.withdrawn_status }}]</code></b>
+ {% endif %}
+ {% if paper.release_stage == "accepted" %}
+ <b style="color: brown;"><code>[{{ paper.release_stage }}]</code></b>
+ {% elif paper.release_stage and paper.release_stage != "published" %}
+ <b style="color: red;"><code>[{{ paper.release_stage }}]</code></b>
+ {% elif not paper.release_stage %}
+ <b style="color: red;"><code>[unpublished?]</code></b>
+ {% endif %}
+
+ {# ### ABSTRACT / QUERY HIGHLIGHT #}
+ {% if paper._highlights %}
+ <div style="padding-top: 1em; padding-bottom: 0.5em;" class="search_highlights">
+ {% for highlight in paper._highlights %}
+ {{ highlight|safe }} ...
+ {% endfor %}
+ </div>
+ {% elif paper.abstract %}
+ <div style="padding-top: 1em; padding-bottom: 0.5em;">
+ {% if paper.abstract[0]|length > 500 %}
+ {{ paper.abstract[0][:500] }}...
+ {% else %}
+ {{ paper.abstract[0][:500] }}...
+ {% endif %}
+ </div>
+ {% else %}
+ <br>
+ {% endif %}
+
+ {# ### IDENTIFIERS #}
+ {% if paper.doi %}
+ <a href="https://doi.org/{{paper.doi }}" style="color: green;">doi:{{ paper.doi }}</a> &nbsp;
+ {% endif %}
+ {% if paper.pmid %}
+ <a href="https://www.ncbi.nlm.nih.gov/pubmed/{{paper.pmid }}" style="color: green;">pmid:{{ paper.pmid }}</a> &nbsp;
+ {% endif %}
+ {% if paper.pmcid %}
+ <a href="https://pubmed.ncbi.nlm.nih.gov/{{paper.pmcid }}/" style="color: green;">pmcid:{{ paper.pmcid }}</a> &nbsp;
+ {% endif %}
+ {% if paper.arxiv_id %}
+ <a href="https://arxiv.org/abs/{{paper.arxiv_id }}" style="color: green;">arXiv:{{ paper.arxiv_id }}</a> &nbsp;
+ {% endif %}
+ {% if paper.fatcat_ident %}
+ <a href="https://fatcat.wiki/release/{{paper.fatcat_ident}}" style="color: green;">fatcat:{{ paper.fatcat_ident}}</a> &nbsp;
+ {% endif %}
+
+ {# ### SOURCE TAGS #}
+ <div style="margin-top: 0.2em;">
+ {% if paper.cord19_uid or 'cord19' in paper.source_tags %}
+ <a href="https://pages.semanticscholar.org/coronavirus-research">
+ <span class="ui label small">CORD-19</span>
+ </a>
+ {% endif %}
+ {% if 'fatcat' in paper.source_tags %}
+ <a href="https://fatcat.wiki">
+ <span class="ui label small">fatcat</span>
+ </a>
+ {% endif %}
+ {% if 'who' in paper.source_tags %}
+ <a href="https://www.who.int/emergencies/diseases/novel-coronavirus-2019/global-research-on-novel-coronavirus-2019-ncov">
+ <span class="ui blue label small">WHO</span>
+ </a>
+ {% endif %}
+ {% if 'wanfang' in paper.source_tags %}
+ <a href="http://subject.med.wanfangdata.com.cn/Channel/7">
+ <span class="ui olive label small">Wanfang</span>
+ </a>
+ {% endif %}
+ {% if 'cnki' in paper.source_tags %}
+ <a href="http://en.gzbd.cnki.net/GZBT/brief/Default.aspx">
+ <span class="ui brown label small">CNKI</span>
+ </a>
+ {% endif %}
+ {# olive, brown, grey, pink, red, etc #}
+ </div>
+
+</div>
+<div class="three wide left aligned column" style="padding-top: 3em; padding-right: 0em;">
+ {% if paper.fulltext.thumbnail_url %}
+ {# <img src="{{ settings.COVID19_FULLTEXT_HOST }}{{ paper.fulltext.thumbnail_url }}" style="border: 1px solid grey; max-height: 12em; max-width: 100%;"> #}
+
+ <div class="ui card">
+ <a class="image"
+ {% if paper.fulltext.ia_pdf_url %}
+ href="{{ paper.fulltext.ia_pdf_url }}"
+ {% else %}
+ href="{{ settings.COVID19_FULLTEXT_HOST }}{{ paper.fulltext.pdf_url }}"
+ {% endif %}>
+ <img src="{{ settings.COVID19_FULLTEXT_HOST }}{{ paper.fulltext.thumbnail_url }}">
+ </a>
+ {#
+ <div class="content">
+ <div class="meta">
+ <span>PDF</span>
+ </div>
+ </div>
+ #}
+ </div>
+
+ </a>
+ <br>
+ {% else %}
+ {# No Fulltext #}
+ {% endif %}
+{# should we include these little links?
+ <code style="font-size: 0.9rem; padding-left: 0.5em;">
+ {% if paper.fulltext.pdf_url %}
+ <a href="{{ settings.COVID19_FULLTEXT_HOST }}{{ paper.fulltext.pdf_url }}">mirror</a>
+ {% endif %}
+ {% if paper.fulltext.grobid_xml_url %}
+ <a href="{{ settings.COVID19_FULLTEXT_HOST }}{{ paper.fulltext.grobid_xml_url }}">xml</a>
+ {% endif %}
+ </code>
+#}
+</div>
+</div>
+{% endmacro %}
diff --git a/fatcat_scholar/web.py b/fatcat_scholar/web.py
index 8725ce0..e1ef478 100644
--- a/fatcat_scholar/web.py
+++ b/fatcat_scholar/web.py
@@ -9,13 +9,17 @@ from enum import Enum
import babel.support
from fastapi import FastAPI, APIRouter, Request, Depends, Header
from fastapi.staticfiles import StaticFiles
-from fatcat_scholar.hacks import Jinja2Templates
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
+from dynaconf import settings
+
+from fatcat_scholar.hacks import Jinja2Templates
+from fatcat_scholar.search import do_fulltext_search
+
+print(settings.as_dict())
-I18N_LANG_DEFAULT = "en"
I18N_LANG_TRANSLATIONS = ["de", "zh"]
-I18N_LANG_OPTIONS = I18N_LANG_TRANSLATIONS + [I18N_LANG_DEFAULT,]
+I18N_LANG_OPTIONS = I18N_LANG_TRANSLATIONS + [settings.I18N_LANG_DEFAULT,]
class SearchParams(BaseModel):
q: str = ""
@@ -31,7 +35,7 @@ class LangPrefix:
def __init__(self, request: Request):
self.prefix : str = ""
- self.code : str = I18N_LANG_DEFAULT
+ self.code : str = settings.I18N_LANG_DEFAULT
for lang_option in I18N_LANG_OPTIONS:
if request.url.path.startswith(f"/{lang_option}/"):
self.prefix = f"/{lang_option}"
@@ -101,6 +105,7 @@ def load_i18n_templates():
locale_ngettext(translations),
newstyle=True,
)
+ templates.env.globals['settings'] = settings
d[lang_opt] = templates
return d
@@ -112,11 +117,19 @@ async def web_home(request: Request, lang: LangPrefix = Depends(LangPrefix), con
return await home()
return i18n_templates[lang.code].TemplateResponse("home.html", {"request": request, "locale": lang.code, "lang_prefix": lang.prefix})
+@web.get("/about", include_in_schema=False)
+async def web_about(request: Request, lang: LangPrefix = Depends(LangPrefix)):
+ return i18n_templates[lang.code].TemplateResponse("about.html", {"request": request, "locale": lang.code, "lang_prefix": lang.prefix})
+
@web.get("/search", include_in_schema=False)
async def web_search(request: Request, query: SearchParams = Depends(SearchParams), lang: LangPrefix = Depends(LangPrefix), content: ContentNegotiation = Depends(ContentNegotiation)):
if content.mimetype == "application/json":
return await search(query)
- return i18n_templates[lang.code].TemplateResponse("search.html", {"request": request})
+ found = None
+ if query.q:
+ found = do_fulltext_search(query.q)
+ return i18n_templates[lang.code].TemplateResponse("search.html", {"request": request, "locale": lang.code, "lang_prefix": lang.prefix, "found": found})
+
app = FastAPI(
title="Fatcat Scholar",