Merge branch 'master' into gigablast

This commit is contained in:
Markus Heiser 2020-06-29 16:09:59 +00:00 committed by GitHub
commit 8d318ee142
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 576 additions and 126 deletions

View File

@ -1,63 +1,73 @@
searx .. SPDX-License-Identifier: AGPL-3.0-or-later
=====
A privacy-respecting, hackable `metasearch .. figure:: https://raw.githubusercontent.com/asciimoo/searx/master/searx/static/themes/oscar/img/logo_searx_a.png
engine <https://en.wikipedia.org/wiki/Metasearch_engine>`__. :target: https://asciimoo.github.io/searx/
:alt: searX
:width: 100%
:align: center
Pronunciation: səːks -------
List of `running
instances <https://searx.space/>`__.
See the `documentation <https://asciimoo.github.io/searx>`__ and the `wiki <https://github.com/asciimoo/searx/wiki>`__ for more information.
|searx install|
|searx homepage|
|searx wiki|
|AGPL License|
|Issues|
|commits|
|OpenCollective searx backers| |OpenCollective searx backers|
|OpenCollective searx sponsors| |OpenCollective searx sponsors|
Installation Privacy-respecting, hackable `metasearch engine`_ / *pronunciation* **səːks**.
~~~~~~~~~~~~
With Docker .. _metasearch engine: https://en.wikipedia.org/wiki/Metasearch_engine
-----------
Go to the `searx-docker <https://github.com/searx/searx-docker>`__ project.
Without Docker .. |searx install| image:: https://img.shields.io/badge/-install-blue
-------------- :target: https://asciimoo.github.io/searx/admin/installation.html
For all of the details, follow this `step by step installation <https://asciimoo.github.io/searx/admin/installation.html>`__.
Note: the documentation needs to be updated. .. |searx homepage| image:: https://img.shields.io/badge/-homepage-blue
:target: https://asciimoo.github.io/searx
If you are in a hurry .. |searx wiki| image:: https://img.shields.io/badge/-wiki-blue
--------------------- :target: https://github.com/asciimoo/searx/wiki
- clone the source:
``git clone https://github.com/asciimoo/searx.git && cd searx``
- install dependencies: ``./manage.sh update_packages``
- edit your
`settings.yml <https://github.com/asciimoo/searx/blob/master/searx/settings.yml>`__
(set your ``secret_key``!)
- run ``python searx/webapp.py`` to start the application
.. |AGPL License| image:: https://img.shields.io/badge/license-AGPL-blue.svg
:target: https://github.com/asciimoo/searx/blob/master/LICENSE
Bugs .. |Issues| image:: https://img.shields.io/github/issues/asciimoo/searx?color=yellow&label=issues
~~~~ :target: https://github.com/asciimoo/searx/issues
Bugs or suggestions? Visit the `issue .. |PR| image:: https://img.shields.io/github/issues-pr-raw/asciimoo/searx?color=yellow&label=PR
tracker <https://github.com/asciimoo/searx/issues>`__. :target: https://github.com/asciimoo/searx/pulls
`License <https://github.com/asciimoo/searx/blob/master/LICENSE>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More about searx
~~~~~~~~~~~~~~~~
- `openhub <https://www.openhub.net/p/searx/>`__
- `twitter <https://twitter.com/Searx_engine>`__
- IRC: #searx @ freenode
.. |commits| image:: https://img.shields.io/github/commit-activity/y/asciimoo/searx?color=yellow&label=commits
:target: https://github.com/asciimoo/searx/commits/master
.. |OpenCollective searx backers| image:: https://opencollective.com/searx/backers/badge.svg .. |OpenCollective searx backers| image:: https://opencollective.com/searx/backers/badge.svg
:target: https://opencollective.com/searx#backer :target: https://opencollective.com/searx#backer
.. |OpenCollective searx sponsors| image:: https://opencollective.com/searx/sponsors/badge.svg .. |OpenCollective searx sponsors| image:: https://opencollective.com/searx/sponsors/badge.svg
:target: https://opencollective.com/searx#sponsor :target: https://opencollective.com/searx#sponsor
If you are looking for running instances, ready to use, then visit searx.space_.
Otherwise jump to the user_, admin_ and developer_ handbooks you will find on
our homepage_.
.. _searx.space: https://searx.space
.. _user: https://asciimoo.github.io/searx/user
.. _admin: https://asciimoo.github.io/searx/admin
.. _developer: https://asciimoo.github.io/searx/dev
.. _homepage: https://asciimoo.github.io/searx
contact:
openhub_ // twitter_ // IRC: #searx @ freenode
.. _openhub: https://www.openhub.net/p/searx
.. _twitter: https://twitter.com/Searx_engine
-------
|gluten free|
.. |gluten free| image:: https://forthebadge.com/images/featured/featured-gluten-free.svg

View File

