Compare commits

...

73 Commits

Author SHA1 Message Date
Fijxu 517839ae24 Merge remote-tracking branch 'librey/main' into librey 2023-09-29 02:33:28 -03:00
Ahwx 4e363c3500
fix: onion address for supernets (merge pull request #60 from codedipper/add-instances4)
supernets onion
2023-09-28 23:15:35 +02:00
Revvy 420949d4b7
supernets onion 2023-09-25 20:13:45 -04:00
Ahwx 217601aa49
feat: add/remove instances (merge pull request #56 from codedipper/add-instances3)
add/remove instances
2023-09-22 23:59:10 +02:00
Revvy b01219c8c6
add/remove instances 2023-09-21 20:52:38 -04:00
Ahwx d92989ed6c
feat: adding instance (merge pull request #53 from codedipper/add-instances2)
Add librex.supernets.org
2023-09-17 12:06:43 +02:00
Revvy 6867fcceb6
librex.supernets.org 2023-09-16 20:40:44 -04:00
Ahwx 0cd23c8e0d
feat: adding pulldown (merge pull request #50 from davidovski/language_dropdown)
Language selection dropdown
2023-09-09 19:46:12 +02:00
Ahwx d64b917077
fix: typo so duckduckgo works again (merge pull request #51 from davidovski/fix_duckduckgo)
Fix typo in duckduckgo
2023-09-09 16:04:23 +02:00
davidovski 049272c043 Fix typo in duckduckgo 2023-09-09 14:45:29 +01:00
davidovski e99670628d Use languages list to generate dropdown in settings 2023-09-09 14:28:04 +01:00
davidovski 6a1dea2581 Use language list for wikipedia 2023-09-09 14:07:34 +01:00
Ahwx d0499bafc0
feat(instances.json): adding @Ahwxorg's 2nd instance in france 2023-09-07 18:18:07 +02:00
Ahwx 5512e5da80
feat(auto_updater.sh): adding auto updater like LibreX used to have 2023-09-07 17:59:39 +02:00
Ahwx 5e2cc89816
fix: edit domain for benike.me (merge pull request #46 from drinkmonster/main)
edit domain
2023-09-07 00:56:49 +02:00
Ahwx efe057ac03
fix: moving logic to printing results (merge pull request #48 from davidovski/frontend_passing)
Moving logic to printing results
2023-09-07 00:55:05 +02:00
davidovski fa07f21f56 Move base_url parsing to print results 2023-09-06 12:23:59 +01:00
davidovski c70436b257 Move checking for frontends to printing instead of parsing 2023-09-06 12:07:38 +01:00
Berényi Bence f79e4f5026
edit domain 2023-09-06 08:47:12 +02:00
Ahwx c9ff9a0de8
feat(instances.json): add librey.baczek.me 2023-09-05 23:42:06 +02:00
Ahwx 2fc6bfe7af
feat(xmr-ahwx.png): adding ahwx' xmr' qr code 2023-09-05 15:50:00 +02:00
Ahwx 43234d6d87
feat(donate.php): adding xmr and qr for ahwx 2023-09-05 15:49:05 +02:00
Ahwx 0e30c8a93a
ci: adding support for multi-arch docker images (merge pull request #44 from mentos1386/patch-1)
ci: multi-arch docker images
2023-09-04 12:21:52 +02:00
Tine Jozelj 3e00dbd788
ci: multi-arch docker images
based on https://docs.docker.com/build/ci/github-actions/multi-platform/
2023-09-03 23:38:39 +02:00
Ahwx 530fbf5a26
style: minor ui improvements on donate page (merge pull request #43 from osarthak/update-donate)
update donate ui && fix footer links margin
2023-09-03 23:07:57 +02:00
Ahwx 66b66a52f7
fix: update instances list to redirect to official instances which generate from json (merge pull request #42 from codedipper/update-readme)
update instance list on readme
2023-09-03 23:06:45 +02:00
Ahwx 97203e72a8
feat: adding more flags to example docker-compose.yaml (merge pull request #41 from codedipper/compose-fix)
update default compose
2023-09-03 23:03:50 +02:00
osarthak 7d260df145 update donate ui && fix footer links margin 2023-09-03 17:56:18 +05:30
Revvy 158a7e0296
more changes 2023-09-02 22:56:39 -04:00
Revvy 30a8802eae
more changes 2023-09-02 22:54:49 -04:00
Revvy aa9f46dbbd
more changes 2023-09-02 22:51:54 -04:00
Revvy ea51467714
update instance list on readme 2023-09-02 22:45:27 -04:00
Revvy ee9f7d8447
update default compose 2023-09-02 22:23:23 -04:00
Ahwx 9361117f09
fix(docker-compose.yml): Add "docs" for Watchtower 2023-09-02 22:33:48 +02:00
Ahwx 2ed2370219
fix(instances.json): fixing order; feat: add watchtower to automatically pull newest image upon release (merge pull request #38 from codedipper/watchtower)
watchtower, fix instances.json order
2023-09-02 22:31:43 +02:00
Revvy 94de6a116b
typo in docker readme 2023-09-02 00:15:52 -04:00
Revvy f73a3f0ff9
fix instances.json order 2023-09-02 00:13:52 -04:00
Revvy 5a8672c150
add watchtower 2023-09-02 00:12:13 -04:00
Ahwx 514c290b46
chore: update instances; feat: docker stuff (merge pull request #37 from codedipper/man)
Update instances, Update Docker configs & docs
2023-09-01 23:08:48 +02:00
Revvy 0c7224a67a
some security headers 2023-09-01 08:19:15 -04:00
Revvy 90f07bceeb
fix default for cache ttl docker 2023-08-31 10:40:14 -04:00
Revvy 5e37afdd12
add cache ttl to docker 2023-08-31 10:39:04 -04:00
Revvy f718c36e45
update cocker configs and docs 2023-08-31 10:22:55 -04:00
Revvy 123b3bfcd4
update instances 2023-08-31 10:18:38 -04:00
Ahwx b8869a217e
feat(SECURITY.md): add something like a security policy 2023-08-31 14:09:39 +02:00
Ahwx dd8df71abd
feat: cache results to combat spammers (merge pull request #34 from davidovski/results_caching)
Results caching
2023-08-31 14:07:17 +02:00
Ahwx 68b5de6bd6
fix: some minor css padding; feat: add instance (merge pull request #36 from whoisYoges/CastorFixes)
Fixed Some CSS and Added a New Instance
2023-08-31 10:41:29 +02:00
Castor 7c31b07811
`Add:` instance to readme 2023-08-31 10:49:09 +05:45
Castor 9f75502627
`Add:` a new libreY instance 2023-08-31 10:25:20 +05:45
Castor 407a4dcb74
`Fix:` indentation for search settings. 2023-08-31 10:23:36 +05:45
Castor 063b6ea608
`Updated:` spacing between instance list and footer. 2023-08-31 10:12:23 +05:45
Ahwx 6c5474c93f
chore: update instances (merge pull request #35 from codedipper/add-instances3)
add/remove instances
2023-08-30 23:18:26 +02:00
davidovski 4a98228a90 Properly remove google request if on cooldown 2023-08-30 22:06:36 +01:00
Ahwx a9ead078ea
fix: docker stuff (merge pull request #33 from nohoster/docker-update)
Docker update
2023-08-30 23:01:03 +02:00
davidovski 37f77e5e8d set default language 2023-08-30 21:47:22 +01:00
Ahwx 0f50470821
fix: ads sometimes show up with ddg (merge pull request #32 from codedipper/ad-ddg-fix)
fix when ads sometimes show up with ddg
2023-08-30 22:46:08 +02:00
davidovski bfe699d5ad Do not throw error if duckduck go query fails 2023-08-30 21:40:30 +01:00
davidovski f8f30323ee do not avoid request if cached 2023-08-30 21:19:50 +01:00
davidovski 01fe983009 curl follow location by default 2023-08-30 21:06:09 +01:00
davidovski 73c5b4b98e fix not respecting cooldown 2023-08-30 21:00:00 +01:00
davidovski 9d431ae8c0 Actually exec fallback requests 2023-08-30 20:50:23 +01:00
Revvy dd41f423ac
add/remove instances 2023-08-30 14:18:49 -04:00
davidovski ad747d51a1 Make fallback work when no results found 2023-08-30 18:11:17 +01:00
davidovski a33f26a638 Add no instances message 2023-08-30 17:50:56 +01:00
davidovski 12f02198f9 Add no results messages 2023-08-30 17:26:34 +01:00
davidovski a00da6eb65 Fix typo 2023-08-30 16:07:35 +01:00
davidovski aaf111abf7 Always do no fallback on fallback requests 2023-08-30 16:05:31 +01:00
davidovski 4da025948b fix missing $ 2023-08-30 14:00:44 +01:00
davidovski 4488200d22 Add ttl on caches 2023-08-30 13:58:47 +01:00
davidovski a8c4f4e609 Use caching for all requests 2023-08-30 13:50:01 +01:00
nohoster efce4e387e fixed var 2023-08-29 20:01:34 -06:00
Revvy 46fe062bd3
fix when ads sometimes show up with ddg 2023-08-29 21:58:27 -04:00
nohoster f9430475bf Updated and simplified the docker building setup 2023-08-29 19:49:11 -06:00
53 changed files with 640 additions and 434 deletions

10
.dockerignore Normal file
View File

@ -0,0 +1,10 @@
.github/
.git/
.gitignore
.dockerignore
config.php.example
docker-compose.yml
Dockerfile
opensearch.xml.example
README.md
docker-old/

View File

@ -22,10 +22,14 @@ jobs:
uses: ASzc/change-string-case-action@v5
with:
string: ${{ github.event.repository.name }}
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/build-push-action@v4
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/${{ steps.owner.outputs.lowercase }}/${{ steps.repo.outputs.lowercase }}:latest

View File

@ -1,10 +1,10 @@
# syntax = edrevo/dockerfile-plus
ARG VERSION="3.18"
FROM alpine:${VERSION} AS librey
FROM alpine:3.18
WORKDIR "/var/www/html"
ADD "." "."
# Docker metadata contains information about the maintainer, such as the name, repository, and support email
# Please add any necessary information or correct any incorrect information
# See more: https://docs.docker.com/config/labels-custom-metadata/
LABEL name="LibreY" \
description="Framework and javascript free privacy respecting meta search engine" \
@ -18,28 +18,25 @@ LABEL name="LibreY" \
# Change or add new arguments to customize the image generated by 'docker build' command
ARG DOCKER_SCRIPTS="docker"
ARG NGINX_PORT=8080
# Set this argument during build time to indicate that the path is for php's www.conf
ARG WWW_CONFIG="/etc/php82/php-fpm.d/www.conf"
# Customize the environment during both execution and build time by modifying the environment variables added to the container's shell
# When building your image, make sure to set the 'TZ' environment variable to your desired time zone location, for example 'America/Sao_Paulo'
# See more: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
ENV TZ="America/New_York"
RUN apk add gettext --no-cache
# Install required packages
RUN apk add gettext php82 php82-fpm php82-dom php82-curl php82-json php82-apcu nginx --no-cache
# The following lines import all Dockerfiles from other folders so that they can be built together in the final build
INCLUDE+ docker/php/php.dockerfile
INCLUDE+ docker/server/nginx.dockerfile
# Include docker scripts, docker images, and the 'GNU License' in the LibreY container
ADD "." "/var/www/html"
# Set permissions for script files as executable scripts inside 'docker/scripts' directory
RUN chmod u+x "${DOCKER_SCRIPTS}/php/prepare.sh" &&\
chmod u+x "${DOCKER_SCRIPTS}/server/prepare.sh" &&\
chmod u+x "${DOCKER_SCRIPTS}/entrypoint.sh" &&\
chmod u+x "${DOCKER_SCRIPTS}/attributes.sh"
# Configure PHP-FPM to listen on a Unix socket instead of a TCP port, which is more secure and efficient
RUN touch /run/php-fpm82.sock && chown nginx:nginx "/run/php-fpm82.sock"
RUN sed -i 's/^\s*listen = 127.0.0.1:9000/listen = \/run\/php-fpm82.sock/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.owner = nobody/listen.owner = nginx/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.group = nobody/listen.group = nginx/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.mode = 0660/listen.mode = 0660/' ${WWW_CONFIG}
EXPOSE ${NGINX_PORT}
# Configures the container to be run as an executable.
ENTRYPOINT ["/bin/sh", "-c", "docker/entrypoint.sh"]
ENTRYPOINT ["/bin/sh", "-c", "docker/entrypoint.sh"]

View File

@ -15,17 +15,22 @@
### Instances
> If you host using CloudFlare, this will be mentioned in the instances list.
You can access the full list of LibreX and LibreY instances on one of the following updated LibreY instances:
| Clearnet | TOR | I2P | Country |
|-|-|-|-|
| [search.ahwx.org](https://search.ahwx.org/) | [](http://hyy7rcvknwb22v4nnoar635wntiwr4uwzhiuyimemyl4fz6k7tahj5id.onion) | ❌ | 🇳🇱 NL |
| [librex.me](https://librex.me/) | [](http://librex.revvybrr6pvbx4n3j4475h4ghw4elqr4t5xo2vtd3gfpu2nrsnhh57id.onion/) | [](http://revekebotog64xrrammtsmjwtwlg3vqyzwdurzt2pu6botg4bejq.b32.i2p/) | 🇨🇦 CA |
| [librex.revvy.de](https://librex.revvy.de/) | [](http://librex.revvybrr6pvbx4n3j4475h4ghw4elqr4t5xo2vtd3gfpu2nrsnhh57id.onion/) | [](http://revekebotog64xrrammtsmjwtwlg3vqyzwdurzt2pu6botg4bejq.b32.i2p/) | 🇨🇦 CA |
| [search.davidovski.xyz](https://search.davidovski.xyz/) | ❌ | ❌ | 🇬🇧 GB |
| [librey.nohost.network](https://librey.nohost.network/) | ❌ | ❌ | 🇲🇽 MX |
You can find a list of instances on any LibreY instance by accessing /instances.php.<br>
Alternatively look at `instances.json` where the list is generated from.<br><br>
While the official instances may be more updated and have better uptime, please consider using another person's instances as these are heavily overloaded.<br>
Support the community. ❤️<br><br>
Instance list on [@codedipper](https://github.com/codedipper)'s instance:<br>
[librex.me](https://librex.me/instances.php)<br>
[librex.revvy.de](https://librex.revvy.de/instances.php)<br>
[Tor](http://librex.revvybrr6pvbx4n3j4475h4ghw4elqr4t5xo2vtd3gfpu2nrsnhh57id.onion/instances.php)<br>
[I2P](http://revekebotog64xrrammtsmjwtwlg3vqyzwdurzt2pu6botg4bejq.b32.i2p/instances.php)<br>
<br>
[@Ahwxorg](https://github.com/Ahwxorg)'s instance:<br>
[search.ahwx.org](https://search.ahwx.org/instances.php)<br>
[Tor](http://hyy7rcvknwb22v4nnoar635wntiwr4uwzhiuyimemyl4fz6k7tahj5id.onion/instances.php)<br>
<br>
[@davidovski](https://github.com/davidovski)'s instance:<br>
[search.davidovski.xyz](https://search.davidovski.xyz/instances.php)<br>
<br>

9
SECURITY.md Normal file
View File

@ -0,0 +1,9 @@
# Security Policy
## Supported Versions
Basically the latest commit. We don't really do versioning with LibreY.
## Reporting a Vulnerability
Please join #librey:ahwx.org on Matrix and please DM me (@ahwx:ahwx.org) or if Matrix is absolutely impossible, email me; ahwx *at* ahwx *dot* org

6
auto_updater.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh
while true; do
git stash
git pull
sleep 60
done

View File

@ -23,6 +23,9 @@
// how long in minutes to put google/other instances on cooldown if they aren't responding
"request_cooldown" => 25,
// how long in minutes to store results for in the cache
"cache_time" => 20,
/*
Preset privacy friendly frontends for users, these can be overwritten by users in the settings
e.g.: Preset the invidious instance URL: "instance_url" => "https://yewtu.be",

View File

@ -1,23 +1,32 @@
version: "2.1"
version: "3"
services:
librey:
image: ahwxorg/librey:latest
image: ghcr.io/ahwxorg/librey:latest
container_name: librey
network_mode: bridge
ports:
- 8080:8080
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
- TZ=America/New_York
- CONFIG_GOOGLE_DOMAIN=com
- CONFIG_GOOGLE_LANGUAGE_SITE=en
- CONFIG_GOOGLE_LANGUAGE_RESULTS=en
- CONFIG_TEXT_SEARCH_ENGINE=google
- CONFIG_LANGUAGE=en
- CONFIG_NUMBER_OF_RESULTS=10
- CONFIG_INVIDIOUS_INSTANCE=https://invidious.snopyta.org
- CONFIG_DISABLE_BITTORRENT_SEARCH=false
- CONFIG_HIDDEN_SERVICE_SEARCH=false
- CONFIG_INSTANCE_FALLBACK=true
- CONFIG_WIKIPEDIA_LANGUAGE=en
- CONFIG_RATE_LIMIT_COOLDOWN=25
- CONFIG_CACHE_TIME=20
- CONFIG_TEXT_SEARCH_ENGINE=google
- CURLOPT_PROXY_ENABLED=false
- CURLOPT_PROXY=192.0.2.53:8388
- CURLOPT_PROXYTYPE=CURLPROXY_HTTP
- CURLOPT_USERAGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:116.0) Gecko/20100101 Firefox/116.0
- CURLOPT_FOLLOWLOCATION=true
volumes:
- ./nginx_logs:/var/log/nginx
- ./php_logs:/var/log/php7
restart: unless-stopped
watchtower: # Watchtower is not required but highly recommended, since Watchtower will re-pull and restart the LibreY container automatically whenever there's an update.
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock

View File

@ -3,15 +3,14 @@
- [Introduction](#introduction)
- [Running a docker container](#running-a-docker-container)
- [Running a Docker container through the Docker hub](#running-a-docker-container-through-the-docker-hub)
- [Running a Docker container through ghcr](#running-a-docker-container-through-ghcr)
- [Running a Docker container with composer](#running-a-docker-container-with-composer)
- [Environment variables that can be set in the Docker container](#environment-variables-that-can-be-set-in-the-docker-container)
- [OpenSearch](#opensearch)
- [Search Config](#search-config)
- [Wikipedia](#wikipedia)
- [Applications](#applications)
- [Engines](#engines)
- [Curl](#curl)
- [Search Configuration](#search)
- [Frontend Configuration](#frontends)
- [Search Engine Configuration](#engines)
- [cURL Configuration](#curl)
- [OpenSearch Configuration](#opensearch)
- [Docker version issues](#docker-version-issues)
- [Building a docker image](#building-a-docker-image)
- [Support for different architectures](#support-for-different-architectures)
@ -20,7 +19,7 @@
Dockerized librey is a way to provide users with yet another way to self-host their own projects with a view to privacy. If you wish to help, please start by looking for bugs in used docker configurations.
### Running a Docker container through the Docker hub
### Running a Docker container through ghcr
To run librey in a docker container, you can simply use the command:
@ -32,7 +31,15 @@ docker run -d \
-e CONFIG_GOOGLE_LANGUAGE="en" \
-e CONFIG_WIKIPEDIA_LANGUAGE="en" \
-p 8080:8080 \
librey/librey:latest
ghcr.io/ahwxorg/librey:latest
```
Also run with watchtower for auto-updating: (optional)
```sh
docker run -d \
--name librey-watchtower-1 \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
```
<br>
@ -40,26 +47,38 @@ docker run -d \
### Running a Docker container with composer
```yml
version: "2.1"
version: "3"
services:
librey:
image: librey/librey:latest
image: ghcr.io/ahwxorg/librey:latest
container_name: librey
network_mode: bridge
ports:
- 8080:8080
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
- TZ="America/New_York"
- CONFIG_GOOGLE_DOMAIN="com"
- CONFIG_GOOGLE_LANGUAGE="en"
- CONFIG_WIKIPEDIA_LANGUAGE="en"
- CONFIG_GOOGLE_DOMAIN=com
- CONFIG_LANGUAGE=en
- CONFIG_NUMBER_OF_RESULTS=10
- CONFIG_INVIDIOUS_INSTANCE=https://invidious.snopyta.org
- CONFIG_DISABLE_BITTORRENT_SEARCH=false
- CONFIG_HIDDEN_SERVICE_SEARCH=false
- CONFIG_INSTANCE_FALLBACK=true
- CONFIG_RATE_LIMIT_COOLDOWN=25
- CONFIG_CACHE_TIME=20
- CONFIG_TEXT_SEARCH_ENGINE=google
- CURLOPT_PROXY_ENABLED=false
- CURLOPT_PROXY=192.0.2.53:8388
- CURLOPT_PROXYTYPE=CURLPROXY_HTTP
- CURLOPT_USERAGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:116.0) Gecko/20100101 Firefox/116.0
- CURLOPT_FOLLOWLOCATION=true
volumes:
- ./nginx_logs:/var/log/nginx
- ./php_logs:/var/log/php7
restart: unless-stopped
watchtower: # Watchtower is not required but highly recommended, since Watchtower will re-pull and restart the LibreY container automatically whenever there's an update.
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
<br>
@ -70,53 +89,25 @@ This docker image was developed with high configurability in mind, so here is th
<br>
### OpenSearch
### Search
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| OPEN_SEARCH_TITLE | "LibreY" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_DESCRIPTION | "Framework and javascript free privacy respecting meta search engine" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_ENCODING | "UTF-8" | "UTF-8" | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_LONG_NAME | "librey Search" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_HOST | "http://localhost:8080" | string | Host used to identify librey on the network |
<br>
### Search Config
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| CONFIG_GOOGLE_DOMAIN | "com" | "com", "com.br", "com.es" | Defines which Google domain the search will be done, change according to your country |
| CONFIG_GOOGLE_LANGUAGE | "en" | "pt", "es", "ru" | Defines the language in which searches will be done, see the list of supported languages [here](https://developers.google.com/custom-search/docs/ref_languages). |
| CONFIG_GOOGLE_NUMBER_OF_RESULTS | "10" | "10", "20", "30" | Number of results for Google to return each page. |
| CONFIG_GOOGLE_DOMAIN | "com" | "com", "com.br", "cat", "se" | Defines which Google domain the search will be done on, change according to your country. |
| CONFIG_LANGUAGE | "en" | "zh-Hans", "fil", "no" | Defines the language in which searches will be done, see the list of supported languages [here](https://developers.google.com/custom-search/docs/ref_languages). |
| CONFIG_NUMBER_OF_RESULTS | 10 | integer | Number of results for Google to return each page. |
| CONFIG_INVIDIOUS_INSTANCE | "https://invidious.snopyta.org" | string | Defines the host that will be used to do video searches using Invidious. |
| CONFIG_DISABLE_BITTORRENT_SEARCH | false | boolean | Defines whether bittorrent search will be disabled |
| CONFIG_BITTORRENT_TRACKERS | "&tr=http://nyaa.tracker.wf:7777/announce&tr=udp://open.stealth.si:80/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://exodus.desync.com:6969/announce&tr=udp://tracker.torrent.eu.org:451/announce" | string | Set list of bittorrent trackers for torrent search. |
| CONFIG_HIDDEN_SERVICE_SEARCH | false | boolean | Defines whether hidden service search will be disabled |
| CONFIG_INSTANCE_FALLBACK | true | boolean | Choose whether or not to use the API on the backend to request to another LibreX/Y instance in case of rate limiting. |
| CONFIG_INVIDIOUS_INSTANCE | "https://invidious.namazso.eu" | string | Defines the host that will be used to do video searches using invidious |
| CONFIG_HIDDEN_SERVICE_SEARCH | false | boolean | Defines whether safesearch will be enabled or disabled |
| CONFIG_DISABLE_BITTORRENT_SEARCH | false | boolean | Defines whether bittorrent support will be enabled or disabled |
| CONFIG_BITTORRENT_TRACKERS | "http://nyaa.tracker.wf:7777/announce" | string | Bittorrent trackers, see the complete example in the `config.php` file. |
<br>
### Wikipedia
| CONFIG_RATE_LIMIT_COOLDOWN | 25 | integer | Time in minutes to wait before sending requests to Google again after a rate limit. |
| CONFIG_CACHE_TIME | 20 | integer | Time in minutes to store results for in the cache. |
### Frontends
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| CONFIG_WIKIPEDIA_LANGUAGE | "en" | "pt", "es", "hu" | Adds language support for Wikipedia results |
<br>
### Engines
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| CONFIG_TEXT_SEARCH_ENGINE | "google" | "google", "duckduckgo" | Change your text search engine. |
<br>
### Applications
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| APP_INVIDIOUS | "" | string | Integration with external self-hosted apps, configure the desired host. |
| APP_INVIDIOUS | "" | "https://example.com", string | Integration with external self-hosted apps, configure the desired host. |
| APP_RIMGO | "" | string | Integration with external self-hosted apps, configure the desired host. |
| APP_SCRIBE | "" | string | Integration with external self-hosted apps, configure the desired host. |
| APP_GOTHUB | "" | string | Integration with external self-hosted apps, configure the desired host. |
@ -131,22 +122,37 @@ This docker image was developed with high configurability in mind, so here is th
| APP_SUDS | "" | string | Integration with external self-hosted apps, configure the desired host. |
| APP_BIBLIOREADS | "" | string | Integration with external self-hosted apps, configure the desired host. |
<br>
### Curl
### Engines
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| CONFIG_TEXT_SEARCH_ENGINE | "google" | "google", "duckduckgo" | Integration with external self-hosted apps, configure the desired host. |
### cURL
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| CURLOPT_PROXY_ENABLED | false | boolean | If you want to use a proxy, you need to set this variable to true. |
| CURLOPT_PROXY | "" | "127.0.0.1:8080" | Set the proxy using the ip and port to be used |
| CURLOPT_PROXYTYPE | "CURLPROXY_HTTP" | "CURLPROXY_SOCKS4A" "CURLPROXY_SOCKS5" "CURLPROXY_SOCKS5_HOSTNAME" | Set the type of proxy connection (if you enabled it). |
| CURLOPT_RETURNTRANSFER | true | boolean | **TODO** |
| CURLOPT_ENCODING | "" | string | Defines the encode that curl should use to display the texts correctly |
| CURLOPT_USERAGENT | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" | string | This variable defines the 'User-Agent' that curl will use to attempt to avoid being blocked |
| CURLOPT_CUSTOMREQUEST | "GET" | "HEAD", "OPTIONS" | Defines the HTTP method that curl will use to make the request |
| CURLOPT_MAXREDIRS | 5 | number | **TODO** |
| CURLOPT_TIMEOUT | 18 | number | Sets the maximum time curl will wait for a response before timing out |
| CURLOPT_VERBOSE | false | boolean | Specifies whether curl should display detailed information on stdout about the request and response when making requests. Setting to 'true' enables verbose mode |
| CURLOPT_PROXY | "" | "192.0.2.53:8388" | Set the proxy using the ip and port to be used. |
| CURLOPT_PROXYTYPE | "CURLPROXY_HTTP" | "CURLPROXY_SOCKS4A", "CURLPROXY_SOCKS5", "CURLPROXY_SOCKS5_HOSTNAME" | Set the type of proxy connection (if you enabled it). |
| CURLOPT_RETURNTRANSFER | true | boolean | Return the transfer as a string of the return value of curl_exec() instead of outputting it directly. |
| CURLOPT_ENCODING | "" | string | Return the transfer as a string of the return value of curl_exec() instead of outputting it directly. |
| CURLOPT_USERAGENT | "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:116.0) Gecko/20100101 Firefox/116.0" | string | This variable defines the 'User-Agent' that curl will use to attempt to avoid being blocked. |
| CURLOPT_IPRESOLVE | "CURL_IPRESOLVE_WHATEVER" | "CURL_IPRESOLVE_V4", "CURL_IPRESOLVE_V6" | Use a fixed IP version for making requests, or what DNS prefers. |
| CURLOPT_CUSTOMREQUEST | "GET" | "POST", "CONNECT" | Defines the HTTP method that curl will use to make the request. |
| CURLOPT_MAXREDIRS | 5 | integer | The maximum amount of HTTP redirections to follow, only enabled with CURLOPT_FOLLOWLOCATION. |
| CURLOPT_TIMEOUT | 3 | integer | The maximum amount of time for cURL requests to complete. |
| CURLOPT_VERBOSE | false | boolean | Whether to output verbose information. |
| CURLOPT_FOLLOWLOCATION | true | boolean | Whether to follow any Location header. Required for instance fallback. |
### OpenSearch
| Variables | Default | Examples | Description |
|:----------|:-------------|:---------|:------|
| OPEN_SEARCH_TITLE | "LibreY" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_DESCRIPTION | "Framework and javascript free privacy respecting meta search engine" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_ENCODING | "UTF-8" | "UTF-8" | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_LONG_NAME | "LibreY Search" | string | [OpenSearch XML](https://developer.mozilla.org/en-US/docs/Web/OpenSearch) |
| OPEN_SEARCH_HOST | "http://localhost:80" | string | Host used to identify librey on the network |
<br>
@ -190,7 +196,7 @@ docker build -t librey:latest .
Supported architectures for the official librey images include the same ones supported by Alpine itself, which are typically denoted as `linux/386`, `linux/amd64`, `linux/arm/v6`. If you need support for a different architecture, such as `linux/arm/v7`, you can modify the 'Dockerfile' to use a more comprehensive base image like `ubuntu:latest` instead.
In this case, you must run the `build` process specifying the desired architecture as shown in the example below:
In this case, you must run the `buildx` process specifying the desired architecture as shown in the example below:
```sh
docker buildx build \

View File

@ -19,19 +19,16 @@ export OPEN_SEARCH_HOST=${OPEN_SEARCH_HOST:-"127.0.0.1"}
# Replace the 'config.php' script, which contains the most common search engine configurations, with these environment setups
# These environment setups can be found in 'config.php', and the default configurations can be useful for most use cases
export CONFIG_GOOGLE_DOMAIN="${CONFIG_GOOGLE_DOMAIN:-"com"}"
export CONFIG_GOOGLE_LANGUAGE_SITE="${CONFIG_GOOGLE_LANGUAGE_SITE:-"en"}"
export CONFIG_GOOGLE_LANGUAGE_RESULTS="${CONFIG_GOOGLE_LANGUAGE_RESULTS:-"en"}"
export CONFIG_GOOGLE_NUMBER_OF_RESULTS="${CONFIG_GOOGLE_NUMBER_OF_RESULTS:-"10"}"
export CONFIG_INSTANCE_FALLBACK="${CONFIG_INSTANCE_FALLBACK:-true}"
export CONFIG_INVIDIOUS_INSTANCE="${CONFIG_INVIDIOUS_INSTANCE:-"invidious.snopyta.org"}"
export CONFIG_HIDDEN_SERVICE_SEARCH=${CONFIG_HIDDEN_SERVICE_SEARCH:-false}
export CONFIG_GOOGLE_DOMAIN=${CONFIG_GOOGLE_DOMAIN:-"com"}
export CONFIG_LANGUAGE=${CONFIG_LANGUAGE:-"en"}
export CONFIG_NUMBER_OF_RESULTS=${CONFIG_NUMBER_OF_RESULTS:-10}
export CONFIG_INVIDIOUS_INSTANCE=${CONFIG_INVIDIOUS_INSTANCE:-"https://invidious.snopyta.org"}
export CONFIG_DISABLE_BITTORRENT_SEARCH=${CONFIG_DISABLE_BITTORRENT_SEARCH:-false}
export CONFIG_BITTORRENT_TRACKERS="${CONFIG_BITTORRENT_TRACKERS:-"&tr=http://nyaa.tracker.wf:7777/announce&tr=udp://open.stealth.si:80/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://exodus.desync.com:6969/announce&tr=udp://tracker.torrent.eu.org:451/announce"}"
# The settings that will be used to handle Wikipedia results displayed on the librey search page
# the settings below can be edited via environment variables.
export CONFIG_WIKIPEDIA_LANGUAGE=${CONFIG_WIKIPEDIA_LANGUAGE:-${CONFIG_GOOGLE_LANGUAGE}}
export CONFIG_BITTORRENT_TRACKERS=${CONFIG_BITTORRENT_TRACKERS:-"&tr=http://nyaa.tracker.wf:7777/announce&tr=udp://open.stealth.si:80/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://exodus.desync.com:6969/announce&tr=udp://tracker.torrent.eu.org:451/announce"}
export CONFIG_HIDDEN_SERVICE_SEARCH=${CONFIG_HIDDEN_SERVICE_SEARCH:-false}
export CONFIG_INSTANCE_FALLBACK="${CONFIG_INSTANCE_FALLBACK:-true}"
export CONFIG_RATE_LIMIT_COOLDOWN="${CONFIG_RATE_LIMIT_COOLDOWN:-25}"
export CONFIG_CACHE_TIME="${CONFIG_CACHE_TIME:-20}"
# Supported apps integration configuration. These empty spaces can be set up using free hosts as pointers
# A particular example is using the "https://yewtu.be" or a self-hosted host to integrate the invidious app to librey
@ -59,11 +56,13 @@ export CURLOPT_PROXY=${CURLOPT_PROXY:-""}
export CURLOPT_PROXYTYPE=${CURLOPT_PROXYTYPE:-"CURLPROXY_HTTP"}
export CURLOPT_RETURNTRANSFER=${CURLOPT_RETURNTRANSFER:-true}
export CURLOPT_ENCODING=${CURLOPT_ENCODING:-""}
export CURLOPT_USERAGENT="${CURLOPT_USERAGENT:-"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"}"
export CURLOPT_USERAGENT=${CURLOPT_USERAGENT:-"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:116.0) Gecko/20100101 Firefox/116.0"}
export CURLOPT_IPRESOLVE=${CURLOPT_IPRESOLVE:-"CURL_IPRESOLVE_WHATEVER"}
export CURLOPT_CUSTOMREQUEST="${CURLOPT_CUSTOMREQUEST:-"GET"}"
export CURLOPT_MAXREDIRS=${CURLOPT_MAXREDIRS:-5}
export CURLOPT_TIMEOUT=${CURLOPT_TIMEOUT:-18}
export CURLOPT_TIMEOUT=${CURLOPT_TIMEOUT:-3}
export CURLOPT_VERBOSE=${CURLOPT_VERBOSE:-true}
export CURLOPT_FOLLOWLOCATION=${CURLOPT_FOLLOWLOCATION:-true}
# These shell functions will be available for use by any function calls
function AwkTrim() { awk '{$1=$1};1'; }

View File

@ -1,17 +1,16 @@
<?php
return (object) array(
"google_domain" => "${CONFIG_GOOGLE_DOMAIN}",
"google_language_site" => "${CONFIG_GOOGLE_LANGUAGE_SITE}",
"google_language_results" => "${CONFIG_GOOGLE_LANGUAGE_RESULTS}",
"google_number_of_results" => "${CONFIG_GOOGLE_NUMBER_OF_RESULTS}",
"wikipedia_language" => "${CONFIG_WIKIPEDIA_LANGUAGE}",
"language" => "${CONFIG_LANGUAGE}",
"number_of_results" => ${CONFIG_NUMBER_OF_RESULTS},
"invidious_instance_for_video_results" => "${CONFIG_INVIDIOUS_INSTANCE}",
"disable_bittorent_search" => ${CONFIG_DISABLE_BITTORRENT_SEARCH},
"bittorent_trackers" => "${CONFIG_BITTORRENT_TRACKERS}",
"disable_hidden_service_search" => ${CONFIG_HIDDEN_SERVICE_SEARCH},
"instance_fallback" => ${CONFIG_INSTANCE_FALLBACK},
"request_cooldown" => ${CONFIG_RATE_LIMIT_COOLDOWN},
"cache_time" => ${CONFIG_CACHE_TIME},
"frontends" => array(
"invidious" => array(
@ -34,7 +33,7 @@
),
"gothub" => array(
"instance_url" => "${APP_GOTHUB}",
"project_url" => "https://codeberg.org/gothub/gothub/wiki/Instances",
"project_url" => "https://codeberg.org/gothub/gothub#instances",
"original_name" => "GitHub",
"original_url" => "github.com"
),
@ -44,10 +43,9 @@
"original_name" => "Twitter",
"original_url" => "twitter.com"
),
"libreddit" => array(
"instance_url" => "${APP_LIBREREDDIT}",
"project_url" => "https://github.com/spikecodes/libreddit",
"project_url" => "https://github.com/libreddit/libreddit-instances/blob/master/instances.md",
"original_name" => "Reddit",
"original_url" => "reddit.com"
),
@ -61,23 +59,23 @@
"instance_url" => "${APP_WIKILESS}",
"project_url" => "https://github.com/Metastem/wikiless#instances",
"original_name" => "Wikipedia",
"original_url" => "wikipedia.com"
"original_url" => "wikipedia.org"
),
"quetre" => array(
"instance_url" => "${APP_QUETRE}",
"project_url" => "https://github.com/zyachel/quetre",
"project_url" => "https://github.com/zyachel/quetre#instances",
"original_name" => "Quora",
"original_url" => "quora.com"
),
"libremdb" => array(
"instance_url" => "${APP_LIBREMDB}",
"project_url" => "https://github.com/zyachel/libremdb",
"project_url" => "https://github.com/zyachel/libremdb#instances",
"original_name" => "IMDb",
"original_url" => "imdb.com"
),
"breezewiki" => array(
"instance_url" => "${APP_BREEZEWIKI}",
"project_url" => "https://gitdab.com/cadence/breezewiki",
"project_url" => "https://docs.breezewiki.com/Links.html",
"original_name" => "Fandom",
"original_url" => "fandom.com"
),
@ -101,23 +99,25 @@
)
),
"preferred_engines" => array(
"text" => "${CONFIG_TEXT_SEARCH_ENGINE}"
),
"curl_settings" => array(
CURLOPT_PROXY => "${CURLOPT_PROXY}",
CURLOPT_PROXYTYPE => "${CURLOPT_PROXYTYPE}",
CURLOPT_PROXYTYPE => ${CURLOPT_PROXYTYPE},
CURLOPT_RETURNTRANSFER => ${CURLOPT_RETURNTRANSFER},
CURLOPT_ENCODING => "${CURLOPT_ENCODING}",
CURLOPT_USERAGENT => "${CURLOPT_USERAGENT}",
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_WHATEVER,
CURLOPT_IPRESOLVE => ${CURLOPT_IPRESOLVE},
CURLOPT_CUSTOMREQUEST => "${CURLOPT_CUSTOMREQUEST}",
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP,
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP,
CURLOPT_MAXREDIRS => ${CURLOPT_MAXREDIRS},
CURLOPT_TIMEOUT => ${CURLOPT_TIMEOUT},
CURLOPT_VERBOSE => ${CURLOPT_VERBOSE}
CURLOPT_VERBOSE => ${CURLOPT_VERBOSE},
CURLOPT_FOLLOWLOCATION => ${CURLOPT_FOLLOWLOCATION}
)
);
?>

View File

@ -1,10 +1,7 @@
#!/bin/sh
# Due to an issue with Docker's 'CMD' directive, the following scripts are not executing as expected.
# This workaround has been implemented to resolve the issue for now
sh "docker/php/prepare.sh"
sh "docker/server/prepare.sh"
/bin/sh -c docker/env-substitution.sh
/bin/sh -c /usr/sbin/php-fpm8
/bin/sh -c /usr/sbin/php-fpm82
exec nginx -g "daemon off;"

View File

@ -1,23 +1,24 @@
#!/bin/sh
echo "[PREPARE] docker/server/prepare.sh'"
# Load all environment variables from 'attributes.sh' using the command 'source /path/attributes.sh'
source "docker/attributes.sh"
# This condition creates the Unix socket if 'php-fpm8.sock' does not already exist.
# This fixes an issue where Nginx starts but does not serve content
if [ ! -d "/run/php8" ] || [ ! -S "/run/php8/php-fpm8.sock" ]; then
mkdir "/run/php8"
touch "/run/php8/php-fpm8.sock"
chmod 660 "/run/php8/php-fpm8.sock"
chown nginx:nginx "/run/php8/php-fpm8.sock"
fi
# The lines below will replace the environment variables in the templates with the corresponding variables listed above. To accomplish this, the GNU 'envsubst' package will be used
# The lines below will replace the environment variables in the templates with the corresponding variables listed above if the config file is not yet provided. To accomplish this, the GNU 'envsubst' package will be used
# Although not recommended (if you do not know what you are doing), you still have the option to add new substitution file templates using any required environment variables
[[ ! -s ${CONFIG_PHP_TEMPLATE} ]] && cat 'docker/php/config.php' | envsubst > ${CONFIG_PHP_TEMPLATE};
[[ ! -s ${CONFIG_OPEN_SEARCH_TEMPLATE} ]] && cat 'docker/php/opensearch.xml' | envsubst > ${CONFIG_OPEN_SEARCH_TEMPLATE};
[[ ! -s ${CONFIG_PHP_TEMPLATE} ]] && cat 'docker/config.php' | envsubst > ${CONFIG_PHP_TEMPLATE};
[[ ! -s ${CONFIG_OPEN_SEARCH_TEMPLATE} ]] && cat 'docker/opensearch.xml' | envsubst > ${CONFIG_OPEN_SEARCH_TEMPLATE};
export OPEN_SEARCH_HOST_FOR_NGINX="$(echo "${OPEN_SEARCH_HOST}" | cut -d "/" -f 3 | cut -d ":" -f 1)"
if [[ ! -s ${CONFIG_NGINX_TEMPLATE} ]]; then
cat 'docker/nginx.conf' | envsubst '${OPEN_SEARCH_HOST_FOR_NGINX}' > ${CONFIG_NGINX_TEMPLATE};
mv "docker/fastcgi.conf" /etc/nginx/fastcgi.conf
chown nginx:nginx "/etc/nginx/fastcgi.conf"
chown nginx:nginx "/etc/nginx/http.d/librey.conf"
fi
# If it is empty or proxy is not enabled, we are using sed to delete
# any line that contains the string 'CURLOPT_PROXY' or 'CURLOPT_PROXYTYPE'

View File

@ -2,6 +2,10 @@ server {
listen 8080;
server_name ${OPEN_SEARCH_HOST_FOR_NGINX} localhost;
add_header Content-Security-Policy "default-src 'none'; style-src 'self'; img-src 'self'";
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff";
root /var/www/html;
index index.php;
@ -10,7 +14,7 @@ server {
}
location ~ \.php$ {
fastcgi_pass unix:/run/php8/php-fpm8.sock;
fastcgi_pass unix:/run/php-fpm82.sock;
fastcgi_index index.php;
include fastcgi.conf;
}

View File

@ -1,65 +0,0 @@
# Set this argument during build time to indicate that the path is for php's www.conf
ARG WWW_CONFIG="/etc/php8/php-fpm.d/www.conf"
# Configure 'opensearch.xml' with librey configuration metadata, such as the encoding and the host that stores the site
# These configurations will replace the 'opensearch.xml' inside '.dockers/templates' for the best setup for your instance
ENV OPEN_SEARCH_TITLE="LibreY"
ENV OPEN_SEARCH_DESCRIPTION="Framework and javascript free privacy respecting meta search engine"
ENV OPEN_SEARCH_ENCODING="UTF-8"
ENV OPEN_SEARCH_LONG_NAME="LibreY search"
ENV OPEN_SEARCH_HOST="http://127.0.0.1:${NGINX_PORT}"
# Replace the 'config.php' script, which contains the most common search engine configurations, with these environment setups
# These environment setups can be found in 'config.php', and the default configurations can be useful for most use cases
ENV CONFIG_GOOGLE_DOMAIN="com"
ENV CONFIG_GOOGLE_LANGUAGE_SITE="en"
ENV CONFIG_GOOGLE_LANGUAGE_RESULTS="en"
ENV CONFIG_GOOGLE_NUMBER_OF_RESULTS="10"
ENV CONFIG_INSTANCE_FALLBACK=true
ENV CONFIG_INVIDIOUS_INSTANCE="https://invidious.snopyta.org"
ENV CONFIG_HIDDEN_SERVICE_SEARCH=false
ENV CONFIG_DISABLE_BITTORRENT_SEARCH=false
ENV CONFIG_BITTORRENT_TRACKERS="&tr=http://nyaa.tracker.wf:7777/announce&tr=udp://open.stealth.si:80/announce&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://exodus.desync.com:6969/announce&tr=udp://tracker.torrent.eu.org:451/announce"
# Supported apps integration configuration. These empty spaces can be set up using free hosts as pointers
# A particular example is using the "https://yewtu.be" or a self-hosted host to integrate the invidious app to librey
ENV APP_INVIDIOUS=""
ENV APP_RIMGO=""
ENV APP_SCRIBE=""
ENV APP_GOTHUB=""
ENV APP_NITTER=""
ENV APP_LIBREREDDIT=""
ENV APP_PROXITOK=""
ENV APP_WIKILESS=""
ENV APP_QUETRE=""
ENV APP_LIBREMDB=""
ENV APP_BREEZEWIKI=""
ENV APP_ANONYMOUS_OVERFLOW=""
ENV APP_SUDS=""
ENV APP_BIBLIOREADS=""
# Preferred search engines.
ENV CONFIG_TEXT_SEARCH_ENGINE="google"
# GNU/Curl configurations. Leave 'CURLOPT_PROXY' blank whether you don't need to use a proxy for requests
# Generally, a proxy is needed when your IP address is blocked by search engines in response to multiple requests within a short time frame. In these cases, it is recommended to use rotating proxies
ENV CURLOPT_PROXY_ENABLED=false
ENV CURLOPT_PROXY=""
ENV CURLOPT_PROXYTYPE="CURLPROXY_HTTP"
ENV CURLOPT_RETURNTRANSFER=true
ENV CURLOPT_ENCODING=""
ENV CURLOPT_USERAGENT="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
ENV CURLOPT_CUSTOMREQUEST="GET"
ENV CURLOPT_MAXREDIRS=5
ENV CURLOPT_TIMEOUT=18
ENV CURLOPT_VERBOSE=true
# Install PHP-FPM using Alpine's package manager, apk
# Configure PHP-FPM to listen on a Unix socket instead of a TCP port, which is more secure and efficient
RUN apk add php8 php8-fpm php8-dom php8-curl php8-json php8-apcu --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing &&\
sed -i 's/^\s*listen = 127.0.0.1:9000/listen = \/run\/php8\/php-fpm8.sock/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.owner = nobody/listen.owner = nginx/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.group = nobody/listen.group = nginx/' ${WWW_CONFIG} &&\
sed -i 's/^\s*;\s*listen.mode = 0660/listen.mode = 0660/' ${WWW_CONFIG}
CMD [ "/bin/sh", "-c", "docker/php/prepare.sh" ]

View File

@ -1,9 +0,0 @@
# Install Nginx with FastCGI enabled, optimizing its performance for serving content
RUN apk add nginx
# Forward request and error logs to docker log collector
# RUN ln -sf /dev/stdout /var/log/nginx/access.log &&\
# ln -sf /dev/stderr /var/log/nginx/error.log
# After executing the 'docker run' command, run the 'prepare.sh' script
CMD [ "/bin/sh", "-c", "docker/server/prepare.sh" ]

View File

@ -1,21 +0,0 @@
#!/bin/sh
echo "[PREPARE] docker/server/prepare.sh'"
# Load all environment variables from 'attributes.sh' using the command 'source /path/attributes.sh'
source "docker/attributes.sh"
export OPEN_SEARCH_HOST_FOR_NGINX="$(echo "${OPEN_SEARCH_HOST}" | cut -d "/" -f 3 | cut -d ":" -f 1)"
# The lines below will replace the environment variables in the templates with the corresponding variables listed above. To accomplish this, the GNU 'envsubst' package will be used
# Although not recommended (if you do not know what you are doing), you still have the option to add new substitution file templates using any required environment variables
if [[ ! -s ${CONFIG_NGINX_TEMPLATE} ]]; then
cp "docker/server/fastcgi.conf" /etc/nginx/fastcgi.conf
cp "docker/server/nginx.conf" /etc/nginx/http.d/librey.conf
# To address issues with 'nginx.conf', the following lines will ensure that these configurations remain executable
chmod u+x "/etc/nginx/fastcgi.conf"
chmod u+x "/etc/nginx/http.d/librey.conf"
cat 'docker/server/nginx.conf' | envsubst '${OPEN_SEARCH_HOST_FOR_NGINX}' > ${CONFIG_NGINX_TEMPLATE};
fi

View File

@ -7,16 +7,86 @@
<title>LibreY - Donate</title>
</head>
<body>
<div class="misc-container">
<h1>Donate to the original developer of LibreX, a project LibreY tries to improve.</h1>
<h2>Bitcoin (BTC):</h2>
<p>bc1qs43kh6tvhch02dtsp7x7hcrwj8fwe4rzy7lp0h</p>
<img src="static/images/btc.png" alt="btc qr code" width="150" height="150"/>
<h2>Monero (XMR):</h2>
<p>41dGQr9EwZBfYBY3fibTtJZYfssfRuzJZDSVDeneoVcgckehK3BiLxAV4FvEVJiVqdiW996zvMxhFB8G8ot9nBFqQ84VkuC</p>
<img src="static/images/xmr.png" alt="xmr qr code" width="150" height="150"/>
<h1>Donate to the person that forked LibreX into LibreY</h1>
<a href="https://ahwx.org/donate.php">Click here</a>
<div class="donate-container">
<!-- librex dev -->
<h2>
Donate to the original developer of Libre<span class="Y">X</span>, a
project LibreY tries to improve.
</h2>
<div class="flexbox-column">
<div class="qr-box">
<div class="inner-wrap">
<h3>Bitcoin [BTC]</h3>
<p>bc1qs43kh6tvhch02dtsp7x7hcrwj8fwe4rzy7lp0h</p>
</div>
<img
src="/static/images/btc.png"
height="160"
width="160"
alt="btc qr code"
/>
</div>
<div class="qr-box">
<div class="inner-wrap">
<h3>Monero [XMR]</h3>
<p>
41dGQr9EwZBfYBY3fibTtJZYfssfRuzJZDSVDeneoVcgckehK3BiLxAV4FvEVJiVqdiW996zvMxhFB8G8ot9nBFqQ84VkuC
</p>
</div>
<img
src="/static/images/xmr.png"
height="160"
width="160"
alt="xmr qr code (hnhx)"
/>
</div>
<hr class="small-line" />
<!-- librey dev -->
<h2>
Donate to the person that forked LibreX into Libre<span class="Y"
>Y</span
>
</h2>
<div class="qr-box">
<div class="inner-wrap">
<h3>Monero [XMR]</h3>
<p>
4ArntPzKpu32s4z2XqYhyaY1eUeUBKtCzJqEqxWtF5mCi5vR6sdhh32Hd2fk9FjeUxYDtaaUexUqoRNxrgfrtuXs4XpgMNJ
</p>
</div>
<img
src="/static/images/xmr-ahwx.png"
height="160"
width="160"
alt="xmr qr code (ahwx)"
/>
</div>
<div class="flex-row">
<a href="https://ko-fi.com/Ahwxorg" target="_blank"
><img
src="/static/images/kofi.png"
alt="kifi img"
height="50"
width="auto"
/></a>
<a href="https://www.buymeacoffee.com/ahwx" target="_blank">
<img
src="/static/images/buy-me-a-coffee.png"
height="50"
width="auto"
alt="buy-me-a-coffee img"
/></a>
</div>
</div>
</div>
<?php require "misc/footer.php"; ?>

View File

@ -6,8 +6,7 @@
return "https://ahmia.fi/search/?q=" . urlencode($this->query);
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$results = array();
$xpath = get_xpath($response);
@ -24,6 +23,7 @@
array (
"title" => $title ? htmlspecialchars($title) : "No description provided",
"url" => htmlspecialchars($url),
// base_url is to be removed in the future, see #47
"base_url" => htmlspecialchars(get_base_url($url)),
"description" => htmlspecialchars($description)
)
@ -33,8 +33,8 @@
return $results;
}
public static function print_results($results) {
TextSearch::print_results($results);
public static function print_results($results, $opts) {
TextSearch::print_results($results, $opts);
}
}
?>

View File

@ -5,9 +5,7 @@
return "https://1337x.to/search/$query/1/";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$xpath = get_xpath($response);
$results = array();

View File

@ -21,7 +21,7 @@
);
}
public function get_results() {
public function parse_results($response) {
$results = array();
foreach ($this->requests as $request) {
if ($request->successful())
@ -34,7 +34,7 @@
return $results;
}
public static function print_results($results) {
public static function print_results($results, $opts) {
echo "<div class=\"text-result-container\">";
if (empty($results)) {

View File

@ -6,8 +6,7 @@
return "https://$this->SOURCE/?q=" . urlencode($this->query);
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$xpath = get_xpath($response);
$results = array();

View File

@ -4,8 +4,7 @@
return "http://rutor.info/search/" . urlencode($this->query);
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$xpath = get_xpath($response);
$results = array();

View File

@ -4,8 +4,7 @@
return "https://apibay.org/q.php?q=" . urlencode($this->query);
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$results = array();
$json_response = json_decode($response, true);

View File

@ -5,8 +5,7 @@
return "https://torrentgalaxy.to/torrents.php?search=$query#results";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$xpath = get_xpath($response);
$results = array();

View File

@ -4,9 +4,8 @@
return "https://yts.mx/api/v2/list_movies.json?query_term=" . urlencode($this->query);
}
public function get_results() {
public function parse_results($response) {
$response = curl_multi_getcontent($this->ch);
global $config;
$results = array();
$json_response = json_decode($response, true);

View File

@ -6,16 +6,14 @@
return "$this->instance_url/api/v1/search?q=$query";
}
public function get_results() {
public function parse_results($response) {
$results = array();
$response = curl_multi_getcontent($this->ch);
$json_response = json_decode($response, true);
foreach ($json_response as $response) {
if ($response["type"] == "video") {
$title = $response["title"];
$url = "https://youtube.com/watch?v=" . $response["videoId"];
$url = check_for_privacy_frontend($url, $this->opts);
$uploader = $response["author"];
$views = $response["viewCount"];
$date = $response["publishedText"];
@ -25,6 +23,7 @@
array (
"title" => htmlspecialchars($title),
"url" => htmlspecialchars($url),
// base_url is to be removed in the future, see #47
"base_url" => htmlspecialchars(get_base_url($url)),
"uploader" => htmlspecialchars($uploader),
"views" => htmlspecialchars($views),
@ -38,13 +37,14 @@
return $results;
}
public static function print_results($results) {
public static function print_results($results, $opts) {
echo "<div class=\"text-result-container\">";
foreach($results as $result) {
$title = $result["title"];
$url = $result["url"];
$base_url = $result["base_url"];
$url = check_for_privacy_frontend($url, $opts);
$base_url = get_base_url($url);
$uploader = $result["uploader"];
$views = $result["views"];
$date = $result["date"];

View File

@ -7,11 +7,10 @@
}
public function get_request_url() {
return $this->instance . "api.php?" . opts_to_params($this->opts);
return $this->instance . "api.php?" . opts_to_params($this->opts) . "&nfb=1";
}
public function get_results() {
$response = curl_exec($this->ch);
public function parse_results($response) {
$response = json_decode($response, true);
if (!$response)
return array();
@ -47,13 +46,17 @@
$instance = array_pop($instances);
if (!$instance)
break;
if (parse_url($instance)["host"] == parse_url($_SERVER['HTTP_HOST'])["host"])
continue;
$librex_request = new LibreXFallback($instance, $opts, null);
$results = $librex_request->get_results();
if (count($results) > 1)
if (!empty($results))
return $results;
// on fail then do this
@ -62,7 +65,11 @@
} while (!empty($instances));
return array();
return array(
"error" => array(
"message" => "No results found. Unable to fallback to other instances."
)
);
}
?>

View File

@ -7,9 +7,9 @@
return "https://lite.qwant.com/?q=$query&t=images&p=$page";
}
public function get_results() {
public function parse_results($response) {
$results = array();
$xpath = get_xpath(curl_multi_getcontent($this->ch));
$xpath = get_xpath($response);
if (!$xpath)
return $results;
@ -24,7 +24,6 @@
$encoded_url_split1 = explode("==/", $encoded_url)[1];
$encoded_url_split2 = explode("?position", $encoded_url_split1)[0];
$real_url = urldecode(base64_decode($encoded_url_split2));
$real_url = check_for_privacy_frontend($real_url, $this->opts);
$alt = $image->getAttribute("alt");
$thumbnail = urlencode($image->getAttribute("src"));
@ -43,7 +42,7 @@
return $results;
}
public static function print_results($results) {
public static function print_results($results, $opts) {
echo "<div class=\"image-result-container\">";
foreach($results as $result)
@ -51,6 +50,7 @@
$thumbnail = urlencode($result["thumbnail"]);
$alt = $result["alt"];
$url = $result["url"];
$url = check_for_privacy_frontend($url, $opts);
echo "<a title=\"$alt\" href=\"$url\" target=\"_blank\">";
echo "<img src=\"image_proxy.php?url=$thumbnail\">";

View File

@ -4,9 +4,7 @@
return "https://cdn.moneyconvert.net/api/latest.json";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$split_query = explode(" ", $this->query);
$base_currency = strtoupper($split_query[1]);

View File

@ -8,9 +8,7 @@
return "https://api.dictionaryapi.dev/api/v2/entries/en/$word_to_define";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$json_response = json_decode($response, true);
if (!array_key_exists("title", $json_response))

View File

@ -1,6 +1,6 @@
<?php
class IPRequest extends EngineRequest {
function get_results() {
public function parse_results($response) {
return array(
"special_response" => array(
"response" => $_SERVER["REMOTE_ADDR"],

View File

@ -5,9 +5,7 @@
return "https://check.torproject.org/torbulkexitlist";
}
public function get_results() {
$response = curl_multi_getcontent($ch);
public function parse_results($response) {
$formatted_response = strpos($response, $_SERVER["REMOTE_ADDR"]) ? "It seems like you are using Tor" : "It seems like you are not using Tor";
$source = "https://check.torproject.org";

View File

@ -1,6 +1,6 @@
<?php
class UserAgentRequest extends EngineRequest {
function get_results() {
public function parse_results($response) {
return array(
"special_response" => array(
"response" => $_SERVER["HTTP_USER_AGENT"],

View File

@ -4,8 +4,7 @@
return "https://wttr.in/@" . $_SERVER["REMOTE_ADDR"] . "?format=j1";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$json_response = json_decode($response, true);
if (!$json_response)

View File

@ -1,18 +1,18 @@
<?php
class WikipediaRequest extends EngineRequest {
public function get_request_url() {
$this->wikipedia_language = $this->opts->language;
$this->wikipedia_domain = "wikipedia.org";
$query_encoded = urlencode($this->query);
if (!in_array($this->wikipedia_language, json_decode(file_get_contents("static/misc/wikipedia_langs.json"), true)))
$this->wikipedia_language = "en";
$languages = json_decode(file_get_contents("static/misc/languages.json"), true);
return "https://$this->wikipedia_language.wikipedia.org/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=$query_encoded";
if (array_key_exists($this->opts->language, $languages))
$this->wikipedia_domain = $languages[$this->opts->language]["wikipedia"] . ".wikipedia.org";
return "https://$this->wikipedia_domain/w/api.php?format=json&action=query&prop=extracts%7Cpageimages&exintro&explaintext&redirects=1&pithumbsize=500&titles=$query_encoded";
}
public function get_results() {
$response = curl_multi_getcontent($this->ch);
public function parse_results($response) {
$json_response = json_decode($response, true);
$first_page = array_values($json_response["query"]["pages"])[0];
@ -22,7 +22,7 @@
$description = substr($first_page["extract"], 0, 250) . "...";
$source = check_for_privacy_frontend("https://$this->wikipedia_language.wikipedia.org/wiki/$this->query", $this->opts);
$source = "https://$this->wikipedia_domain/wiki/$this->query";
$response = array(
"special_response" => array(
"response" => htmlspecialchars($description),

View File

@ -19,30 +19,30 @@
if (isset($_COOKIE["safe_search"]))
$url .= "&safe=medium";
return $url;
}
public function get_results() {
public function parse_results($response) {
$results = array();
$xpath = get_xpath(curl_multi_getcontent($this->ch));
$xpath = get_xpath($response);
if (!$xpath)
return $results;
foreach($xpath->query("/html/body/div[1]/div[". count($xpath->query('/html/body/div[1]/div')) ."]/div/div/div/div") as $result)
{
foreach($xpath->query("/html/body/div[1]/div[". count($xpath->query('/html/body/div[1]/div')) ."]/div/div/div[contains(@class, 'web-result')]/div") as $result) {
$url = $xpath->evaluate(".//h2[@class='result__title']//a/@href", $result)[0];
if ($url == null)
continue;
if (!empty($results)) // filter duplicate results
{
if (!empty($results)) { // filter duplicate results
if (end($results)["url"] == $url->textContent)
continue;
}
$url = $url->textContent;
$url = check_for_privacy_frontend($url, $this->opts);
$title = $xpath->evaluate(".//h2[@class='result__title']", $result)[0];
$description = $xpath->evaluate(".//a[@class='result__snippet']", $result)[0];
@ -50,6 +50,7 @@
array (
"title" => htmlspecialchars($title->textContent),
"url" => htmlspecialchars($url),
// base_url is to be removed in the future, see #47
"base_url" => htmlspecialchars(get_base_url($url)),
"description" => $description == null ?
"No description was provided for this site." :
@ -57,7 +58,7 @@
)
);
}
return $results;
return $results;
}
}

View File

@ -26,9 +26,9 @@
}
public function get_results() {
public function parse_results($response) {
$results = array();
$xpath = get_xpath(curl_multi_getcontent($this->ch));
$xpath = get_xpath($response);
if (!$xpath)
return $results;
@ -53,7 +53,6 @@
}
$url = $url->textContent;
$url = check_for_privacy_frontend($url, $this->opts);
$title = $xpath->evaluate(".//h3", $result)[0];
$description = $xpath->evaluate(".//div[contains(@class, 'VwiC3b')]", $result)[0];
@ -62,6 +61,7 @@
array (
"title" => htmlspecialchars($title->textContent),
"url" => htmlspecialchars($url),
// base_url is to be removed in the future, see #47
"base_url" => htmlspecialchars(get_base_url($url)),
"description" => $description == null ?
"No description was provided for this site." :
@ -70,6 +70,12 @@
);
}
if (empty($results) && !str_contains($response, "Our systems have detected unusual traffic from your computer network.")) {
$results["error"] = array(
"message" => "There are no results. Please try different keywords!"
);
}
return $results;
}
}

View File

@ -12,9 +12,6 @@
if (substr($this->query, 0, 1) == "!" || substr($last_word_query, 0, 1) == "!")
check_ddg_bang($this->query, $opts);
if (has_cooldown($this->engine, $this->opts->cooldowns))
return;
if ($this->engine == "google") {
require "engines/text/google.php";
@ -26,38 +23,53 @@
$this->engine_request = new DuckDuckGoRequest($opts, $mh);
}
if (has_cooldown($this->engine, $this->opts->cooldowns) && !has_cached_results($this->engine_request->url)) {
// TODO dont add it in the first place
curl_multi_remove_handle($mh, $this->engine_request->ch);
$this->engine_request = null;
return;
}
require "engines/special/special.php";
$this->special_request = get_special_search_request($opts, $mh);
}
public function get_results() {
if (!$this->engine_request)
public function parse_results($response) {
if (!isset($this->engine_request))
return array();
$results = $this->engine_request->get_results();
if ($this->special_request) {
$special_result = $this->special_request->get_results();
if ($special_result)
$results = array_merge(array($special_result), $results);
}
if (count($results) <= 1)
if (empty($results)) {
set_cooldown($this->engine, ($opts->request_cooldown ?? "1") * 60, $this->opts->cooldowns);
} else {
if ($this->special_request) {
$special_result = $this->special_request->get_results();
if ($special_result)
$results = array_merge(array($special_result), $results);
}
}
return $results;
}
public static function print_results($results) {
public static function print_results($results, $opts) {
if (empty($results))
if (empty($results)) {
echo "<div class=\"text-result-container\"><p>An error occured fetching results</p></div>";
return;
}
if (array_key_exists("error", $results)) {
echo "<div class=\"text-result-container\"><p>" . $results["error"]["message"] . "</p></div>";
return;
}
$special = $results[0];
if (array_key_exists("did_you_mean", $special))
{
if (array_key_exists("did_you_mean", $special)) {
$didyoumean = $special["did_you_mean"];
$new_url = "/search.php?q=" . urlencode($didyoumean);
echo "<p class=\"did-you-mean\">Did you mean ";
@ -65,33 +77,34 @@
echo "?</p>";
}
if (array_key_exists("special_response", $special))
{
if (array_key_exists("special_response", $special)) {
$response = $special["special_response"]["response"];
$source = $special["special_response"]["source"];
echo "<p class=\"special-result-container\">";
if (array_key_exists("image", $special["special_response"]))
{
if (array_key_exists("image", $special["special_response"])) {
$image_url = $special["special_response"]["image"];
echo "<img src=\"image_proxy.php?url=$image_url\">";
}
echo $response;
if ($source)
if ($source) {
$source = check_for_privacy_frontend($source, $opts);
echo "<a href=\"$source\" target=\"_blank\">$source</a>";
}
echo "</p>";
}
echo "<div class=\"text-result-container\">";
foreach($results as $result)
{
foreach($results as $result) {
if (!array_key_exists("title", $result))
continue;
$title = $result["title"];
$url = $result["url"];
$base_url = $result["base_url"];
$url = check_for_privacy_frontend($url, $opts);
$base_url = get_base_url($url);
$description = $result["description"];
echo "<div class=\"text-result-wrapper\">";
@ -107,8 +120,7 @@
}
}
function check_ddg_bang($query, $opts)
{
function check_ddg_bang($query, $opts) {
$bangs_json = file_get_contents("static/misc/ddg_bang.json");
$bangs = json_decode($bangs_json, true);
@ -120,22 +132,18 @@
$bang_url = null;
foreach($bangs as $bang)
{
if ($bang["t"] == $search_word)
{
foreach($bangs as $bang) {
if ($bang["t"] == $search_word) {
$bang_url = $bang["u"];
break;
}
}
if ($bang_url)
{
if ($bang_url) {
$bang_query_array = explode("!" . $search_word, $query);
$bang_query = trim(implode("", $bang_query_array));
$request_url = str_replace("{{{s}}}", str_replace('%26quot%3B','%22', urlencode($bang_query)), $bang_url);
$request_url = check_for_privacy_frontend($request_url, $opts);
header("Location: " . $request_url);
die();

View File

@ -2,11 +2,18 @@
"instances": [
{
"clearnet": "https://search.ahwx.org/",
"tor": "http://hyy7rcvknwb22v4nnoar635wntiwr4uwzhiuyimemyl4fz6k7tahj5id.onion/",
"tor": "http://wn5jl6fxlzzfenlyu3lc4q7jpw2saplrywxvxtvqbguotwd4y5cjeuqd.onion/",
"i2p": null,
"country": "NL",
"librey": true
},
{
"clearnet": "https://search2.ahwx.org/",
"tor": "http://hyy7rcvknwb22v4nnoar635wntiwr4uwzhiuyimemyl4fz6k7tahj5id.onion/",
"i2p": null,
"country": "FR",
"librey": true
},
{
"clearnet": "https://librex.me/",
"tor": "http://librex.revvybrr6pvbx4n3j4475h4ghw4elqr4t5xo2vtd3gfpu2nrsnhh57id.onion/",
@ -28,6 +35,13 @@
"country": "CL",
"librey": true
},
{
"clearnet": "https://lx.vern.cc/",
"tor": "http://lx.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion/",
"i2p": "http://vernziqfqvweijfaacmwazohgpdo2bt2ib2jlupt2pwwu27bhgxq.b32.i2p/",
"country": "US",
"librey": true
},
{
"clearnet": "https://librey.org/",
"tor": "http://jxhkfulu6wpdl4apuy4dyivuowmpprvsd7e3el2z73crq7fmyv7rjkyd.onion/",
@ -35,6 +49,13 @@
"country": "US",
"librey": true
},
{
"clearnet": "https://librex.supernets.org/",
"tor": "http://ouosr2fq3lktngcvbz4r4op2lab5hbiz5y6g6toorsgieb7elet76jad.onion/",
"i2p": null,
"country": "US",
"librey": true
},
{
"clearnet": "https://search.davidovski.xyz/",
"tor": null,
@ -77,47 +98,47 @@
"country": "MX",
"librey": true
},
{
"clearnet": "https://lx.vern.cc/",
"tor": "http://lx.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad.onion/",
"i2p": "http://vernziqfqvweijfaacmwazohgpdo2bt2ib2jlupt2pwwu27bhgxq.b32.i2p/",
"country": "US",
"librey": false
},
{
"clearnet": "https://lx.owo.si/",
"tor": "http://lx.pk47sgwhncn5cgidm7bofngmh7lc7ukjdpk5bjwfemmyp27ovl25ikyd.onion/",
"i2p": "http://d4vi3tvfui2rfzsxr33tin4a6542heulf4mhkokdpbhbcejlg3la.b32.i2p/",
"country": "DE",
"librey": false
},
{
"clearnet": "https://search.spaceint.fr/",
"tor": null,
"i2p": null,
"country": "FR",
"librey": false
},
{
"clearnet": "https://search.pabloferreiro.es/",
"tor": null,
"i2p": null,
"country": "DE",
"librey": false
"librey": true
},
{
"clearnet": "https://librex.ratakor.com/",
"clearnet": "https://search.ratakor.com/",
"tor": null,
"i2p": null,
"country": "FR",
"librey": false
"librey": true
},
{
"clearnet": "https://search.tildevarsh.in/",
"clearnet": "https://librex.yogeshlamichhane.com.np/",
"tor": null,
"i2p": null,
"country": "IN",
"librey": false
"country": "FI",
"librey": true
},
{
"clearnet": "https://librey.baczek.me/",
"tor": null,
"i2p": null,
"country": "PL",
"librey": true
},
{
"clearnet": "https://lx.benike.me/",
"tor": null,
"i2p": null,
"country": "DE",
"librey": true
},
{
"clearnet": "https://search.seitan-ayoub.lol/",
"tor": null,
"i2p": null,
"country": "DE",
"librey": true
},
{
"clearnet": "https://librex.myroware.eu/",
@ -139,20 +160,6 @@
"i2p": null,
"country": "PL",
"librey": false
},
{
"clearnet": "https://lx.benike.monster/",
"tor": null,
"i2p": null,
"country": "DE",
"librey": false
},
{
"clearnet": "https://librex.pardesicat.xyz/",
"tor": null,
"i2p": null,
"country": "KR",
"librey": false
}
]
}

View File

@ -44,7 +44,7 @@
<title>LibreY - instances</title>
</head>
<body>
<div class="misc-container">
<center>
<h2>Libre<span class="Y">Y</span> instances</h2>
<?php
@ -56,6 +56,7 @@
list_instances($librex_instances);
?>
</center>
</div>
<?php require "misc/footer.php"; ?>

View File

@ -1,4 +1,8 @@
<?php
if (!function_exists("apcu_fetch"))
error_log("apcu is not installed! Please consider installing php-pecl-apcu for significant performance improvements");
function load_cooldowns() {
if (function_exists("apcu_fetch"))
return apcu_exists("cooldowns") ? apcu_fetch("cooldowns") : array();
@ -19,4 +23,23 @@
function has_cooldown($instance, $cooldowns) {
return ($cooldowns[$instance] ?? 0) > time();
}
function has_cached_results($url) {
if (function_exists("apcu_exists"))
return apcu_exists("cached:$url");
return false;
}
function store_cached_results($url, $results, $ttl = 0) {
if (function_exists("apcu_store") && !empty($results))
return apcu_store("cached:$url", $results, $ttl);
}
function fetch_cached_results($url) {
if (function_exists("apcu_fetch"))
return apcu_fetch("cached:$url");
return array();
}
?>

View File

@ -1,15 +1,21 @@
<?php
require "misc/cooldowns.php";
abstract class EngineRequest {
protected $DO_CACHING = true;
function __construct($opts, $mh) {
$this->query = $opts->query;
$this->page = $opts->page;
$this->mh = $mh;
$this->opts = $opts;
$url = $this->get_request_url();
if (!$url)
$this->url = $this->get_request_url();
if (!$this->url)
return;
$this->ch = curl_init($url);
if (has_cached_results($this->url))
return;
$this->ch = curl_init($this->url);
if ($opts->curl_settings)
curl_setopt_array($this->ch, $opts->curl_settings);
@ -23,17 +29,39 @@
}
public function successful() {
return curl_getinfo($this->ch)['http_code'] == '200';
return (isset($this->ch) && curl_getinfo($this->ch)['http_code'] == '200')
|| has_cached_results($this->url);
}
abstract function get_results();
static public function print_results($results){}
abstract function parse_results($response);
public function get_results() {
if (!isset($this->url))
return $this->parse_results(null);
if ($this->DO_CACHING && has_cached_results($this->url))
return fetch_cached_results($this->url);
if (!isset($this->ch))
return $this->parse_results(null);
$response = $this->mh ? curl_multi_getcontent($this->ch) : curl_exec($this->ch);
$results = $this->parse_results($response) ?? array();
if ($this->DO_CACHING && !empty($results))
store_cached_results($this->url, $results, $this->opts->cache_time * 60);
return $results;
}
public static function print_results($results, $opts) {}
}
function load_opts() {
$opts = require "config.php";
$opts->request_cooldown ??= 25;
$opts->cache_time ??= 25;
$opts->query = trim($_REQUEST["q"] ?? "");
$opts->type = (int) ($_REQUEST["t"] ?? 0);
@ -47,7 +75,7 @@
$opts->disable_frontends = (int) ($_REQUEST["nf"] ?? 0) == 1 || isset($_COOKIE["disable_frontends"]);
$opts->language = $_REQUEST["lang"] ?? trim(htmlspecialchars($_COOKIE["language"] ?? $opts->language));
$opts->language = $_REQUEST["lang"] ?? trim(htmlspecialchars($_COOKIE["language"] ?? $opts->language ?? "en"));
$opts->do_fallback = (int) ($_REQUEST["nfb"] ?? 0) == 0;
if (!$opts->instance_fallback) {
@ -60,6 +88,8 @@
$opts->frontends[$frontend]["instance_url"] = $_COOKIE[$frontend] ?? $opts->frontends[$frontend]["instance_url"];
}
$opts->curl_settings[CURLOPT_FOLLOWLOCATION] ??= true;
return $opts;
}
@ -70,7 +100,6 @@
$params .= "p=$opts->page";
$params .= "&q=$query";
$params .= "&t=$opts->type";
$params .= "&nfb=" . ($opts->do_fallback ? 0 : 1);
$params .= "&safe=" . ($opts->safe_search ? 1 : 0);
$params .= "&nf=" . ($opts->disable_frontends ? 1 : 0);
$params .= "&ns=" . ($opts->disable_special ? 1 : 0);
@ -113,7 +142,6 @@
}
function fetch_search_results($opts, $do_print) {
require "misc/cooldowns.php";
$opts->cooldowns = load_cooldowns();
$start_time = microtime(true);
@ -128,7 +156,7 @@
$results = $search_category->get_results();
if (count($results) <= 1) {
if (empty($results)) {
require "engines/librex/fallback.php";
$results = get_librex_results($opts);
}
@ -137,7 +165,7 @@
return $results;
print_elapsed_time($start_time);
$search_category->print_results($results);
$search_category->print_results($results, $opts);
return $results;
}

View File

@ -1,8 +1,7 @@
<?php
function get_base_url($url) {
$split_url = explode("/", $url);
$base_url = $split_url[0] . "//" . $split_url[2] . "/";
return $base_url;
$parsed = parse_url($url);
return $parsed["scheme"] . "://" . $parsed["host"] . "/";
}
function get_root_domain($url) {

View File

@ -1,6 +1,5 @@
<?php
require "misc/search_engine.php";
$opts = load_opts();
// Reset all cookies when resetting, or before saving new cookies
if (isset($_REQUEST["reset"]) || isset($_REQUEST["save"])) {
@ -29,6 +28,8 @@
die();
}
$opts = load_opts();
require "misc/header.php";
?>
@ -59,7 +60,7 @@
<option value=\"ubuntu\">Ubuntu</option>
<option value=\"tokyo_night\">Tokyo night</option>";
if (isset($_COOKIE["theme"])) {
if (isset($opts->theme)) {
$theme = $opts->theme;
$themes = str_replace($theme . "\"", $theme . "\" selected", $themes);
}
@ -97,19 +98,31 @@
<div class="settings-textbox-container">
<div>
<span>Language</span>
<select name="language">
<?php
// TODO make this a dropdown
echo "<input type=\"text\" name=\"language\" placeholder=\"any\" value=\"" . htmlspecialchars($opts->language ?? "") . "\">";
$languages = json_decode(file_get_contents("static/misc/languages.json"), true);
$options = "";
$options .= "<option value=\"\" " . (!isset($opts->language) ? "selected" : "") . ">Any</option>";
foreach ($languages as $lang_code => $language) {
$name = $language["name"];
$selected = $opts->language == $lang_code ? "selected" : "";
$options .= "<option value=\"$lang_code\" $selected>$name</option>";
}
echo $options;
?>
</select>
</div>
<div>
<label>Number of results per page</label>
<input type="number" name="number_of_results" value="<?php echo htmlspecialchars($opts->number_of_results ?? "10") ?>" >
</div>
<div>
<label>Safe search</label>
<input type="checkbox" name="safe_search" <?php echo $opts->safe_search ? "checked" : ""; ?> >
</div>
</div>
<div>
<label>Safe search</label>
<input type="checkbox" name="safe_search" <?php echo $opts->safe_search ? "checked" : ""; ?> >
</div>
<div>

View File

@ -151,7 +151,7 @@ a:hover,
.misc-container {
text-align: center;
word-wrap: break-word;
width: 450px;
width: 460px;
margin-left: auto;
margin-right: auto;
margin-bottom: 100px;
@ -319,8 +319,7 @@ a[title] {
}
.footer-container a {
margin-left: 15px;
margin-right: 15px;
margin-right: 30px;
}
.hide {
@ -339,6 +338,60 @@ a[title] {
color: #ff79c6;
}
/* donate css start */
.donate-container {
width: 700px;
margin-left: auto;
margin-right: auto;
margin-bottom: 100px;
}
.flexbox-column {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 10px;
}
.inner-wrap {
width: 500px;
padding: 20px;
}
.qr-box {
background-color: var(--search-container-background-color);
border: 1px solid var(--search-container-background-border);
border-radius: 10px 0px 0px 10px;
width: 100%;
display: flex;
word-wrap: break-word;
align-items: center;
justify-content: space-between;
}
.flex-row {
width: 700px;
height: auto;
display: flex;
flex-direction: row;
justify-content: space-evenly;
}
hr.small-line {
/* background-color: #f1f3f4; */
border: 2px solid var(--main-fg);
height: 0px;
width: 100px;
margin: 30px;
border-radius: 2px;
}
/* donate css end */
@media only screen and (max-width: 1320px) {
.special-result-container {
position: relative;
@ -485,4 +538,53 @@ a[title] {
margin-left: 20px;
}
/* dontate css start*/
.donate-container {
margin-bottom: 100px;
width: 95%;
text-align: center;
}
.qr-box {
display: flex;
flex-direction: column;
word-wrap: break-word;
align-items: center;
justify-content: space-between;
word-wrap: break-word;
height: auto;
}
.qr-box {
border-radius: 10px;
flex-direction: column;
align-items: center;
}
.inner-wrap {
width: 80%;
text-align: center;
}
.qr-box img {
width: 40%;
height: auto;
padding: 20px;
}
.flex-row {
flex-direction: column;
align-items: center;
gap: 5px;
width: 0;
}
.flex-row a img {
width: 220px;
height: auto;
}
/* donate css end */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
static/images/kofi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

BIN
static/images/xmr-ahwx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
["ab","ace","ady","af","ak","als","am","an","ang","ar","arc","ary","arz","as","ast","atj","av","avk","awa","ay","az","azb","ba","ban","bar","bat-smg","bcl","be","be-tarask","bg","bh","bi","bjn","bm","bn","bo","bpy","br","bs","bug","bxr","ca","cbk-zam","cdo","ce","ceb","ch","chr","chy","ckb","co","cr","crh","cs","csb","cu","cv","cy","da","de","din","diq","dsb","dty","dv","dz","ee","el","eml","en","eo","es","et","eu","ext","fa","ff","fi","fiu-vro","fj","fo","fr","frp","frr","fur","fy","ga","gag","gan","gcr","gd","gl","glk","gn","gom","gor","got","gu","gv","ha","hak","haw","he","hi","hif","hr","hsb","ht","hu","hy","hyw","ia","id","ie","ig","ik","ilo","inh","io","is","it","iu","ja","jam","jbo","jv","ka","kaa","kab","kbd","kbp","kg","ki","kk","kl","km","kn","ko","koi","krc","ks","ksh","ku","kv","kw","ky","la","lad","lb","lbe","lez","lfn","lg","li","lij","lld","lmo","ln","lo","lt","ltg","lv","mad","mai","map-bms","mdf","mg","mhr","mi","min","mk","ml","mn","mnw","mr","mrj","ms","mt","mwl","my","myv","mzn","na","nah","nap","nds","nds-nl","ne","new","nia","nl","nn","no","nostalgia","nov","nqo","nrm","nso","nv","ny","oc","olo","om","or","os","pa","pag","pam","pap","pcd","pdc","pfl","pi","pih","pl","pms","pnb","pnt","ps","pt","qu","rm","rmy","rn","ro","roa-rup","roa-tara","ru","rue","rw","sa","sah","sat","sc","scn","sco","sd","se","sg","sh","shn","si","simple","sk","skr","sl","sm","smn","sn","so","sq","sr","srn","ss","st","stq","su","sv","sw","szl","szy","ta","tcy","te","tet","tg","th","ti","tk","tl","tn","to","tpi","tr","ts","tt","tum","tw","ty","tyv","udm","ug","uk","ur","uz","ve","vec","vep","vi","vls","vo","wa","war","wo","wuu","xal","xh","xmf","yi","yo","za","zea","zh","zh-classical","zh-min-nan","zh-yue","zu","zh-hans","zh-hant","zh-cn","zh-hk","zh-mo","zh-my","zh-sg","zh-tw"]