diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 08aa110d3fd941089728a745a3b93dc8913974e2..0000000000000000000000000000000000000000 --- a/.dockerignore +++ /dev/null @@ -1,37 +0,0 @@ -*~ -*/*~ -*/*/*~ -*/*/*/*~ -*/*/*/*/*~ - -# CI -.codeclimate.yml -.travis.yml -.taskcluster.yml - -# Byte-compiled / optimized / DLL files -__pycache__/ -*/__pycache__/ -*/*/__pycache__/ -*/*/*/__pycache__/ -*.py[cod] -*/*.py[cod] -*/*/*.py[cod] -*/*/*/*.py[cod] - -# to sync with .gitignore -.coverage -coverage/ -.installed.cfg -engines.cfg -env -searx-ve -robot_log.html -robot_output.xml -robot_report.html -test_basic/ -setup.cfg - -node_modules/ - -.tx/ \ No newline at end of file diff --git a/.env b/.env index e01a5e92b2c17396f1f28d4fb3e3c447502fa115..7aa8a06363aa6d1c2e8003eb76442a14a3fb5971 100644 --- a/.env +++ b/.env @@ -1,5 +1,11 @@ SPOT_HOSTNAME=localhost +SPOT_MORTY_HOSTNAME=proxy.localhost +SPOT_MORTY_URL=http://morty.docker SPOT_DOCKER_IMG=registry.gitlab.e.foundation:5000/e/cloud/my-spot SPOT_DOCKER_TAG=latest SPOT_NGINX_DOCKER_IMG=registry.gitlab.e.foundation:5000/e/cloud/my-spot/nginx SPOT_NGINX_DOCKER_TAG=latest +SPOT_FILTRON_DOCKER_IMG=registry.gitlab.e.foundation:5000/e/cloud/my-spot/filtron +SPOT_FILTRON_DOCKER_TAG=latest +SPOT_MORTY_DOCKER_IMG=registry.gitlab.e.foundation:5000/e/cloud/my-spot/morty +SPOT_MORTY_DOCKER_TAG=latest diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index afcaa4c9271b1ed3a1189a706c5acdd00c9c64d4..c3b96ba0ef94f6d06b864c5c5ca954662f610024 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,6 +35,11 @@ build:web: - docker push $CI_REGISTRY_IMAGE - docker build -t $CI_REGISTRY_IMAGE/nginx -f nginx.Dockerfile . - docker push $CI_REGISTRY_IMAGE/nginx + - docker build -t $CI_REGISTRY_IMAGE/filtron -f filtron.Dockerfile . + - docker push $CI_REGISTRY_IMAGE/filtron + - docker build -t $CI_REGISTRY_IMAGE/morty -f morty.Dockerfile . + - docker push $CI_REGISTRY_IMAGE/morty + build:docker:master: extends: .build:docker @@ -48,6 +53,10 @@ build:docker:tags: - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG - docker build -t $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_SLUG -f nginx.Dockerfile . - docker push $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_SLUG + - docker build -t $CI_REGISTRY_IMAGE/filtron:$CI_COMMIT_REF_SLUG -f filtron.Dockerfile . + - docker push $CI_REGISTRY_IMAGE/filtron:$CI_COMMIT_REF_SLUG + - docker build -t $CI_REGISTRY_IMAGE/morty:$CI_COMMIT_REF_SLUG -f morty.Dockerfile . + - docker push $CI_REGISTRY_IMAGE/morty:$CI_COMMIT_REF_SLUG only: - tags @@ -82,7 +91,10 @@ deploy:spot.test.cloud.global: variables: DOCKER_HOST: ssh://root@spot.test.ecloud.global SPOT_HOSTNAME: spot.test.ecloud.global + SPOT_MORTY_HOSTNAME: proxy.spot.test.ecloud.global + SPOT_MORTY_URL: https://proxy.spot.test.ecloud.global COMPOSE_PROJECT_NAME: my-spot + COMPOSE_FILE: docker-compose.yml:docker-compose-build.yml SSH_PRIVATE_KEY: ${SSH_PRIVATE_KEY_TEST} script: - docker-compose up -d --build @@ -97,8 +109,9 @@ deploy:spot.cloud.global: variables: DOCKER_HOST: ssh://root@spot.ecloud.global SPOT_HOSTNAME: spot.ecloud.global + SPOT_MORTY_HOSTNAME: proxy.spot.ecloud.global + SPOT_MORTY_URL: https://proxy.spot.ecloud.global COMPOSE_PROJECT_NAME: my-spot - COMPOSE_FILE: docker-compose.yml:docker-compose-prod.yml SPOT_DOCKER_TAG: ${CI_COMMIT_REF_SLUG} SPOT_NGINX_DOCKER_TAG: ${CI_COMMIT_REF_SLUG} SSH_PRIVATE_KEY: ${SSH_PRIVATE_KEY_PROD} diff --git a/README.md b/README.md index 9c38fd5c75206139975fae6dad9383b13296174a..ba447976eee0ee76a8132103818abb2164353b72 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,27 @@ Spot was forked from searx: read [documentation](https://asciimoo.github.io/sear * docker packaging thinking to be production ready * better locale support +## Architecture + +5 services are used for production: + +* [traefik](https://docs.traefik.io/) as edge router to publish services. +* [filtron](https://github.com/asciimoo/filtron) as reverse HTTP proxy to filter requests by different rules. +* [morty](https://github.com/asciimoo/morty) as proxy to serve thumbnails. +* [nginx](https://www.nginx.com/) as http server to serve static files. +* Spot the meta search engine. + + +```mermaid +graph TD + A(traefik) --> |https://spot.ecloud.global| B(filtron) + A(traefik) --> |https://proxy.spot.ecloud.global| C(morty) + C --> |image link| C + B --> D(nginx) + D --> |static file| D + D --> |API| E(spot) +``` + ## Getting Started You can run spot with docker-compose. First of all you have to install @@ -20,17 +41,16 @@ below to run spot for production or local environment. ### Like production -3 containes are used for production, traefik as edge router, -nginx to server static files and spot as backend. - * Run the docker-compose up command to start the project ``` -docker-compose up --build spot nginx +COMPOSE_FILE=docker-compose.yml:docker-compose-build.yml docker-compose up --build morty +SPOT_MORTY_URL=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-spot_morty_1) +COMPOSE_FILE=docker-compose.yml:docker-compose-build.yml docker-compose up --build spot nginx filtron ``` -* Getting the ip of the nginx service and go to `http://`, below the docker way to get the IP of the nginx container +* Getting the ip of the filtron service and go to `http://`, below the docker way to get the IP of the filtron container ``` -docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-spot_nginx_1 +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-spot_filtron_1 ``` ### For developer @@ -43,4 +63,4 @@ docker run -it --rm -v $(pwd):/ws -w /ws registry.gitlab.e.foundation:5000/e/clo SEARX_DEBUG=1 python -X dev searx/webapp.py ``` -Then go open your browser and navigate to the container IP. +Then, open your browser and navigate to the container IP. diff --git a/docker-compose-build.yml b/docker-compose-build.yml new file mode 100644 index 0000000000000000000000000000000000000000..00d9d36e237acacb3778a58fac2e7953f119f597 --- /dev/null +++ b/docker-compose-build.yml @@ -0,0 +1,20 @@ +version: '3.6' + +services: + spot: + build: . + + nginx: + build: + context: . + dockerfile: nginx.Dockerfile + + filtron: + build: + context: . + dockerfile: filtron.Dockerfile + + morty: + build: + context: . + dockerfile: morty.Dockerfile diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml deleted file mode 100644 index e6937e8400a38b387edd1a07e39b8d16b7fc565a..0000000000000000000000000000000000000000 --- a/docker-compose-prod.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '3.6' - -services: - spot: - image: ${SPOT_DOCKER_IMG}:${SPOT_DOCKER_TAG} - - nginx: - image: ${SPOT_NGINX_DOCKER_IMG}:${SPOT_NGINX_DOCKER_TAG} - diff --git a/docker-compose.yml b/docker-compose.yml index 9090d9d79775f38fe040bf852da88cd424d68e47..103c94849464428c9346eda97d7cf3a29066e1dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,18 +9,25 @@ x-logging: services: spot: - build: . + image: ${SPOT_DOCKER_IMG}:${SPOT_DOCKER_TAG} logging: *default-logging restart: unless-stopped environment: SEARX_SECRET: ":@)%NN0+OqNdy:{prWQlZ{p9|oO9p-UyJq@%V!~G:arrSx6fXz.{jd%=XF44ncj" + SEARX_MORTY_URL: "${SPOT_MORTY_URL}" + SEARX_MORTY_KEY: "${SEARX_MORTY_KEY:-KHN0ZGluKT0gNWNmNzQ0Y2JlNjI4MDRjODAwZGUyMGY5ZjZlZTFmZWI1NTg2YTg5OAo=}" GUNICORN_LOGGER: 1 GUNICORN_LEVEL: INFO nginx: - build: - context: . - dockerfile: nginx.Dockerfile + image: ${SPOT_NGINX_DOCKER_IMG}:${SPOT_NGINX_DOCKER_TAG} + logging: *default-logging + restart: unless-stopped + environment: + SPOT_MORTY_URL: "${SPOT_MORTY_URL}" + + filtron: + image: ${SPOT_FILTRON_DOCKER_IMG}:${SPOT_FILTRON_DOCKER_TAG} logging: *default-logging restart: unless-stopped labels: @@ -32,8 +39,18 @@ services: - "traefik.http.routers.http-catchall.entrypoints=web" - "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - - "traefik.http.middlewares.spot-ratelimit.ratelimit.average=50" - - "traefik.http.middlewares.spot-ratelimit.ratelimit.burst=20" + + morty: + image: ${SPOT_MORTY_DOCKER_IMG}:${SPOT_MORTY_DOCKER_TAG} + logging: *default-logging + restart: unless-stopped + environment: + SEARX_MORTY_KEY: "${SEARX_MORTY_KEY:-KHN0ZGluKT0gNWNmNzQ0Y2JlNjI4MDRjODAwZGUyMGY5ZjZlZTFmZWI1NTg2YTg5OAo=}" + labels: + - "traefik.enable=true" + - "traefik.http.routers.spot_proxy.rule=Host(`${SPOT_MORTY_HOSTNAME}`)" + - "traefik.http.routers.spot_proxy.entrypoints=websecure" + - "traefik.http.routers.spot_proxy.tls.certresolver=spotchallenge" traefik: image: "traefik:v2.1.2" diff --git a/etc/filtron/rules.json b/etc/filtron/rules.json new file mode 100644 index 0000000000000000000000000000000000000000..8d708513485fa9d537f8638e7d35aa0798903d63 --- /dev/null +++ b/etc/filtron/rules.json @@ -0,0 +1,120 @@ +[ + { + "name": "stats.searx.xyz", + "interval": 300, + "limit": 10, + "filters": ["Header:X-Forwarded-For=(2a01:4f8:161:542e::2|5.9.58.49)"], + "stop": true, + "actions": [{ "name": "log"}] + }, + { + "name": "IP limit, all paths", + "interval": 3, + "limit": 25, + "aggregations": ["Header:X-Forwarded-For"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded, try again later."}} + ] + }, + { + "name": "useragent limit, all paths", + "interval": 30, + "limit": 200, + "aggregations": ["Header:X-Forwarded-For", "Header:User-Agent"], + "stop": true, + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded, try again later."}} + ] + }, + { + "name": "search request", + "filters": ["Param:q", "Path=^(/|/search)$"], + "subrules": [ + { + "name": "robot agent forbidden", + "limit": 0, + "stop": true, + "filters": ["Header:User-Agent=([Cc][Uu][Rr][Ll]|[wW]get|Scrapy|splash|JavaFX|FeedFetcher|python-requests|Go-http-client|Java|Jakarta|okhttp|HttpClient|Jersey|Python|libwww-perl|Ruby|SynHttpClient|UniversalFeedParser)"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded"}} + ] + }, + { + "name": "bot forbidden", + "limit": 0, + "stop": true, + "filters": ["Header:User-Agent=(Googlebot|GoogleImageProxy|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT|Sogou|Abonti|Pixray|Spinn3r|SemrushBot|Exabot|ZmEu|BLEXBot|bitlybot)"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded"}} + ] + }, + { + "name": "block missing accept-language", + "filters": ["!Header:Accept-Language"], + "limit": 0, + "stop": true, + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded"}} + ] + }, + { + "name": "block Connection:close", + "filters": ["Header:Connection=close"], + "limit": 0, + "stop": true, + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded"}} + ] + }, + { + "name": "block accept everything", + "filters": ["!Header:Accept=text/html"], + "limit": 0, + "stop": true, + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded"}} + ] + }, + { + "name": "rss/json limit", + "interval": 3600, + "limit": 4, + "stop": true, + "filters": ["Param:format=(csv|json|rss)"], + "aggregations": ["Header:X-Forwarded-For"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded, try again later."}} + ] + }, + { + "name": "IP limit", + "interval": 3, + "limit": 3, + "aggregations": ["Header:X-Forwarded-For"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded, try again later."}} + ] + }, + { + "name": "IP and useragent limit", + "interval": 600, + "limit": 60, + "stop": true, + "aggregations": ["Header:X-Forwarded-For", "Header:User-Agent"], + "actions": [ + {"name": "block", + "params": {"message": "Rate limit exceeded, try again later."}} + ] + } + ] + } +] diff --git a/etc/nginx/conf.d/spot.conf b/etc/nginx/conf.d/spot.conf index 90af2a927a72a85d0f7f8523ea853c3e3e174b73..b18e4da98137b0c64c70b9d52f9ac6d0d4b9d51c 100644 --- a/etc/nginx/conf.d/spot.conf +++ b/etc/nginx/conf.d/spot.conf @@ -4,12 +4,13 @@ server { listen 80; server_name _; - add_header Content-Security-Policy "frame-ancestors 'self'"; add_header Referrer-Policy "no-referrer, strict-origin-when-cross-origin"; - add_header Strict-Transport-Security "max-age=31536000"; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; + add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self'; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src 'self' __SPOT_MORTY_URL__ data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com"; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; + add_header X-Robots-Tag "noindex, noarchive, nofollow"; root /var/www/spot; diff --git a/filtron.Dockerfile b/filtron.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..cb28d921ebb07f85c97de681b709059062db816b --- /dev/null +++ b/filtron.Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.13-alpine as builder + +RUN apk add git && go get github.com/asciimoo/filtron + + +FROM alpine:3.11 + +COPY --from=builder /go/bin/filtron /usr/bin/filtron +COPY etc/filtron/rules.json /etc/filtron/rules.json + +EXPOSE 80 +CMD ["filtron", "-listen", ":80", "-rules", "/etc/filtron/rules.json", "-target", "nginx"] diff --git a/morty.Dockerfile b/morty.Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..984947f6fc8912a474d8b66293a98b42f20182a9 --- /dev/null +++ b/morty.Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.13-alpine as builder + +RUN apk add git && go get github.com/asciimoo/morty + + +FROM alpine:3.11 + +COPY --from=builder /go/bin/morty /usr/bin/morty + +EXPOSE 80 +CMD ["morty", "-listen", ":80", "-timeout", "5", "-ipv6"] diff --git a/nginx-docker-entrypoint.sh b/nginx-docker-entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..02aa89f47b58137919b822612641cd2c88d99eb1 --- /dev/null +++ b/nginx-docker-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +if [ -n "$SPOT_MORTY_URL" ]; then + sed -i 's!__SPOT_MORTY_URL__!'$SPOT_MORTY_URL'!g' /etc/nginx/conf.d/default.conf +fi + +exec "$@" diff --git a/nginx.Dockerfile b/nginx.Dockerfile index 16328ed59f78c571e44205539fde5b34f13345a0..1dafef7cc7403f8400708657a9935be431da60c7 100644 --- a/nginx.Dockerfile +++ b/nginx.Dockerfile @@ -4,3 +4,7 @@ COPY etc/nginx/conf.d/spot.conf /etc/nginx/conf.d/default.conf COPY etc/nginx/proxy_spot_params /etc/nginx/proxy_spot_params RUN sed -i 's!remote_addr!http_x_forwarded_for!g' /etc/nginx/nginx.conf COPY --chown=nginx:nginx searx/static /var/www/spot/static +COPY nginx-docker-entrypoint.sh /docker-entrypoint.sh + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["nginx", "-g", "daemon off;"] diff --git a/searx/__init__.py b/searx/__init__.py index 2d7a03301ebe7198eb2bf82b6ecdcb581cd3d5fa..682fc98bd50122857f2651062c3df66fd7a8d99f 100644 --- a/searx/__init__.py +++ b/searx/__init__.py @@ -100,3 +100,7 @@ if 'SEARX_SECRET' in environ: settings['server']['secret_key'] = environ['SEARX_SECRET'] if 'SEARX_BIND_ADDRESS' in environ: settings['server']['bind_address'] = environ['SEARX_BIND_ADDRESS'] +if 'SEARX_MORTY_URL' in environ: + settings.setdefault('result_proxy', {})['url'] = environ['SEARX_MORTY_URL'] +if 'SEARX_MORTY_KEY' in environ: + settings.setdefault('result_proxy', {})['key'] = bytes(environ['SEARX_MORTY_KEY'], 'utf-8') diff --git a/searx/settings.yml b/searx/settings.yml index fa58d1a993b21143c71877e38e7f3ade9b72f901..cc12969b5955d6c9ab546996ad08caff0ad381e2 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -13,7 +13,7 @@ server: bind_address : "0.0.0.0" # address to listen on secret_key : "ultrasecretkey" # change this! base_url : False # Set custom base_url. Possible values: False or "https://your.custom.host/location/" - image_proxy : False # Proxying image results through searx + image_proxy : True # Proxying image results through searx http_protocol_version : "1.0" # 1.0 and 1.1 are supported ui: @@ -91,6 +91,7 @@ engines: - name : bing engine : bing shortcut : bi + disabled : True - name : bing images engine : bing_images @@ -197,7 +198,6 @@ engines: - name : duckduckgo engine : duckduckgo shortcut : ddg - disabled : True - name : duckduckgo images engine : duckduckgo_images @@ -292,6 +292,7 @@ engines: - name : google engine : google shortcut : go + disabled : True - name : google images engine : google_images @@ -536,7 +537,6 @@ engines: engine : qwant shortcut : qw categories : general - disabled : True - name : qwant images engine : qwant diff --git a/searx/static/themes/eelo/js/searx.js b/searx/static/themes/eelo/js/searx.js index 1f5b9e7eb8a5ae26f1f5d26238825f004a1d024b..ec0c9cab34c590d919754fd1d3f0d719f9c58ec7 100644 --- a/searx/static/themes/eelo/js/searx.js +++ b/searx/static/themes/eelo/js/searx.js @@ -88,34 +88,37 @@ $(document).ready(function(){ }); } }); -; -function configure_image_view(target) { - document.getElementById("image_view_image").src = target.href; - document.getElementById("image_view_file_link").href = target.href; - document.getElementById("image_view_url_link").href = target.dataset.url; -} - -function show_image_view_modal(event) { - event.preventDefault(); - var target = event.target; - if (target.tagName == "IMG") { - target = target.parentElement; +;$(document).ready(function(){ + function configure_image_view(target, view_url) { + document.getElementById("image_view_image").src = view_url; + document.getElementById("image_view_file_link").href = target.href; + document.getElementById("image_view_url_link").href = target.dataset.url; } - var modal = document.getElementById("image_view_modal"); - modal.classList.remove("hidden"); - modal.style.top = window.scrollY + "px"; - configure_image_view(target); - document.body.classList.add("lock"); -} + $(".result.result-images").click(function (event) { + event.preventDefault(); + var target = event.target; + var view_url = target.src; + if (target.tagName == "IMG") { + target = target.parentElement; + } -function close_image_view_modal() { - document.getElementById("image_view_modal").classList.add("hidden"); - document.getElementById("image_view_image").src = ""; - document.getElementById("image_view_file_link").href = "#"; - document.getElementById("image_view_url_link").href = "#"; - document.body.classList.remove("lock"); -};/** + var modal = document.getElementById("image_view_modal"); + modal.classList.remove("hidden"); + modal.style.top = window.scrollY + "px"; + configure_image_view(target, view_url); + document.body.classList.add("lock"); + }); + + $("#close_image_view_modal").click(function () { + document.getElementById("image_view_modal").classList.add("hidden"); + document.getElementById("image_view_image").src = ""; + document.getElementById("image_view_file_link").href = "#"; + document.getElementById("image_view_url_link").href = "#"; + document.body.classList.remove("lock"); + }); +}); +;/** * searx 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 diff --git a/searx/static/themes/eelo/js/searx.min.js b/searx/static/themes/eelo/js/searx.min.js index d9dd67f9a71c04650813a1178c1b69fd8371136a..28d6dcd927c5f6cf56be8fb10f9dc984c41ab70c 100644 Binary files a/searx/static/themes/eelo/js/searx.min.js and b/searx/static/themes/eelo/js/searx.min.js differ diff --git a/searx/static/themes/eelo/js/searx_src/custom.js b/searx/static/themes/eelo/js/searx_src/custom.js index 848300231bf61937934a6108eeee8add263a1364..9a6bc1f0f33871d85e402ff65c98b0369b03402e 100644 --- a/searx/static/themes/eelo/js/searx_src/custom.js +++ b/searx/static/themes/eelo/js/searx_src/custom.js @@ -1,28 +1,30 @@ - -function configure_image_view(target) { - document.getElementById("image_view_image").src = target.href; - document.getElementById("image_view_file_link").href = target.href; - document.getElementById("image_view_url_link").href = target.dataset.url; -} - -function show_image_view_modal(event) { - event.preventDefault(); - var target = event.target; - if (target.tagName == "IMG") { - target = target.parentElement; +$(document).ready(function(){ + function configure_image_view(target, view_url) { + document.getElementById("image_view_image").src = view_url; + document.getElementById("image_view_file_link").href = target.href; + document.getElementById("image_view_url_link").href = target.dataset.url; } - var modal = document.getElementById("image_view_modal"); - modal.classList.remove("hidden"); - modal.style.top = window.scrollY + "px"; - configure_image_view(target); - document.body.classList.add("lock"); -} + $(".result.result-images").click(function (event) { + event.preventDefault(); + var target = event.target; + var view_url = target.src; + if (target.tagName == "IMG") { + target = target.parentElement; + } + + var modal = document.getElementById("image_view_modal"); + modal.classList.remove("hidden"); + modal.style.top = window.scrollY + "px"; + configure_image_view(target, view_url); + document.body.classList.add("lock"); + }); -function close_image_view_modal() { - document.getElementById("image_view_modal").classList.add("hidden"); - document.getElementById("image_view_image").src = ""; - document.getElementById("image_view_file_link").href = "#"; - document.getElementById("image_view_url_link").href = "#"; - document.body.classList.remove("lock"); -} \ No newline at end of file + $("#close_image_view_modal").click(function () { + document.getElementById("image_view_modal").classList.add("hidden"); + document.getElementById("image_view_image").src = ""; + document.getElementById("image_view_file_link").href = "#"; + document.getElementById("image_view_url_link").href = "#"; + document.body.classList.remove("lock"); + }); +}); diff --git a/searx/templates/eelo/base.html b/searx/templates/eelo/base.html index cb2ab9c1b5398f9f7424da6a3e3df5c13af8ac22..7b56a553cab3d4a4ce90de1e6411cca9a0c2fb10 100644 --- a/searx/templates/eelo/base.html +++ b/searx/templates/eelo/base.html @@ -66,7 +66,7 @@