@ -108,6 +108,7 @@ restart the uwsgi application.
:start-after: START searx uwsgi-description ubuntu-20.04 :start-after: START searx uwsgi-description ubuntu-20.04
:end-before: END searx uwsgi-description ubuntu-20.04 :end-before: END searx uwsgi-description ubuntu-20.04
.. hotfix: a bug group-tab need this comment
.. group-tab:: Arch Linux .. group-tab:: Arch Linux
@ -115,6 +116,7 @@ restart the uwsgi application.
:start-after: START searx uwsgi-description arch :start-after: START searx uwsgi-description arch
:end-before: END searx uwsgi-description arch :end-before: END searx uwsgi-description arch
.. hotfix: a bug group-tab need this comment
.. group-tab:: Fedora / RHEL .. group-tab:: Fedora / RHEL
@ -128,22 +130,21 @@ restart the uwsgi application.
.. group-tab:: Ubuntu / debian .. group-tab:: Ubuntu / debian
.. kernel-include:: $DOCS_BUILD/includes/searx.rst .. kernel-include:: $DOCS_BUILD/includes/searx.rst
:code: ini
:start-after: START searx uwsgi-appini ubuntu-20.04 :start-after: START searx uwsgi-appini ubuntu-20.04
:end-before: END searx uwsgi-appini ubuntu-20.04 :end-before: END searx uwsgi-appini ubuntu-20.04
.. hotfix: a bug group-tab need this comment
.. group-tab:: Arch Linux .. group-tab:: Arch Linux
.. kernel-include:: $DOCS_BUILD/includes/searx.rst .. kernel-include:: $DOCS_BUILD/includes/searx.rst
:code: ini
:start-after: START searx uwsgi-appini arch :start-after: START searx uwsgi-appini arch
:end-before: END searx uwsgi-appini arch :end-before: END searx uwsgi-appini arch
.. hotfix: a bug group-tab need this comment
.. group-tab:: Fedora / RHEL .. group-tab:: Fedora / RHEL
.. kernel-include:: $DOCS_BUILD/includes/searx.rst .. kernel-include:: $DOCS_BUILD/includes/searx.rst
:code: ini
:start-after: START searx uwsgi-appini fedora :start-after: START searx uwsgi-appini fedora
:end-before: END searx uwsgi-appini fedora :end-before: END searx uwsgi-appini fedora

View File

@ -6,6 +6,7 @@ Blog
:maxdepth: 2 :maxdepth: 2
:caption: Contents :caption: Contents
lxcdev-202006
python3 python3
admin admin
intro-offline intro-offline

413
docs/blog/lxcdev-202006.rst Normal file
View File

