on master help sign in
Merge pull request #522 from jibe-b/master

add BASE engine in category "Science"

commitfff9460238f63f05113c8dfc970b69d84b99a991 authorAdam Tauber <asciimoo@gmail.com> dateWed 30 Mar 2016, 11:09 (11 years ago) parent26c81810b90cd4
3 files changed+140−10
searx/engines/base.py+122 searx/settings.yml+4 searx/webapp.py+14−10
searx/engines/base.pynew file+122
@@ -0,0 +1,122 @@
1+#!/usr/bin/env python
2+
3+"""
4+ BASE (Scholar publications)
5+
6+ @website https://base-search.net
7+ @provide-api yes with authorization (https://api.base-search.net/)
8+
9+ @using-api yes
10+ @results XML
11+ @stable ?
12+ @parse url, title, publishedDate, content
13+ More info on api: http://base-search.net/about/download/base_interface.pdf
14+"""
15+
16+from lxml import etree
17+from urllib import urlencode
18+from searx.utils import searx_useragent
19+from cgi import escape
20+from datetime import datetime
21+import re
22+
23+
24+categories = ['science']
25+
26+base_url = 'https://api.base-search.net/cgi-bin/BaseHttpSearchInterface.fcgi'\
27+ + '?func=PerformSearch&{query}&boost=oa&hits={hits}&offset={offset}'
28+
29+# engine dependent config
30+paging = True
31+number_of_results = 10
32+
33+# shortcuts for advanced search
34+shorcut_dict = {
35+ # user-friendly keywords
36+ 'format:': 'dcformat:',
37+ 'author:': 'dccreator:',
38+ 'collection:': 'dccollection:',
39+ 'hdate:': 'dchdate:',
40+ 'contributor:': 'dccontributor:',
41+ 'coverage:': 'dccoverage:',
42+ 'date:': 'dcdate:',
43+ 'abstract:': 'dcdescription:',
44+ 'urls:': 'dcidentifier:',
45+ 'language:': 'dclanguage:',
46+ 'publisher:': 'dcpublisher:',
47+ 'relation:': 'dcrelation:',
48+ 'rights:': 'dcrights:',
49+ 'source:': 'dcsource:',
50+ 'subject:': 'dcsubject:',
51+ 'title:': 'dctitle:',
52+ 'type:': 'dcdctype:'
53+}
54+
55+
56+def request(query, params):
57+ # replace shortcuts with API advanced search keywords
58+ for key in shorcut_dict.keys():
59+ query = re.sub(str(key), str(shorcut_dict[key]), query)
60+
61+ # basic search
62+ offset = (params['pageno'] - 1) * number_of_results
63+
64+ string_args = dict(query=urlencode({'query': query}),
65+ offset=offset,
66+ hits=number_of_results)
67+
68+ params['url'] = base_url.format(**string_args)
69+
70+ params['headers']['User-Agent'] = searx_useragent()
71+ return params
72+
73+
74+def response(resp):
75+ results = []
76+
77+ search_results = etree.XML(resp.content)
78+
79+ for entry in search_results.xpath('./result/doc'):
80+ content = "No description available"
81+
82+ date = datetime.now() # needed in case no dcdate is available for an item
83+ for item in entry:
84+ if item.attrib["name"] == "dchdate":
85+ harvestDate = item.text
86+
87+ elif item.attrib["name"] == "dcdate":
88+ date = item.text
89+
90+ elif item.attrib["name"] == "dctitle":
91+ title = item.text
92+
93+ elif item.attrib["name"] == "dclink":
94+ url = item.text
95+
96+ elif item.attrib["name"] == "dcdescription":
97+ content = escape(item.text[:300])
98+ if len(item.text) > 300:
99+ content += "..."
100+
101+# dates returned by the BASE API are not several formats
102+ publishedDate = None
103+ for date_format in ['%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%d', '%Y-%m', '%Y']:
104+ try:
105+ publishedDate = datetime.strptime(date, date_format)
106+ break
107+ except:
108+ pass
109+
110+ if publishedDate is not None:
111+ res_dict = {'url': url,
112+ 'title': title,
113+ 'publishedDate': publishedDate,
114+ 'content': content}
115+ else:
116+ res_dict = {'url': url,
117+ 'title': title,
118+ 'content': content}
119+
120+ results.append(res_dict)
121+
122+ return results
searx/settings.yml+4
@@ -38,6 +38,10 @@ engines:
3838 engine : archlinux
3939 shortcut : al
4040
41+ - name : base
42+ engine : base
43+ shortcut : bs
44+
4145 - name : wikipedia
4246 engine : mediawiki
4347 shortcut : wp
searx/webapp.py+14−10
@@ -408,17 +408,21 @@ def index():
408408
409409 # TODO, check if timezone is calculated right
410410 if 'publishedDate' in result:
411− result['pubdate'] = result['publishedDate'].strftime('%Y-%m-%d %H:%M:%S%z')
412− if result['publishedDate'].replace(tzinfo=None) >= datetime.now() - timedelta(days=1):
413− timedifference = datetime.now() - result['publishedDate'].replace(tzinfo=None)
414− minutes = int((timedifference.seconds / 60) % 60)
415− hours = int(timedifference.seconds / 60 / 60)
416− if hours == 0:
417− result['publishedDate'] = gettext(u'{minutes} minute(s) ago').format(minutes=minutes)
418− else:
419− result['publishedDate'] = gettext(u'{hours} hour(s), {minutes} minute(s) ago').format(hours=hours, minutes=minutes) # noqa
411+ try: # test if publishedDate >= 1900 (datetime module bug)
412+ result['pubdate'] = result['publishedDate'].strftime('%Y-%m-%d %H:%M:%S%z')
413+ except ValueError:
414+ result['publishedDate'] = None
420415 else:
421− result['publishedDate'] = format_date(result['publishedDate'])
416+ if result['publishedDate'].replace(tzinfo=None) >= datetime.now() - timedelta(days=1):
417+ timedifference = datetime.now() - result['publishedDate'].replace(tzinfo=None)
418+ minutes = int((timedifference.seconds / 60) % 60)
419+ hours = int(timedifference.seconds / 60 / 60)
420+ if hours == 0:
421+ result['publishedDate'] = gettext(u'{minutes} minute(s) ago').format(minutes=minutes)
422+ else:
423+ result['publishedDate'] = gettext(u'{hours} hour(s), {minutes} minute(s) ago').format(hours=hours, minutes=minutes) # noqa
424+ else:
425+ result['publishedDate'] = format_date(result['publishedDate'])
422426
423427 if search.request_data.get('format') == 'json':
424428 return Response(json.dumps({'query': search.query,