diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..f1ef68f7
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,44 @@
+name: Create markdown list
+
+on:
+ workflow_dispatch:
+ push:
+ branches: "*"
+ paths:
+ - 'instances.yaml'
+
+ pull_request:
+ branches: "*"
+ paths:
+ - 'instances.yaml'
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup python
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.9.5
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r src/requirements.txt
+
+ - name: Create markdown instance list
+ run: |
+ python src/create-instance-md.py
+
+ # Auto commit resulting md file
+ - name: "Auto commiting resulting markdown instance list"
+ uses: stefanzweifel/git-auto-commit-action@v4
+ with:
+ commit_message: Update Invidious-Instances.md
+ file_pattern: Invidious-Instances.md
\ No newline at end of file
diff --git a/Invidious-Instances.md b/Invidious-Instances.md
index 560f75ac..e4bd3ac0 100644
--- a/Invidious-Instances.md
+++ b/Invidious-Instances.md
@@ -1,82 +1,70 @@
----
-title: Invidious-Instances
-description:
-published: true
-date: 2021-05-23T16:58:51.441Z
-tags:
-editor: markdown
-dateCreated: 2021-05-23T16:58:48.431Z
----
-# Public Invidious Instances:
-[Uptime History provided by Uptimerobot](https://stats.uptimerobot.com/89VnzSKAn)
-[Instances API](https://instances.invidio.us/)
-
-**Note:**
-
-Instances using Cloudflare are marked as such. Instances using any type of anti-bot protection are marked as such.
-
-Instances using any type of analytics are marked as such, must be GDPR compliant (if it's usable in the EU), must be CCPA compliant (if it's usable in California), and must respect the AGPL by explaining their changes and by publishing their source code. In short: instances shouldn't run analytics, because it's not worth it.
-
-To be in this list, instances must have been updated in the last month. An instance that hasn't been updated in the last month is considered unmaintained and will be removed from the list.
-
-**Warning: Any public instance that isn't in this list is considered untrustworthy. Use them at your own risk.**
-
-## List of public Invidious Instances (sorted from oldest to newest):
-
-* [invidious.snopyta.org](https://invidious.snopyta.org/) 🇫🇮
-
-* [yewtu.be](https://yewtu.be) 🇳🇱 [](https://uptime.invidious.io/784257752)
-
-* [invidious.kavin.rocks](https://invidious.kavin.rocks) 🇮🇳 [](https://status.kavin.rocks/786132664) [invidious-us.kavin.rocks](https://invidious-us.kavin.rocks) 🇺🇸 [](https://status.kavin.rocks/788216947) [invidious-jp.kavin.rocks](https://invidious-jp.kavin.rocks) 🇯🇵 [](https://status.kavin.rocks/788866642) (uses Cloudflare)
-
-* [vid.puffyan.us](https://vid.puffyan.us) 🇺🇸 [](https://stats.uptimerobot.com/n7A08HGVl6/786947233)
-
-* [ytprivate.com](https://ytprivate.com) 🇺🇸 [](https://status.ytprivate.com/786947505) (uses DDoS-Guard) (is running a modified source code) - Source Code: https://github.com/ytprivatecom/invidious - Changes: https://github.com/ytprivatecom/invidious#source-changes
-
-* [invidious.namazso.eu](https://invidious.namazso.eu) 🇩🇪
-
-* [invidious.silkky.cloud](https://invidious.silkky.cloud) 🇫🇮 [](https://status.silkky.cloud/787784614) - Uses anti-bot protection by bunkerized-nginx: https://github.com/bunkerity/bunkerized-nginx
-
-* [invidious.exonip.de](https://invidious.exonip.de) 🇩🇪 [Status Page](https://status.exonip.de/) - Source code/changes: https://github.com/exonip-de/invidious-source-modifications - Uses anti-bot protection by bunkerized-nginx: https://github.com/bunkerity/bunkerized-nginx
-
-* [inv.riverside.rocks](https://inv.riverside.rocks) 🇺🇸
-
-* [vid.mint.lgbt](https://vid.mint.lgbt) 🇨🇦 [Status Page](https://status.mint.lgbt/service/lesvidious)
-
-* [ytb.trom.tf](https://ytb.trom.tf) 🇩🇪 Source code/changes (just CSS additions): https://gitlab.com/TioTrom/trom.tf-invidious
-
-* [y.com.cm](https://y.com.cm) 🇩🇪 (uses Cloudflare)
-
-* [invidious.hub.ne.kr](https://invidious.hub.ne.kr) 🇰🇷
-
-* [invidio.xamh.de](https://invidio.xamh.de) 🇩🇪 
-
-* [youtube.076.ne.jp](https://youtube.076.ne.jp) 🇯🇵 - Source code/changes: https://git.076.ne.jp/TechnicalSuwako/invidious-mod
-
-* [yt.didw.to](https://yt.didw.to/) 🇸🇪
-
-* [yt.artemislena.eu](https://yt.artemislena.eu) 🇩🇪
-
-
-### Tor Onion Services:
-* [c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion](http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion)
-
-* [w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion](http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion/)
-
-* [kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion](http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion/) 🇳🇱
-
-* [grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion](http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion) 🇺🇸
-
-* [hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion](http://hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion) 🇺🇸 (Onion of invidious-us.kavin.rocks)
-
-* [invidc4i7i5uci6cledxsao6w7ng5etpflagdzoxj3yhipztwzvqjryd.onion](http://invidc4i7i5uci6cledxsao6w7ng5etpflagdzoxj3yhipztwzvqjryd.onion) 🇩🇪 (Onion of invidious.exonip.de)
-
-* [osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion](http://osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd.onion) 🇰🇷 (Onion of invidious.hub.ne.kr)
-
-* [p4ozd76i5zmqepf6xavtehswcve2taptxbwpswkq5osfvncwylavllid.onion](http://p4ozd76i5zmqepf6xavtehswcve2taptxbwpswkq5osfvncwylavllid.onion) 🇯🇵 (Onion of invidious-jp.kavin.rocks)
-
-* [k7mnd6gyelynroxoncodxjz44fd5ch2ewfjl2a6ozmg3jy6fwyxq3cyd.onion](http://k7mnd6gyelynroxoncodxjz44fd5ch2ewfjl2a6ozmg3jy6fwyxq3cyd.onion/) 🇸🇪 (Onion of yt.didw.to)
+# Public Instances
+
+
+Uptime History: [uptime.invidious.io](https://uptime.invidious.io)
+
+Instances API: [api.invidious.io](api.invidious.io)
+
+# Instances list
+
+|Address|Country|Mirrors|Status|Privacy policy|DDos Protection / MITM|Owner|Notes|
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+|[invidious.snopyta.org](https://invidious.snopyta.org)|Finland 🇫🇮||[](https://status.unixfox.eu/783898765)|[Here](https://snopyta.org/privacy_policy)||[@Perflyst](https://github.com/Perflyst)||
+|[yewtu.be](https://yewtu.be)|Niger 🇳🇪||[](https://uptime.invidious.io/784257752)|||[@unixfox](https://github.com/unixfox)||
+|[invidious.kavin.rocks](https://invidious.kavin.rocks)|India 🇮🇳|[United States 🇺🇸](https://invidious-us.kavin.rocks)
[Japan 🇯🇵](https://invidious-jp.kavin.rocks)|[](https://status.kavin.rocks/786132664)||Cloudflare|[@FireMasterK](https://github.com/FireMasterK)||
+|[vid.puffyan.us](https://vid.puffyan.us)|United States 🇺🇸||[](https://stats.uptimerobot.com/n7A08HGVl6/786947233)|||[@ItsSt0ne](https://github.com/ItsSt0ne)||
+|[ytprivate.com](https://ytprivate.com)|United States 🇺🇸||[](https://status.ytprivate.com/786947505)||DDoS-Guard|[@ytprivatecom](https://github.com/ytprivatecom)| - [Modified source code](https://github.com/ytprivatecom/invidious)
- [Changes](https://github.com/ytprivatecom/invidious#source-changes)|
+|[invidious.namazso.eu](https://invidious.namazso.eu)|Germany 🇩🇪|||[Here](https://namazso.eu/privacy.html)||[@namazso](https://github.com/namazso)||
+|[invidious.silkky.cloud](https://invidious.silkky.cloud)|Finland 🇫🇮||[](https://status.silkky.cloud/787784614)|[Here](https://silkky.cloud/privacy)||[@silkkycloud](https://github.com/silkkycloud)| - [Anti-bot protection](https://github.com/bunkerity/bunkerized-nginx)|
+|[invidious.exonip.de](https://invidious.exonip.de)|Germany 🇩🇪||[Status Page](https://status.exonip.de/)|||[@Exonip](https://github.com/Exonip)| - [Modified source code](https://github.com/exonip-de/invidious-source-modifications)
- [Changes](https://github.com/exonip-de/invidious-source-modifications)
- [Anti-bot protection](https://github.com/bunkerity/bunkerized-nginx)|
+|[inv.riverside.rocks](https://inv.riverside.rocks)|United States 🇺🇸|||||[@RiversideRocks](https://github.com/RiversideRocks)||
+|[vid.mint.lgbt](https://vid.mint.lgbt/)|Canada 🇨🇦||[Status Page](https://status.mint.lgbt/service/lesvidious)|||[@mintphin](https://github.com/mintphin)||
+|[ytb.trom.tf](https://ytb.trom.tf)|Germany 🇩🇪|||||[@TROMsite](https://github.com/TROMsite)| - [Modified source code](https://gitlab.com/TioTrom/trom.tf-invidious)
- [Changes](https://gitlab.com/TioTrom/trom.tf-invidious)|
+|[y.com.cm](https://y.com.cm/)|Germany 🇩🇪||||Cloudflare|[@Showfom](https://github.com/Showfom)||
+|[invidious.hub.ne.kr](https://invidious.hub.ne.kr)|Korea, Republic of 🇰🇷|||[Here](https://privacy.osbusiness.net/)||[@hys0star](https://github.com/hys0star)||
+|[invidio.xamh.de](https://invidio.xamh.de)|Germany 🇩🇪||[](https://img.shields.io/uptimerobot/status/m788804183-a33a0af7fb40e3bafa617cd8)|||[@11Tuvork28](https://github.com/11Tuvork28)||
+|[youtube.076.ne.jp](https://youtube.076.ne.jp)|Japan 🇯🇵|||||[@TechnicalSuwako](https://github.com/TechnicalSuwako)| - [Modified source code](https://git.076.ne.jp/TechnicalSuwako/invidious-mod)
- [Changes](https://git.076.ne.jp/TechnicalSuwako/invidious-mod#change)|
+|[yt.didw.to](https://yt.didw.to/)|Sweden 🇸🇪|||||[@didw-to](https://github.com/didw-to)||
+|[yt.artemislena.eu](https://yt.artemislena.eu)|Germany 🇩🇪|||[Here](https://artemislena.eu/privacy.html)||[@artemislena](https://github.com/artemislena)||
+
+
+# Onion instances list
+
+|Address|Country|Mirrors|Associated clearnet instance|Privacy policy|Owner|Notes|
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+|[c7hqkpkpemu6e7emz5b4vyz7idjgdv...](http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion)|Finland 🇫🇮||[invidious.snopyta.org](https://invidious.snopyta.org)|[Here](https://snopyta.org/privacy_policy)|[@Perflyst](https://github.com/Perflyst)||
+|[w6ijuptxiku4xpnnaetxvnkc5vqcdu...](http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion/)|India 🇮🇳|[United States 🇺🇸](http://hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion/)
[Japan 🇯🇵](http://p4ozd76i5zmqepf6xavtehswcve2taptxbwpswkq5osfvncwylavllid.onion/)|[invidious.kavin.rocks](https://invidious.kavin.rocks)||[@FireMasterK](https://github.com/FireMasterK)||
+|[kbjggqkzv65ivcqj6bumvp337z6264...](http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion/)|Netherlands 🇳🇱||||[@tirz](https://github.com/tirz)||
+|[grwp24hodrefzvjjuccrkw3mjq4tzh...](http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion/)|United States 🇺🇸||[vid.puffyan.us](https://vid.puffyan.us)||[@ItsSt0ne](https://github.com/ItsSt0ne)||
+|[invidc4i7i5uci6cledxsao6w7ng5e...](http://invidc4i7i5uci6cledxsao6w7ng5etpflagdzoxj3yhipztwzvqjryd.onion/)|Germany 🇩🇪||[invidious.exonip.de](https://invidious.exonip.de)||[@Exonip](https://github.com/Exonip)| - [Modified source code](https://github.com/exonip-de/invidious-source-modifications)
- [Changes](https://github.com/exonip-de/invidious-source-modifications)|
+|[pwo2md4lgxs3hvroqi6wg33h6a3pv4...](http://pwo2md4lgxs3hvroqi6wg33h6a3pv47euax6km3alke7letglieokyd.onion)|Korea, Republic of 🇰🇷||[invidious.hub.ne.kr](https://invidious.hub.ne.kr)||[@hys0star](https://github.com/hys0star)||
+|[k7mnd6gyelynroxoncodxjz44fd5ch...](http://k7mnd6gyelynroxoncodxjz44fd5ch2ewfjl2a6ozmg3jy6fwyxq3cyd.onion/)|Sweden 🇸🇪||[yt.didw.to](https://yt.didw.to/)||[@didw-to](https://github.com/didw-to)||
+
+
+# Adding your instance
+
+## Prerequisites
+
+- Instances must have been updated in the last month. An instance that hasn't been updated in the last month is considered unmaintained and is removed from the list.
+- Instances must have statistics (/api/v1/stats) enabled (statistics_enabled:true in the configuration file)
+- Instances must be served via domain name.
+- Instances must be served via HTTPS.
+- Instances using any DDoS Protection / MITM are marked as such.
+- Instances using any type of anti-bot protection are marked as such.
+- Instances using any type of analytics are marked as such, must be GDPR compliant (if it's usable in the EU), must be CCPA compliant (if it's usable in California), and must respect the AGPL by explaining their changes and by publishing their source code. In short: instances shouldn't run analytics, because it's not worth it.
+- Instances running a modified source code must respect the AGPL by publishing their source code and stating their changes before they are be added to the list, and must publish any later modification in a timely manner.
+ - The instance must also contain a link to *both* the modified and original source code of Invidious. Ideally in the footer.
+- Instances should be up and functional at least 90% of the time.
+
+
+
+## Directions
+
+1. Fork the documentation repo.
+2. Open `instances.yaml` for editing.
+3. Append your instance to the bottom of the HTTPS (or onion) list. See the examples in the yaml file for more info.
+4. Make a pull request.
diff --git a/instances.yaml b/instances.yaml
new file mode 100644
index 00000000..892d563a
--- /dev/null
+++ b/instances.yaml
@@ -0,0 +1,348 @@
+adding_instance:
+ prerequisites:
+ - Instances must have been updated in the last month. An instance that hasn't been updated in the last month is considered unmaintained and is removed from the list.
+ - Instances must have statistics (/api/v1/stats) enabled (statistics_enabled:true in the configuration file)
+ - Instances must be served via domain name.
+ - Instances must be served via HTTPS.
+ - Instances using any DDoS Protection / MITM are marked as such.
+ - Instances using any type of anti-bot protection are marked as such.
+ - "Instances using any type of analytics are marked as such, must be GDPR compliant (if it's usable in the EU), must be CCPA compliant (if it's usable in California), and must respect the AGPL by explaining their changes and by publishing their source code. In short: instances shouldn't run analytics, because it's not worth it."
+ - Instances running a modified source code must respect the AGPL by publishing their source code and stating their changes before they are be added to the list, and must publish any later modification in a timely manner.
+ - - The instance must also contain a link to *both* the modified and original source code of Invidious. Ideally in the footer.
+ - Instances should be up and functional at least 90% of the time.
+ directions:
+ - Fork the documentation repo.
+ - Open `instances.yaml` for editing.
+ - Append your instance to the bottom of the HTTPS (or onion) list. See the examples in the yaml file for more info.
+ - Make a pull request.
+
+instances:
+ https:
+ # Template instance
+ # - url: https://example.com
+ # country: FI
+ # status:
+ # url: https://status.example.com
+ # image: https://status-image.example.com
+ # text: Status Page
+ # privacy_policy: example.com/privacy
+ # ddos_mitm_protection:
+ # owner: https://github.com/example
+ # is_modified:
+ # source:
+ # notes:
+ # _ Hi I am an example!
+ # mirrors: # Mirrors should follow a reduced syntax of the base instance
+ # - url: https://us.example.com
+ # - country: US
+ #
+ # *Image attribute in status has higher prioirty than text. Thus, if this attribute is filled out
+ # The text attribute would only be used as a fallback.
+
+
+ - url: https://invidious.snopyta.org
+ country: FI
+ status:
+ url: https://status.unixfox.eu/783898765
+ image: https://img.shields.io/uptimerobot/status/m783898765-2a4efa67aa8d1c7be6b1dd9d
+ text: Uptime Robot status
+ privacy_policy: https://snopyta.org/privacy_policy
+ ddos_mitm_protection: null
+ owner: https://github.com/Perflyst
+ modified:
+ notes:
+ mirrors:
+
+ - url: https://yewtu.be
+ country: NE
+ status:
+ url: https://uptime.invidious.io/784257752
+ image: https://img.shields.io/uptimerobot/status/m783898765-2a4efa67aa8d1c7be6b1dd9d
+ text: Uptime Robot status
+ privacy_policy: null
+ ddos_mitm_protection: null
+ owner: https://github.com/unixfox
+ modified:
+ notes:
+ mirrors:
+
+ - url: https://invidious.kavin.rocks
+ country: IN
+ status:
+ url: https://status.kavin.rocks/786132664
+ image: https://img.shields.io/uptimerobot/status/m786132664-f9fa738fba1c4dc2f7364f71
+ text: Uptime Robot status
+ privacy_policy:
+ ddos_mitm_protection: Cloudflare
+ owner: https://github.com/FireMasterK
+ modified:
+ notes:
+ mirrors:
+ - url: https://invidious-us.kavin.rocks
+ country: US
+
+ - url: https://invidious-jp.kavin.rocks
+ country: JP
+
+ - url: https://vid.puffyan.us
+ country: US
+ status:
+ url: https://stats.uptimerobot.com/n7A08HGVl6/786947233
+ image: https://img.shields.io/uptimerobot/status/m786947233-1131c3f67b9a20621b1926d3
+ text: Uptime Robot status
+ privacy_policy:
+ ddos_mitm_protection:
+ owner: https://github.com/ItsSt0ne
+ modified:
+ notes:
+ mirrors:
+
+ - url: https://ytprivate.com
+ country: US
+ status:
+ url: https://status.ytprivate.com/786947505
+ image: https://img.shields.io/uptimerobot/status/m786947505-2a50cf3262906bb28c6cf8fc
+ text: Uptime Robot status
+ privacy_policy:
+ ddos_mitm_protection: DDoS-Guard
+ owner: https://github.com/ytprivatecom
+ modified:
+ source: https://github.com/ytprivatecom/invidious
+ changes: https://github.com/ytprivatecom/invidious#source-changes
+ notes:
+ mirrors:
+
+ - url: https://invidious.namazso.eu
+ country: DE
+ status:
+ privacy_policy: https://namazso.eu/privacy.html
+ ddos_mitm_protection:
+ owner: https://github.com/namazso
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: https://invidious.silkky.cloud
+ country: FI
+ status:
+ url: https://status.silkky.cloud/787784614
+ image: https://img.shields.io/uptimerobot/status/m787784614-79d1acc4b425d1ed813fc793
+ text: Uptime Robot status
+ privacy_policy: https://silkky.cloud/privacy
+ ddos_mitm_protection:
+ owner: https://github.com/silkkycloud
+ modified:
+ source:
+ notes:
+ - "[Anti-bot protection](https://github.com/bunkerity/bunkerized-nginx)"
+ mirrors:
+
+ - url: https://invidious.exonip.de
+ country: DE
+ status:
+ url: https://status.exonip.de/
+ text: Status Page
+ privacy_policy:
+ ddos_mitm_protection:
+ owner: https://github.com/Exonip
+ modified:
+ source: https://github.com/exonip-de/invidious-source-modifications
+ changes: https://github.com/exonip-de/invidious-source-modifications
+ notes:
+ - "[Anti-bot protection](https://github.com/bunkerity/bunkerized-nginx)"
+ mirrors:
+
+ - url: https://inv.riverside.rocks
+ country: US
+ status:
+ privacy_policy:
+ ddos_mitm_protection:
+ owner: https://github.com/RiversideRocks
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: https://vid.mint.lgbt/
+ country: CA
+ status:
+ url: https://status.mint.lgbt/service/lesvidious
+ text: Status Page
+ privacy_policy:
+ ddos_mitm_protection:
+ owner: https://github.com/mintphin
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: https://ytb.trom.tf
+ country: DE
+ status:
+ privacy_policy:
+ ddos_mitm_protection:
+ owner: https://github.com/TROMsite
+ modified:
+ source: https://gitlab.com/TioTrom/trom.tf-invidious
+ changes: https://gitlab.com/TioTrom/trom.tf-invidious
+ notes:
+ mirrors:
+
+ - url: https://y.com.cm/
+ country: DE
+ status:
+ privacy_policy:
+ ddos_mitm_protection: Cloudflare
+ owner: https://github.com/Showfom
+ modified:
+ notes:
+ mirrors:
+
+ - url: https://invidious.hub.ne.kr
+ country: KR
+ status:
+ privacy_policy: https://privacy.osbusiness.net/
+ ddos_mitm_protection: null
+ owner: https://github.com/hys0star
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: https://invidio.xamh.de
+ country: DE
+ status:
+ url: https://img.shields.io/uptimerobot/status/m788804183-a33a0af7fb40e3bafa617cd8
+ image: https://img.shields.io/uptimerobot/status/m788804183-a33a0af7fb40e3bafa617cd8
+ text: Uptime Robot status
+ privacy_policy:
+ ddos_mitm_protection: null
+ owner: https://github.com/11Tuvork28
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: https://youtube.076.ne.jp
+ country: JP
+ status:
+ privacy_policy:
+ ddos_mitm_protection: null
+ owner: https://github.com/TechnicalSuwako
+ modified:
+ source: https://git.076.ne.jp/TechnicalSuwako/invidious-mod
+ changes: https://git.076.ne.jp/TechnicalSuwako/invidious-mod#change
+ notes:
+ mirrors:
+
+ - url: https://yt.didw.to/
+ country: SE
+ status:
+ privacy_policy:
+ ddos_mitm_protection: null
+ owner: https://github.com/didw-to
+ modified:
+ notes:
+ mirrors:
+
+ - url: https://yt.artemislena.eu
+ country: DE
+ status:
+ privacy_policy: https://artemislena.eu/privacy.html
+ ddos_mitm_protection: null
+ owner: https://github.com/artemislena
+ modified:
+ notes:
+ mirrors:
+
+
+ onion:
+ # Template onion instance
+ # url: http://example.onion
+ # country: FI
+ # associated_clearnet_instance: https://example.com
+ # privacy_policy: https://privacy.example.com
+ # owner: https://github.com/example
+ # modified:
+ # is_modified: false
+ # source: null
+
+ - url: http://c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion
+ country: FI
+ associated_clearnet_instance: https://invidious.snopyta.org
+ status:
+ image: https://status-image.example.com
+ text: Status Page
+ privacy_policy: https://snopyta.org/privacy_policy
+ owner: https://github.com/Perflyst
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: http://w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd.onion/
+ country: IN
+ associated_clearnet_instance: https://invidious.kavin.rocks
+ privacy_policy:
+ owner: https://github.com/FireMasterK
+ modified:
+ source:
+ notes:
+ mirrors:
+ - url: http://hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid.onion/
+ country: US
+
+ - url: http://p4ozd76i5zmqepf6xavtehswcve2taptxbwpswkq5osfvncwylavllid.onion/
+ country: JP
+
+ - url: http://kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad.onion/
+ country: NL
+ associated_clearnet_instance:
+ privacy_policy:
+ owner: https://github.com/tirz
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: http://grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad.onion/
+ country: US
+ associated_clearnet_instance: https://vid.puffyan.us
+ privacy_policy:
+ owner: https://github.com/ItsSt0ne
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: http://invidc4i7i5uci6cledxsao6w7ng5etpflagdzoxj3yhipztwzvqjryd.onion/
+ country: DE
+ associated_clearnet_instance: https://invidious.exonip.de
+ privacy_policy:
+ owner: https://github.com/Exonip
+ modified:
+ source: https://github.com/exonip-de/invidious-source-modifications
+ changes: https://github.com/exonip-de/invidious-source-modifications
+ notes:
+ mirrors:
+
+ - url: http://pwo2md4lgxs3hvroqi6wg33h6a3pv47euax6km3alke7letglieokyd.onion
+ country: KR
+ associated_clearnet_instance: https://invidious.hub.ne.kr
+ privacy_policy:
+ owner: https://github.com/hys0star
+ modified:
+ source:
+ notes:
+ mirrors:
+
+ - url: http://k7mnd6gyelynroxoncodxjz44fd5ch2ewfjl2a6ozmg3jy6fwyxq3cyd.onion/
+ country: SE
+ associated_clearnet_instance: https://yt.didw.to/
+ privacy_policy:
+ owner: https://github.com/didw-to
+ modified:
+ source:
+ notes:
+ mirrors:
\ No newline at end of file
diff --git a/src/create-instance-md.py b/src/create-instance-md.py
new file mode 100644
index 00000000..30e4ab82
--- /dev/null
+++ b/src/create-instance-md.py
@@ -0,0 +1,189 @@
+"""Extremely quick and dirty module for creating a markdown file from the instances.yaml file"""
+from urllib.parse import urlparse
+
+import pycountry
+import yaml
+from mdutils.mdutils import MdUtils
+
+
+class ColumnBuilder:
+ def route(self, name):
+ router = {
+ "url": self._create_url_column,
+ "associated_clearnet_instance": self._create_url_column,
+ "country": self._create_country_column,
+ "status": self._create_status_column,
+ "privacy_policy": self._create_privacy_policy_column,
+ "ddos_mitm_protection": self.ddos_protection,
+ "owner": self._create_owner_column,
+ "notes": self._create_notes_column,
+ "mirrors": self._create_mirror_column
+ }
+
+ return router[name]
+
+ @staticmethod
+ def get_country_name_and_flag_from_code(code):
+ name = pycountry.countries.get(alpha_2=code).name
+ # https://stackoverflow.com/a/42235254
+ flag = (lambda s, e: chr(ord(s.upper()) - 0x41 + 0x1F1E6) +
+ chr(ord(e.upper()) - 0x41 + 0x1F1E6))(*list(code))
+
+ return name, flag
+
+
+ @staticmethod
+ def _create_url_column(url):
+ if not url:
+ return ""
+
+ hostname = urlparse(url).hostname
+ return f"[{hostname[:30] + (hostname[30:] and '...')}]({url})"
+
+ def _create_country_column(self, country_code):
+ main_name, main_flag = self.get_country_name_and_flag_from_code(country_code)
+ return f"{main_name} {main_flag}"
+
+ @staticmethod
+ def _create_status_column(status_dict):
+ if not status_dict:
+ return ""
+
+ status_url = status_dict["url"]
+ image = status_dict.get("image")
+ text = status_dict.get("text", "Status Page")
+
+ if image:
+ return f"[]({status_url})"
+ else:
+ return f"[{text}]({status_url})"
+
+ @staticmethod
+ def _create_privacy_policy_column(privacy):
+ if not privacy:
+ return ""
+
+ return f"[Here]({privacy})"
+
+ @staticmethod
+ def ddos_protection(ddos):
+ if not ddos:
+ return ""
+ return f"{ddos}"
+
+ @staticmethod
+ def _create_owner_column(owner):
+ author_name = owner.split("/")
+ return f"[@{author_name[-1]}]({owner})"
+
+ @staticmethod
+ def _create_notes_column(notes, modified):
+ # It is possible for both the notes and is_modified data to be falsey
+ if not notes and not modified:
+ return ""
+
+ notes_list = []
+ if modified:
+ notes_list.append(f" - [Modified source code]({modified['source']})")
+ notes_list.append(f" - [Changes]({modified['changes']})")
+ if notes:
+ [notes_list.append(f" - {note}") for note in notes]
+
+ return '
'.join(notes_list)
+
+ def _create_mirror_column(self, mirrors):
+ if not mirrors:
+ return ""
+
+ country_column = []
+
+ for mirror in mirrors:
+ name, flag = self.get_country_name_and_flag_from_code(mirror["country"])
+ country_column.append(f"[{name} {flag}]({mirror['url']})")
+
+ return "
".join(country_column)
+
+
+class MDInstanceListBuilder:
+ def __init__(self, instance_list_config):
+ self.config = instance_list_config
+ self.md = MdUtils(file_name='Invidious-Instances.md')
+ self.builder = ColumnBuilder()
+
+ def _generate_heading(self):
+ self.md.new_header(level=1, title='Public Instances')
+ self.md.new_paragraph("Uptime History: [uptime.invidious.io](https://uptime.invidious.io)")
+ self.md.new_paragraph("Instances API: [api.invidious.io](api.invidious.io)")
+
+ def _create_instance_tables(self):
+ # HTTPS
+ self.md.new_header(level=1, title='Instances list')
+ rows = ["Address", "Country", "Mirrors", "Status", "Privacy policy", "DDos Protection / MITM", "Owner", "Notes"]
+ for instance in self.config["instances"]["https"]:
+ rows.extend(self._create_http_row(instance))
+
+ self.md.new_table(columns=8, rows=len(self.config["instances"]["https"]) + 1, text=rows, text_align='center')
+
+ self.md.new_line()
+
+ # Onion
+ self.md.new_header(level=1, title='Onion instances list')
+ rows = ["Address", "Country", "Mirrors", "Associated clearnet instance", "Privacy policy", "Owner", "Notes"]
+ for instance in self.config["instances"]["onion"]:
+ rows.extend(self._create_onion_row(instance))
+ self.md.new_table(columns=7, rows=len(self.config["instances"]["onion"]) + 1, text=rows, text_align='center')
+
+ def _create_prerequisite_list(self):
+ self.md.new_header(level=2, title='Prerequisites')
+ self.md.new_list(self.config["adding_instance"]["prerequisites"])
+ self.md.new_line()
+
+ def _create_direction_list(self):
+ self.md.new_header(level=2, title='Directions')
+ self.md.new_list(self.config["adding_instance"]["directions"], marked_with="1")
+ self.md.create_md_file()
+
+ def _create_http_row(self, instance):
+ return [
+ self.builder.route("url")(instance["url"]),
+ self.builder.route("country")(instance["country"]),
+ self.builder.route("mirrors")(instance["mirrors"]),
+ self.builder.route("status")(instance["status"]),
+ self.builder.route("privacy_policy")(instance["privacy_policy"]),
+ self.builder.route("ddos_mitm_protection")(instance["ddos_mitm_protection"]),
+ self.builder.route("owner")(instance["owner"]),
+ self.builder.route("notes")(instance["notes"], instance["modified"]),
+ ]
+
+ def _create_onion_row(self, instance):
+ return [
+ self.builder.route("url")(instance["url"]),
+ self.builder.route("country")(instance["country"]),
+ self.builder.route("mirrors")(instance["mirrors"]),
+ self.builder.route("associated_clearnet_instance")(instance["associated_clearnet_instance"]),
+ self.builder.route("privacy_policy")(instance["privacy_policy"]),
+ self.builder.route("owner")(instance["owner"]),
+ self.builder.route("notes")(instance["notes"], instance["modified"]),
+ ]
+
+ def create(self):
+ self._generate_heading()
+ self.md.new_line()
+
+ self._create_instance_tables()
+ self.md.new_line()
+
+ # Instance adding directions and prerequisites
+ self.md.new_header(level=1, title='Adding your instance')
+ self._create_prerequisite_list()
+ self.md.new_line()
+ self._create_direction_list()
+
+ self.md.create_md_file()
+
+
+with open("instances.yaml") as configuration_yaml:
+ data = yaml.safe_load(configuration_yaml)
+
+md_builder = MDInstanceListBuilder(data)
+md_builder.create()
\ No newline at end of file
diff --git a/src/requirements.txt b/src/requirements.txt
new file mode 100644
index 00000000..18b78e32
--- /dev/null
+++ b/src/requirements.txt
@@ -0,0 +1,3 @@
+mdutils==1.3.1
+pycountry==20.7.3
+PyYAML==5.4.1