@ -0,0 +1,413 @@
.. _blog-lxcdev-202006:
=======================================
Developing in Linux containers [202006]
=======================================
.. _LXC: https://linuxcontainers.org/lxc/introduction/
.. sidebar:: Audience
This blog post is written for experienced admins and developers / readers
should have a serious meaning about: *distributed*, *merge* and *linux
container*.
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
In PR :PR:`1803` we added a lot of scripts to Searx's boilerplate. In this blog
post I will show you, how you can make use of them in *distributed and
heterogeneous development cycles* (TL;DR; jump to the :ref:`blog-lxcdev-202006
abstract`).
Motivation
==========
Normally in our development cycle, we edit the sources and run some test and/or
builds by using ``make`` before we commit. This cycle is simple and perfect but
might fail in some aspects we should not overlook.
The environment in which we run all our development processes matters!
The :ref:`makefile` and the :ref:`make pyenv` encapsulate a lot for us, but they
do not have access to all prerequisites. For example, there may have
dependencies on packages that are installed on the developer's desktop, but
usually are not preinstalled on a server or client system. Another examples
are; settings have been made to the software on the developer's host that would
never be set on a *production* system.
*Linux Containers* (LXC_) are isolate environments and not to mix up on
developer's all the prerequisites of all the projects he contribute to, is
always a good choice.
The scripts from PR :PR:`1803` can divide in those to install and maintain
software:
- :ref:`searx.sh`
- :ref:`filtron.sh`
- :ref:`morty.sh`
and the script :ref:`lxc.sh`, with we can scale our installation, maintenance or
even development tasks over a stack of containers, what we call: *Searx's lxc
suite*.
Gentlemen, start your engines!
==============================
.. _LXD: https://linuxcontainers.org/lxd/introduction/
.. _archlinux: https://www.archlinux.org/
Before you can start with containers, you need to install and initiate LXD_
once:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ snap install lxd
$ lxd init --auto
And you need to clone from origin or if you have your own fork, clone from your
fork:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ cd ~/Downloads
$ git clone https://github.com/asciimoo/searx.git
$ cd searx
The :ref:`lxc-searx.env` consists of several images, see ``export
LXC_SUITE=(...`` near by :origin:`utils/lxc-searx.env#L19`. For this blog post
we exercise on a archlinux_ image. The container of this image is named
``searx-archlinux``. Lets build the container, but be sure that this container
does not already exists, so first lets remove possible old one:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh remove searx-archlinux
$ sudo -H ./utils/lxc.sh build searx-archlinux
.. sidebar:: The ``searx-archlinux`` container
is the base of all our exercises here.
In this container we install all services :ref:`including searx, morty & filtron
<lxc.sh install suite>` in once:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh install suite searx-archlinux
To proxy HTTP from filtron and morty in the container to the outside of the
container, install nginx into the container. Once for the bot blocker filtron:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
./utils/filtron.sh nginx install
...
INFO: got 429 from http://10.174.184.156/searx
and once for the content sanitizer (content proxy morty):
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
./utils/morty.sh nginx install
...
INFO: got 200 from http://10.174.184.156/morty/
.. sidebar:: Fully functional searx suite
From here on you have a fully functional searx suite running with bot blocker
(filtron) and Web content sanitizer (content proxy morty) needed for a
*privacy protecting* search engine.
On your system, the IP of your ``searx-archlinux`` container differs from
http://10.174.184.156/searx, just open the URL reported in your installation
protocol in your WEB browser from the desktop to test the instance from outside
of the container.
In such a searx suite admins can maintain and access the debug log of the
different services quite easy.
.. _working in containers:
In containers, work as usual
============================
Usually you open a root-bash using ``sudo -H bash``. In case of LXC containers
open the root-bash in the container using ``./utils/lxc.sh cmd
searx-archlinux``:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux bash
INFO: [searx-archlinux] bash
[root@searx-archlinux searx]# pwd
/share/searx
The prompt ``[root@searx-archlinux ...]`` signals, that you are the root user in
the searx-container. To debug the running searx instance use:
.. tabs::
.. group-tab:: root@searx-archlinux
.. code:: sh
$ ./utils/searx.sh inspect service
...
use [CTRL-C] to stop monitoring the log
...
Back in the browser on your desktop open the service http://10.174.184.156/searx
and run your application tests while the debug log is shown in the terminal from
above. You can stop monitoring using ``CTRL-C``, this also disables the *"debug
option"* in searx's settings file and restarts the searx uwsgi application. To
debug services from filtron and morty analogous use:
.. tabs::
.. group-tab:: root@searx-archlinux
.. code:: sh
$ ./utils/filtron.sh inspect service
$ ./utils/morty.sh inspect service
Another point we have to notice is that each service (:ref:`searx <searx.sh>`,
:ref:`filtron <filtron.sh>` and :ref:`morty <morty.sh>`) runs under dedicated
system user account with the same name (compare :ref:`create searx user`). To
get a shell from theses accounts, simply call one of the scripts:
.. tabs::
.. group-tab:: root@searx-archlinux
.. code:: sh
$ ./utils/searx.sh shell
$ ./utils/filtron.sh shell
$ ./utils/morty.sh shell
To get in touch, open a shell from the service user (searx@searx-archlinux):
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
./utils/searx.sh shell
// exit with [CTRL-D]
(searx-pyenv) [searx@searx-archlinux ~]$ ...
The prompt ``[searx@searx-archlinux]`` signals that you are logged in as system
user ``searx`` in the ``searx-archlinux`` container and the python *virtualenv*
``(searx-pyenv)`` environment is activated.
.. tabs::
.. group-tab:: searx@searx-archlinux
.. code:: sh
(searx-pyenv) [searx@searx-archlinux ~]$ pwd
/usr/local/searx
Wrap production into developer suite
====================================
In this section we will see how to change the *"Fully functional searx suite"*
from a LXC container (which is quite ready for production) into a developer
suite. For this, we have to keep an eye on the :ref:`installation basic`:
- searx setup in: ``/etc/searx/settings.yml``
- searx user's home: ``/usr/local/searx``
- virtualenv in: ``/usr/local/searx/searx-pyenv``
- searx software in: ``/usr/local/searx/searx-src``
The searx software is a clone of the ``GIT_URL`` (see :ref:`makefile setup`) and
the working tree is checked out from the ``GIT_BRANCH``. With the use of the
:ref:`searx.sh` the searx service was installed as :ref:`uWSGI application
<searx uwsgi>`. To maintain this service, we can use ``systemctl`` (compare
:ref:`service architectures on distributions <uwsgi configuration>`).
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
systemctl stop uwsgi@searx
With the command above, we stopped the searx uWSGI-App in the archlinux
container.
The uWSGI-App for the archlinux dsitros is configured in
:origin:`utils/templates/etc/uwsgi/apps-archlinux/searx.ini`, from where at
least you should attend the settings of ``uid``, ``chdir``, ``env`` and
``http``::
env = SEARX_SETTINGS_PATH=/etc/searx/settings.yml
http = 127.0.0.1:8888
chdir = /usr/local/searx/searx-src/searx
virtualenv = /usr/local/searx/searx-pyenv
pythonpath = /usr/local/searx/searx-src
If you have read the :ref:`"Good to know section" <lxc.sh>` you remember, that
each container shares the root folder of the repository and the command
``utils/lxc.sh cmd`` handles relative path names **transparent**. To wrap the
searx installation into a developer one, we simple have to create a smylink to
the **transparent** reposetory from the desktop. Now lets replace the
repository at ``searx-src`` in the container with the working tree from outside
of the container:
.. tabs::
.. group-tab:: container becomes a developer suite
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
mv /usr/local/searx/searx-src /usr/local/searx/searx-src.old
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
ln -s /share/searx/ /usr/local/searx/searx-src
Now we can develop as usual in the working tree of our desktop system. Every
time the software was changed, you have to restart the searx service (in the
conatiner):
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
systemctl restart uwsgi@searx
Remember: :ref:`working in containers` .. here are just some examples from my
daily usage:
.. tabs::
.. group-tab:: desktop
To *inspect* the searx instance (already described above):
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
./utils/searx.sh inspect service
Run :ref:`makefile`, e.g. to test inside the container:
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
make test
To install all prerequisites needed for a :ref:`buildhosts`:
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
./utils/searx.sh install buildhost
To build the docs on a buildhost :ref:`buildhosts`:
.. code:: sh
$ sudo -H ./utils/lxc.sh cmd searx-archlinux \
make docs
.. _blog-lxcdev-202006 abstract:
Abstract
========
We build up a fully functional searx suite in a archlinux container:
.. code:: sh
$ sudo -H ./utils/lxc.sh install suite searx-archlinux
To access HTTP from the desktop we installed nginx for the services inside the
conatiner:
.. tabs::
.. group-tab:: [root@searx-archlinux]
.. code:: sh
$ ./utils/filtron.sh nginx install
$ ./utils/morty.sh nginx install
To wrap the suite into a developer one, we created a symbolic link to the
repository which is shared **transparent** from the desktop's file system into
the container :
.. tabs::
.. group-tab:: [root@searx-archlinux]
.. code:: sh
$ mv /usr/local/searx/searx-src /usr/local/searx/searx-src.old
$ ln -s /share/searx/ /usr/local/searx/searx-src
$ systemctl restart uwsgi@searx
To get remarks from the suite of the archlinux container we can use:
.. tabs::
.. group-tab:: desktop
.. code:: sh
$ sudo -H ./utils/lxc.sh show suite searx-archlinux
...
[searx-archlinux] INFO: (eth0) filtron: http://10.174.184.156:4004/ http://10.174.184.156/searx
[searx-archlinux] INFO: (eth0) morty: http://10.174.184.156:3000/
[searx-archlinux] INFO: (eth0) docs-live: http://10.174.184.156:8080/
[searx-archlinux] INFO: (eth0) IPv6: http://[fd42:573b:e0b3:e97e:216:3eff:fea5:9b65]
...

View File

@ -13,7 +13,7 @@ Private engines
To solve this issue private engines were introduced in :pull:`1823`. To solve this issue private engines were introduced in :pull:`1823`.
A new option was added to engines named `tokens`. It expects a list A new option was added to engines named `tokens`. It expects a list
of strings. If the user making a request presents one of the tokens of strings. If the user making a request presents one of the tokens
of an engine, he/she is able to access information about the engine of an engine, they can access information about the engine
and make search requests. and make search requests.
Example configuration to restrict access to the Arch Linux Wiki engine: Example configuration to restrict access to the Arch Linux Wiki engine:

View File

@ -81,7 +81,7 @@ Parameters
Theme of instance. Theme of instance.
Please note, available themes depend on an instance. It is possible that an Please note, available themes depend on an instance. It is possible that an
instance administrator deleted, created or renamed themes on his/her instance. instance administrator deleted, created or renamed themes on their instance.
See the available options in the preferences page of the instance. See the available options in the preferences page of the instance.
``oscar-style`` : default ``logicodev`` ``oscar-style`` : default ``logicodev``
@ -91,7 +91,7 @@ Parameters
``oscar``. ``oscar``.
Please note, available styles depend on an instance. It is possible that an Please note, available styles depend on an instance. It is possible that an
instance administrator deleted, created or renamed styles on his/her instance administrator deleted, created or renamed styles on their
instance. See the available options in the preferences page of the instance. instance. See the available options in the preferences page of the instance.
``enabled_plugins`` : optional ``enabled_plugins`` : optional

View File

@ -44,9 +44,9 @@ hidden from visited result pages.
What are the consequences of using public instances? What are the consequences of using public instances?
---------------------------------------------------- ----------------------------------------------------
If someone uses a public instance, he/she has to trust the administrator of that If someone uses a public instance, they have to trust the administrator of that
instance. This means that the user of the public instance does not know whether instance. This means that the user of the public instance does not know whether
his/her requests are logged, aggregated and sent or sold to a third party. their requests are logged, aggregated and sent or sold to a third party.
Also, public instances without proper protection are more vulnerable to abusing Also, public instances without proper protection are more vulnerable to abusing
the search service, In this case the external service in exchange returns the search service, In this case the external service in exchange returns

View File

@ -47,9 +47,9 @@ one**::
*Good to know ...* *Good to know ...*
Eeach container shares the root folder of the repository and the Each container shares the root folder of the repository and the command
command ``utils/lxc.sh cmd`` **handles relative path names transparent**, ``utils/lxc.sh cmd`` **handles relative path names transparent**, compare output
compare output of:: of::
$ sudo -H ./utils/lxc.sh cmd -- ls -la Makefile $ sudo -H ./utils/lxc.sh cmd -- ls -la Makefile
... ...
@ -66,6 +66,7 @@ If there comes the time you want to **get rid off all** the containers and
$ sudo -H ./utils/lxc.sh remove $ sudo -H ./utils/lxc.sh remove
$ sudo -H ./utils/lxc.sh remove images $ sudo -H ./utils/lxc.sh remove images
.. _lxc.sh install suite:
Install suite Install suite
============= =============

View File

@ -50,6 +50,7 @@ result_xpath = '//div[@class="result results_links results_links_deep web-result
url_xpath = './/a[@class="result__a"]/@href' url_xpath = './/a[@class="result__a"]/@href'
title_xpath = './/a[@class="result__a"]' title_xpath = './/a[@class="result__a"]'
content_xpath = './/a[@class="result__snippet"]' content_xpath = './/a[@class="result__snippet"]'
correction_xpath = '//div[@id="did_you_mean"]//a'
# match query's language to a region code that duckduckgo will accept # match query's language to a region code that duckduckgo will accept
@ -125,6 +126,11 @@ def response(resp):
'content': content, 'content': content,
'url': res_url}) 'url': res_url})
# parse correction
for correction in eval_xpath(doc, correction_xpath):
# append correction
results.append({'correction': extract_text(correction)})
# return results # return results
return results return results

