summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--locales/el.json8
-rw-r--r--locales/fi.json456
-rw-r--r--locales/hu-HU.json6
-rw-r--r--locales/id.json2
-rw-r--r--src/invidious.cr45
-rw-r--r--src/invidious/helpers/errors.cr32
-rw-r--r--src/invidious/helpers/helpers.cr57
-rw-r--r--src/invidious/helpers/logger.cr2
-rw-r--r--src/invidious/helpers/utils.cr12
-rw-r--r--src/invidious/jobs/bypass_captcha_job.cr29
-rw-r--r--src/invidious/jobs/refresh_channels_job.cr7
-rw-r--r--src/invidious/jobs/refresh_feeds_job.cr5
-rw-r--r--src/invidious/jobs/statistics_refresh_job.cr5
-rw-r--r--src/invidious/jobs/subscribe_to_feeds_job.cr9
-rw-r--r--src/invidious/routes/base_route.cr4
-rw-r--r--src/invidious/routes/login.cr24
-rw-r--r--src/invidious/routes/user_preferences.cr31
-rw-r--r--src/invidious/routing.cr4
-rw-r--r--src/invidious/views/preferences.ecr14
-rw-r--r--src/invidious/views/template.ecr2
20 files changed, 398 insertions, 356 deletions
diff --git a/locales/el.json b/locales/el.json
index 23b3cdf9..f74f2421 100644
--- a/locales/el.json
+++ b/locales/el.json
@@ -1,11 +1,11 @@
{
- "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητής",
+ "`x` subscribers.([^.,0-9]|^)1([^.,0-9]|$)": "`x` συνδρομητές.([^.,0-9]|^)1([^.,0-9]|$)",
"`x` subscribers.": "`x` συνδρομητές.",
- "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο",
+ "`x` videos.([^.,0-9]|^)1([^.,0-9]|$)": "`x` βίντεο.([^.,0-9]|^)1([^.,0-9]|$)",
"`x` videos.": "`x` βίντεο.",
- "`x` playlists": "`x` κατάλογοι αναπαραγωγής",
+ "`x` playlists": "`x` λίστες αναπαραγωγής",
"LIVE": "ΖΩΝΤΑΝΑ",
- "Shared `x` ago": "Μοιράστηκε πριν `x`",
+ "Shared `x` ago": "Μοιράστηκε πριν από `x`",
"Unsubscribe": "Απεγγραφή",
"Subscribe": "Εγγραφή",
"View channel on YouTube": "Προβολή καναλιού στο YouTube",
diff --git a/locales/fi.json b/locales/fi.json
index 7de46bf4..0b2db9a1 100644
--- a/locales/fi.json
+++ b/locales/fi.json
@@ -118,236 +118,236 @@
"Token": "Tunnus",
"`x` subscriptions.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tilausta.([^.,0-9]|^)1([^.,0-9]|$)",
"`x` subscriptions.": "`x` tilausta.",
- "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` tokens.": "",
+ "`x` tokens.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tunnistetta.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` tokens.": "`x` tunnistetta.",
"Import/export": "Tuo/vie",
"unsubscribe": "peru tilaus",
"revoke": "kumoa",
"Subscriptions": "Tilaukset",
- "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` unseen notifications.": "",
- "search": "",
- "Log out": "",
- "Released under the AGPLv3 by Omar Roth.": "",
- "Source available here.": "",
- "View JavaScript license information.": "",
- "View privacy policy.": "",
- "Trending": "",
- "Public": "",
- "Unlisted": "",
- "Private": "",
- "View all playlists": "",
- "Updated `x` ago": "",
- "Delete playlist `x`?": "",
- "Delete playlist": "",
- "Create playlist": "",
- "Title": "",
- "Playlist privacy": "",
- "Editing playlist `x`": "",
- "Watch on YouTube": "",
- "Hide annotations": "",
- "Show annotations": "",
- "Genre: ": "",
- "License: ": "",
- "Family friendly? ": "",
- "Wilson score: ": "",
- "Engagement: ": "",
- "Whitelisted regions: ": "",
- "Blacklisted regions: ": "",
- "Shared `x`": "",
- "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` views.": "",
- "Premieres in `x`": "",
- "Premieres `x`": "",
- "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "",
- "View YouTube comments": "",
- "View more comments on Reddit": "",
- "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "View `x` comments.": "",
- "View Reddit comments": "",
- "Hide replies": "",
- "Show replies": "",
- "Incorrect password": "",
- "Quota exceeded, try again in a few hours": "",
- "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "",
- "Invalid TFA code": "",
- "Login failed. This may be because two-factor authentication is not turned on for your account.": "",
- "Wrong answer": "",
- "Erroneous CAPTCHA": "",
- "CAPTCHA is a required field": "",
- "User ID is a required field": "",
- "Password is a required field": "",
- "Wrong username or password": "",
- "Please sign in using 'Log in with Google'": "",
- "Password cannot be empty": "",
- "Password cannot be longer than 55 characters": "",
- "Please log in": "",
- "Invidious Private Feed for `x`": "",
- "channel:`x`": "",
- "Deleted or invalid channel": "",
- "This channel does not exist.": "",
- "Could not get channel info.": "",
- "Could not fetch comments": "",
- "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "View `x` replies.": "",
- "`x` ago": "",
- "Load more": "",
- "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` points.": "",
- "Could not create mix.": "",
- "Empty playlist": "",
- "Not a playlist.": "",
- "Playlist does not exist.": "",
- "Could not pull trending pages.": "",
- "Hidden field \"challenge\" is a required field": "",
- "Hidden field \"token\" is a required field": "",
- "Erroneous challenge": "",
- "Erroneous token": "",
- "No such user": "",
- "Token is expired, please try again": "",
- "English": "",
- "English (auto-generated)": "",
- "Afrikaans": "",
- "Albanian": "",
- "Amharic": "",
- "Arabic": "",
- "Armenian": "",
- "Azerbaijani": "",
- "Bangla": "",
- "Basque": "",
- "Belarusian": "",
- "Bosnian": "",
- "Bulgarian": "",
- "Burmese": "",
- "Catalan": "",
- "Cebuano": "",
- "Chinese (Simplified)": "",
- "Chinese (Traditional)": "",
- "Corsican": "",
- "Croatian": "",
- "Czech": "",
- "Danish": "",
- "Dutch": "",
- "Esperanto": "",
- "Estonian": "",
- "Filipino": "",
- "Finnish": "",
- "French": "",
- "Galician": "",
- "Georgian": "",
- "German": "",
- "Greek": "",
- "Gujarati": "",
- "Haitian Creole": "",
- "Hausa": "",
- "Hawaiian": "",
- "Hebrew": "",
- "Hindi": "",
- "Hmong": "",
- "Hungarian": "",
- "Icelandic": "",
- "Igbo": "",
- "Indonesian": "",
- "Irish": "",
- "Italian": "",
- "Japanese": "",
- "Javanese": "",
- "Kannada": "",
- "Kazakh": "",
- "Khmer": "",
- "Korean": "",
- "Kurdish": "",
- "Kyrgyz": "",
- "Lao": "",
- "Latin": "",
- "Latvian": "",
- "Lithuanian": "",
- "Luxembourgish": "",
- "Macedonian": "",
- "Malagasy": "",
- "Malay": "",
- "Malayalam": "",
- "Maltese": "",
- "Maori": "",
- "Marathi": "",
- "Mongolian": "",
- "Nepali": "",
- "Norwegian Bokmål": "",
- "Nyanja": "",
- "Pashto": "",
- "Persian": "",
- "Polish": "",
- "Portuguese": "",
- "Punjabi": "",
- "Romanian": "",
- "Russian": "",
- "Samoan": "",
- "Scottish Gaelic": "",
- "Serbian": "",
- "Shona": "",
- "Sindhi": "",
- "Sinhala": "",
- "Slovak": "",
- "Slovenian": "",
- "Somali": "",
- "Southern Sotho": "",
- "Spanish": "",
- "Spanish (Latin America)": "",
- "Sundanese": "",
- "Swahili": "",
- "Swedish": "",
- "Tajik": "",
- "Tamil": "",
- "Telugu": "",
- "Thai": "",
- "Turkish": "",
- "Ukrainian": "",
- "Urdu": "",
- "Uzbek": "",
- "Vietnamese": "",
- "Welsh": "",
- "Western Frisian": "",
- "Xhosa": "",
- "Yiddish": "",
- "Yoruba": "",
- "Zulu": "",
- "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` years.": "",
- "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` months.": "",
- "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` weeks.": "",
- "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` days.": "",
- "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` hours.": "",
- "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` minutes.": "",
- "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "",
- "`x` seconds.": "",
- "Fallback comments: ": "",
- "Popular": "",
- "Top": "",
- "About": "",
- "Rating: ": "",
- "Language: ": "",
- "View as playlist": "",
- "Default": "",
- "Music": "",
- "Gaming": "",
- "News": "",
- "Movies": "",
- "Download": "",
- "Download as: ": "",
- "%A %B %-d, %Y": "",
- "(edited)": "",
- "YouTube comment permalink": "",
- "permalink": "",
- "`x` marked it with a ❤": "",
- "Audio mode": "",
- "Video mode": "",
- "Videos": "",
- "Playlists": "",
- "Community": "",
- "Current version: ": ""
+ "`x` unseen notifications.([^.,0-9]|^)1([^.,0-9]|$)": "`x` näkemätöntä ilmoitusta.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` unseen notifications.": "`x` näkemätöntä ilmoitusta.",
+ "search": "haku",
+ "Log out": "Kirjaudu ulos",
+ "Released under the AGPLv3 by Omar Roth.": "Julkaissut AGPLv3-lisenssillä: Omar Roth.",
+ "Source available here.": "Lähdekoodi on saatavilla täällä.",
+ "View JavaScript license information.": "JavaScript-koodin lisenssit.",
+ "View privacy policy.": "Katso tietosuojaseloste.",
+ "Trending": "Nousussa",
+ "Public": "Julkinen",
+ "Unlisted": "Listaamaton",
+ "Private": "Yksityinen",
+ "View all playlists": "Kaikki soittolistat",
+ "Updated `x` ago": "Päivitetty `x` sitten",
+ "Delete playlist `x`?": "Poistetaanko soittolista `x`?",
+ "Delete playlist": "Poista soittolista",
+ "Create playlist": "Luo soittolista",
+ "Title": "Nimi",
+ "Playlist privacy": "Soittolistan yksityisyys",
+ "Editing playlist `x`": "Muokataan soittolistaa `x`",
+ "Watch on YouTube": "Katso YouTubessa",
+ "Hide annotations": "Piilota merkkaukset",
+ "Show annotations": "Näytä merkkaukset",
+ "Genre: ": "Genre: ",
+ "License: ": "Lisenssi: ",
+ "Family friendly? ": "Kaiken ikäisille sopiva? ",
+ "Wilson score: ": "Wilson-pistemäärä: ",
+ "Engagement: ": "Huomio: ",
+ "Whitelisted regions: ": "valkolistatut alueet: ",
+ "Blacklisted regions: ": "mustalla listalla olevat alueet: ",
+ "Shared `x`": "Jaettu `x`",
+ "`x` views.([^.,0-9]|^)1([^.,0-9]|$)": "`x` katselukertaa.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` views.": "`x` katselukertaa.",
+ "Premieres in `x`": "Ensiesitykseen aikaa `x`",
+ "Premieres `x`": "Ensiesitykseen `x`",
+ "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hei! Vaikuttaa siltä, että sinulla on JavaScript pois käytöstä. Klikkaa tästä nähdäksesi kommentit, huomioi että lataamisessa voi kestää melko kauan.",
+ "View YouTube comments": "Näytä YouTube-kommentit",
+ "View more comments on Reddit": "Katso lisää kommentteja Redditissä",
+ "View `x` comments.([^.,0-9]|^)1([^.,0-9]|$)": "Näytä `x` komenttia.([^.,0-9]|^)1([^.,0-9]|$)",
+ "View `x` comments.": "Näytä `x` kommenttia.",
+ "View Reddit comments": "Näytä Reddit-kommentit",
+ "Hide replies": "Piilota vastaukset",
+ "Show replies": "Näytä vastaukset",
+ "Incorrect password": "Väärä salasana",
+ "Quota exceeded, try again in a few hours": "Kiintiö ylitetty, yritä parin tunnin kuluttua uudestaan",
+ "Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Sisäänkirjautuminen epäonnistui. Varmista, että kaksivaiheinen tunnistautuminen (Authenticator tai tekstiviesti) on käytössä.",
+ "Invalid TFA code": "Virheellinen turvakoodi",
+ "Login failed. This may be because two-factor authentication is not turned on for your account.": "Sisäänkirjautuminen epäonnistui. Tämä voi johtua siitä, että kaksivaiheinen tunnistautuminen on pois käytöstä tunnuksellasi.",
+ "Wrong answer": "Väärä vastaus",
+ "Erroneous CAPTCHA": "Virheellinen CAPTCHA",
+ "CAPTCHA is a required field": "CAPTCHA-kenttä vaaditaan",
+ "User ID is a required field": "Käyttäjätunnus vaaditaan",
+ "Password is a required field": "Salasana vaaditaan",
+ "Wrong username or password": "Väärä käyttäjänimi tai salasana",
+ "Please sign in using 'Log in with Google'": "Ole hyvä ja kirjaudu sisään Google-tunnuksella",
+ "Password cannot be empty": "Salasana ei voi olla tyhjä",
+ "Password cannot be longer than 55 characters": "Salasana ei voi olla yli 55 merkkiä pitkä",
+ "Please log in": "Kirjaudu sisään, ole hyvä",
+ "Invidious Private Feed for `x`": "Invidousin yksityinen syöte `x`:lle",
+ "channel:`x`": "kanava:`x`",
+ "Deleted or invalid channel": "Poistettu tai virheellinen kanava",
+ "This channel does not exist.": "Tätä kanavaa ei ole olemassa.",
+ "Could not get channel info.": "Kanavatietoa ei saatu ladattua.",
+ "Could not fetch comments": "Kommenttien nouto epäonnistui",
+ "View `x` replies.([^.,0-9]|^)1([^.,0-9]|$)": "Näytä `x` vastausta.([^.,0-9]|^)1([^.,0-9]|$)",
+ "View `x` replies.": "Näytä `x` vastausta.",
+ "`x` ago": "`x` sitten",
+ "Load more": "Lataa lisää",
+ "`x` points.([^.,0-9]|^)1([^.,0-9]|$)": "`x` pistettä.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` points.": "`x` pistettä.",
+ "Could not create mix.": "Sekoituksen luominen epäonnistui.",
+ "Empty playlist": "Tyhjennä soittolista",
+ "Not a playlist.": "Ei ole soittolista.",
+ "Playlist does not exist.": "Soittolistaa ei ole olemassa.",
+ "Could not pull trending pages.": "Nousussa olevien sivujen lataus epäonnitui.",
+ "Hidden field \"challenge\" is a required field": "Piilotettu kenttä \"challenge\" on vaaditaan",
+ "Hidden field \"token\" is a required field": "Piilotettu kenttä \"tunniste\" vaaditaan",
+ "Erroneous challenge": "Virheellinen haaste",
+ "Erroneous token": "Virheellinen tunniste",
+ "No such user": "Käyttäjää ei ole olemassa",
+ "Token is expired, please try again": "Tunniste on vanhentunut, yritä uudestaan",
+ "English": "englanti",
+ "English (auto-generated)": "englanti (automaattisesti luotu)",
+ "Afrikaans": "afrikaans",
+ "Albanian": "albania",
+ "Amharic": "amhara",
+ "Arabic": "arabia",
+ "Armenian": "armenia",
+ "Azerbaijani": "azeri",
+ "Bangla": "bengali",
+ "Basque": "baski",
+ "Belarusian": "valkovenäjä",
+ "Bosnian": "bosnia",
+ "Bulgarian": "bulgaria",
+ "Burmese": "burma",
+ "Catalan": "katalaani",
+ "Cebuano": "cebuano",
+ "Chinese (Simplified)": "kiina (yksinkertaistettu)",
+ "Chinese (Traditional)": "kiina (perinteinen)",
+ "Corsican": "korsika",
+ "Croatian": "kroaatti",
+ "Czech": "tšekki",
+ "Danish": "tanska",
+ "Dutch": "hollanti",
+ "Esperanto": "esperanto",
+ "Estonian": "eesti",
+ "Filipino": "filipino",
+ "Finnish": "suomi",
+ "French": "ranska",
+ "Galician": "galego",
+ "Georgian": "georgia",
+ "German": "saksa",
+ "Greek": "kreikka",
+ "Gujarati": "gujarati",
+ "Haitian Creole": "haitinkreoli",
+ "Hausa": "hausa",
+ "Hawaiian": "havaiji",
+ "Hebrew": "heprea",
+ "Hindi": "hindi",
+ "Hmong": "hmong",
+ "Hungarian": "unkari",
+ "Icelandic": "islanti",
+ "Igbo": "igbo",
+ "Indonesian": "indonesia",
+ "Irish": "iiri",
+ "Italian": "italia",
+ "Japanese": "japani",
+ "Javanese": "jaava",
+ "Kannada": "kannada",
+ "Kazakh": "kazakki",
+ "Khmer": "khmer",
+ "Korean": "korea",
+ "Kurdish": "kurdi",
+ "Kyrgyz": "kirgiisi",
+ "Lao": "lao",
+ "Latin": "latina",
+ "Latvian": "latvia",
+ "Lithuanian": "liettua",
+ "Luxembourgish": "luksemburgi",
+ "Macedonian": "makedonia",
+ "Malagasy": "malagassi",
+ "Malay": "malaiji",
+ "Malayalam": "malajalam",
+ "Maltese": "malta",
+ "Maori": "maori",
+ "Marathi": "marathi",
+ "Mongolian": "mongoli",
+ "Nepali": "nepali",
+ "Norwegian Bokmål": "kirjanorja",
+ "Nyanja": "njandža",
+ "Pashto": "paštu",
+ "Persian": "persia",
+ "Polish": "puola",
+ "Portuguese": "portugali",
+ "Punjabi": "pandžabi",
+ "Romanian": "romania",
+ "Russian": "venäjä",
+ "Samoan": "samoa",
+ "Scottish Gaelic": "gaeli",
+ "Serbian": "serbia",
+ "Shona": "šona",
+ "Sindhi": "sindhi",
+ "Sinhala": "sinhali",
+ "Slovak": "slovakki",
+ "Slovenian": "sloveeni",
+ "Somali": "somali",
+ "Southern Sotho": "eteläsotho",
+ "Spanish": "espanja",
+ "Spanish (Latin America)": "espanja (Latinalainen Amerikka)",
+ "Sundanese": "sunda",
+ "Swahili": "swahili",
+ "Swedish": "ruotsi",
+ "Tajik": "tadžikki",
+ "Tamil": "tamili",
+ "Telugu": "telugu",
+ "Thai": "thai",
+ "Turkish": "turkki",
+ "Ukrainian": "ukraina",
+ "Urdu": "urdu",
+ "Uzbek": "uzbekki",
+ "Vietnamese": "vietnam",
+ "Welsh": "kymri",
+ "Western Frisian": "länsifriisi",
+ "Xhosa": "xhosa",
+ "Yiddish": "jiddiš",
+ "Yoruba": "joruba",
+ "Zulu": "zulu",
+ "`x` years.([^.,0-9]|^)1([^.,0-9]|$)": "`x` vuotta.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` years.": "`x` vuotta.",
+ "`x` months.([^.,0-9]|^)1([^.,0-9]|$)": "`x` kuukautta.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` months.": "`x` kuukautta.",
+ "`x` weeks.([^.,0-9]|^)1([^.,0-9]|$)": "`x` viikkoa.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` weeks.": "`x` viikkoa.",
+ "`x` days.([^.,0-9]|^)1([^.,0-9]|$)": "`x` päivää.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` days.": "`x` päivää.",
+ "`x` hours.([^.,0-9]|^)1([^.,0-9]|$)": "`x` tuntia.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` hours.": "`x` tuntia.",
+ "`x` minutes.([^.,0-9]|^)1([^.,0-9]|$)": "`x` minuuttia.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` minutes.": "`x` minuuttia.",
+ "`x` seconds.([^.,0-9]|^)1([^.,0-9]|$)": "`x` sekuntia.([^.,0-9]|^)1([^.,0-9]|$)",
+ "`x` seconds.": "`x` sekuntia.",
+ "Fallback comments: ": "varakommentit: ",
+ "Popular": "Suosittu",
+ "Top": "Ylin",
+ "About": "Tietoa",
+ "Rating: ": "Arvosana: ",
+ "Language: ": "Kieli: ",
+ "View as playlist": "Näytä soittolistana",
+ "Default": "Oletus",
+ "Music": "Musiikki",
+ "Gaming": "Videopelit",
+ "News": "Uutiset",
+ "Movies": "Elokuvat",
+ "Download": "Tallenna",
+ "Download as: ": "Tallennusmuoto: ",
+ "%A %B %-d, %Y": "%A %-d. %Bta, %Y",
+ "(edited)": "(muokattu)",
+ "YouTube comment permalink": "Pysyvä linkki YouTube-kommenttiin",
+ "permalink": "pysyvä linkki",
+ "`x` marked it with a ❤": "`x` merkattu ❤:llä",
+ "Audio mode": "Äänitila",
+ "Video mode": "Videotila",
+ "Videos": "Videot",
+ "Playlists": "Soittolistat",
+ "Community": "Yhteisö",
+ "Current version: ": "Tämänhetkinen versio: "
}
diff --git a/locales/hu-HU.json b/locales/hu-HU.json
index b21ae93a..f60bb7d2 100644
--- a/locales/hu-HU.json
+++ b/locales/hu-HU.json
@@ -83,9 +83,9 @@
"published": "közzétéve",
"published - reverse": "közzétéve (ford.)",
"alphabetically": "ABC sorrend",
- "alphabetically - reverse": "ABC sorrend (ford.)",
+ "alphabetically - reverse": "ABC sorrend (ford.)",
"channel name": "csatorna neve",
- "channel name - reverse": "csatorna neve (ford.)",
+ "channel name - reverse": "csatorna neve (ford.)",
"Only show latest video from channel: ": "Csak a legutolsó videó mutatása a csatornából: ",
"Only show latest unwatched video from channel: ": "Csak a legutolsó nem megtekintett videó mutatása a csatornából: ",
"Only show unwatched: ": "Csak a nem megtekintettek mutatása: ",
@@ -332,4 +332,4 @@
"Playlists": "Playlistek",
"Community": "Közösség",
"Current version: ": "Jelenlegi verzió: "
-} \ No newline at end of file
+}
diff --git a/locales/id.json b/locales/id.json
index 217ea1c7..62577127 100644
--- a/locales/id.json
+++ b/locales/id.json
@@ -377,7 +377,7 @@
"(edited)": "(disunting)",
"YouTube comment permalink": "",
"permalink": "",
- "`x` marked it with a ❤": "`x` telah ditandai dengan ❤",
+ "`x` marked it with a ❤": "`x` telah ditandai dengan ❤",
"Audio mode": "Mode audio",
"Video mode": "Mode video",
"Videos": "Video",
diff --git a/src/invidious.cr b/src/invidious.cr
index b320d344..713d193e 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -30,11 +30,8 @@ require "./invidious/*"
require "./invidious/routes/**"
require "./invidious/jobs/**"
-ENV_CONFIG_NAME = "INVIDIOUS_CONFIG"
-
-CONFIG_STR = ENV.has_key?(ENV_CONFIG_NAME) ? ENV.fetch(ENV_CONFIG_NAME) : File.read("config/config.yml")
-CONFIG = Config.from_yaml(CONFIG_STR)
-HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
+CONFIG = Config.load
+HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
PG_URL = URI.new(
scheme: "postgres",
@@ -52,7 +49,7 @@ PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
REDDIT_URL = URI.parse("https://www.reddit.com")
TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
YT_URL = URI.parse("https://www.youtube.com")
-HOST_URL = make_host_url(CONFIG, Kemal.config)
+HOST_URL = make_host_url(Kemal.config)
CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"}
@@ -85,6 +82,7 @@ LOCALES = {
"eo" => load_locale("eo"),
"es" => load_locale("es"),
"fa" => load_locale("fa"),
+ "fi" => load_locale("fi"),
"fr" => load_locale("fr"),
"hr" => load_locale("hr"),
"is" => load_locale("is"),
@@ -145,8 +143,6 @@ end
OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a")
LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level)
-config = CONFIG
-
# Check table integrity
if CONFIG.check_tables
check_enum(PG_DB, "privacy", PlaylistPrivacy)
@@ -167,28 +163,33 @@ end
# Start jobs
-Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, config)
-Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, config)
+if CONFIG.channel_threads > 0
+ Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB)
+end
+
+if CONFIG.feed_threads > 0
+ Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB)
+end
DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling)
-if config.decrypt_polling
+if CONFIG.decrypt_polling
Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new
end
-if config.statistics_enabled
- Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE)
+if CONFIG.statistics_enabled
+ Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, SOFTWARE)
end
-if (config.use_pubsub_feeds.is_a?(Bool) && config.use_pubsub_feeds.as(Bool)) || (config.use_pubsub_feeds.is_a?(Int32) && config.use_pubsub_feeds.as(Int32) > 0)
- Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, config, HMAC_KEY)
+if (CONFIG.use_pubsub_feeds.is_a?(Bool) && CONFIG.use_pubsub_feeds.as(Bool)) || (CONFIG.use_pubsub_feeds.is_a?(Int32) && CONFIG.use_pubsub_feeds.as(Int32) > 0)
+ Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, HMAC_KEY)
end
-if config.popular_enabled
+if CONFIG.popular_enabled
Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB)
end
-if config.captcha_key
- Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(config)
+if CONFIG.captcha_key
+ Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new
end
connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32)
@@ -219,7 +220,7 @@ before_all do |env|
env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}; child-src blob:"
env.response.headers["Referrer-Policy"] = "same-origin"
- if (Kemal.config.ssl || config.https_only) && config.hsts
+ if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts
env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
end
@@ -1164,7 +1165,7 @@ end
get "/feed/popular" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- if config.popular_enabled
+ if CONFIG.popular_enabled
templated "popular"
else
message = translate(locale, "The Popular feed has been disabled by the administrator.")
@@ -1822,7 +1823,7 @@ get "/api/v1/stats" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/json"
- if !config.statistics_enabled
+ if !CONFIG.statistics_enabled
next error_json(400, "Statistics are not enabled.")
end
@@ -2232,7 +2233,7 @@ get "/api/v1/popular" do |env|
env.response.content_type = "application/json"
- if !config.popular_enabled
+ if !CONFIG.popular_enabled
error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
env.response.status_code = 400
next error_message
diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr
index 2c62d44b..68ced430 100644
--- a/src/invidious/helpers/errors.cr
+++ b/src/invidious/helpers/errors.cr
@@ -7,7 +7,7 @@ class InfoException < Exception
end
macro error_template(*args)
- error_template_helper(env, config, locale, {{*args}})
+ error_template_helper(env, locale, {{*args}})
end
def github_details(summary : String, content : String)
@@ -22,9 +22,9 @@ def github_details(summary : String, content : String)
return HTML.escape(details)
end
-def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
if exception.is_a?(InfoException)
- return error_template_helper(env, config, locale, status_code, exception.message || "")
+ return error_template_helper(env, locale, status_code, exception.message || "")
end
env.response.content_type = "text/html"
env.response.status_code = status_code
@@ -43,7 +43,7 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale :
return templated "error"
end
-def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
env.response.content_type = "text/html"
env.response.status_code = status_code
error_message = translate(locale, message)
@@ -51,31 +51,31 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale :
end
macro error_atom(*args)
- error_atom_helper(env, config, locale, {{*args}})
+ error_atom_helper(env, locale, {{*args}})
end
-def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
if exception.is_a?(InfoException)
- return error_atom_helper(env, config, locale, status_code, exception.message || "")
+ return error_atom_helper(env, locale, status_code, exception.message || "")
end
env.response.content_type = "application/atom+xml"
env.response.status_code = status_code
return "<error>#{exception.inspect_with_backtrace}</error>"
end
-def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
env.response.content_type = "application/atom+xml"
env.response.status_code = status_code
return "<error>#{message}</error>"
end
macro error_json(*args)
- error_json_helper(env, config, locale, {{*args}})
+ error_json_helper(env, locale, {{*args}})
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil)
if exception.is_a?(InfoException)
- return error_json_helper(env, config, locale, status_code, exception.message || "", additional_fields)
+ return error_json_helper(env, locale, status_code, exception.message || "", additional_fields)
end
env.response.content_type = "application/json"
env.response.status_code = status_code
@@ -86,11 +86,11 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has
return error_message.to_json
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
- return error_json_helper(env, config, locale, status_code, exception, nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+ return error_json_helper(env, locale, status_code, exception, nil)
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil)
env.response.content_type = "application/json"
env.response.status_code = status_code
error_message = {"error" => message}
@@ -100,6 +100,6 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has
return error_message.to_json
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
- error_json_helper(env, config, locale, status_code, message, nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+ error_json_helper(env, locale, status_code, message, nil)
end
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 6bbb18cb..00087143 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -115,6 +115,63 @@ class Config
return false
end
end
+
+ def self.load
+ # Load config from file or YAML string env var
+ env_config_file = "INVIDIOUS_CONFIG_FILE"
+ env_config_yaml = "INVIDIOUS_CONFIG"
+
+ config_file = ENV.has_key?(env_config_file) ? ENV.fetch(env_config_file) : "config/config.yml"
+ config_yaml = ENV.has_key?(env_config_yaml) ? ENV.fetch(env_config_yaml) : File.read(config_file)
+
+ config = Config.from_yaml(config_yaml)
+
+ # Update config from env vars (upcased and prefixed with "INVIDIOUS_")
+ {% for ivar in Config.instance_vars %}
+ {% env_id = "INVIDIOUS_#{ivar.id.upcase}" %}
+
+ if ENV.has_key?({{env_id}})
+ # puts %(Config.{{ivar.id}} : Loading from env var {{env_id}})
+ env_value = ENV.fetch({{env_id}})
+ success = false
+
+ # Use YAML converter if specified
+ {% ann = ivar.annotation(::YAML::Field) %}
+ {% if ann && ann[:converter] %}
+ puts %(Config.{{ivar.id}} : Parsing "#{env_value}" as {{ivar.type}} with {{ann[:converter]}} converter)
+ config.{{ivar.id}} = {{ann[:converter]}}.from_yaml(YAML::ParseContext.new, YAML::Nodes.parse(ENV.fetch({{env_id}})).nodes[0])
+ puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}})
+ success = true
+
+ # Use regular YAML parser otherwise
+ {% else %}
+ {% ivar_types = ivar.type.union? ? ivar.type.union_types : [ivar.type] %}
+ # Sort types to avoid parsing nulls and numbers as strings
+ {% ivar_types = ivar_types.sort_by { |ivar_type| ivar_type == Nil ? 0 : ivar_type == Int32 ? 1 : 2 } %}
+ {{ivar_types}}.each do |ivar_type|
+ if !success
+ begin
+ # puts %(Config.{{ivar.id}} : Trying to parse "#{env_value}" as #{ivar_type})
+ config.{{ivar.id}} = ivar_type.from_yaml(env_value)
+ puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}} (#{ivar_type}))
+ success = true
+ rescue
+ # nop
+ end
+ end
+ end
+ {% end %}
+
+ # Exit on fail
+ if !success
+ puts %(Config.{{ivar.id}} failed to parse #{env_value} as {{ivar.type}})
+ exit(1)
+ end
+ end
+ {% end %}
+
+ return config
+ end
end
struct DBConfig
diff --git a/src/invidious/helpers/logger.cr b/src/invidious/helpers/logger.cr
index 7c5b0247..5d91a258 100644
--- a/src/invidious/helpers/logger.cr
+++ b/src/invidious/helpers/logger.cr
@@ -1,5 +1,3 @@
-require "logger"
-
enum LogLevel
All = 0
Trace = 1
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index f068b5f2..7d94a6e5 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -280,9 +280,9 @@ def arg_array(array, start = 1)
return args
end
-def make_host_url(config, kemal_config)
- ssl = config.https_only || kemal_config.ssl
- port = config.external_port || kemal_config.port
+def make_host_url(kemal_config)
+ ssl = CONFIG.https_only || kemal_config.ssl
+ port = CONFIG.external_port || kemal_config.port
if ssl
scheme = "https://"
@@ -297,11 +297,11 @@ def make_host_url(config, kemal_config)
port = ""
end
- if !config.domain
+ if !CONFIG.domain
return ""
end
- host = config.domain.not_nil!.lchop(".")
+ host = CONFIG.domain.not_nil!.lchop(".")
return "#{scheme}#{host}#{port}"
end
@@ -345,7 +345,7 @@ def sha256(text)
return digest.final.hexstring
end
-def subscribe_pubsub(topic, key, config)
+def subscribe_pubsub(topic, key)
case topic
when .match(/^UC[A-Za-z0-9_-]{22}$/)
topic = "channel_id=#{topic}"
diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr
index 22c54036..8b1aed5f 100644
--- a/src/invidious/jobs/bypass_captcha_job.cr
+++ b/src/invidious/jobs/bypass_captcha_job.cr
@@ -1,9 +1,4 @@
class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
- private getter config : Config
-
- def initialize(@config)
- end
-
def begin
loop do
begin
@@ -22,9 +17,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
headers = response.cookies.add_request_headers(HTTP::Headers.new)
- response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/createTask",
+ response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/createTask",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"task" => {
"type" => "NoCaptchaTaskProxyless",
"websiteURL" => "https://www.youtube.com#{path}",
@@ -39,9 +34,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
loop do
sleep 10.seconds
- response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/getTaskResult",
+ response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/getTaskResult",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"taskId" => task_id,
}.to_json).body)
@@ -58,10 +53,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
response.cookies
.select { |cookie| cookie.name != "PREF" }
- .each { |cookie| config.cookies << cookie }
+ .each { |cookie| CONFIG.cookies << cookie }
# Persist cookies between runs
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
elsif response.headers["Location"]?.try &.includes?("/sorry/index")
location = response.headers["Location"].try { |u| URI.parse(u) }
headers = HTTP::Headers{":authority" => location.host.not_nil!}
@@ -77,11 +72,11 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
inputs[node["name"]] = node["value"]
end
- captcha_client = HTTPClient.new(URI.parse(config.captcha_api_url))
- captcha_client.family = config.force_resolve || Socket::Family::INET
+ captcha_client = HTTPClient.new(URI.parse(CONFIG.captcha_api_url))
+ captcha_client.family = CONFIG.force_resolve || Socket::Family::INET
response = JSON.parse(captcha_client.post("/createTask",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"task" => {
"type" => "NoCaptchaTaskProxyless",
"websiteURL" => location.to_s,
@@ -100,7 +95,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
response = JSON.parse(captcha_client.post("/getTaskResult",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"taskId" => task_id,
}.to_json).body)
@@ -119,10 +114,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
}
cookies = HTTP::Cookies.from_headers(headers)
- cookies.each { |cookie| config.cookies << cookie }
+ cookies.each { |cookie| CONFIG.cookies << cookie }
# Persist cookies between runs
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
end
end
rescue ex
diff --git a/src/invidious/jobs/refresh_channels_job.cr b/src/invidious/jobs/refresh_channels_job.cr
index 3e94a56e..fbe6d381 100644
--- a/src/invidious/jobs/refresh_channels_job.cr
+++ b/src/invidious/jobs/refresh_channels_job.cr
@@ -1,12 +1,11 @@
class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config)
+ def initialize(@db)
end
def begin
- max_fibers = config.channel_threads
+ max_fibers = CONFIG.channel_threads
lim_fibers = max_fibers
active_fibers = 0
active_channel = Channel(Bool).new
@@ -31,7 +30,7 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
spawn do
begin
LOGGER.trace("RefreshChannelsJob: #{id} fiber : Fetching channel")
- channel = fetch_channel(id, db, config.full_refresh)
+ channel = fetch_channel(id, db, CONFIG.full_refresh)
lim_fibers = max_fibers
diff --git a/src/invidious/jobs/refresh_feeds_job.cr b/src/invidious/jobs/refresh_feeds_job.cr
index 7b4ccdea..926c27fa 100644
--- a/src/invidious/jobs/refresh_feeds_job.cr
+++ b/src/invidious/jobs/refresh_feeds_job.cr
@@ -1,12 +1,11 @@
class Invidious::Jobs::RefreshFeedsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config)
+ def initialize(@db)
end
def begin
- max_fibers = config.feed_threads
+ max_fibers = CONFIG.feed_threads
active_fibers = 0
active_channel = Channel(Bool).new
diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr
index 021671be..aa46fb0e 100644
--- a/src/invidious/jobs/statistics_refresh_job.cr
+++ b/src/invidious/jobs/statistics_refresh_job.cr
@@ -21,9 +21,8 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob
}
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config, @software_config : Hash(String, String))
+ def initialize(@db, @software_config : Hash(String, String))
end
def begin
@@ -43,7 +42,7 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob
"version" => @software_config["version"],
"branch" => @software_config["branch"],
}
- STATISTICS["openRegistration"] = config.registration_enabled
+ STATISTICS["openRegistration"] = CONFIG.registration_enabled
end
private def refresh_stats
diff --git a/src/invidious/jobs/subscribe_to_feeds_job.cr b/src/invidious/jobs/subscribe_to_feeds_job.cr
index 750aceb8..a431a48a 100644
--- a/src/invidious/jobs/subscribe_to_feeds_job.cr
+++ b/src/invidious/jobs/subscribe_to_feeds_job.cr
@@ -1,15 +1,14 @@
class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
private getter hmac_key : String
- private getter config : Config
- def initialize(@db, @config, @hmac_key)
+ def initialize(@db, @hmac_key)
end
def begin
max_fibers = 1
- if config.use_pubsub_feeds.is_a?(Int32)
- max_fibers = config.use_pubsub_feeds.as(Int32)
+ if CONFIG.use_pubsub_feeds.is_a?(Int32)
+ max_fibers = CONFIG.use_pubsub_feeds.as(Int32)
end
active_fibers = 0
@@ -30,7 +29,7 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob
spawn do
begin
- response = subscribe_pubsub(ucid, hmac_key, config)
+ response = subscribe_pubsub(ucid, hmac_key)
if response.status_code >= 400
LOGGER.error("SubscribeToFeedsJob: #{ucid} : #{response.body}")
diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr
index 37624267..07c6f15b 100644
--- a/src/invidious/routes/base_route.cr
+++ b/src/invidious/routes/base_route.cr
@@ -1,6 +1,2 @@
abstract class Invidious::Routes::BaseRoute
- private getter config : Config
-
- def initialize(@config)
- end
end
diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr
index 45a6d4d8..662fdf13 100644
--- a/src/invidious/routes/login.cr
+++ b/src/invidious/routes/login.cr
@@ -6,7 +6,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
return env.redirect "/feed/subscriptions" if user
- if !config.login_enabled
+ if !CONFIG.login_enabled
return error_template(400, "Login has been disabled by administrator.")
end
@@ -33,7 +33,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
referer = get_referer(env, "/feed/subscriptions")
- if !config.login_enabled
+ if !CONFIG.login_enabled
return error_template(403, "Login has been disabled by administrator.")
end
@@ -274,14 +274,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
host = URI.parse(env.request.headers["Host"]).host
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
cookies.each do |cookie|
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
cookie.secure = secure
else
cookie.secure = secure
@@ -330,14 +330,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.utc)
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years,
@@ -354,7 +354,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
env.response.cookies << cookie
end
else
- if !config.registration_enabled
+ if !CONFIG.registration_enabled
return error_template(400, "Registration has been disabled by administrator.")
end
@@ -369,7 +369,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
password = password.byte_slice(0, 55)
- if config.captcha_enabled
+ if CONFIG.captcha_enabled
captcha_type = env.params.body["captcha_type"]?
answer = env.params.body["answer"]?
change_type = env.params.body["change_type"]?
@@ -445,14 +445,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
view_name = "subscriptions_#{sha256(user.email)}"
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years,
diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/user_preferences.cr
index 7f334115..a689a2a2 100644
--- a/src/invidious/routes/user_preferences.cr
+++ b/src/invidious/routes/user_preferences.cr
@@ -146,8 +146,8 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
user = user.as(User)
PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email)
- if config.admins.includes? user.email
- config.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || config.default_user_preferences.default_home
+ if CONFIG.admins.includes? user.email
+ CONFIG.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || CONFIG.default_user_preferences.default_home
admin_feed_menu = [] of String
4.times do |index|
@@ -156,40 +156,39 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
admin_feed_menu << option
end
end
- config.default_user_preferences.feed_menu = admin_feed_menu
+ CONFIG.default_user_preferences.feed_menu = admin_feed_menu
popular_enabled = env.params.body["popular_enabled"]?.try &.as(String)
popular_enabled ||= "off"
- config.popular_enabled = popular_enabled == "on"
+ CONFIG.popular_enabled = popular_enabled == "on"
captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String)
captcha_enabled ||= "off"
- config.captcha_enabled = captcha_enabled == "on"
+ CONFIG.captcha_enabled = captcha_enabled == "on"
login_enabled = env.params.body["login_enabled"]?.try &.as(String)
login_enabled ||= "off"
- config.login_enabled = login_enabled == "on"
+ CONFIG.login_enabled = login_enabled == "on"
registration_enabled = env.params.body["registration_enabled"]?.try &.as(String)
registration_enabled ||= "off"
- config.registration_enabled = registration_enabled == "on"
+ CONFIG.registration_enabled = registration_enabled == "on"
statistics_enabled = env.params.body["statistics_enabled"]?.try &.as(String)
statistics_enabled ||= "off"
- config.statistics_enabled = statistics_enabled == "on"
+ CONFIG.statistics_enabled = statistics_enabled == "on"
- CONFIG.default_user_preferences = config.default_user_preferences
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
end
else
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years,
@@ -234,14 +233,14 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
preferences = preferences.to_json
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years,
diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr
index 593c7372..82d0028b 100644
--- a/src/invidious/routing.cr
+++ b/src/invidious/routing.cr
@@ -1,14 +1,14 @@
module Invidious::Routing
macro get(path, controller, method = :handle)
get {{ path }} do |env|
- controller_instance = {{ controller }}.new(config)
+ controller_instance = {{ controller }}.new
controller_instance.{{ method.id }}(env)
end
end
macro post(path, controller, method = :handle)
post {{ path }} do |env|
- controller_instance = {{ controller }}.new(config)
+ controller_instance = {{ controller }}.new
controller_instance.{{ method.id }}(env)
end
end
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 1ef080be..14d63536 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -208,14 +208,14 @@
</div>
<% # Web notifications are only supported over HTTPS %>
- <% if Kemal.config.ssl || config.https_only %>
+ <% if Kemal.config.ssl || CONFIG.https_only %>
<div class="pure-control-group">
<a href="#" data-onclick="notification_requestPermission"><%= translate(locale, "Enable web notifications") %></a>
</div>
<% end %>
<% end %>
- <% if env.get?("user") && config.admins.includes? env.get?("user").as(User).email %>
+ <% if env.get?("user") && CONFIG.admins.includes? env.get?("user").as(User).email %>
<legend><%= translate(locale, "Administrator preferences") %></legend>
<div class="pure-control-group">
@@ -240,28 +240,28 @@
<div class="pure-control-group">
<label for="popular_enabled"><%= translate(locale, "Popular enabled: ") %></label>
- <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if config.popular_enabled %>checked<% end %>>
+ <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if CONFIG.popular_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled: ") %></label>
- <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>>
+ <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if CONFIG.captcha_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="login_enabled"><%= translate(locale, "Login enabled: ") %></label>
- <input name="login_enabled" id="login_enabled" type="checkbox" <% if config.login_enabled %>checked<% end %>>
+ <input name="login_enabled" id="login_enabled" type="checkbox" <% if CONFIG.login_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="registration_enabled"><%= translate(locale, "Registration enabled: ") %></label>
- <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if config.registration_enabled %>checked<% end %>>
+ <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if CONFIG.registration_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="statistics_enabled"><%= translate(locale, "Report statistics: ") %></label>
- <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if config.statistics_enabled %>checked<% end %>>
+ <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if CONFIG.statistics_enabled %>checked<% end %>>
</div>
<% end %>
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index f6e5262d..61b900e3 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -87,7 +87,7 @@
<i class="icon ion-ios-cog"></i>
</a>
</div>
- <% if config.login_enabled %>
+ <% if CONFIG.login_enabled %>
<div class="pure-u-1-3">
<a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
<%= translate(locale, "Log in") %>