summaryrefslogtreecommitdiff
path: root/src/portal/patches
diff options
context:
space:
mode:
Diffstat (limited to 'src/portal/patches')
-rw-r--r--src/portal/patches/instagrapi_no_android.diff17
-rw-r--r--src/portal/patches/pixivpy_reauth.diff96
-rw-r--r--src/portal/patches/searxng_disable_engines_default.diff3675
-rw-r--r--src/portal/patches/snscrape_1036.diff28
-rw-r--r--src/portal/patches/snscrape_auth.diff216
5 files changed, 4032 insertions, 0 deletions
diff --git a/src/portal/patches/instagrapi_no_android.diff b/src/portal/patches/instagrapi_no_android.diff
new file mode 100644
index 0000000..6f4fd34
--- /dev/null
+++ b/src/portal/patches/instagrapi_no_android.diff
@@ -0,0 +1,17 @@
+diff --git a/instagrapi/mixins/private.py b/instagrapi/mixins/private.py
+index 9db04b0..2b17d75 100644
+--- a/instagrapi/mixins/private.py
++++ b/instagrapi/mixins/private.py
+@@ -129,9 +129,9 @@ class PrivateRequestMixin:
+ # X-IG-WWW-Claim: hmac.AR3zruvyGTlwHvVd2ACpGCWLluOppXX4NAVDV-iYslo9CaDd
+ "X-Bloks-Is-Layout-RTL": "false",
+ "X-Bloks-Is-Panorama-Enabled": "true",
+- "X-IG-Device-ID": self.uuid,
+- "X-IG-Family-Device-ID": self.phone_id,
+- "X-IG-Android-ID": self.android_device_id,
++ #"X-IG-Device-ID": self.uuid,
++ #"X-IG-Family-Device-ID": self.phone_id,
++ #"X-IG-Android-ID": self.android_device_id,
+ "X-IG-Timezone-Offset": str(self.timezone_offset),
+ "X-IG-Connection-Type": "WIFI",
+ "X-IG-Capabilities": "3brTvx0=", # "3brTvwE=" in instabot
diff --git a/src/portal/patches/pixivpy_reauth.diff b/src/portal/patches/pixivpy_reauth.diff
new file mode 100644
index 0000000..d9ce0d6
--- /dev/null
+++ b/src/portal/patches/pixivpy_reauth.diff
@@ -0,0 +1,96 @@
+diff --git a/pixivpy3/aapi.py b/pixivpy3/aapi.py
+index 1492385..ffc88c0 100644
+--- a/pixivpy3/aapi.py
++++ b/pixivpy3/aapi.py
+@@ -76,12 +76,11 @@ class AppPixivAPI(BasePixivAPI):
+ ) -> Response:
+ headers_ = CaseInsensitiveDict(headers or {})
+ if self.hosts != "https://app-api.pixiv.net":
+- headers_["host"] = "app-api.pixiv.net"
+- if "user-agent" not in headers_:
+- # Set User-Agent if not provided
+- headers_["app-os"] = "ios"
+- headers_["app-os-version"] = "14.6"
+- headers_["user-agent"] = "PixivIOSApp/7.13.3 (iOS 14.6; iPhone13,2)"
++ headers_["Host"] = "app-api.pixiv.net"
++ headers_["App-OS"] = "ios"
++ headers_["App-OS-Version"] = "16.7.2"
++ headers_["App-Version"] = "7.19.6"
++ headers_["User-Agent"] = "PixivIOSApp/7.19.6 (iOS 16.7.2; iPhone13,2)"
+
+ if not req_auth:
+ return self.requests_call(method, url, headers_, params, data)
+diff --git a/pixivpy3/api.py b/pixivpy3/api.py
+index c26dda2..d0e1c0f 100644
+--- a/pixivpy3/api.py
++++ b/pixivpy3/api.py
+@@ -26,6 +26,7 @@ class BasePixivAPI:
+ self.user_id: int | str = 0
+ self.access_token: str | None = None
+ self.refresh_token: str | None = None
++ self.token_expiration: int | None = None
+ self.hosts = "https://app-api.pixiv.net"
+
+ # self.requests = requests.Session()
+@@ -62,6 +63,11 @@ class BasePixivAPI:
+ stream: bool = False,
+ ) -> Response:
+ """requests http/https call for Pixiv API"""
++ if self.token_expiration is not None and datetime.utcnow().timestamp() >= self.token_expiration:
++ # Token expired refresh auth
++ print('Token expired, refreshing auth')
++ self.token_expiration = None
++ self.auth()
+ merged_headers = self.additional_headers.copy()
+ if headers:
+ # Use the headers in the parameter to override the
+@@ -118,23 +124,22 @@ class BasePixivAPI:
+ headers: ParamDict = None,
+ ) -> ParsedJson:
+ """Login with password, or use the refresh_token to acquire a new bearer token"""
+- local_time = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S+00:00")
++ local_time = datetime.utcnow()
++ local_time_str = local_time.strftime("%Y-%m-%dT%H:%M:%S+00:00")
+ headers_ = CaseInsensitiveDict(headers or {})
+- headers_["x-client-time"] = local_time
+- headers_["x-client-hash"] = hashlib.md5((local_time + self.hash_secret).encode("utf-8")).hexdigest()
+- # Allow mock UA due to #171: https://github.com/upbit/pixivpy/issues/171
+- if "user-agent" not in headers_:
+- headers_["app-os"] = "ios"
+- headers_["app-os-version"] = "14.6"
+- headers_["user-agent"] = "PixivIOSApp/7.13.3 (iOS 14.6; iPhone13,2)"
+-
++ headers_["X-Client-Time"] = local_time_str
++ headers_["X-Client-Hash"] = hashlib.md5((local_time_str + self.hash_secret).encode("utf-8")).hexdigest()
++ headers_["App-OS"] = "ios"
++ headers_["App-OS-Version"] = "16.7.2"
++ headers_["App-Version"] = "7.19.6"
++ headers_["User-Agent"] = "PixivIOSApp/7.19.6 (iOS 16.7.2; iPhone13,2)"
+ # noinspection PyUnresolvedReferences
+ if not hasattr(self, "hosts") or self.hosts == "https://app-api.pixiv.net":
+ auth_hosts = "https://oauth.secure.pixiv.net"
+ else:
+ # noinspection PyUnresolvedReferences
+ auth_hosts = self.hosts # BAPI解析成IP的场景
+- headers_["host"] = "oauth.secure.pixiv.net"
++ headers_["Host"] = "oauth.secure.pixiv.net"
+ url = "%s/auth/token" % auth_hosts
+ data = {
+ "get_secure_url": 1,
+@@ -149,6 +154,8 @@ class BasePixivAPI:
+ elif refresh_token or self.refresh_token:
+ data["grant_type"] = "refresh_token"
+ data["refresh_token"] = refresh_token or self.refresh_token
++ if self.access_token:
++ data["access_token"] = self.access_token
+ else:
+ raise PixivError("[ERROR] auth() but no password or refresh_token is set.")
+
+@@ -174,6 +181,7 @@ class BasePixivAPI:
+ self.user_id = token.response.user.id
+ self.access_token = token.response.access_token
+ self.refresh_token = token.response.refresh_token
++ self.token_expiration = local_time.timestamp() + token.response.expires_in
+ except json.JSONDecodeError:
+ raise PixivError(
+ "Get access_token error! Response: %s" % token,
diff --git a/src/portal/patches/searxng_disable_engines_default.diff b/src/portal/patches/searxng_disable_engines_default.diff
new file mode 100644
index 0000000..923519c
--- /dev/null
+++ b/src/portal/patches/searxng_disable_engines_default.diff
@@ -0,0 +1,3675 @@
+diff --git a/searx/settings.yml b/searx/settings.yml
+index 6946b89d..92378207 100644
+--- a/searx/settings.yml
++++ b/searx/settings.yml
+@@ -294,468 +294,6 @@ categories_as_tabs:
+ social media:
+
+ engines:
+- - name: 9gag
+- engine: 9gag
+- shortcut: 9g
+- disabled: true
+-
+- - name: annas archive
+- engine: annas_archive
+- disabled: true
+- shortcut: aa
+-
+- # - name: annas articles
+- # engine: annas_archive
+- # shortcut: aaa
+- # # https://docs.searxng.org/dev/engines/online/annas_archive.html
+- # aa_content: 'journal_article' # book_any .. magazine, standards_document
+- # aa_ext: 'pdf' # pdf, epub, ..
+- # aa_sort: 'newest' # newest, oldest, largest, smallest
+-
+- - name: apk mirror
+- engine: apkmirror
+- timeout: 4.0
+- shortcut: apkm
+- disabled: true
+-
+- - name: apple app store
+- engine: apple_app_store
+- shortcut: aps
+- disabled: true
+-
+- # Requires Tor
+- - name: ahmia
+- engine: ahmia
+- categories: onions
+- enable_http: true
+- shortcut: ah
+-
+- - name: anaconda
+- engine: xpath
+- paging: true
+- first_page_num: 0
+- search_url: https://anaconda.org/search?q={query}&page={pageno}
+- results_xpath: //tbody/tr
+- url_xpath: ./td/h5/a[last()]/@href
+- title_xpath: ./td/h5
+- content_xpath: ./td[h5]/text()
+- categories: it
+- timeout: 6.0
+- shortcut: conda
+- disabled: true
+-
+- - name: arch linux wiki
+- engine: archlinux
+- shortcut: al
+-
+- - name: artic
+- engine: artic
+- shortcut: arc
+- timeout: 4.0
+-
+- - name: arxiv
+- engine: arxiv
+- shortcut: arx
+- timeout: 4.0
+-
+- # tmp suspended: dh key too small
+- # - name: base
+- # engine: base
+- # shortcut: bs
+-
+- - name: bandcamp
+- engine: bandcamp
+- shortcut: bc
+- categories: music
+-
+- - name: wikipedia
+- engine: wikipedia
+- shortcut: wp
+- # add "list" to the array to get results in the results list
+- display_type: ["infobox"]
+- base_url: 'https://{language}.wikipedia.org/'
+- categories: [general]
+-
+- - name: bilibili
+- engine: bilibili
+- shortcut: bil
+- disabled: true
+-
+- - name: bing
+- engine: bing
+- shortcut: bi
+- disabled: true
+-
+- - name: bing images
+- engine: bing_images
+- shortcut: bii
+-
+- - name: bing news
+- engine: bing_news
+- shortcut: bin
+-
+- - name: bing videos
+- engine: bing_videos
+- shortcut: biv
+-
+- - name: bitbucket
+- engine: xpath
+- paging: true
+- search_url: https://bitbucket.org/repo/all/{pageno}?name={query}
+- url_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]/@href
+- title_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]
+- content_xpath: //article[@class="repo-summary"]/p
+- categories: [it, repos]
+- timeout: 4.0
+- disabled: true
+- shortcut: bb
+- about:
+- website: https://bitbucket.org/
+- wikidata_id: Q2493781
+- official_api_documentation: https://developer.atlassian.com/bitbucket
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: btdigg
+- engine: btdigg
+- shortcut: bt
+- disabled: true
+-
+- - name: ccc-tv
+- engine: xpath
+- paging: false
+- search_url: https://media.ccc.de/search/?q={query}
+- url_xpath: //div[@class="caption"]/h3/a/@href
+- title_xpath: //div[@class="caption"]/h3/a/text()
+- content_xpath: //div[@class="caption"]/h4/@title
+- categories: videos
+- disabled: true
+- shortcut: c3tv
+- about:
+- website: https://media.ccc.de/
+- wikidata_id: Q80729951
+- official_api_documentation: https://github.com/voc/voctoweb
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+- # We don't set language: de here because media.ccc.de is not just
+- # for a German audience. It contains many English videos and many
+- # German videos have English subtitles.
+-
+- - name: openverse
+- engine: openverse
+- categories: images
+- shortcut: opv
+-
+- - name: chefkoch
+- engine: chefkoch
+- shortcut: chef
+- # to show premium or plus results too:
+- # skip_premium: false
+-
+- # - name: core.ac.uk
+- # engine: core
+- # categories: science
+- # shortcut: cor
+- # # get your API key from: https://core.ac.uk/api-keys/register/
+- # api_key: 'unset'
+-
+- - name: crossref
+- engine: crossref
+- shortcut: cr
+- timeout: 30
+- disabled: true
+-
+- - name: crowdview
+- engine: json_engine
+- shortcut: cv
+- categories: general
+- paging: false
+- search_url: https://crowdview-next-js.onrender.com/api/search-v3?query={query}
+- results_query: results
+- url_query: link
+- title_query: title
+- content_query: snippet
+- disabled: true
+- about:
+- website: https://crowdview.ai/
+-
+- - name: yep
+- engine: json_engine
+- shortcut: yep
+- categories: general
+- disabled: true
+- paging: false
+- content_html_to_text: true
+- title_html_to_text: true
+- search_url: https://api.yep.com/fs/1/?type=web&q={query}&no_correct=false&limit=100
+- results_query: 1/results
+- title_query: title
+- url_query: url
+- content_query: snippet
+- about:
+- website: https://yep.com
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- - name: curlie
+- engine: xpath
+- shortcut: cl
+- categories: general
+- disabled: true
+- paging: true
+- lang_all: ''
+- search_url: https://curlie.org/search?q={query}&lang={lang}&start={pageno}&stime=92452189
+- page_size: 20
+- results_xpath: //div[@id="site-list-content"]/div[@class="site-item"]
+- url_xpath: ./div[@class="title-and-desc"]/a/@href
+- title_xpath: ./div[@class="title-and-desc"]/a/div
+- content_xpath: ./div[@class="title-and-desc"]/div[@class="site-descr"]
+- about:
+- website: https://curlie.org/
+- wikidata_id: Q60715723
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: currency
+- engine: currency_convert
+- categories: general
+- shortcut: cc
+-
+- - name: deezer
+- engine: deezer
+- shortcut: dz
+- disabled: true
+-
+- - name: deviantart
+- engine: deviantart
+- shortcut: da
+- timeout: 3.0
+-
+- - name: ddg definitions
+- engine: duckduckgo_definitions
+- shortcut: ddd
+- weight: 2
+- disabled: true
+- tests: *tests_infobox
+-
+- # cloudflare protected
+- # - name: digbt
+- # engine: digbt
+- # shortcut: dbt
+- # timeout: 6.0
+- # disabled: true
+-
+- - name: docker hub
+- engine: docker_hub
+- shortcut: dh
+- categories: [it, packages]
+-
+- - name: erowid
+- engine: xpath
+- paging: true
+- first_page_num: 0
+- page_size: 30
+- search_url: https://www.erowid.org/search.php?q={query}&s={pageno}
+- url_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/@href
+- title_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/text()
+- content_xpath: //dl[@class="results-list"]/dd[@class="result-details"]
+- categories: []
+- shortcut: ew
+- disabled: true
+- about:
+- website: https://www.erowid.org/
+- wikidata_id: Q1430691
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- # - name: elasticsearch
+- # shortcut: es
+- # engine: elasticsearch
+- # base_url: http://localhost:9200
+- # username: elastic
+- # password: changeme
+- # index: my-index
+- # # available options: match, simple_query_string, term, terms, custom
+- # query_type: match
+- # # if query_type is set to custom, provide your query here
+- # #custom_query_json: {"query":{"match_all": {}}}
+- # #show_metadata: false
+- # disabled: true
+-
+- - name: wikidata
+- engine: wikidata
+- shortcut: wd
+- timeout: 3.0
+- weight: 2
+- # add "list" to the array to get results in the results list
+- display_type: ["infobox"]
+- tests: *tests_infobox
+- categories: [general]
+-
+- - name: duckduckgo
+- engine: duckduckgo
+- shortcut: ddg
+-
+- - name: duckduckgo images
+- engine: duckduckgo_images
+- shortcut: ddi
+- timeout: 3.0
+- disabled: true
+-
+- - name: duckduckgo weather
+- engine: duckduckgo_weather
+- shortcut: ddw
+- disabled: true
+-
+- - name: apple maps
+- engine: apple_maps
+- shortcut: apm
+- disabled: true
+- timeout: 5.0
+-
+- - name: emojipedia
+- engine: emojipedia
+- timeout: 4.0
+- shortcut: em
+- disabled: true
+-
+- - name: tineye
+- engine: tineye
+- shortcut: tin
+- timeout: 9.0
+- disabled: true
+-
+- - name: etymonline
+- engine: xpath
+- paging: true
+- search_url: https://etymonline.com/search?page={pageno}&q={query}
+- url_xpath: //a[contains(@class, "word__name--")]/@href
+- title_xpath: //a[contains(@class, "word__name--")]
+- content_xpath: //section[contains(@class, "word__defination")]
+- first_page_num: 1
+- shortcut: et
+- categories: [dictionaries]
+- about:
+- website: https://www.etymonline.com/
+- wikidata_id: Q1188617
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- # - name: ebay
+- # engine: ebay
+- # shortcut: eb
+- # base_url: 'https://www.ebay.com'
+- # disabled: true
+- # timeout: 5
+-
+- - name: 1x
+- engine: www1x
+- shortcut: 1x
+- timeout: 3.0
+- disabled: true
+-
+- - name: fdroid
+- engine: fdroid
+- shortcut: fd
+- disabled: true
+-
+- - name: flickr
+- categories: images
+- shortcut: fl
+- # You can use the engine using the official stable API, but you need an API
+- # key, see: https://www.flickr.com/services/apps/create/
+- # engine: flickr
+- # api_key: 'apikey' # required!
+- # Or you can use the html non-stable engine, activated by default
+- engine: flickr_noapi
+-
+- - name: free software directory
+- engine: mediawiki
+- shortcut: fsd
+- categories: [it, software wikis]
+- base_url: https://directory.fsf.org/
+- search_type: title
+- timeout: 5.0
+- disabled: true
+- about:
+- website: https://directory.fsf.org/
+- wikidata_id: Q2470288
+-
+- # - name: freesound
+- # engine: freesound
+- # shortcut: fnd
+- # disabled: true
+- # timeout: 15.0
+- # API key required, see: https://freesound.org/docs/api/overview.html
+- # api_key: MyAPIkey
+-
+- - name: frinkiac
+- engine: frinkiac
+- shortcut: frk
+- disabled: true
+-
+- - name: genius
+- engine: genius
+- shortcut: gen
+-
+- - name: gentoo
+- engine: gentoo
+- shortcut: ge
+- timeout: 10.0
+-
+- - name: gitlab
+- engine: json_engine
+- paging: true
+- search_url: https://gitlab.com/api/v4/projects?search={query}&page={pageno}
+- url_query: web_url
+- title_query: name_with_namespace
+- content_query: description
+- page_size: 20
+- categories: [it, repos]
+- shortcut: gl
+- timeout: 10.0
+- disabled: true
+- about:
+- website: https://about.gitlab.com/
+- wikidata_id: Q16639197
+- official_api_documentation: https://docs.gitlab.com/ee/api/
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- - name: github
+- engine: github
+- shortcut: gh
+-
+- # This a Gitea service. If you would like to use a different instance,
+- # change codeberg.org to URL of the desired Gitea host. Or you can create a
+- # new engine by copying this and changing the name, shortcut and search_url.
+-
+- - name: codeberg
+- engine: json_engine
+- search_url: https://codeberg.org/api/v1/repos/search?q={query}&limit=10
+- url_query: html_url
+- title_query: name
+- content_query: description
+- categories: [it, repos]
+- shortcut: cb
+- disabled: true
+- about:
+- website: https://codeberg.org/
+- wikidata_id:
+- official_api_documentation: https://try.gitea.io/api/swagger
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+ - name: google
+ engine: google
+ shortcut: go
+@@ -774,1372 +312,1837 @@ engines:
+ # result_container:
+ # - ['one_title_contains', 'Salvador']
+
+- - name: google news
+- engine: google_news
+- shortcut: gon
+- # additional_tests:
+- # android: *test_android
+-
+- - name: google videos
+- engine: google_videos
+- shortcut: gov
+- # additional_tests:
+- # android: *test_android
+-
+- - name: google scholar
+- engine: google_scholar
+- shortcut: gos
+-
+- - name: google play apps
+- engine: google_play
+- categories: [files, apps]
+- shortcut: gpa
+- play_categ: apps
+- disabled: true
+-
+- - name: google play movies
+- engine: google_play
+- categories: videos
+- shortcut: gpm
+- play_categ: movies
+- disabled: true
+-
+- - name: material icons
+- engine: material_icons
+- categories: images
+- shortcut: mi
+- disabled: true
+-
+- - name: gpodder
+- engine: json_engine
+- shortcut: gpod
+- timeout: 4.0
+- paging: false
+- search_url: https://gpodder.net/search.json?q={query}
+- url_query: url
+- title_query: title
+- content_query: description
+- page_size: 19
+- categories: music
+- disabled: true
+- about:
+- website: https://gpodder.net
+- wikidata_id: Q3093354
+- official_api_documentation: https://gpoddernet.readthedocs.io/en/latest/api/
+- use_official_api: false
+- requires_api_key: false
+- results: JSON
+-
+- - name: habrahabr
+- engine: xpath
+- paging: true
+- search_url: https://habr.com/en/search/page{pageno}/?q={query}
+- results_xpath: //article[contains(@class, "tm-articles-list__item")]
+- url_xpath: .//a[@class="tm-title__link"]/@href
+- title_xpath: .//a[@class="tm-title__link"]
+- content_xpath: .//div[contains(@class, "article-formatted-body")]
+- categories: it
+- timeout: 4.0
+- disabled: true
+- shortcut: habr
+- about:
+- website: https://habr.com/
+- wikidata_id: Q4494434
+- official_api_documentation: https://habr.com/en/docs/help/api/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: hoogle
+- engine: xpath
+- paging: true
+- search_url: https://hoogle.haskell.org/?hoogle={query}&start={pageno}
+- results_xpath: '//div[@class="result"]'
+- title_xpath: './/div[@class="ans"]//a'
+- url_xpath: './/div[@class="ans"]//a/@href'
+- content_xpath: './/div[@class="from"]'
+- page_size: 20
+- categories: [it, packages]
+- shortcut: ho
+- about:
+- website: https://hoogle.haskell.org/
+- wikidata_id: Q34010
+- official_api_documentation: https://hackage.haskell.org/api
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- - name: imdb
+- engine: imdb
+- shortcut: imdb
+- timeout: 6.0
+- disabled: true
+-
+- - name: ina
+- engine: ina
+- shortcut: in
+- timeout: 6.0
+- disabled: true
+-
+- - name: invidious
+- engine: invidious
+- # Instanes will be selected randomly, see https://api.invidious.io/ for
+- # instances that are stable (good uptime) and close to you.
+- base_url:
+- - https://invidious.io.lol
+- - https://invidious.fdn.fr
+- - https://yt.artemislena.eu
+- - https://invidious.tiekoetter.com
+- - https://invidious.flokinet.to
+- - https://vid.puffyan.us
+- - https://invidious.privacydev.net
+- - https://inv.tux.pizza
+- shortcut: iv
+- timeout: 3.0
+- disabled: true
+-
+- - name: jisho
+- engine: jisho
+- shortcut: js
+- timeout: 3.0
+- disabled: true
+-
+- - name: kickass
+- engine: kickass
+- shortcut: kc
+- timeout: 4.0
+- disabled: true
+-
+- - name: lemmy communities
+- engine: lemmy
+- lemmy_type: Communities
+- shortcut: leco
+-
+- - name: lemmy users
+- engine: lemmy
+- network: lemmy communities
+- lemmy_type: Users
+- shortcut: leus
+-
+- - name: lemmy posts
+- engine: lemmy
+- network: lemmy communities
+- lemmy_type: Posts
+- shortcut: lepo
+-
+- - name: lemmy comments
+- engine: lemmy
+- network: lemmy communities
+- lemmy_type: Comments
+- shortcut: lecom
+-
+- - name: library genesis
+- engine: xpath
+- search_url: https://libgen.fun/search.php?req={query}
+- url_xpath: //a[contains(@href,"get.php?md5")]/@href
+- title_xpath: //a[contains(@href,"book/")]/text()[1]
+- content_xpath: //td/a[1][contains(@href,"=author")]/text()
+- categories: files
+- timeout: 7.0
+- disabled: true
+- shortcut: lg
+- about:
+- website: https://libgen.fun/
+- wikidata_id: Q22017206
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: z-library
+- engine: zlibrary
+- shortcut: zlib
+- categories: files
+- timeout: 7.0
+-
+- - name: library of congress
+- engine: loc
+- shortcut: loc
+- categories: images
+-
+- - name: lingva
+- engine: lingva
+- shortcut: lv
+- # set lingva instance in url, by default it will use the official instance
+- # url: https://lingva.ml
+-
+- - name: lobste.rs
+- engine: xpath
+- search_url: https://lobste.rs/search?utf8=%E2%9C%93&q={query}&what=stories&order=relevance
+- results_xpath: //li[contains(@class, "story")]
+- url_xpath: .//a[@class="u-url"]/@href
+- title_xpath: .//a[@class="u-url"]
+- content_xpath: .//a[@class="domain"]
+- categories: it
+- shortcut: lo
+- timeout: 5.0
+- disabled: true
+- about:
+- website: https://lobste.rs/
+- wikidata_id: Q60762874
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: azlyrics
+- shortcut: lyrics
+- engine: xpath
+- timeout: 4.0
+- disabled: true
+- categories: [music, lyrics]
+- paging: true
+- search_url: https://search.azlyrics.com/search.php?q={query}&w=lyrics&p={pageno}
+- url_xpath: //td[@class="text-left visitedlyr"]/a/@href
+- title_xpath: //span/b/text()
+- content_xpath: //td[@class="text-left visitedlyr"]/a/small
+- about:
+- website: https://azlyrics.com
+- wikidata_id: Q66372542
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: metacpan
+- engine: metacpan
+- shortcut: cpan
+- disabled: true
+- number_of_results: 20
+-
+- # - name: meilisearch
+- # engine: meilisearch
+- # shortcut: mes
+- # enable_http: true
+- # base_url: http://localhost:7700
+- # index: my-index
+-
+- - name: mixcloud
+- engine: mixcloud
+- shortcut: mc
+-
+- # MongoDB engine
+- # Required dependency: pymongo
+- # - name: mymongo
+- # engine: mongodb
+- # shortcut: md
+- # exact_match_only: false
+- # host: '127.0.0.1'
+- # port: 27017
+- # enable_http: true
+- # results_per_page: 20
+- # database: 'business'
+- # collection: 'reviews' # name of the db collection
+- # key: 'name' # key in the collection to search for
+-
+- - name: mwmbl
+- engine: mwmbl
+- # api_url: https://api.mwmbl.org
+- shortcut: mwm
+- disabled: true
+-
+- - name: npm
+- engine: json_engine
+- paging: true
+- first_page_num: 0
+- search_url: https://api.npms.io/v2/search?q={query}&size=25&from={pageno}
+- results_query: results
+- url_query: package/links/npm
+- title_query: package/name
+- content_query: package/description
+- page_size: 25
+- categories: [it, packages]
+- disabled: true
+- timeout: 5.0
+- shortcut: npm
+- about:
+- website: https://npms.io/
+- wikidata_id: Q7067518
+- official_api_documentation: https://api-docs.npms.io/
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- - name: nyaa
+- engine: nyaa
+- shortcut: nt
+- disabled: true
+-
+- - name: mankier
+- engine: json_engine
+- search_url: https://www.mankier.com/api/v2/mans/?q={query}
+- results_query: results
+- url_query: url
+- title_query: name
+- content_query: description
+- categories: it
+- shortcut: man
+- about:
+- website: https://www.mankier.com/
+- official_api_documentation: https://www.mankier.com/api
+- use_official_api: true
+- require_api_key: false
+- results: JSON
+-
+- - name: odysee
+- engine: odysee
+- shortcut: od
+- disabled: true
+-
+- - name: openairedatasets
+- engine: json_engine
+- paging: true
+- search_url: https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
+- results_query: response/results/result
+- url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
+- title_query: metadata/oaf:entity/oaf:result/title/$
+- content_query: metadata/oaf:entity/oaf:result/description/$
+- content_html_to_text: true
+- categories: "science"
+- shortcut: oad
+- timeout: 5.0
+- about:
+- website: https://www.openaire.eu/
+- wikidata_id: Q25106053
+- official_api_documentation: https://api.openaire.eu/
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- - name: openairepublications
+- engine: json_engine
+- paging: true
+- search_url: https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
+- results_query: response/results/result
+- url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
+- title_query: metadata/oaf:entity/oaf:result/title/$
+- content_query: metadata/oaf:entity/oaf:result/description/$
+- content_html_to_text: true
+- categories: science
+- shortcut: oap
+- timeout: 5.0
+- about:
+- website: https://www.openaire.eu/
+- wikidata_id: Q25106053
+- official_api_documentation: https://api.openaire.eu/
+- use_official_api: false
+- require_api_key: false
+- results: JSON
+-
+- # - name: opensemanticsearch
+- # engine: opensemantic
+- # shortcut: oss
+- # base_url: 'http://localhost:8983/solr/opensemanticsearch/'
+-
+- - name: openstreetmap
+- engine: openstreetmap
+- shortcut: osm
+-
+- - name: openrepos
+- engine: xpath
+- paging: true
+- search_url: https://openrepos.net/search/node/{query}?page={pageno}
+- url_xpath: //li[@class="search-result"]//h3[@class="title"]/a/@href
+- title_xpath: //li[@class="search-result"]//h3[@class="title"]/a
+- content_xpath: //li[@class="search-result"]//div[@class="search-snippet-info"]//p[@class="search-snippet"]
+- categories: files
+- timeout: 4.0
+- disabled: true
+- shortcut: or
+- about:
+- website: https://openrepos.net/
+- wikidata_id:
+- official_api_documentation:
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: packagist
+- engine: json_engine
+- paging: true
+- search_url: https://packagist.org/search.json?q={query}&page={pageno}
+- results_query: results
+- url_query: url
+- title_query: name
+- content_query: description
+- categories: [it, packages]
+- disabled: true
+- timeout: 5.0
+- shortcut: pack
+- about:
+- website: https://packagist.org
+- wikidata_id: Q108311377
+- official_api_documentation: https://packagist.org/apidoc
+- use_official_api: true
+- require_api_key: false
+- results: JSON
+-
+- - name: pdbe
+- engine: pdbe
+- shortcut: pdb
+- # Hide obsolete PDB entries. Default is not to hide obsolete structures
+- # hide_obsolete: false
+-
+- - name: photon
+- engine: photon
+- shortcut: ph
+-
+- - name: piped
+- engine: piped
+- shortcut: ppd
+- categories: videos
+- piped_filter: videos
+- timeout: 3.0
+-
+- # URL to use as link and for embeds
+- frontend_url: https://srv.piped.video
+- # Instance will be selected randomly, for more see https://piped-instances.kavin.rocks/
+- backend_url:
+- - https://pipedapi.kavin.rocks
+- - https://pipedapi-libre.kavin.rocks
+- - https://pipedapi.adminforge.de
+-
+- - name: piped.music
+- engine: piped
+- network: piped
+- shortcut: ppdm
+- categories: music
+- piped_filter: music_songs
+- timeout: 3.0
+-
+- - name: piratebay
+- engine: piratebay
+- shortcut: tpb
+- # You may need to change this URL to a proxy if piratebay is blocked in your
+- # country
+- url: https://thepiratebay.org/
+- timeout: 3.0
+-
+- # Required dependency: psychopg2
+- # - name: postgresql
+- # engine: postgresql
+- # database: postgres
+- # username: postgres
+- # password: postgres
+- # limit: 10
+- # query_str: 'SELECT * from my_table WHERE my_column = %(query)s'
+- # shortcut : psql
+-
+- - name: pub.dev
+- engine: xpath
+- shortcut: pd
+- search_url: https://pub.dev/packages?q={query}&page={pageno}
+- paging: true
+- results_xpath: //div[contains(@class,"packages-item")]
+- url_xpath: ./div/h3/a/@href
+- title_xpath: ./div/h3/a
+- content_xpath: ./div/div/div[contains(@class,"packages-description")]/span
+- categories: [packages, it]
+- timeout: 3.0
+- disabled: true
+- first_page_num: 1
+- about:
+- website: https://pub.dev/
+- official_api_documentation: https://pub.dev/help/api
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: pubmed
+- engine: pubmed
+- shortcut: pub
+- timeout: 3.0
+-
+- - name: pypi
+- shortcut: pypi
+- engine: xpath
+- paging: true
+- search_url: https://pypi.org/search/?q={query}&page={pageno}
+- results_xpath: /html/body/main/div/div/div/form/div/ul/li/a[@class="package-snippet"]
+- url_xpath: ./@href
+- title_xpath: ./h3/span[@class="package-snippet__name"]
+- content_xpath: ./p
+- suggestion_xpath: /html/body/main/div/div/div/form/div/div[@class="callout-block"]/p/span/a[@class="link"]
+- first_page_num: 1
+- categories: [it, packages]
+- about:
+- website: https://pypi.org
+- wikidata_id: Q2984686
+- official_api_documentation: https://warehouse.readthedocs.io/api-reference/index.html
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: qwant
+- qwant_categ: web
+- engine: qwant
+- shortcut: qw
+- categories: [general, web]
+- additional_tests:
+- rosebud: *test_rosebud
+-
+- - name: qwant news
+- qwant_categ: news
+- engine: qwant
+- shortcut: qwn
+- categories: news
+- network: qwant
+-
+- - name: qwant images
+- qwant_categ: images
+- engine: qwant
+- shortcut: qwi
+- categories: [images, web]
+- network: qwant
+-
+- - name: qwant videos
+- qwant_categ: videos
+- engine: qwant
+- shortcut: qwv
+- categories: [videos, web]
+- network: qwant
+-
+- # - name: library
+- # engine: recoll
+- # shortcut: lib
+- # base_url: 'https://recoll.example.org/'
+- # search_dir: ''
+- # mount_prefix: /export
+- # dl_prefix: 'https://download.example.org'
+- # timeout: 30.0
+- # categories: files
+- # disabled: true
+-
+- # - name: recoll library reference
+- # engine: recoll
+- # base_url: 'https://recoll.example.org/'
+- # search_dir: reference
+- # mount_prefix: /export
+- # dl_prefix: 'https://download.example.org'
+- # shortcut: libr
+- # timeout: 30.0
+- # categories: files
+- # disabled: true
+-
+- - name: reddit
+- engine: reddit
+- shortcut: re
+- page_size: 25
+-
+- # Required dependency: redis
+- # - name: myredis
+- # shortcut : rds
+- # engine: redis_server
+- # exact_match_only: false
+- # host: '127.0.0.1'
+- # port: 6379
+- # enable_http: true
+- # password: ''
+- # db: 0
++ - name: bing images
++ engine: bing_images
++ shortcut: bii
+
+- # tmp suspended: bad certificate
+- # - name: scanr structures
+- # shortcut: scs
+- # engine: scanr_structures
++ # - name: 9gag
++ # engine: 9gag
++ # shortcut: 9g
+ # disabled: true
+-
+- - name: sepiasearch
+- engine: sepiasearch
+- shortcut: sep
+-
+- - name: soundcloud
+- engine: soundcloud
+- shortcut: sc
+-
+- - name: stackoverflow
+- engine: stackexchange
+- shortcut: st
+- api_site: 'stackoverflow'
+- categories: [it, q&a]
+-
+- - name: askubuntu
+- engine: stackexchange
+- shortcut: ubuntu
+- api_site: 'askubuntu'
+- categories: [it, q&a]
+-
+- - name: internetarchivescholar
+- engine: internet_archive_scholar
+- shortcut: ias
+- timeout: 5.0
+-
+- - name: superuser
+- engine: stackexchange
+- shortcut: su
+- api_site: 'superuser'
+- categories: [it, q&a]
+-
+- - name: searchcode code
+- engine: searchcode_code
+- shortcut: scc
+- disabled: true
+-
+- - name: framalibre
+- engine: framalibre
+- shortcut: frl
+- disabled: true
+-
+- # - name: searx
+- # engine: searx_engine
+- # shortcut: se
+- # instance_urls :
+- # - http://127.0.0.1:8888/
+- # - ...
+- # disabled: true
+-
+- - name: semantic scholar
+- engine: semantic_scholar
+- disabled: true
+- shortcut: se
+-
+- # Spotify needs API credentials
+- # - name: spotify
+- # engine: spotify
+- # shortcut: stf
+- # api_client_id: *******
+- # api_client_secret: *******
+-
+- # - name: solr
+- # engine: solr
+- # shortcut: slr
+- # base_url: http://localhost:8983
+- # collection: collection_name
+- # sort: '' # sorting: asc or desc
+- # field_list: '' # comma separated list of field names to display on the UI
+- # default_fields: '' # default field to query
+- # query_fields: '' # query fields
+- # enable_http: true
+-
+- # - name: springer nature
+- # engine: springer
+- # # get your API key from: https://dev.springernature.com/signup
+- # # working API key, for test & debug: "a69685087d07eca9f13db62f65b8f601"
+- # api_key: 'unset'
+- # shortcut: springer
+- # timeout: 15.0
+-
+- - name: startpage
+- engine: startpage
+- shortcut: sp
+- timeout: 6.0
+- disabled: true
+- additional_tests:
+- rosebud: *test_rosebud
+-
+- - name: tokyotoshokan
+- engine: tokyotoshokan
+- shortcut: tt
+- timeout: 6.0
+- disabled: true
+-
+- - name: solidtorrents
+- engine: solidtorrents
+- shortcut: solid
+- timeout: 4.0
+- base_url:
+- - https://solidtorrents.to
+- - https://bitsearch.to
+-
+- # For this demo of the sqlite engine download:
+- # https://liste.mediathekview.de/filmliste-v2.db.bz2
+- # and unpack into searx/data/filmliste-v2.db
+- # Query to test: "!demo concert"
+- #
+- # - name: demo
+- # engine: sqlite
+- # shortcut: demo
+- # categories: general
+- # result_template: default.html
+- # database: searx/data/filmliste-v2.db
+- # query_str: >-
+- # SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
+- # COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
+- # description AS content
+- # FROM film
+- # WHERE title LIKE :wildcard OR description LIKE :wildcard
+- # ORDER BY duration DESC
+-
+- - name: tagesschau
+- engine: tagesschau
+- shortcut: ts
+- disabled: true
+-
+- - name: tmdb
+- engine: xpath
+- paging: true
+- search_url: https://www.themoviedb.org/search?page={pageno}&query={query}
+- results_xpath: //div[contains(@class,"movie") or contains(@class,"tv")]//div[contains(@class,"card")]
+- url_xpath: .//div[contains(@class,"poster")]/a/@href
+- thumbnail_xpath: .//img/@src
+- title_xpath: .//div[contains(@class,"title")]//h2
+- content_xpath: .//div[contains(@class,"overview")]
+- shortcut: tm
+- disabled: true
+-
+- # Requires Tor
+- - name: torch
+- engine: xpath
+- paging: true
+- search_url:
+- http://xmh57jrknzkhv6y3ls3ubitzfqnkrwxhopf5aygthi7d6rplyvk3noyd.onion/cgi-bin/omega/omega?P={query}&DEFAULTOP=and
+- results_xpath: //table//tr
+- url_xpath: ./td[2]/a
+- title_xpath: ./td[2]/b
+- content_xpath: ./td[2]/small
+- categories: onions
+- enable_http: true
+- shortcut: tch
+-
+- # torznab engine lets you query any torznab compatible indexer. Using this
+- # engine in combination with Jackett opens the possibility to query a lot of
+- # public and private indexers directly from SearXNG. More details at:
+- # https://docs.searxng.org/dev/engines/online/torznab.html
+- #
+- # - name: Torznab EZTV
+- # engine: torznab
+- # shortcut: eztv
+- # base_url: http://localhost:9117/api/v2.0/indexers/eztv/results/torznab
+- # enable_http: true # if using localhost
+- # api_key: xxxxxxxxxxxxxxx
+- # show_magnet_links: true
+- # show_torrent_files: false
+- # # https://github.com/Jackett/Jackett/wiki/Jackett-Categories
+- # torznab_categories: # optional
+- # - 2000
+- # - 5000
+-
+- - name: twitter
+- shortcut: tw
+- engine: twitter
+- disabled: true
+-
+- # tmp suspended - too slow, too many errors
+- # - name: urbandictionary
+- # engine : xpath
+- # search_url : https://www.urbandictionary.com/define.php?term={query}
+- # url_xpath : //*[@class="word"]/@href
+- # title_xpath : //*[@class="def-header"]
+- # content_xpath: //*[@class="meaning"]
+- # shortcut: ud
+-
+- - name: unsplash
+- engine: unsplash
+- shortcut: us
+-
+- - name: yahoo
+- engine: yahoo
+- shortcut: yh
+- disabled: true
+-
+- - name: yahoo news
+- engine: yahoo_news
+- shortcut: yhn
+-
+- - name: youtube
+- shortcut: yt
+- # You can use the engine using the official stable API, but you need an API
+- # key See: https://console.developers.google.com/project
+- #
+- # engine: youtube_api
+- # api_key: 'apikey' # required!
+- #
+- # Or you can use the html non-stable engine, activated by default
+- engine: youtube_noapi
+-
+- - name: dailymotion
+- engine: dailymotion
+- shortcut: dm
+-
+- - name: vimeo
+- engine: vimeo
+- shortcut: vm
+-
+- - name: wiby
+- engine: json_engine
+- paging: true
+- search_url: https://wiby.me/json/?q={query}&p={pageno}
+- url_query: URL
+- title_query: Title
+- content_query: Snippet
+- categories: [general, web]
+- shortcut: wib
+- disabled: true
+- about:
+- website: https://wiby.me/
+-
+- - name: alexandria
+- engine: json_engine
+- shortcut: alx
+- categories: general
+- paging: true
+- search_url: https://api.alexandria.org/?a=1&q={query}&p={pageno}
+- results_query: results
+- title_query: title
+- url_query: url
+- content_query: snippet
+- timeout: 1.5
+- disabled: true
+- about:
+- website: https://alexandria.org/
+- official_api_documentation: https://github.com/alexandria-org/alexandria-api/raw/master/README.md
+- use_official_api: true
+- require_api_key: false
+- results: JSON
+-
+- - name: wikibooks
+- engine: mediawiki
+- weight: 0.5
+- shortcut: wb
+- categories: [general, wikimedia]
+- base_url: "https://{language}.wikibooks.org/"
+- search_type: text
+- disabled: true
+- about:
+- website: https://www.wikibooks.org/
+- wikidata_id: Q367
+-
+- - name: wikinews
+- engine: mediawiki
+- shortcut: wn
+- categories: [news, wikimedia]
+- base_url: "https://{language}.wikinews.org/"
+- search_type: text
+- srsort: create_timestamp_desc
+- about:
+- website: https://www.wikinews.org/
+- wikidata_id: Q964
+-
+- - name: wikiquote
+- engine: mediawiki
+- weight: 0.5
+- shortcut: wq
+- categories: [general, wikimedia]
+- base_url: "https://{language}.wikiquote.org/"
+- search_type: text
+- disabled: true
+- additional_tests:
+- rosebud: *test_rosebud
+- about:
+- website: https://www.wikiquote.org/
+- wikidata_id: Q369
+-
+- - name: wikisource
+- engine: mediawiki
+- weight: 0.5
+- shortcut: ws
+- categories: [general, wikimedia]
+- base_url: "https://{language}.wikisource.org/"
+- search_type: text
+- disabled: true
+- about:
+- website: https://www.wikisource.org/
+- wikidata_id: Q263
+-
+- - name: wikispecies
+- engine: mediawiki
+- shortcut: wsp
+- categories: [general, science, wikimedia]
+- base_url: "https://species.wikimedia.org/"
+- search_type: text
+- disabled: true
+- about:
+- website: https://species.wikimedia.org/
+- wikidata_id: Q13679
+-
+- - name: wiktionary
+- engine: mediawiki
+- shortcut: wt
+- categories: [dictionaries, wikimedia]
+- base_url: "https://{language}.wiktionary.org/"
+- search_type: text
+- about:
+- website: https://www.wiktionary.org/
+- wikidata_id: Q151
+-
+- - name: wikiversity
+- engine: mediawiki
+- weight: 0.5
+- shortcut: wv
+- categories: [general, wikimedia]
+- base_url: "https://{language}.wikiversity.org/"
+- search_type: text
+- disabled: true
+- about:
+- website: https://www.wikiversity.org/
+- wikidata_id: Q370
+-
+- - name: wikivoyage
+- engine: mediawiki
+- weight: 0.5
+- shortcut: wy
+- categories: [general, wikimedia]
+- base_url: "https://{language}.wikivoyage.org/"
+- search_type: text
+- disabled: true
+- about:
+- website: https://www.wikivoyage.org/
+- wikidata_id: Q373
+-
+- - name: wikicommons.images
+- engine: wikicommons
+- shortcut: wc
+- categories: images
+- number_of_results: 10
+-
+- - name: wolframalpha
+- shortcut: wa
+- # You can use the engine using the official stable API, but you need an API
+- # key. See: https://products.wolframalpha.com/api/
+- #
+- # engine: wolframalpha_api
+- # api_key: ''
+- #
+- # Or you can use the html non-stable engine, activated by default
+- engine: wolframalpha_noapi
+- timeout: 6.0
+- categories: general
+- disabled: true
+-
+- - name: dictzone
+- engine: dictzone
+- shortcut: dc
+-
+- - name: mymemory translated
+- engine: translated
+- shortcut: tl
+- timeout: 5.0
+- # You can use without an API key, but you are limited to 1000 words/day
+- # See: https://mymemory.translated.net/doc/usagelimits.php
+- # api_key: ''
+-
+- # Required dependency: mysql-connector-python
+- # - name: mysql
+- # engine: mysql_server
+- # database: mydatabase
+- # username: user
+- # password: pass
+- # limit: 10
+- # query_str: 'SELECT * from mytable WHERE fieldname=%(query)s'
+- # shortcut: mysql
+-
+- - name: 1337x
+- engine: 1337x
+- shortcut: 1337x
+- disabled: true
+-
+- - name: duden
+- engine: duden
+- shortcut: du
+- disabled: true
+-
+- - name: seznam
+- shortcut: szn
+- engine: seznam
+- disabled: true
+-
+- # - name: deepl
+- # engine: deepl
+- # shortcut: dpl
+- # # You can use the engine using the official stable API, but you need an API key
+- # # See: https://www.deepl.com/pro-api?cta=header-pro-api
+- # api_key: '' # required!
+- # timeout: 5.0
+- # disabled: true
+-
+- - name: mojeek
+- shortcut: mjk
+- engine: xpath
+- paging: true
+- categories: [general, web]
+- search_url: https://www.mojeek.com/search?q={query}&s={pageno}&lang={lang}&lb={lang}
+- results_xpath: //ul[@class="results-standard"]/li/a[@class="ob"]
+- url_xpath: ./@href
+- title_xpath: ../h2/a
+- content_xpath: ..//p[@class="s"]
+- suggestion_xpath: //div[@class="top-info"]/p[@class="top-info spell"]/em/a
+- first_page_num: 0
+- page_size: 10
+- disabled: true
+- about:
+- website: https://www.mojeek.com/
+- wikidata_id: Q60747299
+- official_api_documentation: https://www.mojeek.com/services/api.html/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: moviepilot
+- engine: moviepilot
+- shortcut: mp
+- disabled: true
+-
+- - name: naver
+- shortcut: nvr
+- categories: [general, web]
+- engine: xpath
+- paging: true
+- search_url: https://search.naver.com/search.naver?where=webkr&sm=osp_hty&ie=UTF-8&query={query}&start={pageno}
+- url_xpath: //a[@class="link_tit"]/@href
+- title_xpath: //a[@class="link_tit"]
+- content_xpath: //a[@class="total_dsc"]/div
+- first_page_num: 1
+- page_size: 10
+- disabled: true
+- about:
+- website: https://www.naver.com/
+- wikidata_id: Q485639
+- official_api_documentation: https://developers.naver.com/docs/nmt/examples/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+- language: ko
+-
+- - name: rubygems
+- shortcut: rbg
+- engine: xpath
+- paging: true
+- search_url: https://rubygems.org/search?page={pageno}&query={query}
+- results_xpath: /html/body/main/div/a[@class="gems__gem"]
+- url_xpath: ./@href
+- title_xpath: ./span/h2
+- content_xpath: ./span/p
+- suggestion_xpath: /html/body/main/div/div[@class="search__suggestions"]/p/a
+- first_page_num: 1
+- categories: [it, packages]
+- disabled: true
+- about:
+- website: https://rubygems.org/
+- wikidata_id: Q1853420
+- official_api_documentation: https://guides.rubygems.org/rubygems-org-api/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: peertube
+- engine: peertube
+- shortcut: ptb
+- paging: true
+- # alternatives see: https://instances.joinpeertube.org/instances
+- # base_url: https://tube.4aem.com
+- categories: videos
+- disabled: true
+- timeout: 6.0
+-
+- - name: mediathekviewweb
+- engine: mediathekviewweb
+- shortcut: mvw
+- disabled: true
+-
+- # - name: yacy
+- # engine: yacy
+- # shortcut: ya
+- # base_url: http://localhost:8090
+- # # required if you aren't using HTTPS for your local yacy instance'
+- # enable_http: true
+- # timeout: 3.0
+- # # Yacy search mode. 'global' or 'local'.
+- # search_mode: 'global'
+-
+- - name: rumble
+- engine: rumble
+- shortcut: ru
+- base_url: https://rumble.com/
+- paging: true
+- categories: videos
+- disabled: true
+-
+- - name: wordnik
+- engine: wordnik
+- shortcut: def
+- base_url: https://www.wordnik.com/
+- categories: [dictionaries]
+- timeout: 5.0
+-
+- - name: woxikon.de synonyme
+- engine: xpath
+- shortcut: woxi
+- categories: [dictionaries]
+- timeout: 5.0
+- disabled: true
+- search_url: https://synonyme.woxikon.de/synonyme/{query}.php
+- url_xpath: //div[@class="upper-synonyms"]/a/@href
+- content_xpath: //div[@class="synonyms-list-group"]
+- title_xpath: //div[@class="upper-synonyms"]/a
+- no_result_for_http_status: [404]
+- about:
+- website: https://www.woxikon.de/
+- wikidata_id: # No Wikidata ID
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+- language: de
+-
+- - name: seekr news
+- engine: seekr
+- shortcut: senews
+- categories: news
+- seekr_category: news
+- disabled: true
+-
+- - name: seekr images
+- engine: seekr
+- network: seekr news
+- shortcut: seimg
+- categories: images
+- seekr_category: images
+- disabled: true
+-
+- - name: seekr videos
+- engine: seekr
+- network: seekr news
+- shortcut: sevid
+- categories: videos
+- seekr_category: videos
+- disabled: true
+-
+- - name: sjp.pwn
+- engine: sjp
+- shortcut: sjp
+- base_url: https://sjp.pwn.pl/
+- timeout: 5.0
+- disabled: true
+-
+- - name: svgrepo
+- engine: svgrepo
+- shortcut: svg
+- timeout: 10.0
+- disabled: true
+-
+- - name: wallhaven
+- engine: wallhaven
+- # api_key: abcdefghijklmnopqrstuvwxyz
+- shortcut: wh
+-
+- # wikimini: online encyclopedia for children
+- # The fulltext and title parameter is necessary for Wikimini because
+- # sometimes it will not show the results and redirect instead
+- - name: wikimini
+- engine: xpath
+- shortcut: wkmn
+- search_url: https://fr.wikimini.org/w/index.php?search={query}&title=Sp%C3%A9cial%3ASearch&fulltext=Search
+- url_xpath: //li/div[@class="mw-search-result-heading"]/a/@href
+- title_xpath: //li//div[@class="mw-search-result-heading"]/a
+- content_xpath: //li/div[@class="searchresult"]
+- categories: general
+- disabled: true
+- about:
+- website: https://wikimini.org/
+- wikidata_id: Q3568032
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+- language: fr
+-
+- - name: wttr.in
+- engine: wttr
+- shortcut: wttr
+- timeout: 9.0
+-
+- - name: yummly
+- engine: yummly
+- shortcut: yum
+- disabled: true
+-
+- - name: brave
+- engine: brave
+- shortcut: br
+- time_range_support: true
+- paging: true
+- categories: [general, web]
+- brave_category: search
+- # brave_spellcheck: true
+-
+- - name: brave.images
+- engine: brave
+- network: brave
+- shortcut: brimg
+- categories: [images, web]
+- brave_category: images
+-
+- - name: brave.videos
+- engine: brave
+- network: brave
+- shortcut: brvid
+- categories: [videos, web]
+- brave_category: videos
+-
+- - name: brave.news
+- engine: brave
+- network: brave
+- shortcut: brnews
+- categories: news
+- brave_category: news
+-
+- - name: lib.rs
+- shortcut: lrs
+- engine: xpath
+- search_url: https://lib.rs/search?q={query}
+- results_xpath: /html/body/main/div/ol/li/a
+- url_xpath: ./@href
+- title_xpath: ./div[@class="h"]/h4
+- content_xpath: ./div[@class="h"]/p
+- categories: [it, packages]
+- disabled: true
+- about:
+- website: https://lib.rs
+- wikidata_id: Q113486010
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: sourcehut
+- shortcut: srht
+- engine: xpath
+- paging: true
+- search_url: https://sr.ht/projects?page={pageno}&search={query}
+- results_xpath: (//div[@class="event-list"])[1]/div[@class="event"]
+- url_xpath: ./h4/a[2]/@href
+- title_xpath: ./h4/a[2]
+- content_xpath: ./p
+- first_page_num: 1
+- categories: [it, repos]
+- disabled: true
+- about:
+- website: https://sr.ht
+- wikidata_id: Q78514485
+- official_api_documentation: https://man.sr.ht/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+- - name: goo
+- shortcut: goo
+- engine: xpath
+- paging: true
+- search_url: https://search.goo.ne.jp/web.jsp?MT={query}&FR={pageno}0
+- url_xpath: //div[@class="result"]/p[@class='title fsL1']/a/@href
+- title_xpath: //div[@class="result"]/p[@class='title fsL1']/a
+- content_xpath: //p[contains(@class,'url fsM')]/following-sibling::p
+- first_page_num: 0
+- categories: [general, web]
+- disabled: true
+- timeout: 4.0
+- about:
+- website: https://search.goo.ne.jp
+- wikidata_id: Q249044
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+- language: ja
+-
+- - name: bt4g
+- engine: bt4g
+- shortcut: bt4g
+-
+- - name: pkg.go.dev
+- engine: xpath
+- shortcut: pgo
+- search_url: https://pkg.go.dev/search?limit=100&m=package&q={query}
+- results_xpath: /html/body/main/div[contains(@class,"SearchResults")]/div[not(@class)]/div[@class="SearchSnippet"]
+- url_xpath: ./div[@class="SearchSnippet-headerContainer"]/h2/a/@href
+- title_xpath: ./div[@class="SearchSnippet-headerContainer"]/h2/a
+- content_xpath: ./p[@class="SearchSnippet-synopsis"]
+- categories: [packages, it]
+- timeout: 3.0
+- disabled: true
+- about:
+- website: https://pkg.go.dev/
+- use_official_api: false
+- require_api_key: false
+- results: HTML
+-
+-# Doku engine lets you access to any Doku wiki instance:
+-# A public one or a privete/corporate one.
+-# - name: ubuntuwiki
+-# engine: doku
+-# shortcut: uw
+-# base_url: 'https://doc.ubuntu-fr.org'
+-
+-# Be careful when enabling this engine if you are
+-# running a public instance. Do not expose any sensitive
+-# information. You can restrict access by configuring a list
+-# of access tokens under tokens.
+-# - name: git grep
+-# engine: command
+-# command: ['git', 'grep', '{{QUERY}}']
+-# shortcut: gg
+-# tokens: []
+-# disabled: true
+-# delimiter:
+-# chars: ':'
+-# keys: ['filepath', 'code']
+-
+-# Be careful when enabling this engine if you are
+-# running a public instance. Do not expose any sensitive
+-# information. You can restrict access by configuring a list
+-# of access tokens under tokens.
+-# - name: locate
+-# engine: command
+-# command: ['locate', '{{QUERY}}']
+-# shortcut: loc
+-# tokens: []
+-# disabled: true
+-# delimiter:
+-# chars: ' '
+-# keys: ['line']
+-
+-# Be careful when enabling this engine if you are
+-# running a public instance. Do not expose any sensitive
+-# information. You can restrict access by configuring a list
+-# of access tokens under tokens.
+-# - name: find
+-# engine: command
+-# command: ['find', '.', '-name', '{{QUERY}}']
+-# query_type: path
+-# shortcut: fnd
+-# tokens: []
+-# disabled: true
+-# delimiter:
+-# chars: ' '
+-# keys: ['line']
+-
+-# Be careful when enabling this engine if you are
+-# running a public instance. Do not expose any sensitive
+-# information. You can restrict access by configuring a list
+-# of access tokens under tokens.
+-# - name: pattern search in files
+-# engine: command
+-# command: ['fgrep', '{{QUERY}}']
+-# shortcut: fgr
+-# tokens: []
+-# disabled: true
+-# delimiter:
+-# chars: ' '
+-# keys: ['line']
+-
+-# Be careful when enabling this engine if you are
+-# running a public instance. Do not expose any sensitive
+-# information. You can restrict access by configuring a list
+-# of access tokens under tokens.
+-# - name: regex search in files
+-# engine: command
+-# command: ['grep', '{{QUERY}}']
+-# shortcut: gr
+-# tokens: []
+-# disabled: true
+-# delimiter:
+-# chars: ' '
+-# keys: ['line']
++ #
++ # - name: annas archive
++ # engine: annas_archive
++ # disabled: true
++ # shortcut: aa
++ #
++ # # - name: annas articles
++ # # engine: annas_archive
++ # # shortcut: aaa
++ # # # https://docs.searxng.org/dev/engines/online/annas_archive.html
++ # # aa_content: 'journal_article' # book_any .. magazine, standards_document
++ # # aa_ext: 'pdf' # pdf, epub, ..
++ # # aa_sort: 'newest' # newest, oldest, largest, smallest
++ #
++ # - name: apk mirror
++ # engine: apkmirror
++ # timeout: 4.0
++ # shortcut: apkm
++ # disabled: true
++ #
++ # - name: apple app store
++ # engine: apple_app_store
++ # shortcut: aps
++ # disabled: true
++ #
++ # # Requires Tor
++ # - name: ahmia
++ # engine: ahmia
++ # categories: onions
++ # enable_http: true
++ # shortcut: ah
++ #
++ # - name: anaconda
++ # engine: xpath
++ # paging: true
++ # first_page_num: 0
++ # search_url: https://anaconda.org/search?q={query}&page={pageno}
++ # results_xpath: //tbody/tr
++ # url_xpath: ./td/h5/a[last()]/@href
++ # title_xpath: ./td/h5
++ # content_xpath: ./td[h5]/text()
++ # categories: it
++ # timeout: 6.0
++ # shortcut: conda
++ # disabled: true
++ #
++ # - name: arch linux wiki
++ # engine: archlinux
++ # shortcut: al
++ #
++ # - name: artic
++ # engine: artic
++ # shortcut: arc
++ # timeout: 4.0
++ #
++ # - name: arxiv
++ # engine: arxiv
++ # shortcut: arx
++ # timeout: 4.0
++ #
++ # # tmp suspended: dh key too small
++ # # - name: base
++ # # engine: base
++ # # shortcut: bs
++ #
++ # - name: bandcamp
++ # engine: bandcamp
++ # shortcut: bc
++ # categories: music
++ #
++ # - name: wikipedia
++ # engine: wikipedia
++ # shortcut: wp
++ # # add "list" to the array to get results in the results list
++ # display_type: ["infobox"]
++ # base_url: 'https://{language}.wikipedia.org/'
++ # categories: [general]
++ #
++ # - name: bilibili
++ # engine: bilibili
++ # shortcut: bil
++ # disabled: true
++ #
++ # - name: bing
++ # engine: bing
++ # shortcut: bi
++ # disabled: true
++ #
++ #
++ # - name: bing news
++ # engine: bing_news
++ # shortcut: bin
++ #
++ # - name: bing videos
++ # engine: bing_videos
++ # shortcut: biv
++ #
++ # - name: bitbucket
++ # engine: xpath
++ # paging: true
++ # search_url: https://bitbucket.org/repo/all/{pageno}?name={query}
++ # url_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]/@href
++ # title_xpath: //article[@class="repo-summary"]//a[@class="repo-link"]
++ # content_xpath: //article[@class="repo-summary"]/p
++ # categories: [it, repos]
++ # timeout: 4.0
++ # disabled: true
++ # shortcut: bb
++ # about:
++ # website: https://bitbucket.org/
++ # wikidata_id: Q2493781
++ # official_api_documentation: https://developer.atlassian.com/bitbucket
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: btdigg
++ # engine: btdigg
++ # shortcut: bt
++ # disabled: true
++ #
++ # - name: ccc-tv
++ # engine: xpath
++ # paging: false
++ # search_url: https://media.ccc.de/search/?q={query}
++ # url_xpath: //div[@class="caption"]/h3/a/@href
++ # title_xpath: //div[@class="caption"]/h3/a/text()
++ # content_xpath: //div[@class="caption"]/h4/@title
++ # categories: videos
++ # disabled: true
++ # shortcut: c3tv
++ # about:
++ # website: https://media.ccc.de/
++ # wikidata_id: Q80729951
++ # official_api_documentation: https://github.com/voc/voctoweb
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ # # We don't set language: de here because media.ccc.de is not just
++ # # for a German audience. It contains many English videos and many
++ # # German videos have English subtitles.
++ #
++ # - name: openverse
++ # engine: openverse
++ # categories: images
++ # shortcut: opv
++ #
++ # - name: chefkoch
++ # engine: chefkoch
++ # shortcut: chef
++ # # to show premium or plus results too:
++ # # skip_premium: false
++ #
++ # # - name: core.ac.uk
++ # # engine: core
++ # # categories: science
++ # # shortcut: cor
++ # # # get your API key from: https://core.ac.uk/api-keys/register/
++ # # api_key: 'unset'
++ #
++ # - name: crossref
++ # engine: crossref
++ # shortcut: cr
++ # timeout: 30
++ # disabled: true
++ #
++ # - name: crowdview
++ # engine: json_engine
++ # shortcut: cv
++ # categories: general
++ # paging: false
++ # search_url: https://crowdview-next-js.onrender.com/api/search-v3?query={query}
++ # results_query: results
++ # url_query: link
++ # title_query: title
++ # content_query: snippet
++ # disabled: true
++ # about:
++ # website: https://crowdview.ai/
++ #
++ # - name: yep
++ # engine: json_engine
++ # shortcut: yep
++ # categories: general
++ # disabled: true
++ # paging: false
++ # content_html_to_text: true
++ # title_html_to_text: true
++ # search_url: https://api.yep.com/fs/1/?type=web&q={query}&no_correct=false&limit=100
++ # results_query: 1/results
++ # title_query: title
++ # url_query: url
++ # content_query: snippet
++ # about:
++ # website: https://yep.com
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: curlie
++ # engine: xpath
++ # shortcut: cl
++ # categories: general
++ # disabled: true
++ # paging: true
++ # lang_all: ''
++ # search_url: https://curlie.org/search?q={query}&lang={lang}&start={pageno}&stime=92452189
++ # page_size: 20
++ # results_xpath: //div[@id="site-list-content"]/div[@class="site-item"]
++ # url_xpath: ./div[@class="title-and-desc"]/a/@href
++ # title_xpath: ./div[@class="title-and-desc"]/a/div
++ # content_xpath: ./div[@class="title-and-desc"]/div[@class="site-descr"]
++ # about:
++ # website: https://curlie.org/
++ # wikidata_id: Q60715723
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: currency
++ # engine: currency_convert
++ # categories: general
++ # shortcut: cc
++ #
++ # - name: deezer
++ # engine: deezer
++ # shortcut: dz
++ # disabled: true
++ #
++ # - name: deviantart
++ # engine: deviantart
++ # shortcut: da
++ # timeout: 3.0
++ #
++ # - name: ddg definitions
++ # engine: duckduckgo_definitions
++ # shortcut: ddd
++ # weight: 2
++ # disabled: true
++ # tests: *tests_infobox
++ #
++ # # cloudflare protected
++ # # - name: digbt
++ # # engine: digbt
++ # # shortcut: dbt
++ # # timeout: 6.0
++ # # disabled: true
++ #
++ # - name: docker hub
++ # engine: docker_hub
++ # shortcut: dh
++ # categories: [it, packages]
++ #
++ # - name: erowid
++ # engine: xpath
++ # paging: true
++ # first_page_num: 0
++ # page_size: 30
++ # search_url: https://www.erowid.org/search.php?q={query}&s={pageno}
++ # url_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/@href
++ # title_xpath: //dl[@class="results-list"]/dt[@class="result-title"]/a/text()
++ # content_xpath: //dl[@class="results-list"]/dd[@class="result-details"]
++ # categories: []
++ # shortcut: ew
++ # disabled: true
++ # about:
++ # website: https://www.erowid.org/
++ # wikidata_id: Q1430691
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # # - name: elasticsearch
++ # # shortcut: es
++ # # engine: elasticsearch
++ # # base_url: http://localhost:9200
++ # # username: elastic
++ # # password: changeme
++ # # index: my-index
++ # # # available options: match, simple_query_string, term, terms, custom
++ # # query_type: match
++ # # # if query_type is set to custom, provide your query here
++ # # #custom_query_json: {"query":{"match_all": {}}}
++ # # #show_metadata: false
++ # # disabled: true
++ #
++ # - name: wikidata
++ # engine: wikidata
++ # shortcut: wd
++ # timeout: 3.0
++ # weight: 2
++ # # add "list" to the array to get results in the results list
++ # display_type: ["infobox"]
++ # tests: *tests_infobox
++ # categories: [general]
++ #
++ # - name: duckduckgo
++ # engine: duckduckgo
++ # shortcut: ddg
++ #
++ # - name: duckduckgo images
++ # engine: duckduckgo_images
++ # shortcut: ddi
++ # timeout: 3.0
++ # disabled: true
++ #
++ # - name: duckduckgo weather
++ # engine: duckduckgo_weather
++ # shortcut: ddw
++ # disabled: true
++ #
++ # - name: apple maps
++ # engine: apple_maps
++ # shortcut: apm
++ # disabled: true
++ # timeout: 5.0
++ #
++ # - name: emojipedia
++ # engine: emojipedia
++ # timeout: 4.0
++ # shortcut: em
++ # disabled: true
++ #
++ # - name: tineye
++ # engine: tineye
++ # shortcut: tin
++ # timeout: 9.0
++ # disabled: true
++ #
++ # - name: etymonline
++ # engine: xpath
++ # paging: true
++ # search_url: https://etymonline.com/search?page={pageno}&q={query}
++ # url_xpath: //a[contains(@class, "word__name--")]/@href
++ # title_xpath: //a[contains(@class, "word__name--")]
++ # content_xpath: //section[contains(@class, "word__defination")]
++ # first_page_num: 1
++ # shortcut: et
++ # categories: [dictionaries]
++ # about:
++ # website: https://www.etymonline.com/
++ # wikidata_id: Q1188617
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # # - name: ebay
++ # # engine: ebay
++ # # shortcut: eb
++ # # base_url: 'https://www.ebay.com'
++ # # disabled: true
++ # # timeout: 5
++ #
++ # - name: 1x
++ # engine: www1x
++ # shortcut: 1x
++ # timeout: 3.0
++ # disabled: true
++ #
++ # - name: fdroid
++ # engine: fdroid
++ # shortcut: fd
++ # disabled: true
++ #
++ # - name: flickr
++ # categories: images
++ # shortcut: fl
++ # # You can use the engine using the official stable API, but you need an API
++ # # key, see: https://www.flickr.com/services/apps/create/
++ # # engine: flickr
++ # # api_key: 'apikey' # required!
++ # # Or you can use the html non-stable engine, activated by default
++ # engine: flickr_noapi
++ #
++ # - name: free software directory
++ # engine: mediawiki
++ # shortcut: fsd
++ # categories: [it, software wikis]
++ # base_url: https://directory.fsf.org/
++ # search_type: title
++ # timeout: 5.0
++ # disabled: true
++ # about:
++ # website: https://directory.fsf.org/
++ # wikidata_id: Q2470288
++ #
++ # # - name: freesound
++ # # engine: freesound
++ # # shortcut: fnd
++ # # disabled: true
++ # # timeout: 15.0
++ # # API key required, see: https://freesound.org/docs/api/overview.html
++ # # api_key: MyAPIkey
++ #
++ # - name: frinkiac
++ # engine: frinkiac
++ # shortcut: frk
++ # disabled: true
++ #
++ # - name: genius
++ # engine: genius
++ # shortcut: gen
++ #
++ # - name: gentoo
++ # engine: gentoo
++ # shortcut: ge
++ # timeout: 10.0
++ #
++ # - name: gitlab
++ # engine: json_engine
++ # paging: true
++ # search_url: https://gitlab.com/api/v4/projects?search={query}&page={pageno}
++ # url_query: web_url
++ # title_query: name_with_namespace
++ # content_query: description
++ # page_size: 20
++ # categories: [it, repos]
++ # shortcut: gl
++ # timeout: 10.0
++ # disabled: true
++ # about:
++ # website: https://about.gitlab.com/
++ # wikidata_id: Q16639197
++ # official_api_documentation: https://docs.gitlab.com/ee/api/
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: github
++ # engine: github
++ # shortcut: gh
++ #
++ # # This a Gitea service. If you would like to use a different instance,
++ # # change codeberg.org to URL of the desired Gitea host. Or you can create a
++ # # new engine by copying this and changing the name, shortcut and search_url.
++ #
++ # - name: codeberg
++ # engine: json_engine
++ # search_url: https://codeberg.org/api/v1/repos/search?q={query}&limit=10
++ # url_query: html_url
++ # title_query: name
++ # content_query: description
++ # categories: [it, repos]
++ # shortcut: cb
++ # disabled: true
++ # about:
++ # website: https://codeberg.org/
++ # wikidata_id:
++ # official_api_documentation: https://try.gitea.io/api/swagger
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ #
++ #
++ # - name: google news
++ # engine: google_news
++ # shortcut: gon
++ # # additional_tests:
++ # # android: *test_android
++ #
++ # - name: google videos
++ # engine: google_videos
++ # shortcut: gov
++ # # additional_tests:
++ # # android: *test_android
++ #
++ # - name: google scholar
++ # engine: google_scholar
++ # shortcut: gos
++ #
++ # - name: google play apps
++ # engine: google_play
++ # categories: [files, apps]
++ # shortcut: gpa
++ # play_categ: apps
++ # disabled: true
++ #
++ # - name: google play movies
++ # engine: google_play
++ # categories: videos
++ # shortcut: gpm
++ # play_categ: movies
++ # disabled: true
++ #
++ # - name: material icons
++ # engine: material_icons
++ # categories: images
++ # shortcut: mi
++ # disabled: true
++ #
++ # - name: gpodder
++ # engine: json_engine
++ # shortcut: gpod
++ # timeout: 4.0
++ # paging: false
++ # search_url: https://gpodder.net/search.json?q={query}
++ # url_query: url
++ # title_query: title
++ # content_query: description
++ # page_size: 19
++ # categories: music
++ # disabled: true
++ # about:
++ # website: https://gpodder.net
++ # wikidata_id: Q3093354
++ # official_api_documentation: https://gpoddernet.readthedocs.io/en/latest/api/
++ # use_official_api: false
++ # requires_api_key: false
++ # results: JSON
++ #
++ # - name: habrahabr
++ # engine: xpath
++ # paging: true
++ # search_url: https://habr.com/en/search/page{pageno}/?q={query}
++ # results_xpath: //article[contains(@class, "tm-articles-list__item")]
++ # url_xpath: .//a[@class="tm-title__link"]/@href
++ # title_xpath: .//a[@class="tm-title__link"]
++ # content_xpath: .//div[contains(@class, "article-formatted-body")]
++ # categories: it
++ # timeout: 4.0
++ # disabled: true
++ # shortcut: habr
++ # about:
++ # website: https://habr.com/
++ # wikidata_id: Q4494434
++ # official_api_documentation: https://habr.com/en/docs/help/api/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: hoogle
++ # engine: xpath
++ # paging: true
++ # search_url: https://hoogle.haskell.org/?hoogle={query}&start={pageno}
++ # results_xpath: '//div[@class="result"]'
++ # title_xpath: './/div[@class="ans"]//a'
++ # url_xpath: './/div[@class="ans"]//a/@href'
++ # content_xpath: './/div[@class="from"]'
++ # page_size: 20
++ # categories: [it, packages]
++ # shortcut: ho
++ # about:
++ # website: https://hoogle.haskell.org/
++ # wikidata_id: Q34010
++ # official_api_documentation: https://hackage.haskell.org/api
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: imdb
++ # engine: imdb
++ # shortcut: imdb
++ # timeout: 6.0
++ # disabled: true
++ #
++ # - name: ina
++ # engine: ina
++ # shortcut: in
++ # timeout: 6.0
++ # disabled: true
++ #
++ # - name: invidious
++ # engine: invidious
++ # # Instanes will be selected randomly, see https://api.invidious.io/ for
++ # # instances that are stable (good uptime) and close to you.
++ # base_url:
++ # - https://invidious.io.lol
++ # - https://invidious.fdn.fr
++ # - https://yt.artemislena.eu
++ # - https://invidious.tiekoetter.com
++ # - https://invidious.flokinet.to
++ # - https://vid.puffyan.us
++ # - https://invidious.privacydev.net
++ # - https://inv.tux.pizza
++ # shortcut: iv
++ # timeout: 3.0
++ # disabled: true
++ #
++ # - name: jisho
++ # engine: jisho
++ # shortcut: js
++ # timeout: 3.0
++ # disabled: true
++ #
++ # - name: kickass
++ # engine: kickass
++ # shortcut: kc
++ # timeout: 4.0
++ # disabled: true
++ #
++ # - name: lemmy communities
++ # engine: lemmy
++ # lemmy_type: Communities
++ # shortcut: leco
++ #
++ # - name: lemmy users
++ # engine: lemmy
++ # network: lemmy communities
++ # lemmy_type: Users
++ # shortcut: leus
++ #
++ # - name: lemmy posts
++ # engine: lemmy
++ # network: lemmy communities
++ # lemmy_type: Posts
++ # shortcut: lepo
++ #
++ # - name: lemmy comments
++ # engine: lemmy
++ # network: lemmy communities
++ # lemmy_type: Comments
++ # shortcut: lecom
++ #
++ # - name: library genesis
++ # engine: xpath
++ # search_url: https://libgen.fun/search.php?req={query}
++ # url_xpath: //a[contains(@href,"get.php?md5")]/@href
++ # title_xpath: //a[contains(@href,"book/")]/text()[1]
++ # content_xpath: //td/a[1][contains(@href,"=author")]/text()
++ # categories: files
++ # timeout: 7.0
++ # disabled: true
++ # shortcut: lg
++ # about:
++ # website: https://libgen.fun/
++ # wikidata_id: Q22017206
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: z-library
++ # engine: zlibrary
++ # shortcut: zlib
++ # categories: files
++ # timeout: 7.0
++ #
++ # - name: library of congress
++ # engine: loc
++ # shortcut: loc
++ # categories: images
++ #
++ # - name: lingva
++ # engine: lingva
++ # shortcut: lv
++ # # set lingva instance in url, by default it will use the official instance
++ # # url: https://lingva.ml
++ #
++ # - name: lobste.rs
++ # engine: xpath
++ # search_url: https://lobste.rs/search?utf8=%E2%9C%93&q={query}&what=stories&order=relevance
++ # results_xpath: //li[contains(@class, "story")]
++ # url_xpath: .//a[@class="u-url"]/@href
++ # title_xpath: .//a[@class="u-url"]
++ # content_xpath: .//a[@class="domain"]
++ # categories: it
++ # shortcut: lo
++ # timeout: 5.0
++ # disabled: true
++ # about:
++ # website: https://lobste.rs/
++ # wikidata_id: Q60762874
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: azlyrics
++ # shortcut: lyrics
++ # engine: xpath
++ # timeout: 4.0
++ # disabled: true
++ # categories: [music, lyrics]
++ # paging: true
++ # search_url: https://search.azlyrics.com/search.php?q={query}&w=lyrics&p={pageno}
++ # url_xpath: //td[@class="text-left visitedlyr"]/a/@href
++ # title_xpath: //span/b/text()
++ # content_xpath: //td[@class="text-left visitedlyr"]/a/small
++ # about:
++ # website: https://azlyrics.com
++ # wikidata_id: Q66372542
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: metacpan
++ # engine: metacpan
++ # shortcut: cpan
++ # disabled: true
++ # number_of_results: 20
++ #
++ # # - name: meilisearch
++ # # engine: meilisearch
++ # # shortcut: mes
++ # # enable_http: true
++ # # base_url: http://localhost:7700
++ # # index: my-index
++ #
++ # - name: mixcloud
++ # engine: mixcloud
++ # shortcut: mc
++ #
++ # # MongoDB engine
++ # # Required dependency: pymongo
++ # # - name: mymongo
++ # # engine: mongodb
++ # # shortcut: md
++ # # exact_match_only: false
++ # # host: '127.0.0.1'
++ # # port: 27017
++ # # enable_http: true
++ # # results_per_page: 20
++ # # database: 'business'
++ # # collection: 'reviews' # name of the db collection
++ # # key: 'name' # key in the collection to search for
++ #
++ # - name: mwmbl
++ # engine: mwmbl
++ # # api_url: https://api.mwmbl.org
++ # shortcut: mwm
++ # disabled: true
++ #
++ # - name: npm
++ # engine: json_engine
++ # paging: true
++ # first_page_num: 0
++ # search_url: https://api.npms.io/v2/search?q={query}&size=25&from={pageno}
++ # results_query: results
++ # url_query: package/links/npm
++ # title_query: package/name
++ # content_query: package/description
++ # page_size: 25
++ # categories: [it, packages]
++ # disabled: true
++ # timeout: 5.0
++ # shortcut: npm
++ # about:
++ # website: https://npms.io/
++ # wikidata_id: Q7067518
++ # official_api_documentation: https://api-docs.npms.io/
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: nyaa
++ # engine: nyaa
++ # shortcut: nt
++ # disabled: true
++ #
++ # - name: mankier
++ # engine: json_engine
++ # search_url: https://www.mankier.com/api/v2/mans/?q={query}
++ # results_query: results
++ # url_query: url
++ # title_query: name
++ # content_query: description
++ # categories: it
++ # shortcut: man
++ # about:
++ # website: https://www.mankier.com/
++ # official_api_documentation: https://www.mankier.com/api
++ # use_official_api: true
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: odysee
++ # engine: odysee
++ # shortcut: od
++ # disabled: true
++ #
++ # - name: openairedatasets
++ # engine: json_engine
++ # paging: true
++ # search_url: https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
++ # results_query: response/results/result
++ # url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
++ # title_query: metadata/oaf:entity/oaf:result/title/$
++ # content_query: metadata/oaf:entity/oaf:result/description/$
++ # content_html_to_text: true
++ # categories: "science"
++ # shortcut: oad
++ # timeout: 5.0
++ # about:
++ # website: https://www.openaire.eu/
++ # wikidata_id: Q25106053
++ # official_api_documentation: https://api.openaire.eu/
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: openairepublications
++ # engine: json_engine
++ # paging: true
++ # search_url: https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
++ # results_query: response/results/result
++ # url_query: metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
++ # title_query: metadata/oaf:entity/oaf:result/title/$
++ # content_query: metadata/oaf:entity/oaf:result/description/$
++ # content_html_to_text: true
++ # categories: science
++ # shortcut: oap
++ # timeout: 5.0
++ # about:
++ # website: https://www.openaire.eu/
++ # wikidata_id: Q25106053
++ # official_api_documentation: https://api.openaire.eu/
++ # use_official_api: false
++ # require_api_key: false
++ # results: JSON
++ #
++ # # - name: opensemanticsearch
++ # # engine: opensemantic
++ # # shortcut: oss
++ # # base_url: 'http://localhost:8983/solr/opensemanticsearch/'
++ #
++ # - name: openstreetmap
++ # engine: openstreetmap
++ # shortcut: osm
++ #
++ # - name: openrepos
++ # engine: xpath
++ # paging: true
++ # search_url: https://openrepos.net/search/node/{query}?page={pageno}
++ # url_xpath: //li[@class="search-result"]//h3[@class="title"]/a/@href
++ # title_xpath: //li[@class="search-result"]//h3[@class="title"]/a
++ # content_xpath: //li[@class="search-result"]//div[@class="search-snippet-info"]//p[@class="search-snippet"]
++ # categories: files
++ # timeout: 4.0
++ # disabled: true
++ # shortcut: or
++ # about:
++ # website: https://openrepos.net/
++ # wikidata_id:
++ # official_api_documentation:
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: packagist
++ # engine: json_engine
++ # paging: true
++ # search_url: https://packagist.org/search.json?q={query}&page={pageno}
++ # results_query: results
++ # url_query: url
++ # title_query: name
++ # content_query: description
++ # categories: [it, packages]
++ # disabled: true
++ # timeout: 5.0
++ # shortcut: pack
++ # about:
++ # website: https://packagist.org
++ # wikidata_id: Q108311377
++ # official_api_documentation: https://packagist.org/apidoc
++ # use_official_api: true
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: pdbe
++ # engine: pdbe
++ # shortcut: pdb
++ # # Hide obsolete PDB entries. Default is not to hide obsolete structures
++ # # hide_obsolete: false
++ #
++ # - name: photon
++ # engine: photon
++ # shortcut: ph
++ #
++ # - name: piped
++ # engine: piped
++ # shortcut: ppd
++ # categories: videos
++ # piped_filter: videos
++ # timeout: 3.0
++ #
++ # # URL to use as link and for embeds
++ # frontend_url: https://srv.piped.video
++ # # Instance will be selected randomly, for more see https://piped-instances.kavin.rocks/
++ # backend_url:
++ # - https://pipedapi.kavin.rocks
++ # - https://pipedapi-libre.kavin.rocks
++ # - https://pipedapi.adminforge.de
++ #
++ # - name: piped.music
++ # engine: piped
++ # network: piped
++ # shortcut: ppdm
++ # categories: music
++ # piped_filter: music_songs
++ # timeout: 3.0
++ #
++ # - name: piratebay
++ # engine: piratebay
++ # shortcut: tpb
++ # # You may need to change this URL to a proxy if piratebay is blocked in your
++ # # country
++ # url: https://thepiratebay.org/
++ # timeout: 3.0
++ #
++ # # Required dependency: psychopg2
++ # # - name: postgresql
++ # # engine: postgresql
++ # # database: postgres
++ # # username: postgres
++ # # password: postgres
++ # # limit: 10
++ # # query_str: 'SELECT * from my_table WHERE my_column = %(query)s'
++ # # shortcut : psql
++ #
++ # - name: pub.dev
++ # engine: xpath
++ # shortcut: pd
++ # search_url: https://pub.dev/packages?q={query}&page={pageno}
++ # paging: true
++ # results_xpath: //div[contains(@class,"packages-item")]
++ # url_xpath: ./div/h3/a/@href
++ # title_xpath: ./div/h3/a
++ # content_xpath: ./div/div/div[contains(@class,"packages-description")]/span
++ # categories: [packages, it]
++ # timeout: 3.0
++ # disabled: true
++ # first_page_num: 1
++ # about:
++ # website: https://pub.dev/
++ # official_api_documentation: https://pub.dev/help/api
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: pubmed
++ # engine: pubmed
++ # shortcut: pub
++ # timeout: 3.0
++ #
++ # - name: pypi
++ # shortcut: pypi
++ # engine: xpath
++ # paging: true
++ # search_url: https://pypi.org/search/?q={query}&page={pageno}
++ # results_xpath: /html/body/main/div/div/div/form/div/ul/li/a[@class="package-snippet"]
++ # url_xpath: ./@href
++ # title_xpath: ./h3/span[@class="package-snippet__name"]
++ # content_xpath: ./p
++ # suggestion_xpath: /html/body/main/div/div/div/form/div/div[@class="callout-block"]/p/span/a[@class="link"]
++ # first_page_num: 1
++ # categories: [it, packages]
++ # about:
++ # website: https://pypi.org
++ # wikidata_id: Q2984686
++ # official_api_documentation: https://warehouse.readthedocs.io/api-reference/index.html
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: qwant
++ # qwant_categ: web
++ # engine: qwant
++ # shortcut: qw
++ # categories: [general, web]
++ # additional_tests:
++ # rosebud: *test_rosebud
++ #
++ # - name: qwant news
++ # qwant_categ: news
++ # engine: qwant
++ # shortcut: qwn
++ # categories: news
++ # network: qwant
++ #
++ # - name: qwant images
++ # qwant_categ: images
++ # engine: qwant
++ # shortcut: qwi
++ # categories: [images, web]
++ # network: qwant
++ #
++ # - name: qwant videos
++ # qwant_categ: videos
++ # engine: qwant
++ # shortcut: qwv
++ # categories: [videos, web]
++ # network: qwant
++ #
++ # # - name: library
++ # # engine: recoll
++ # # shortcut: lib
++ # # base_url: 'https://recoll.example.org/'
++ # # search_dir: ''
++ # # mount_prefix: /export
++ # # dl_prefix: 'https://download.example.org'
++ # # timeout: 30.0
++ # # categories: files
++ # # disabled: true
++ #
++ # # - name: recoll library reference
++ # # engine: recoll
++ # # base_url: 'https://recoll.example.org/'
++ # # search_dir: reference
++ # # mount_prefix: /export
++ # # dl_prefix: 'https://download.example.org'
++ # # shortcut: libr
++ # # timeout: 30.0
++ # # categories: files
++ # # disabled: true
++ #
++ # - name: reddit
++ # engine: reddit
++ # shortcut: re
++ # page_size: 25
++ #
++ # # Required dependency: redis
++ # # - name: myredis
++ # # shortcut : rds
++ # # engine: redis_server
++ # # exact_match_only: false
++ # # host: '127.0.0.1'
++ # # port: 6379
++ # # enable_http: true
++ # # password: ''
++ # # db: 0
++ #
++ # # tmp suspended: bad certificate
++ # # - name: scanr structures
++ # # shortcut: scs
++ # # engine: scanr_structures
++ # # disabled: true
++ #
++ # - name: sepiasearch
++ # engine: sepiasearch
++ # shortcut: sep
++ #
++ # - name: soundcloud
++ # engine: soundcloud
++ # shortcut: sc
++ #
++ # - name: stackoverflow
++ # engine: stackexchange
++ # shortcut: st
++ # api_site: 'stackoverflow'
++ # categories: [it, q&a]
++ #
++ # - name: askubuntu
++ # engine: stackexchange
++ # shortcut: ubuntu
++ # api_site: 'askubuntu'
++ # categories: [it, q&a]
++ #
++ # - name: internetarchivescholar
++ # engine: internet_archive_scholar
++ # shortcut: ias
++ # timeout: 5.0
++ #
++ # - name: superuser
++ # engine: stackexchange
++ # shortcut: su
++ # api_site: 'superuser'
++ # categories: [it, q&a]
++ #
++ # - name: searchcode code
++ # engine: searchcode_code
++ # shortcut: scc
++ # disabled: true
++ #
++ # - name: framalibre
++ # engine: framalibre
++ # shortcut: frl
++ # disabled: true
++ #
++ # # - name: searx
++ # # engine: searx_engine
++ # # shortcut: se
++ # # instance_urls :
++ # # - http://127.0.0.1:8888/
++ # # - ...
++ # # disabled: true
++ #
++ # - name: semantic scholar
++ # engine: semantic_scholar
++ # disabled: true
++ # shortcut: se
++ #
++ # # Spotify needs API credentials
++ # # - name: spotify
++ # # engine: spotify
++ # # shortcut: stf
++ # # api_client_id: *******
++ # # api_client_secret: *******
++ #
++ # # - name: solr
++ # # engine: solr
++ # # shortcut: slr
++ # # base_url: http://localhost:8983
++ # # collection: collection_name
++ # # sort: '' # sorting: asc or desc
++ # # field_list: '' # comma separated list of field names to display on the UI
++ # # default_fields: '' # default field to query
++ # # query_fields: '' # query fields
++ # # enable_http: true
++ #
++ # # - name: springer nature
++ # # engine: springer
++ # # # get your API key from: https://dev.springernature.com/signup
++ # # # working API key, for test & debug: "a69685087d07eca9f13db62f65b8f601"
++ # # api_key: 'unset'
++ # # shortcut: springer
++ # # timeout: 15.0
++ #
++ # - name: startpage
++ # engine: startpage
++ # shortcut: sp
++ # timeout: 6.0
++ # disabled: true
++ # additional_tests:
++ # rosebud: *test_rosebud
++ #
++ # - name: tokyotoshokan
++ # engine: tokyotoshokan
++ # shortcut: tt
++ # timeout: 6.0
++ # disabled: true
++ #
++ # - name: solidtorrents
++ # engine: solidtorrents
++ # shortcut: solid
++ # timeout: 4.0
++ # base_url:
++ # - https://solidtorrents.to
++ # - https://bitsearch.to
++ #
++ # # For this demo of the sqlite engine download:
++ # # https://liste.mediathekview.de/filmliste-v2.db.bz2
++ # # and unpack into searx/data/filmliste-v2.db
++ # # Query to test: "!demo concert"
++ # #
++ # # - name: demo
++ # # engine: sqlite
++ # # shortcut: demo
++ # # categories: general
++ # # result_template: default.html
++ # # database: searx/data/filmliste-v2.db
++ # # query_str: >-
++ # # SELECT title || ' (' || time(duration, 'unixepoch') || ')' AS title,
++ # # COALESCE( NULLIF(url_video_hd,''), NULLIF(url_video_sd,''), url_video) AS url,
++ # # description AS content
++ # # FROM film
++ # # WHERE title LIKE :wildcard OR description LIKE :wildcard
++ # # ORDER BY duration DESC
++ #
++ # - name: tagesschau
++ # engine: tagesschau
++ # shortcut: ts
++ # disabled: true
++ #
++ # - name: tmdb
++ # engine: xpath
++ # paging: true
++ # search_url: https://www.themoviedb.org/search?page={pageno}&query={query}
++ # results_xpath: //div[contains(@class,"movie") or contains(@class,"tv")]//div[contains(@class,"card")]
++ # url_xpath: .//div[contains(@class,"poster")]/a/@href
++ # thumbnail_xpath: .//img/@src
++ # title_xpath: .//div[contains(@class,"title")]//h2
++ # content_xpath: .//div[contains(@class,"overview")]
++ # shortcut: tm
++ # disabled: true
++ #
++ # # Requires Tor
++ # - name: torch
++ # engine: xpath
++ # paging: true
++ # search_url:
++ # http://xmh57jrknzkhv6y3ls3ubitzfqnkrwxhopf5aygthi7d6rplyvk3noyd.onion/cgi-bin/omega/omega?P={query}&DEFAULTOP=and
++ # results_xpath: //table//tr
++ # url_xpath: ./td[2]/a
++ # title_xpath: ./td[2]/b
++ # content_xpath: ./td[2]/small
++ # categories: onions
++ # enable_http: true
++ # shortcut: tch
++ #
++ # # torznab engine lets you query any torznab compatible indexer. Using this
++ # # engine in combination with Jackett opens the possibility to query a lot of
++ # # public and private indexers directly from SearXNG. More details at:
++ # # https://docs.searxng.org/dev/engines/online/torznab.html
++ # #
++ # # - name: Torznab EZTV
++ # # engine: torznab
++ # # shortcut: eztv
++ # # base_url: http://localhost:9117/api/v2.0/indexers/eztv/results/torznab
++ # # enable_http: true # if using localhost
++ # # api_key: xxxxxxxxxxxxxxx
++ # # show_magnet_links: true
++ # # show_torrent_files: false
++ # # # https://github.com/Jackett/Jackett/wiki/Jackett-Categories
++ # # torznab_categories: # optional
++ # # - 2000
++ # # - 5000
++ #
++ # - name: twitter
++ # shortcut: tw
++ # engine: twitter
++ # disabled: true
++ #
++ # # tmp suspended - too slow, too many errors
++ # # - name: urbandictionary
++ # # engine : xpath
++ # # search_url : https://www.urbandictionary.com/define.php?term={query}
++ # # url_xpath : //*[@class="word"]/@href
++ # # title_xpath : //*[@class="def-header"]
++ # # content_xpath: //*[@class="meaning"]
++ # # shortcut: ud
++ #
++ # - name: unsplash
++ # engine: unsplash
++ # shortcut: us
++ #
++ # - name: yahoo
++ # engine: yahoo
++ # shortcut: yh
++ # disabled: true
++ #
++ # - name: yahoo news
++ # engine: yahoo_news
++ # shortcut: yhn
++ #
++ # - name: youtube
++ # shortcut: yt
++ # # You can use the engine using the official stable API, but you need an API
++ # # key See: https://console.developers.google.com/project
++ # #
++ # # engine: youtube_api
++ # # api_key: 'apikey' # required!
++ # #
++ # # Or you can use the html non-stable engine, activated by default
++ # engine: youtube_noapi
++ #
++ # - name: dailymotion
++ # engine: dailymotion
++ # shortcut: dm
++ #
++ # - name: vimeo
++ # engine: vimeo
++ # shortcut: vm
++ #
++ # - name: wiby
++ # engine: json_engine
++ # paging: true
++ # search_url: https://wiby.me/json/?q={query}&p={pageno}
++ # url_query: URL
++ # title_query: Title
++ # content_query: Snippet
++ # categories: [general, web]
++ # shortcut: wib
++ # disabled: true
++ # about:
++ # website: https://wiby.me/
++ #
++ # - name: alexandria
++ # engine: json_engine
++ # shortcut: alx
++ # categories: general
++ # paging: true
++ # search_url: https://api.alexandria.org/?a=1&q={query}&p={pageno}
++ # results_query: results
++ # title_query: title
++ # url_query: url
++ # content_query: snippet
++ # timeout: 1.5
++ # disabled: true
++ # about:
++ # website: https://alexandria.org/
++ # official_api_documentation: https://github.com/alexandria-org/alexandria-api/raw/master/README.md
++ # use_official_api: true
++ # require_api_key: false
++ # results: JSON
++ #
++ # - name: wikibooks
++ # engine: mediawiki
++ # weight: 0.5
++ # shortcut: wb
++ # categories: [general, wikimedia]
++ # base_url: "https://{language}.wikibooks.org/"
++ # search_type: text
++ # disabled: true
++ # about:
++ # website: https://www.wikibooks.org/
++ # wikidata_id: Q367
++ #
++ # - name: wikinews
++ # engine: mediawiki
++ # shortcut: wn
++ # categories: [news, wikimedia]
++ # base_url: "https://{language}.wikinews.org/"
++ # search_type: text
++ # srsort: create_timestamp_desc
++ # about:
++ # website: https://www.wikinews.org/
++ # wikidata_id: Q964
++ #
++ # - name: wikiquote
++ # engine: mediawiki
++ # weight: 0.5
++ # shortcut: wq
++ # categories: [general, wikimedia]
++ # base_url: "https://{language}.wikiquote.org/"
++ # search_type: text
++ # disabled: true
++ # additional_tests:
++ # rosebud: *test_rosebud
++ # about:
++ # website: https://www.wikiquote.org/
++ # wikidata_id: Q369
++ #
++ # - name: wikisource
++ # engine: mediawiki
++ # weight: 0.5
++ # shortcut: ws
++ # categories: [general, wikimedia]
++ # base_url: "https://{language}.wikisource.org/"
++ # search_type: text
++ # disabled: true
++ # about:
++ # website: https://www.wikisource.org/
++ # wikidata_id: Q263
++ #
++ # - name: wikispecies
++ # engine: mediawiki
++ # shortcut: wsp
++ # categories: [general, science, wikimedia]
++ # base_url: "https://species.wikimedia.org/"
++ # search_type: text
++ # disabled: true
++ # about:
++ # website: https://species.wikimedia.org/
++ # wikidata_id: Q13679
++ #
++ # - name: wiktionary
++ # engine: mediawiki
++ # shortcut: wt
++ # categories: [dictionaries, wikimedia]
++ # base_url: "https://{language}.wiktionary.org/"
++ # search_type: text
++ # about:
++ # website: https://www.wiktionary.org/
++ # wikidata_id: Q151
++ #
++ # - name: wikiversity
++ # engine: mediawiki
++ # weight: 0.5
++ # shortcut: wv
++ # categories: [general, wikimedia]
++ # base_url: "https://{language}.wikiversity.org/"
++ # search_type: text
++ # disabled: true
++ # about:
++ # website: https://www.wikiversity.org/
++ # wikidata_id: Q370
++ #
++ # - name: wikivoyage
++ # engine: mediawiki
++ # weight: 0.5
++ # shortcut: wy
++ # categories: [general, wikimedia]
++ # base_url: "https://{language}.wikivoyage.org/"
++ # search_type: text
++ # disabled: true
++ # about:
++ # website: https://www.wikivoyage.org/
++ # wikidata_id: Q373
++ #
++ # - name: wikicommons.images
++ # engine: wikicommons
++ # shortcut: wc
++ # categories: images
++ # number_of_results: 10
++ #
++ # - name: wolframalpha
++ # shortcut: wa
++ # # You can use the engine using the official stable API, but you need an API
++ # # key. See: https://products.wolframalpha.com/api/
++ # #
++ # # engine: wolframalpha_api
++ # # api_key: ''
++ # #
++ # # Or you can use the html non-stable engine, activated by default
++ # engine: wolframalpha_noapi
++ # timeout: 6.0
++ # categories: general
++ # disabled: true
++ #
++ # - name: dictzone
++ # engine: dictzone
++ # shortcut: dc
++ #
++ # - name: mymemory translated
++ # engine: translated
++ # shortcut: tl
++ # timeout: 5.0
++ # # You can use without an API key, but you are limited to 1000 words/day
++ # # See: https://mymemory.translated.net/doc/usagelimits.php
++ # # api_key: ''
++ #
++ # # Required dependency: mysql-connector-python
++ # # - name: mysql
++ # # engine: mysql_server
++ # # database: mydatabase
++ # # username: user
++ # # password: pass
++ # # limit: 10
++ # # query_str: 'SELECT * from mytable WHERE fieldname=%(query)s'
++ # # shortcut: mysql
++ #
++ # - name: 1337x
++ # engine: 1337x
++ # shortcut: 1337x
++ # disabled: true
++ #
++ # - name: duden
++ # engine: duden
++ # shortcut: du
++ # disabled: true
++ #
++ # - name: seznam
++ # shortcut: szn
++ # engine: seznam
++ # disabled: true
++ #
++ # # - name: deepl
++ # # engine: deepl
++ # # shortcut: dpl
++ # # # You can use the engine using the official stable API, but you need an API key
++ # # # See: https://www.deepl.com/pro-api?cta=header-pro-api
++ # # api_key: '' # required!
++ # # timeout: 5.0
++ # # disabled: true
++ #
++ # - name: mojeek
++ # shortcut: mjk
++ # engine: xpath
++ # paging: true
++ # categories: [general, web]
++ # search_url: https://www.mojeek.com/search?q={query}&s={pageno}&lang={lang}&lb={lang}
++ # results_xpath: //ul[@class="results-standard"]/li/a[@class="ob"]
++ # url_xpath: ./@href
++ # title_xpath: ../h2/a
++ # content_xpath: ..//p[@class="s"]
++ # suggestion_xpath: //div[@class="top-info"]/p[@class="top-info spell"]/em/a
++ # first_page_num: 0
++ # page_size: 10
++ # disabled: true
++ # about:
++ # website: https://www.mojeek.com/
++ # wikidata_id: Q60747299
++ # official_api_documentation: https://www.mojeek.com/services/api.html/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: moviepilot
++ # engine: moviepilot
++ # shortcut: mp
++ # disabled: true
++ #
++ # - name: naver
++ # shortcut: nvr
++ # categories: [general, web]
++ # engine: xpath
++ # paging: true
++ # search_url: https://search.naver.com/search.naver?where=webkr&sm=osp_hty&ie=UTF-8&query={query}&start={pageno}
++ # url_xpath: //a[@class="link_tit"]/@href
++ # title_xpath: //a[@class="link_tit"]
++ # content_xpath: //a[@class="total_dsc"]/div
++ # first_page_num: 1
++ # page_size: 10
++ # disabled: true
++ # about:
++ # website: https://www.naver.com/
++ # wikidata_id: Q485639
++ # official_api_documentation: https://developers.naver.com/docs/nmt/examples/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ # language: ko
++ #
++ # - name: rubygems
++ # shortcut: rbg
++ # engine: xpath
++ # paging: true
++ # search_url: https://rubygems.org/search?page={pageno}&query={query}
++ # results_xpath: /html/body/main/div/a[@class="gems__gem"]
++ # url_xpath: ./@href
++ # title_xpath: ./span/h2
++ # content_xpath: ./span/p
++ # suggestion_xpath: /html/body/main/div/div[@class="search__suggestions"]/p/a
++ # first_page_num: 1
++ # categories: [it, packages]
++ # disabled: true
++ # about:
++ # website: https://rubygems.org/
++ # wikidata_id: Q1853420
++ # official_api_documentation: https://guides.rubygems.org/rubygems-org-api/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: peertube
++ # engine: peertube
++ # shortcut: ptb
++ # paging: true
++ # # alternatives see: https://instances.joinpeertube.org/instances
++ # # base_url: https://tube.4aem.com
++ # categories: videos
++ # disabled: true
++ # timeout: 6.0
++ #
++ # - name: mediathekviewweb
++ # engine: mediathekviewweb
++ # shortcut: mvw
++ # disabled: true
++ #
++ # # - name: yacy
++ # # engine: yacy
++ # # shortcut: ya
++ # # base_url: http://localhost:8090
++ # # # required if you aren't using HTTPS for your local yacy instance'
++ # # enable_http: true
++ # # timeout: 3.0
++ # # # Yacy search mode. 'global' or 'local'.
++ # # search_mode: 'global'
++ #
++ # - name: rumble
++ # engine: rumble
++ # shortcut: ru
++ # base_url: https://rumble.com/
++ # paging: true
++ # categories: videos
++ # disabled: true
++ #
++ # - name: wordnik
++ # engine: wordnik
++ # shortcut: def
++ # base_url: https://www.wordnik.com/
++ # categories: [dictionaries]
++ # timeout: 5.0
++ #
++ # - name: woxikon.de synonyme
++ # engine: xpath
++ # shortcut: woxi
++ # categories: [dictionaries]
++ # timeout: 5.0
++ # disabled: true
++ # search_url: https://synonyme.woxikon.de/synonyme/{query}.php
++ # url_xpath: //div[@class="upper-synonyms"]/a/@href
++ # content_xpath: //div[@class="synonyms-list-group"]
++ # title_xpath: //div[@class="upper-synonyms"]/a
++ # no_result_for_http_status: [404]
++ # about:
++ # website: https://www.woxikon.de/
++ # wikidata_id: # No Wikidata ID
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ # language: de
++ #
++ # - name: seekr news
++ # engine: seekr
++ # shortcut: senews
++ # categories: news
++ # seekr_category: news
++ # disabled: true
++ #
++ # - name: seekr images
++ # engine: seekr
++ # network: seekr news
++ # shortcut: seimg
++ # categories: images
++ # seekr_category: images
++ # disabled: true
++ #
++ # - name: seekr videos
++ # engine: seekr
++ # network: seekr news
++ # shortcut: sevid
++ # categories: videos
++ # seekr_category: videos
++ # disabled: true
++ #
++ # - name: sjp.pwn
++ # engine: sjp
++ # shortcut: sjp
++ # base_url: https://sjp.pwn.pl/
++ # timeout: 5.0
++ # disabled: true
++ #
++ # - name: svgrepo
++ # engine: svgrepo
++ # shortcut: svg
++ # timeout: 10.0
++ # disabled: true
++ #
++ # - name: wallhaven
++ # engine: wallhaven
++ # # api_key: abcdefghijklmnopqrstuvwxyz
++ # shortcut: wh
++ #
++ # # wikimini: online encyclopedia for children
++ # # The fulltext and title parameter is necessary for Wikimini because
++ # # sometimes it will not show the results and redirect instead
++ # - name: wikimini
++ # engine: xpath
++ # shortcut: wkmn
++ # search_url: https://fr.wikimini.org/w/index.php?search={query}&title=Sp%C3%A9cial%3ASearch&fulltext=Search
++ # url_xpath: //li/div[@class="mw-search-result-heading"]/a/@href
++ # title_xpath: //li//div[@class="mw-search-result-heading"]/a
++ # content_xpath: //li/div[@class="searchresult"]
++ # categories: general
++ # disabled: true
++ # about:
++ # website: https://wikimini.org/
++ # wikidata_id: Q3568032
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ # language: fr
++ #
++ # - name: wttr.in
++ # engine: wttr
++ # shortcut: wttr
++ # timeout: 9.0
++ #
++ # - name: yummly
++ # engine: yummly
++ # shortcut: yum
++ # disabled: true
++ #
++ # - name: brave
++ # engine: brave
++ # shortcut: br
++ # time_range_support: true
++ # paging: true
++ # categories: [general, web]
++ # brave_category: search
++ # # brave_spellcheck: true
++ #
++ # - name: brave.images
++ # engine: brave
++ # network: brave
++ # shortcut: brimg
++ # categories: [images, web]
++ # brave_category: images
++ #
++ # - name: brave.videos
++ # engine: brave
++ # network: brave
++ # shortcut: brvid
++ # categories: [videos, web]
++ # brave_category: videos
++ #
++ # - name: brave.news
++ # engine: brave
++ # network: brave
++ # shortcut: brnews
++ # categories: news
++ # brave_category: news
++ #
++ # - name: lib.rs
++ # shortcut: lrs
++ # engine: xpath
++ # search_url: https://lib.rs/search?q={query}
++ # results_xpath: /html/body/main/div/ol/li/a
++ # url_xpath: ./@href
++ # title_xpath: ./div[@class="h"]/h4
++ # content_xpath: ./div[@class="h"]/p
++ # categories: [it, packages]
++ # disabled: true
++ # about:
++ # website: https://lib.rs
++ # wikidata_id: Q113486010
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: sourcehut
++ # shortcut: srht
++ # engine: xpath
++ # paging: true
++ # search_url: https://sr.ht/projects?page={pageno}&search={query}
++ # results_xpath: (//div[@class="event-list"])[1]/div[@class="event"]
++ # url_xpath: ./h4/a[2]/@href
++ # title_xpath: ./h4/a[2]
++ # content_xpath: ./p
++ # first_page_num: 1
++ # categories: [it, repos]
++ # disabled: true
++ # about:
++ # website: https://sr.ht
++ # wikidata_id: Q78514485
++ # official_api_documentation: https://man.sr.ht/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ # - name: goo
++ # shortcut: goo
++ # engine: xpath
++ # paging: true
++ # search_url: https://search.goo.ne.jp/web.jsp?MT={query}&FR={pageno}0
++ # url_xpath: //div[@class="result"]/p[@class='title fsL1']/a/@href
++ # title_xpath: //div[@class="result"]/p[@class='title fsL1']/a
++ # content_xpath: //p[contains(@class,'url fsM')]/following-sibling::p
++ # first_page_num: 0
++ # categories: [general, web]
++ # disabled: true
++ # timeout: 4.0
++ # about:
++ # website: https://search.goo.ne.jp
++ # wikidata_id: Q249044
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ # language: ja
++ #
++ # - name: bt4g
++ # engine: bt4g
++ # shortcut: bt4g
++ #
++ # - name: pkg.go.dev
++ # engine: xpath
++ # shortcut: pgo
++ # search_url: https://pkg.go.dev/search?limit=100&m=package&q={query}
++ # results_xpath: /html/body/main/div[contains(@class,"SearchResults")]/div[not(@class)]/div[@class="SearchSnippet"]
++ # url_xpath: ./div[@class="SearchSnippet-headerContainer"]/h2/a/@href
++ # title_xpath: ./div[@class="SearchSnippet-headerContainer"]/h2/a
++ # content_xpath: ./p[@class="SearchSnippet-synopsis"]
++ # categories: [packages, it]
++ # timeout: 3.0
++ # disabled: true
++ # about:
++ # website: https://pkg.go.dev/
++ # use_official_api: false
++ # require_api_key: false
++ # results: HTML
++ #
++ ## Doku engine lets you access to any Doku wiki instance:
++ ## A public one or a privete/corporate one.
++ ## - name: ubuntuwiki
++ ## engine: doku
++ ## shortcut: uw
++ ## base_url: 'https://doc.ubuntu-fr.org'
++ #
++ ## Be careful when enabling this engine if you are
++ ## running a public instance. Do not expose any sensitive
++ ## information. You can restrict access by configuring a list
++ ## of access tokens under tokens.
++ ## - name: git grep
++ ## engine: command
++ ## command: ['git', 'grep', '{{QUERY}}']
++ ## shortcut: gg
++ ## tokens: []
++ ## disabled: true
++ ## delimiter:
++ ## chars: ':'
++ ## keys: ['filepath', 'code']
++ #
++ ## Be careful when enabling this engine if you are
++ ## running a public instance. Do not expose any sensitive
++ ## information. You can restrict access by configuring a list
++ ## of access tokens under tokens.
++ ## - name: locate
++ ## engine: command
++ ## command: ['locate', '{{QUERY}}']
++ ## shortcut: loc
++ ## tokens: []
++ ## disabled: true
++ ## delimiter:
++ ## chars: ' '
++ ## keys: ['line']
++ #
++ ## Be careful when enabling this engine if you are
++ ## running a public instance. Do not expose any sensitive
++ ## information. You can restrict access by configuring a list
++ ## of access tokens under tokens.
++ ## - name: find
++ ## engine: command
++ ## command: ['find', '.', '-name', '{{QUERY}}']
++ ## query_type: path
++ ## shortcut: fnd
++ ## tokens: []
++ ## disabled: true
++ ## delimiter:
++ ## chars: ' '
++ ## keys: ['line']
++ #
++ ## Be careful when enabling this engine if you are
++ ## running a public instance. Do not expose any sensitive
++ ## information. You can restrict access by configuring a list
++ ## of access tokens under tokens.
++ ## - name: pattern search in files
++ ## engine: command
++ ## command: ['fgrep', '{{QUERY}}']
++ ## shortcut: fgr
++ ## tokens: []
++ ## disabled: true
++ ## delimiter:
++ ## chars: ' '
++ ## keys: ['line']
++ #
++ ## Be careful when enabling this engine if you are
++ ## running a public instance. Do not expose any sensitive
++ ## information. You can restrict access by configuring a list
++ ## of access tokens under tokens.
++ ## - name: regex search in files
++ ## engine: command
++ ## command: ['grep', '{{QUERY}}']
++ ## shortcut: gr
++ ## tokens: []
++ ## disabled: true
++ ## delimiter:
++ ## chars: ' '
++ ## keys: ['line']
+
+ doi_resolvers:
+ oadoi.org: 'https://oadoi.org/'
diff --git a/src/portal/patches/snscrape_1036.diff b/src/portal/patches/snscrape_1036.diff
new file mode 100644
index 0000000..0512f56
--- /dev/null
+++ b/src/portal/patches/snscrape_1036.diff
@@ -0,0 +1,28 @@
+diff --git a/.editorconfig b/.editorconfig
+new file mode 100644
+index 0000000..e7c6935
+--- /dev/null
++++ b/.editorconfig
+@@ -0,0 +1,3 @@
++[*.py]
++indent_style = tab
++tab_width = 8
+diff --git a/snscrape/modules/__init__.py b/snscrape/modules/__init__.py
+index e15a7b9..8963b93 100644
+--- a/snscrape/modules/__init__.py
++++ b/snscrape/modules/__init__.py
+@@ -1,4 +1,5 @@
+ import pkgutil
++import importlib
+
+
+ __all__ = []
+@@ -10,7 +11,7 @@ def _import_modules():
+ assert not isPkg
+ moduleNameWithoutPrefix = moduleName[prefixLen:]
+ __all__.append(moduleNameWithoutPrefix)
+- module = importer.find_module(moduleName).load_module(moduleName)
++ module = importlib.import_module(moduleName)
+ globals()[moduleNameWithoutPrefix] = module
+
+
diff --git a/src/portal/patches/snscrape_auth.diff b/src/portal/patches/snscrape_auth.diff
new file mode 100644
index 0000000..67962a9
--- /dev/null
+++ b/src/portal/patches/snscrape_auth.diff
@@ -0,0 +1,216 @@
+diff --git a/snscrape/modules/twitter.py b/snscrape/modules/twitter.py
+index d1719a8..43d9076 100644
+--- a/snscrape/modules/twitter.py
++++ b/snscrape/modules/twitter.py
+@@ -92,6 +92,7 @@ import typing
+ import urllib.parse
+ import urllib3.util.ssl_
+ import warnings
++import hashlib
+
+
+ _logger = logging.getLogger(__name__)
+@@ -99,10 +100,12 @@ _API_AUTHORIZATION_HEADER = 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOu
+ _globalGuestTokenManager = None
+ _GUEST_TOKEN_VALIDITY = 10800
+ _CIPHERS_CHROME = 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA'
++_AGE_RESTRICTED_MSG = 'Age-restricted adult content. This content might not be appropriate for people under 18 years old. To view this media, you’ll need to log in to Twitter. Learn more'
+
+
+ @dataclasses.dataclass
+ class Tweet(snscrape.base.Item):
++ rawResponses: typing.Dict[str, str]
+ url: str
+ date: datetime.datetime
+ rawContent: str
+@@ -793,17 +796,23 @@ class _TwitterAPIType(enum.Enum):
+ V2 = 0 # Introduced with the redesign
+ GRAPHQL = 1
+
++class _TwitterAPIAuthType(enum.Enum):
++ GUEST_TOKEN = 0
++ OAUTH2 = 1
+
+ class _TwitterAPIScraper(snscrape.base.Scraper):
+- def __init__(self, baseUrl, *, guestTokenManager = None, maxEmptyPages = 0, **kwargs):
++ def __init__(self, baseUrl, *, guestTokenManager = None, maxEmptyPages = 0, cookies = None, **kwargs):
+ super().__init__(**kwargs)
+ self._baseUrl = baseUrl
+- if guestTokenManager is None:
++ self._syndicationUrl = 'https://cdn.syndication.twimg.com/tweet?id='
++ self._authType = _TwitterAPIAuthType.OAUTH2
++ if self._authType == _TwitterAPIAuthType.GUEST_TOKEN and guestTokenManager is None:
+ global _globalGuestTokenManager
+ if _globalGuestTokenManager is None:
+ _globalGuestTokenManager = GuestTokenManager()
+ guestTokenManager = _globalGuestTokenManager
+ self._guestTokenManager = guestTokenManager
++ self._cookies = cookies
+ self._maxEmptyPages = maxEmptyPages
+ self._apiHeaders = {
+ 'Authorization': _API_AUTHORIZATION_HEADER,
+@@ -813,6 +822,11 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ adapter = _TwitterTLSAdapter()
+ self._session.mount('https://twitter.com', adapter)
+ self._session.mount('https://api.twitter.com', adapter)
++ if self._authType == _TwitterAPIAuthType.OAUTH2:
++ self._ensure_oauth()
++ self._lastResponse = None
++ self._lastResponseHash = None
++ self._lastSentResponseHash = None
+
+ def _check_guest_token_response(self, r):
+ if r.status_code != 200:
+@@ -820,6 +834,8 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ return True, None
+
+ def _ensure_guest_token(self, url = None):
++ if not self._guestTokenManager:
++ return
+ if self._guestTokenManager.token is None:
+ _logger.info('Retrieving guest token')
+ r = self._get(self._baseUrl if url is None else url, responseOkCallback = self._check_guest_token_response)
+@@ -843,18 +859,42 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ self._apiHeaders['x-guest-token'] = self._guestTokenManager.token
+
+ def _unset_guest_token(self, blockUntil):
++ if not self._guestTokenManager:
++ return
+ self._guestTokenManager.reset(blockUntil = blockUntil)
+ del self._session.cookies['gt']
+ del self._apiHeaders['x-guest-token']
+
++ def _ensure_oauth(self):
++ if not self._cookies:
++ return
++ for k, v in self._cookies.items():
++ self._session.cookies.set(k, v, domain = '.twitter.com', path = '/', secure = True)
++ self._apiHeaders['x-csrf-token'] = self._session.cookies.get('ct0')
++ self._apiHeaders['x-twitter-active-user'] = 'yes'
++ self._apiHeaders['x-twitter-auth-type'] = 'OAuth2Session'
++ self._apiHeaders['x-twitter-client-language'] = 'en'
++
++ def _ensure_auth_updated(self, url = None):
++ if self._authType == _TwitterAPIAuthType.OAUTH2:
++ self._ensure_oauth()
++ else:
++ self._ensure_guest_token(url)
++
+ def _check_api_response(self, r, apiType, instructionsPath):
+ if r.status_code in (403, 404, 429):
++ currentTime = time.time()
+ if r.status_code == 429 and r.headers.get('x-rate-limit-remaining', '') == '0' and 'x-rate-limit-reset' in r.headers:
+- blockUntil = min(int(r.headers['x-rate-limit-reset']), int(time.time()) + 900)
++ blockUntil = min(int(r.headers['x-rate-limit-reset']), int(currentTime) + 900)
++ else:
++ blockUntil = int(currentTime) + 300
++ if self._authType == _TwitterAPIAuthType.GUEST_TOKEN:
++ self._unset_guest_token(blockUntil)
++ self._ensure_guest_token()
+ else:
+- blockUntil = int(time.time()) + 300
+- self._unset_guest_token(blockUntil)
+- self._ensure_guest_token()
++ blockFor = (blockUntil - currentTime) * (int(r.headers.get('x-rate-limit-remaining', '0')) + 1)
++ _logger.warn(f'Got too many requests, blocking for {blockFor} seconds ({r.headers['x-rate-limit-reset']}) ({r.headers.get('x-rate-limit-remaining', '0')})')
++ time.sleep(blockFor)
+ return False, f'blocked ({r.status_code})'
+ if r.headers.get('content-type', '').replace(' ', '') != 'application/json;charset=utf-8':
+ return False, 'content type is not JSON'
+@@ -868,6 +908,11 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ r._snscrapeObj = obj
+ if apiType is _TwitterAPIType.GRAPHQL and 'errors' in obj:
+ msg = 'Twitter responded with an error: ' + ', '.join(f'{e["name"]}: {e["message"]}' for e in obj['errors'])
++ blockFor = 30.0
++ _logger.warn(f'Got errors waiting for {blockFor} seconds')
++ time.sleep(blockFor)
++ return False, msg
++ '''
+ instructions = obj
+ for k in instructionsPath:
+ instructions = instructions.get(k, {})
+@@ -877,13 +922,23 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ return True, None
+ else:
+ return False, msg
++ '''
+ return True, None
+
+ def _get_api_data(self, endpoint, apiType, params, instructionsPath = None):
+- self._ensure_guest_token()
++ self._ensure_auth_updated()
+ if apiType is _TwitterAPIType.GRAPHQL:
+ params = urllib.parse.urlencode({k: json.dumps(v, separators = (',', ':')) for k, v in params.items()}, quote_via = urllib.parse.quote)
+ r = self._get(endpoint, params = params, headers = self._apiHeaders, responseOkCallback = functools.partial(self._check_api_response, apiType = apiType, instructionsPath = instructionsPath))
++ if self._authType == _TwitterAPIAuthType.OAUTH2:
++ csrf = r.cookies.get('ct0')
++ if csrf:
++ _logger.warn('Response contained updated csrf token')
++ self._apiHeaders['x-csrf-token'] = csrf
++ self._lastResponse = r._snscrapeObj
++ hasher = hashlib.new('sha256')
++ hasher.update(json.dumps(self._lastResponse).encode('utf-8'))
++ self._lastResponseHash = hasher.hexdigest()
+ return r._snscrapeObj
+
+ def _iter_api_data(self, endpoint, apiType, params, paginationParams = None, cursor = None, direction = _ScrollDirection.BOTTOM, instructionsPath = None):
+@@ -988,8 +1043,50 @@ class _TwitterAPIScraper(snscrape.base.Scraper):
+ def _get_tweet_id(self, tweet):
+ return tweet['id'] if 'id' in tweet else int(tweet['id_str'])
+
++ def _entry_is_age_restricted(self, entry):
++ if entry['entryId'].startswith('tombstone-') and entry['content']['entryType'] == 'TimelineTimelineItem':
++ if entry['content']['itemContent']['tombstoneInfo']['richText']['text'] == _AGE_RESTRICTED_MSG:
++ return True
++ return False
++
++ # Can we parse out more data here?
++ def _syndication_make_tweet(self, tweet):
++ tweetId = self._get_tweet_id(tweet)
++ kwargs = {}
++ kwargs['rawResponses'] = {
++ 'detached_api' : json.dumps(tweet)
++ }
++ kwargs['id'] = tweetId
++ kwargs['rawContent'] = tweet['text']
++ kwargs['renderedContent'] = ''
++ username = tweet['user']['screen_name']
++ kwargs['user'] = User(id = int(tweet['user']['id_str']), username = username, displayname = tweet['user']['name'])
++ kwargs['date'] = datetime.datetime.strptime(tweet['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ')
++ kwargs['replyCount'] = tweet['conversation_count']
++ kwargs['retweetCount'] = 0
++ kwargs['quoteCount'] = 0
++ kwargs['conversationId'] = 0
++ kwargs['lang'] = tweet['lang']
++ kwargs['source'] = ''
++ kwargs['url'] = f'https://twitter.com/{username}/status/{tweetId}'
++ kwargs['likeCount'] = tweet['favorite_count']
++ media = []
++ for p in tweet['photos']:
++ media.append(Photo(previewUrl = '', fullUrl = p['url']))
++ kwargs['media'] = media
++ return Tweet(**kwargs)
++
++
+ def _make_tweet(self, tweet, user, retweetedTweet = None, quotedTweet = None, card = None, noteTweet = None, **kwargs):
+ tweetId = self._get_tweet_id(tweet)
++ kwargs['rawResponses'] = {
++ 'hash': self._lastResponseHash,
++ 'tweet': json.dumps(tweet),
++ 'user': user.json()
++ }
++ if not self._lastSentResponseHash or self._lastResponseHash != self._lastSentResponseHash:
++ kwargs['rawResponses']['detached_api'] = json.dumps(self._lastResponse)
++ self._lastSentResponseHash = self._lastResponseHash
+ kwargs['id'] = tweetId
+ if noteTweet and 'text' in noteTweet:
+ kwargs['rawContent'] = noteTweet['text']
+@@ -1789,7 +1886,7 @@ class TwitterUserScraper(TwitterSearchScraper):
+ self._baseUrl = f'https://twitter.com/{self._user}' if not self._isUserId else f'https://twitter.com/i/user/{self._user}'
+
+ def _get_entity(self):
+- self._ensure_guest_token()
++ self._ensure_auth_updated()
+ if not self._isUserId:
+ fieldName = 'screen_name'
+ endpoint = 'https://twitter.com/i/api/graphql/pVrmNaXcxPjisIvKtLDMEA/UserByScreenName'