View File

@ -75,7 +75,7 @@ def response(resp):
for result in search_results[0].get('items', []): for result in search_results[0].get('items', []):
# parse image results # parse image results
if result.get('image'): if result.get('image') and result.get('width') and result.get('height'):
result_url = '' result_url = ''
if 'url' in result: if 'url' in result:

View File

@ -59,12 +59,16 @@
<h2 id='add to browser'>How to set as the default search engine?</h2> <h2 id='add to browser'>How to set as the default search engine?</h2>
<dt>Firefox</dt> <p>
Searx supports <a href="https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md">OpenSearch</a>.
For more information on changing your default search engine, see your browser's documentation:
</p>
<dd> <ul>
<a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> <li><a href="https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox">Firefox</a></li>
searx as a search engine on any version of Firefox! (javascript required) <li><a href="https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine" >Microsoft Egde</a></li>
</dd> <li>Chrome based browsers <a href="https://www.chromium.org/tab-to-search">only add websites that the user navigates to without a path.</a>
</ul>
<h2>Where to find anonymous usage statistics of this instance ?</h2> <h2>Where to find anonymous usage statistics of this instance ?</h2>

View File

@ -8,7 +8,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="generator" content="searx/{{ searx_version }}"> <meta name="generator" content="searx/{{ searx_version }}">
<meta name="referrer" content="no-referrer"> <meta name="referrer" content="no-referrer">
<meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" /> <meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=2.0, user-scalable=1" />
{% block meta %}{% endblock %} {% block meta %}{% endblock %}
<script src="{{ url_for('js_translations') }}"></script> <script src="{{ url_for('js_translations') }}"></script>
<title>{% block title %}{% endblock %}{{ instance_name }}</title> <title>{% block title %}{% endblock %}{{ instance_name }}</title>
@ -42,7 +42,7 @@
<style type="text/css"> <style type="text/css">
.tab-content > .active_if_nojs, .active_if_nojs {display: block !important; visibility: visible !important;} .tab-content > .active_if_nojs, .active_if_nojs {display: block !important; visibility: visible !important;}
.margin_top_if_nojs {margin-top: 20px;} .margin_top_if_nojs {margin-top: 20px;}
.hide_if_nojs {display: none !important;overflow:none !important;} .hide_if_nojs {display: none !important;overflow: hidden !important;}
.disabled_if_nojs {pointer-events: none; cursor: default; text-decoration: line-through;} .disabled_if_nojs {pointer-events: none; cursor: default; text-decoration: line-through;}
</style> </style>
</noscript> </noscript>

