# HG changeset patch # User Arthur Lutz <arthur.lutz@logilab.fr> # Date 1463580414 -7200 # Wed May 18 16:06:54 2016 +0200 # Node ID d1881dfe6959a7d4691bd401477505023b981373 # Parent 4e15941f6ce191d0f946955a8048e0249488f88d [views] initial prototype view to display results from elasticsearch (as startup view for now) diff --git a/views.py b/views.py --- a/views.py +++ b/views.py @@ -15,4 +15,71 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -"""cubicweb-elasticsearch views/forms/actions/components for web ui""" +"""elasticsearch search views""" +from elasticsearch import Elasticsearch +from elasticsearch.exceptions import NotFoundError +from elasticsearch_dsl import Search +from bs4 import BeautifulSoup + +from logilab.mtconverter import xml_escape + +from cubicweb.view import StartupView + +from cubes.elasticsearch.es import indexable_types + + +class ElasticSearchView(StartupView): + __regid__ = "esearch" + + def call(self, **kwargs): + search_comp = self._cw.vreg['components'].select_or_none('search-comp', + self._cw) + if search_comp: + search_comp.render(w=self.w) + + self.w(u'<h1>%s</h1>' % self._cw._('Recherche')) + query_string = xml_escape(self._cw.form.get('search', '')) + self.w(u'<h2>Résultats pour : <em>%s</em></h2>' % query_string) + locations = self._cw.vreg.config['elasticsearch-locations'] + index_name = self._cw.vreg.config['index-name'] + # TODO sanitize locations + # TODO create a es objet/connexion outside of each request and reuse it + if locations: + es = Elasticsearch(locations.split(',')) + else: + es = Elasticsearch() + search = Search(using=es, index=index_name, + doc_type=indexable_types(self._cw.vreg.schema)) + search = search.query('multi_match', + query=query_string, + fields=("title^3", "name^3", "content^2", "_all",)) + search = search.highlight('content') + search = search.highlight_options(pre_tags="", post_tags="", fragment_size=150) + + try: + response = search.execute() + except NotFoundError: + self.w(u'index not found in elasticsearch') + return + self.w(u'Resultats: %s' % response.hits.total) + self.w(u'<ul>') + for result in response: + self.w(u'<li>') + infos = result.to_dict() + infos['_score'] = result.meta.score + infos['keys'] = result.to_dict().keys() + infos.setdefault('title', infos.get('name', infos.get('reference', u'n/a'))) + try: + self.w(u'<a href="%(cwuri)s">%(title)s</a> (%(_score).2f)<br/>' % (infos)) + if self._cw.form.get('debug-es'): + self.w(u' [%(keys)s] <br/>' % infos) + except KeyError: + self.w(u'Missing key in : %s' % infos.keys()) + try: + for fragment in result.meta.highlight.content: + self.w(u'... %s' % BeautifulSoup(fragment, 'lxml').get_text()) + self.w(u' ... <br/>') + except AttributeError: + pass + self.w(u'</li>') + self.w(u'</ul>')