diff options
Diffstat (limited to 'fatcat_scholar')
-rw-r--r-- | fatcat_scholar/search.py | 139 | ||||
-rw-r--r-- | fatcat_scholar/static/ia-favicon.ico | bin | 0 -> 4286 bytes | |||
-rw-r--r-- | fatcat_scholar/static/ia-logo.svg | 13 | ||||
-rw-r--r-- | fatcat_scholar/static/ia-wordmark.svg | 1 | ||||
-rw-r--r-- | fatcat_scholar/templates/base.html | 212 | ||||
-rw-r--r-- | fatcat_scholar/templates/home.html | 104 | ||||
-rw-r--r-- | fatcat_scholar/templates/search.html | 74 | ||||
-rw-r--r-- | fatcat_scholar/templates/search_macros.html | 203 | ||||
-rw-r--r-- | fatcat_scholar/web.py | 23 |
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 Binary files differnew file mode 100644 index 0000000..363e30d --- /dev/null +++ b/fatcat_scholar/static/ia-favicon.ico 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> + </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 & 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> + {% endif %} + {% if paper.pmid %} + <a href="https://www.ncbi.nlm.nih.gov/pubmed/{{paper.pmid }}" style="color: green;">pmid:{{ paper.pmid }}</a> + {% endif %} + {% if paper.pmcid %} + <a href="https://pubmed.ncbi.nlm.nih.gov/{{paper.pmcid }}/" style="color: green;">pmcid:{{ paper.pmcid }}</a> + {% endif %} + {% if paper.arxiv_id %} + <a href="https://arxiv.org/abs/{{paper.arxiv_id }}" style="color: green;">arXiv:{{ paper.arxiv_id }}</a> + {% endif %} + {% if paper.fatcat_ident %} + <a href="https://fatcat.wiki/release/{{paper.fatcat_ident}}" style="color: green;">fatcat:{{ paper.fatcat_ident}}</a> + {% 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", |