View File

@ -8,34 +8,34 @@
<img width="32" height="32" class="favicon" src="{{ url_for('static', filename='themes/oscar/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}" /> <img width="32" height="32" class="favicon" src="{{ url_for('static', filename='themes/oscar/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}" />
{%- endmacro %} {%- endmacro %}
{%- macro result_link(url, title, classes='') -%} {%- macro result_link(url, title, classes='', id='') -%}
<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ title }}</a> <a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}{% if id %} aria-labelledby="result-{{id}}"{%endif%}>{{ title }}</a>
{%- endmacro -%} {%- endmacro -%}
<!-- Draw result header --> <!-- Draw result header -->
{% macro result_header(result, favicons) -%} {% macro result_header(result, favicons, id) -%}
<h4 class="result_header">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{% if result.url %}{{ result_link(result.url, result.title|safe) }}{% else %}{{ result.title|safe}}{% endif %}</h4> <h4 class="result_header" id="result-{{id}}">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{% if result.url %}{{ result_link(result.url, result.title|safe, id=id) }}{% else %}{{ result.title|safe}}{% endif %}</h4>
{%- endmacro %} {%- endmacro %}
<!-- Draw result sub header --> <!-- Draw result sub header -->
{% macro result_sub_header(result) -%} {% macro result_sub_header(result, id) -%}
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %} {% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
{% if result.magnetlink %}<small> &bull; {{ result_link(result.magnetlink, icon('magnet') + _('magnet link'), "magnetlink") }}</small>{% endif %} {% if result.magnetlink %}<small> &bull; {{ result_link(result.magnetlink, icon('magnet') + _('magnet link'), "magnetlink", id) }}</small>{% endif %}
{% if result.torrentfile %}<small> &bull; {{ result_link(result.torrentfile, icon('download-alt') + _('torrent file'), "torrentfile") }}</small>{% endif %} {% if result.torrentfile %}<small> &bull; {{ result_link(result.torrentfile, icon('download-alt') + _('torrent file'), "torrentfile", id) }}</small>{% endif %}
{%- endmacro %} {%- endmacro %}
<!-- Draw result footer --> <!-- Draw result footer -->
{% macro result_footer(result) -%} {% macro result_footer(result, id) -%}
<div class="clearfix"></div>{{- "" -}} <div class="clearfix"></div>{{- "" -}}
<div class="pull-right"> <div class="pull-right">
{%- for engine in result.engines -%} {%- for engine in result.engines -%}
<span class="label label-default">{{ engine }}</span> <span class="label label-default">{{ engine }}</span>
{%- endfor -%} {%- endfor -%}
{%- if result.url -%} {%- if result.url -%}
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small> <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
{%- endif -%} {%- endif -%}
{%- if proxify -%} {%- if proxify -%}
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small> <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info", id) }}</small>
{%- endif -%} {%- endif -%}
</div> </div>
{%- if result.pretty_url -%} {%- if result.pretty_url -%}
@ -44,16 +44,16 @@
{%- endmacro %} {%- endmacro %}
<!-- Draw result footer --> <!-- Draw result footer -->
{% macro result_footer_rtl(result) -%} {% macro result_footer_rtl(result, id) -%}
<div class="clearfix"></div>{{- "" -}} <div class="clearfix"></div>{{- "" -}}
{% for engine in result.engines -%} {% for engine in result.engines -%}
<span class="label label-default">{{ engine }}</span> <span class="label label-default">{{ engine }}</span>
{%- endfor %} {%- endfor %}
{%- if result.url -%} {%- if result.url -%}
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small> <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
{%- endif -%} {%- endif -%}
{% if proxify -%} {% if proxify -%}
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small> <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info", id) }}</small>
{%- endif %} {%- endif %}
{%- if result.pretty_url -%} {%- if result.pretty_url -%}
<div class="external-link">{{ result.pretty_url }}</div> <div class="external-link">{{ result.pretty_url }}</div>

View File

@ -1,11 +1,11 @@
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %} {% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon with context%}
{{ result_header(result, favicons) }} {{ result_header(result, favicons) }}
{{ result_sub_header(result) }} {{ result_sub_header(result) }}
{% if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif %} {% if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif %}
{% if result.repository %}<p class="result-content">{{ icon('file') }} <a href="{{ result.repository }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %} {% if result.repository %}<p class="result-content">{{ icon('file') }} <a href="{{ result.repository }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} aria-labelledby="result-{{loop.index}}">{{ result.repository }}</a></p>{% endif %}
<div dir="ltr"> <div dir="ltr">
{{ result.codelines|code_highlighter(result.code_language)|safe }} {{ result.codelines|code_highlighter(result.code_language)|safe }}

View File

@ -1,10 +1,10 @@
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon with context %} {% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon with context %}
{{- result_header(result, favicons) -}} {{- result_header(result, favicons, loop.index) -}}
{{- result_sub_header(result) -}} {{- result_sub_header(result, loop.index) -}}
{%- if result.embedded -%} {%- if result.embedded -%}
<small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">{{ icon('music') }} {{ _('show media') }}</a></small> <small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}" aria-labelledby="result-{{loop.index}}">{{ icon('music') }} {{ _('show media') }}</a></small>
{%- endif -%} {%- endif -%}
{%- if result.embedded -%} {%- if result.embedded -%}
@ -25,7 +25,7 @@
{%- endif -%} {%- endif -%}
{%- if rtl -%} {%- if rtl -%}
{{ result_footer_rtl(result) }} {{ result_footer_rtl(result, loop.index) }}
{%- else -%} {%- else -%}
{{ result_footer(result) }} {{ result_footer(result, loop.index) }}
{%- endif -%} {%- endif -%}

View File

@ -1,6 +1,6 @@
{%- from 'oscar/macros.html' import draw_favicon -%} {%- from 'oscar/macros.html' import draw_favicon with context -%}
<a href="{{ result.img_src }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} data-toggle="modal" data-target="#modal-{{ index }}-{{pageno}}">{{- "" -}} <a href="{{ result.img_src }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} data-toggle="modal" data-target="#modal-{{ index }}-{{pageno}}" id="result-{{loop.index}}">{{- "" -}}
<img src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" class="img-thumbnail">{{- "" -}} <img src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" class="img-thumbnail">{{- "" -}}
</a> </a>
<div class="modal fade" id="modal-{{ index }}-{{ pageno }}" tabindex="-1" role="dialog" aria-hidden="true">{{- "" -}} <div class="modal fade" id="modal-{{ index }}-{{ pageno }}" tabindex="-1" role="dialog" aria-hidden="true">{{- "" -}}

View File

@ -1,7 +1,7 @@
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %} {% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %}
{{ result_header(result, favicons) }} {{ result_header(result, favicons, loop.index) }}
{{ result_sub_header(result) }} {{ result_sub_header(result, loop.index) }}
{% if (result.latitude and result.longitude) or result.boundingbox %} {% if (result.latitude and result.longitude) or result.boundingbox %}
<small> &bull; <a class="text-info btn-collapse collapsed searx_init_map cursor-pointer disabled_if_nojs" data-toggle="collapse" data-target="#result-map-{{ index }}" data-leaflet-target="osm-map-{{ index }}" data-map-lon="{{ result.longitude }}" data-map-lat="{{ result.latitude }}" {% if result.boundingbox %}data-map-boundingbox='{{ result.boundingbox|tojson|safe }}'{% endif %} {% if result.geojson %}data-map-geojson='{{ result.geojson|tojson|safe }}'{% endif %} data-btn-text-collapsed="{{ _('show map') }}" data-btn-text-not-collapsed="{{ _('hide map') }}">{{ icon('globe') }} {{ _('show map') }}</a></small> <small> &bull; <a class="text-info btn-collapse collapsed searx_init_map cursor-pointer disabled_if_nojs" data-toggle="collapse" data-target="#result-map-{{ index }}" data-leaflet-target="osm-map-{{ index }}" data-map-lon="{{ result.longitude }}" data-map-lat="{{ result.latitude }}" {% if result.boundingbox %}data-map-boundingbox='{{ result.boundingbox|tojson|safe }}'{% endif %} {% if result.geojson %}data-map-geojson='{{ result.geojson|tojson|safe }}'{% endif %} data-btn-text-collapsed="{{ _('show map') }}" data-btn-text-not-collapsed="{{ _('hide map') }}">{{ icon('globe') }} {{ _('show map') }}</a></small>
@ -66,7 +66,7 @@
{% endif %} {% endif %}
{% if rtl %} {% if rtl %}
{{ result_footer_rtl(result) }} {{ result_footer_rtl(result, loop.index) }}
{% else %} {% else %}
{{ result_footer(result) }} {{ result_footer(result, loop.index) }}
{% endif %} {% endif %}

View File

@ -1,7 +1,7 @@
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %} {% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %}
{{ result_header(result, favicons) }} {{ result_header(result, favicons, loop.index) }}
{{ result_sub_header(result) }} {{ result_sub_header(result, loop.index) }}
{% if result.seed is defined %}<p class="result-content">{{ icon('transfer') }} {{ _('Seeder') }} <span class="badge">{{ result.seed }}</span> &bull; {{ _('Leecher') }} <span class="badge">{{ result.leech }}</span>{% endif %} {% if result.seed is defined %}<p class="result-content">{{ icon('transfer') }} {{ _('Seeder') }} <span class="badge">{{ result.seed }}</span> &bull; {{ _('Leecher') }} <span class="badge">{{ result.leech }}</span>{% endif %}
{% if result.filesize %}<br />{{ icon('floppy-disk') }} {{ _('Filesize') }} {% if result.filesize %}<br />{{ icon('floppy-disk') }} {{ _('Filesize') }}
@ -19,7 +19,7 @@
</p> </p>
{% if rtl %} {% if rtl %}
{{ result_footer_rtl(result) }} {{ result_footer_rtl(result, loop.index) }}
{% else %} {% else %}
{{ result_footer(result) }} {{ result_footer(result, loop.index) }}
{% endif %} {% endif %}

View File

@ -1,10 +1,10 @@
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %} {% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %}
{{ result_header(result, favicons) }} {{ result_header(result, favicons, loop.index) }}
{{ result_sub_header(result) }} {{ result_sub_header(result, loop.index) }}
{% if result.embedded %} {% if result.embedded %}
<small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-video-{{ index }}" data-btn-text-collapsed="{{ _('show video') }}" data-btn-text-not-collapsed="{{ _('hide video') }}">{{ icon('film') }} {{ _('show video') }}</a></small> <small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-video-{{ index }}" data-btn-text-collapsed="{{ _('show video') }}" data-btn-text-not-collapsed="{{ _('hide video') }}" aria-labelledby="result-{{loop.index}}">{{ icon('film') }} {{ _('show video') }}</a></small>
{% endif %} {% endif %}
{% if result.embedded %} {% if result.embedded %}
@ -15,7 +15,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ image_proxify(result.thumbnail) }}" /></a> <a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ image_proxify(result.thumbnail) }}" aria-labelledby="result-{{loop.index}}" /></a>
{% if result.author %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Author') }}</b>: {{ result.author }}</p>{% endif %} {% if result.author %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Author') }}</b>: {{ result.author }}</p>{% endif %}
{% if result.length %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Length') }}</b>: {{ result.length }}</p>{% endif %} {% if result.length %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Length') }}</b>: {{ result.length }}</p>{% endif %}
{% if result.content %}<p class="col-xs-12 col-sm-8 col-md-8 result-content">{{ result.content|safe }}</p>{% endif %} {% if result.content %}<p class="col-xs-12 col-sm-8 col-md-8 result-content">{{ result.content|safe }}</p>{% endif %}
@ -23,7 +23,7 @@
</div> </div>
{% if rtl %} {% if rtl %}
{{ result_footer_rtl(result) }} {{ result_footer_rtl(result, loop.index) }}
{% else %} {% else %}
{{ result_footer(result) }} {{ result_footer(result, loop.index) }}
{% endif %} {% endif %}

View File

@ -816,47 +816,61 @@ rst-doc() {
case $DIST_ID-$DIST_VERS in case $DIST_ID-$DIST_VERS in
ubuntu-*|debian-*) cat <<EOF ubuntu-*|debian-*) cat <<EOF
# init.d --> /usr/share/doc/uwsgi/README.Debian.gz
# For uWSGI debian uses the LSB init process, this might be changed
# one day, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=833067
create ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} .. code:: bash
enable: sudo -H ln -s ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} ${uWSGI_APPS_ENABLED}/
start: sudo -H service uwsgi start ${SEARX_UWSGI_APP%.*} # init.d --> /usr/share/doc/uwsgi/README.Debian.gz
restart: sudo -H service uwsgi restart ${SEARX_UWSGI_APP%.*} # For uWSGI debian uses the LSB init process, this might be changed
stop: sudo -H service uwsgi stop ${SEARX_UWSGI_APP%.*} # one day, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=833067
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
create ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}
enable: sudo -H ln -s ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} ${uWSGI_APPS_ENABLED}/
start: sudo -H service uwsgi start ${SEARX_UWSGI_APP%.*}
restart: sudo -H service uwsgi restart ${SEARX_UWSGI_APP%.*}
stop: sudo -H service uwsgi stop ${SEARX_UWSGI_APP%.*}
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
EOF EOF
;; ;;
arch-*) cat <<EOF arch-*) cat <<EOF
# systemd --> /usr/lib/systemd/system/uwsgi@.service
# For uWSGI archlinux uses systemd template units, see
# - http://0pointer.de/blog/projects/instances.html
# - https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP} .. code:: bash
enable: sudo -H systemctl enable uwsgi@${SEARX_UWSGI_APP%.*}
start: sudo -H systemctl start uwsgi@${SEARX_UWSGI_APP%.*} # systemd --> /usr/lib/systemd/system/uwsgi@.service
restart: sudo -H systemctl restart uwsgi@${SEARX_UWSGI_APP%.*} # For uWSGI archlinux uses systemd template units, see
stop: sudo -H systemctl stop uwsgi@${SEARX_UWSGI_APP%.*} # - http://0pointer.de/blog/projects/instances.html
disable: sudo -H systemctl disable uwsgi@${SEARX_UWSGI_APP%.*} # - https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
enable: sudo -H systemctl enable uwsgi@${SEARX_UWSGI_APP%.*}
start: sudo -H systemctl start uwsgi@${SEARX_UWSGI_APP%.*}
restart: sudo -H systemctl restart uwsgi@${SEARX_UWSGI_APP%.*}
stop: sudo -H systemctl stop uwsgi@${SEARX_UWSGI_APP%.*}
disable: sudo -H systemctl disable uwsgi@${SEARX_UWSGI_APP%.*}
EOF EOF
;; ;;
fedora-*) cat <<EOF fedora-*) cat <<EOF
# systemd --> /usr/lib/systemd/system/uwsgi.service
# The unit file starts uWSGI in emperor mode (/etc/uwsgi.ini), see
# - https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP} .. code:: bash
restart: sudo -H touch ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP} # systemd --> /usr/lib/systemd/system/uwsgi.service
# The unit file starts uWSGI in emperor mode (/etc/uwsgi.ini), see
# - https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
restart: sudo -H touch ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
EOF EOF
;; ;;
esac esac
echo -e ".. END searx uwsgi-description $DIST_NAME" echo -e ".. END searx uwsgi-description $DIST_NAME"
echo -e "\n.. START searx uwsgi-appini $DIST_NAME" echo -e "\n.. START searx uwsgi-appini $DIST_NAME"
eval "echo \"$(< "${TEMPLATES}/${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}")\"" echo ".. code:: bash"
echo
eval "echo \"$(< "${TEMPLATES}/${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}")\"" | prefix_stdout " "
echo -e "\n.. END searx uwsgi-appini $DIST_NAME" echo -e "\n.. END searx uwsgi-appini $DIST_NAME"
) )