Merge branch 'iv-org:master' into verified-badge

This commit is contained in:
Jonas 2022-03-13 19:06:52 +01:00 committed by GitHub
commit a09fbad8b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 842 additions and 108 deletions

View File

@ -31,7 +31,7 @@
  
<a href="https://instances.invidious.io/">Instances list</a>
&nbsp;&nbsp;
<a href="https://docs.invidious.io/FAQ.md">FAQ</a>
<a href="https://docs.invidious.io/FAQ/">FAQ</a>
&nbsp;&nbsp;
<a href="https://docs.invidious.io/">Documentation</a>
&nbsp;&nbsp;
@ -88,7 +88,7 @@
**Technical features**
- Embedded video support
- [Developer API](https://docs.invidious.io/API.md)
- [Developer API](https://docs.invidious.io/API/)
- Does not use official YouTube APIs
- No Contributor License Agreement (CLA)
@ -101,7 +101,7 @@
**Hosting invidious:**
- [Follow the installation instructions](https://docs.invidious.io/Installation.md)
- [Follow the installation instructions](https://docs.invidious.io/Installation/)
## Documentation
@ -119,7 +119,7 @@ embedded youtube videos on other websites with invidious.
The documentation contains a list of browser extensions that we recommended to use along with Invidious.
You can read more here: https://docs.invidious.io/Extensions.md
You can read more here: https://docs.invidious.io/Extensions/
## Contribute

View File

@ -1,6 +1,6 @@
dependencies:
- name: postgresql
repository: https://kubernetes-charts.storage.googleapis.com/
version: 8.3.0
digest: sha256:1feec3c396cbf27573dc201831ccd3376a4a6b58b2e7618ce30a89b8f5d707fd
generated: "2020-02-07T13:39:38.624846+01:00"
repository: https://charts.bitnami.com/bitnami/
version: 11.1.3
digest: sha256:79061645472b6fb342d45e8e5b3aacd018ef5067193e46a060bccdc99fe7f6e1
generated: "2022-03-02T05:57:20.081432389+13:00"

View File

@ -1,7 +1,7 @@
apiVersion: v2
name: invidious
description: Invidious is an alternative front-end to YouTube
version: 1.1.0
version: 1.1.1
appVersion: 0.20.1
keywords:
- youtube
@ -17,6 +17,6 @@ maintainers:
email: mail@leonklingele.de
dependencies:
- name: postgresql
version: ~8.3.0
repository: "https://kubernetes-charts.storage.googleapis.com/"
version: ~11.1.3
repository: "https://charts.bitnami.com/bitnami/"
engine: gotpl

View File

@ -14,7 +14,7 @@ autoscaling:
targetCPUUtilizationPercentage: 50
service:
type: clusterIP
type: ClusterIP
port: 3000
#loadBalancerIP:
@ -32,14 +32,19 @@ securityContext:
runAsGroup: 1000
fsGroup: 1000
# See https://github.com/helm/charts/tree/master/stable/postgresql
# See https://github.com/bitnami/charts/tree/master/bitnami/postgresql
postgresql:
postgresqlUsername: kemal
postgresqlPassword: kemal
postgresqlDatabase: invidious
initdbUsername: kemal
initdbPassword: kemal
initdbScriptsConfigMap: invidious-postgresql-init
image:
registry: quay.io
auth:
username: kemal
password: kemal
database: invidious
primary:
initdb:
username: kemal
password: kemal
scriptsConfigMap: invidious-postgresql-init
# Adapted from ../config/config.yml
config:

View File

@ -21,15 +21,15 @@
"No": "لا",
"Import and Export Data": "اِستيراد البيانات وتصديرها",
"Import": "استيراد",
"Import Invidious data": "استيراد بيانات انفيدياس",
"Import YouTube subscriptions": "استيراد اشتراكات يوتيوب",
"Import Invidious data": "استيراد بيانات JSON Invidious",
"Import YouTube subscriptions": "استيراد اشتراكات YouTube/OPML",
"Import FreeTube subscriptions (.db)": "استيراد اشتراكات فريتيوب (.db)",
"Import NewPipe subscriptions (.json)": "استيراد اشتراكات نيو بايب (.json)",
"Import NewPipe data (.zip)": "استيراد بيانات نيو بايب (.zip)",
"Export": "تصدير",
"Export subscriptions as OPML": "تصدير الاشتراكات كـOPML",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "تصدير الاشتراكات كـOPML (لِنيو بايب و فريتيوب)",
"Export data as JSON": "تصدير البيانات بتنسيق JSON",
"Export data as JSON": "تصدير بيانات Invidious كـ JSON",
"Delete account?": "حذف الحساب؟",
"History": "السِّجل",
"An alternative front-end to YouTube": "واجهة أمامية بديلة لموقع يوتيوب",
@ -66,7 +66,7 @@
"preferences_related_videos_label": "اعرض الفيديوهات ذات الصلة: ",
"preferences_annotations_label": "اعرض الملاحظات في الفيديو تلقائيا: ",
"preferences_extend_desc_label": "توسيع وصف الفيديو تلقائيا: ",
"preferences_vr_mode_label": "مقاطع فيديو تفاعلية ب درجة 360: ",
"preferences_vr_mode_label": "مقاطع فيديو تفاعلية بزاوية 360 درجة (تتطلب WebGL): ",
"preferences_category_visual": "التفضيلات المرئية",
"preferences_player_style_label": "شكل مشغل الفيديوهات: ",
"Dark mode: ": "الوضع الليلي: ",
@ -108,9 +108,9 @@
"preferences_show_nick_label": "إظهار اللقب في الأعلى: ",
"Top enabled: ": "تفعيل 'الأفضل' ؟ ",
"CAPTCHA enabled: ": "تفعيل الكابتشا: ",
"Login enabled: ": فعيل الولوج: ",
"Login enabled: ": مكين تسجيل الدخول: ",
"Registration enabled: ": "تفعيل التسجيل: ",
"Report statistics: ": "الإبلاغ عن الإحصائيات: ",
"Report statistics: ": "تقرير الإحصائيات: ",
"Save preferences": "حفظ الإعدادات",
"Subscription manager": "مدير الاشتراكات",
"Token manager": "إداره الرمز",
@ -175,7 +175,7 @@
"User ID is a required field": "مكان اسم المستخدم مطلوب",
"Password is a required field": "مكان كلمة السر مطلوب",
"Wrong username or password": "اسم المستخدم او كلمة السر غير صحيح",
"Please sign in using 'Log in with Google'": "الرجاء تسجيل الدخول 'تسجيل الدخول بواسطة جوجل'",
"Please sign in using 'Log in with Google'": "الرجاء تسجيل الدخول باستخدام \"تسجيل الدخول باستخدام Google\"",
"Password cannot be empty": "لا يمكن أن تكون كلمة السر فارغة",
"Password cannot be longer than 55 characters": "يجب أن لا تتعدى كلمة السر 55 حرفًا",
"Please log in": "الرجاء تسجيل الدخول",
@ -187,7 +187,7 @@
"Could not fetch comments": "لم يتمكن من إحضار التعليقات",
"`x` ago": "`x` منذ",
"Load more": "عرض المزيد",
"Could not create mix.": "لم يستطع عمل خلط.",
"Could not create mix.": "تعذر إنشاء مزيج.",
"Empty playlist": "قائمة التشغيل فارغة",
"Not a playlist.": "قائمة التشغيل غير صالحة.",
"Playlist does not exist.": "قائمة التشغيل غير موجودة.",
@ -195,7 +195,7 @@
"Hidden field \"challenge\" is a required field": "مكان مخفي \"تحدي\" مكان مطلوب",
"Hidden field \"token\" is a required field": "مكان مخفي \"رمز\" مكان مطلوب",
"Erroneous challenge": "تحدي غير صالح",
"Erroneous token": وز غير صالح",
"Erroneous token": مز مميز خاطئ",
"No such user": "مستخدم غير صالح",
"Token is expired, please try again": "الرمز منتهى الصلاحية، الرجاء المحاولة مرة اخرى",
"English": "إنجليزي",
@ -337,7 +337,7 @@
"duration": "المدة الزمنية",
"features": "الميزات",
"sort": "فرز",
"hour": "ساعة",
"hour": "آخر ساعة",
"today": "اليوم",
"week": "هذا الأسبوع",
"month": "هذا الشهر",
@ -363,7 +363,7 @@
"short": "قصير (< 4 دقائق)",
"long": "طويل (> 20 دقيقة)",
"footer_source_code": "شفرة المصدر",
"footer_original_source_code": "شفرة المصدر الأصلية",
"footer_original_source_code": "كود المصدر الأصلي",
"footer_modfied_source_code": "شفرة المصدر المعدلة",
"adminprefs_modified_source_code_url_label": "URL إلى مستودع التعليمات البرمجية المصدرية المعدلة",
"footer_documentation": "التوثيق",
@ -398,7 +398,7 @@
"360": "360°",
"download_subtitles": "ترجمات - 'x' (.vtt)",
"invidious": "الخيالي",
"preferences_save_player_pos_label": "احفظ وقت الفيديو الحالي: ",
"preferences_save_player_pos_label": "حفظ موضع التشغيل: ",
"crash_page_you_found_a_bug": "يبدو أنك قد وجدت خطأً برمجيًّا في Invidious!",
"generic_videos_count_0": "لا فيديوهات",
"generic_videos_count_1": "فيديو واحد",
@ -429,5 +429,35 @@
"generic_playlists_count_2": "قائمتا تشغيل",
"generic_playlists_count_3": "{{count}} قوائم تشغيل",
"generic_playlists_count_4": "{{count}} قائمة تشغيل",
"generic_playlists_count_5": "{{count}} قائمة تشغيل"
"generic_playlists_count_5": "{{count}} قائمة تشغيل",
"English (United States)": "الإنجليزية (الولايات المتحدة)",
"Indonesian (auto-generated)": "إندونيسي (مُنشأ تلقائيًا)",
"Interlingue": "إنترلينغوي",
"Italian (auto-generated)": "الإيطالية (مُنشأة تلقائيًا)",
"Spanish (auto-generated)": "الأسبانية (تم إنشاؤه تلقائيًا)",
"crash_page_before_reporting": "قبل الإبلاغ عن خطأ، تأكد من وجود:",
"French (auto-generated)": "الفرنسية (مُنشأة تلقائيًا)",
"Portuguese (auto-generated)": "البرتغالية (تم إنشاؤه تلقائيًا)",
"Turkish (auto-generated)": "التركية (تم إنشاؤها تلقائيًا)",
"crash_page_refresh": "حاول <a href=\"`x`\"> تحديث الصفحة </a>",
"crash_page_switch_instance": "حاول <a href=\"`x`\"> استخدام مثيل آخر </a>",
"Korean (auto-generated)": "كوري (تم إنشاؤه تلقائيًا)",
"Spanish (Mexico)": "الإسبانية (المكسيك)",
"Vietnamese (auto-generated)": "فيتنامي (تم إنشاؤه تلقائيًا)",
"crash_page_report_issue": "إذا لم يساعد أي مما سبق، يرجى فتح <a href=\"`x`\"> مشكلة جديدة على GitHub </a> (ويفضل أن يكون باللغة الإنجليزية) وتضمين النص التالي في رسالتك (لا تترجم هذا النص):",
"crash_page_read_the_faq": "قراءة <a href=\"`x`\"> الأسئلة المتكررة (الأسئلة الشائعة) </a>",
"preferences_watch_history_label": "تمكين سجل المشاهدة: ",
"English (United Kingdom)": "الإنجليزية (المملكة المتحدة)",
"Cantonese (Hong Kong)": "الكانتونية (هونغ كونغ)",
"Chinese": "الصينية",
"Chinese (China)": "الصينية (الصين)",
"Chinese (Hong Kong)": "الصينية (هونج كونج)",
"Chinese (Taiwan)": "الصينية (تايوان)",
"Dutch (auto-generated)": "هولندي (تم إنشاؤه تلقائيًا)",
"German (auto-generated)": "ألماني (تم إنشاؤه تلقائيًا)",
"Japanese (auto-generated)": "اليابانية (مُنشأة تلقائيًا)",
"Portuguese (Brazil)": "البرتغالية (البرازيل)",
"Russian (auto-generated)": "الروسية (منشأة تلقائيا)",
"Spanish (Spain)": "الإسبانية (إسبانيا)",
"crash_page_search_issue": "بحثت عن <a href=\"`x`\"> المشكلات الموجودة على Github </a>"
}

View File

@ -1,6 +1,6 @@
{
"LIVE": "ŽIVĚ",
"Shared `x` ago": "Sdíleno před `x`",
"Shared `x` ago": "Zveřejněno před `x`",
"Unsubscribe": "Odhlásit odběr",
"Subscribe": "Odebírat",
"View channel on YouTube": "Otevřít kanál na YouTube",
@ -19,17 +19,17 @@
"Authorize token for `x`?": "Autorizovat token pro `x`?",
"Yes": "Ano",
"No": "Ne",
"Import and Export Data": "Import a Export údajů",
"Import": "Inport",
"Import Invidious data": "Importovat údaje Invidious",
"Import YouTube subscriptions": "Importovat odběry z YouTube",
"Import and Export Data": "Import a export dat",
"Import": "Importovat",
"Import Invidious data": "Importovat JSON údaje Invidious",
"Import YouTube subscriptions": "Importovat odběry z YouTube/OPML",
"Import FreeTube subscriptions (.db)": "Importovat odběry z FreeTube (.db)",
"Import NewPipe subscriptions (.json)": "Importovat odběry z NewPipe (.json)",
"Import NewPipe data (.zip)": "Importovat údeje z NewPipe (.zip)",
"Export": "Exportovat",
"Export subscriptions as OPML": "Exportovat odběry jako OPML",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Exportovat údaje jako OPML (na NewPipe a FreeTube)",
"Export data as JSON": "Exportovat data jako JSON",
"Export data as JSON": "Exportovat data Invidious jako JSON",
"Delete account?": "Smazat účet?",
"History": "Historie",
"An alternative front-end to YouTube": "Alternativní front-end pro YouTube",
@ -38,7 +38,7 @@
"Log in": "Přihlásit se",
"Log in/register": "Přihlásit se/vytvořit účet",
"Log in with Google": "Přihlásit se s Googlem",
"User ID": "Uživatelské IČ",
"User ID": "ID uživatele",
"Password": "Heslo",
"Time (h:mm:ss):": "Čas (h:mm:ss):",
"Text CAPTCHA": "Textové CAPTCHA",
@ -51,16 +51,16 @@
"preferences_category_player": "Nastavení přehravače",
"preferences_video_loop_label": "Vždy opakovat: ",
"preferences_autoplay_label": "Automatické přehrávání: ",
"preferences_continue_label": "Přehrát další ve výchozím stavu: ",
"preferences_continue_label": "Automaticky přehrát další: ",
"preferences_continue_autoplay_label": "Automaticky přehrát další video: ",
"preferences_listen_label": "Poslouchat ve výchozím nastavení: ",
"preferences_local_label": "Video přes proxy: ",
"preferences_speed_label": "Základní Rychlost: ",
"preferences_speed_label": "Výchozí rychlost: ",
"preferences_quality_label": "Preferovaná kvalita videa: ",
"preferences_volume_label": "Hlasitost přehrávače: ",
"preferences_comments_label": "Předpřipravené komentáře: ",
"youtube": "YouTube",
"reddit": "reddit",
"reddit": "Reddit",
"preferences_captions_label": "Standartní Titulky: ",
"Fallback captions: ": "Záložní titulky: ",
"preferences_related_videos_label": "Zobrazit podobné videa: ",
@ -93,23 +93,23 @@
"`x` is live": "`x` je živě",
"preferences_category_data": "Nastavení dat",
"Clear watch history": "Smazat historii",
"Import/export data": "importovat/exportovat data",
"Import/export data": "Importovat/exportovat data",
"Change password": "Změnit heslo",
"Manage subscriptions": "Spravovat odebírané kanály",
"Manage tokens": "Spravovat klíče",
"Watch history": "Historie Sledování",
"Delete account": "Smazat Účet",
"Manage tokens": "Spravovat tokeny",
"Watch history": "Historie sledování",
"Delete account": "Smazat účet",
"preferences_category_admin": "Administrátorská nastavení",
"preferences_default_home_label": "Základní domovská stránka: ",
"preferences_feed_menu_label": "Menu doporučených: ",
"CAPTCHA enabled: ": "CAPTCHA povolen: ",
"CAPTCHA enabled: ": "CAPTCHA povolena: ",
"Login enabled: ": "Přihlášení povoleno: ",
"Registration enabled: ": "Registrace povolena ",
"Report statistics: ": "Oznámit statistiky: ",
"Save preferences": "Uložit nastavení",
"Subscription manager": "Správa Odběrů",
"Token manager": "Správa klíčů",
"Token": "Klíč",
"Subscription manager": "Správa odběrů",
"Token manager": "Správa tokenů",
"Token": "Token",
"Import/export": "Importovat/exportovat",
"unsubscribe": "odhlásit odběr",
"revoke": "vrátit zpět",
@ -118,10 +118,10 @@
"Log out": "Odhlásit se",
"Source available here.": "Zdrojový kód dostupný zde.",
"View JavaScript license information.": "Zobrazit informace o licenci JavaScript .",
"View privacy policy.": "Zobrazit Zásady ochrany osobních údajů.",
"View privacy policy.": "Zobrazit zásady ochrany osobních údajů.",
"Trending": "Trendy",
"Public": "Veřejné",
"Unlisted": "Nevypsáno",
"Unlisted": "Neveřejné",
"Private": "Soukromé",
"View all playlists": "Zobrazit všechny playlisty",
"Updated `x` ago": "Aktualizováno před `x`",
@ -133,12 +133,12 @@
"Show more": "Zobrazit více",
"Show less": "Zobrazit méně",
"Watch on YouTube": "Sledovat na YouTube",
"Hide annotations": "Skrýt vysvětlivky",
"Show annotations": "Zobrazit vysvětlivky",
"Hide annotations": "Skrýt poznámky",
"Show annotations": "Zobrazit poznámky",
"Genre: ": "Žánr: ",
"License: ": "Licence: ",
"Family friendly? ": "Vhodné pro děti? ",
"Engagement: ": "Závaznost: ",
"Engagement: ": "Zapojení: ",
"English": "Angličtina",
"English (auto-generated)": "Angličtina (automaticky generováno)",
"Afrikaans": "Afrikánština",
@ -262,27 +262,220 @@
"Video mode": "Videový režim",
"Videos": "Videa",
"Community": "Komunita",
"rating": "hodnocení",
"date": "datum",
"views": "zhlédnutí",
"duration": "délka",
"hour": "hodina",
"today": "dnes",
"week": "týden",
"month": "měsíc",
"year": "rok",
"video": "video",
"channel": "kanál",
"playlist": "playlist",
"movie": "film",
"show": "zobrazit",
"rating": "Hodnocení",
"date": "Datum zveřejnění",
"views": "Počet zhlédnutí",
"duration": "Délka",
"hour": "Před hodinou",
"today": "Dnes",
"week": "Tento týden",
"month": "Tento měsíc",
"year": "Tento rok",
"video": "Video",
"channel": "Kanál",
"playlist": "Playlist",
"movie": "Film",
"show": "Show",
"hd": "HD",
"subtitles": "titulky",
"subtitles": "Titulky",
"creative_commons": "Creative Commons",
"3d": "3D",
"live": "živě",
"4k": "4k",
"location": "umístění",
"live": "Živě",
"4k": "4K",
"location": "Umístění",
"hdr": "HDR",
"filter": "filtr"
"filter": "Filtr",
"generic_count_days_0": "{{count}} den",
"generic_count_days_1": "{{count}} dny",
"generic_count_days_2": "{{count}} dní",
"generic_count_hours_0": "{{count}} hodina",
"generic_count_hours_1": "{{count}} hodiny",
"generic_count_hours_2": "{{count}} hodin",
"crash_page_refresh": "zkusili <a href=\"`x`\">obnovit stránku</a>",
"crash_page_switch_instance": "zkusili <a href=\"`x`\">použít jinou instanci</a>",
"preferences_vr_mode_label": "Interaktivní 360-stupňová videa (vyžaduje WebGL): ",
"English (United Kingdom)": "Angličtina (Spojené království)",
"Chinese (China)": "Čínština (Čína)",
"Chinese (Hong Kong)": "Čínština (Hong Kong)",
"Chinese (Taiwan)": "Čínština (Taiwan)",
"Portuguese (auto-generated)": "Portugalština (automaticky generováno)",
"Spanish (auto-generated)": "Španělština (automaticky generováno)",
"Spanish (Mexico)": "Španělština (Mexiko)",
"Spanish (Spain)": "Španělština (Španělsko)",
"generic_count_years_0": "{{count}} rok",
"generic_count_years_1": "{{count}} roky",
"generic_count_years_2": "{{count}} let",
"Fallback comments: ": "Záložní komentáře: ",
"Search": "Hledat",
"Top": "Nejlepší",
"Playlists": "Playlisty",
"videoinfo_started_streaming_x_ago": "Stream spuštěn před `x`",
"videoinfo_watch_on_youTube": "Sledovat na YouTube",
"videoinfo_youTube_embed_link": "Vložení",
"crash_page_read_the_faq": "si přečetli <a href=\"`x`\">často kladené otázky (FAQ)</a>",
"crash_page_before_reporting": "Před nahlášením chyby se ujistěte, že jste:",
"preferences_quality_option_hd720": "HD720",
"preferences_quality_option_dash": "DASH (adaptivní kvalita)",
"generic_views_count_0": "{{count}} zhlédnutí",
"generic_views_count_1": "{{count}} zhlédnutí",
"generic_views_count_2": "{{count}} zhlédnutí",
"generic_subscriptions_count_0": "{{count}} odběr",
"generic_subscriptions_count_1": "{{count}} odběry",
"generic_subscriptions_count_2": "{{count}} odběrů",
"preferences_quality_dash_option_4320p": "4320p",
"generic_videos_count_0": "{{count}} video",
"generic_videos_count_1": "{{count}} videa",
"generic_videos_count_2": "{{count}} videí",
"preferences_quality_option_small": "Nízká",
"preferences_quality_dash_option_2160p": "2160p",
"preferences_quality_dash_option_1080p": "1080p",
"preferences_quality_dash_option_720p": "720p",
"preferences_quality_dash_option_360p": "360p",
"preferences_quality_dash_option_144p": "144p",
"preferences_quality_option_medium": "Střední",
"preferences_quality_dash_option_1440p": "1440p",
"invidious": "Invidious",
"View more comments on Reddit": "Zobrazit více komentářů na Redditu",
"Invalid TFA code": "Nesprávný TFA kód",
"generic_playlists_count_0": "{{count}} playlist",
"generic_playlists_count_1": "{{count}} playlisty",
"generic_playlists_count_2": "{{count}} playlistů",
"generic_subscribers_count_0": "{{count}} odběratel",
"generic_subscribers_count_1": "{{count}} odběratelé",
"generic_subscribers_count_2": "{{count}} odběratelů",
"preferences_watch_history_label": "Povolit historii sledování: ",
"preferences_quality_dash_option_240p": "240p",
"preferences_region_label": "Země obsahu: ",
"subscriptions_unseen_notifs_count_0": "{{count}} nezobrazené oznámení",
"subscriptions_unseen_notifs_count_1": "{{count}} nezobrazená oznámení",
"subscriptions_unseen_notifs_count_2": "{{count}} nezobrazených oznámení",
"Show replies": "Zobrazit odpovědi",
"Quota exceeded, try again in a few hours": "Kvóta překročena, zkuste to znovu za pár hodin",
"Password cannot be longer than 55 characters": "Heslo nesmí být delší než 55 znaků",
"comments_view_x_replies_0": "Zobrazit {{count}} odpověď",
"comments_view_x_replies_1": "Zobrazit {{count}} odpovědi",
"comments_view_x_replies_2": "Zobrazit {{count}} odpovědí",
"comments_points_count_0": "{{count}} bod",
"comments_points_count_1": "{{count}} body",
"comments_points_count_2": "{{count}} bodů",
"German (auto-generated)": "Němčina (automaticky generováno)",
"Indonesian (auto-generated)": "Indonéština (automaticky generováno)",
"Interlingue": "Interlingue",
"Italian (auto-generated)": "Italština (automaticky generováno)",
"Japanese (auto-generated)": "Japonština (automaticky generováno)",
"Korean (auto-generated)": "Korejština (automaticky generováno)",
"Russian (auto-generated)": "Ruština (automaticky generováno)",
"generic_count_months_0": "{{count}} měsíc",
"generic_count_months_1": "{{count}} měsíce",
"generic_count_months_2": "{{count}} měsíců",
"generic_count_weeks_0": "{{count}} týden",
"generic_count_weeks_1": "{{count}} týdny",
"generic_count_weeks_2": "{{count}} týdnů",
"generic_count_minutes_0": "{{count}} minuta",
"generic_count_minutes_1": "{{count}} minuty",
"generic_count_minutes_2": "{{count}} minut",
"short": "Krátké (< 4 minuty)",
"long": "Dlouhé (> 20 minut)",
"footer_documentation": "Dokumentace",
"next_steps_error_message_refresh": "Obnovit stránku",
"Chinese": "Čínština",
"360": "360°",
"Dutch (auto-generated)": "Nizozemština (automaticky generováno)",
"Erroneous token": "Chybný token",
"tokens_count_0": "{{count}} token",
"tokens_count_1": "{{count}} tokeny",
"tokens_count_2": "{{count}} tokenů",
"Portuguese (Brazil)": "Portugalština (Brazílie)",
"content_type": "Typ",
"sort": "Řazení",
"Token is expired, please try again": "Token vypršel, zkuste to prosím znovu",
"English (United States)": "Angličtina (Spojené státy)",
"Cantonese (Hong Kong)": "Kantonština (Hong Kong)",
"French (auto-generated)": "Francouzština (automaticky generováno)",
"Turkish (auto-generated)": "Turečtina (automaticky generováno)",
"Vietnamese (auto-generated)": "Vietnamština (automaticky generováno)",
"Current version: ": "Aktuální verze: ",
"next_steps_error_message": "Měli byste zkusit: ",
"footer_donate_page": "Přispět",
"download_subtitles": "Titulky - `x` (.vtt)",
"%A %B %-d, %Y": "%A %B %-d, %Y",
"YouTube comment permalink": "Permanentní odkaz YouTube komentáře",
"permalink": "permalink",
"purchased": "Zakoupeno",
"footer_original_source_code": "Původní zdrojový kód",
"adminprefs_modified_source_code_url_label": "URL repozitáře s upraveným zdrojovým kódem",
"Video unavailable": "Video není dostupné",
"next_steps_error_message_go_to_youtube": "Jít na YouTube",
"footer_modfied_source_code": "Upravený zdrojový kód",
"none": "žádné",
"videoinfo_invidious_embed_link": "Odkaz na vložení",
"user_saved_playlists": "`x` uložených playlistů",
"crash_page_you_found_a_bug": "Vypadá to, že jste našli chybu v Invidious!",
"user_created_playlists": "`x` vytvořených playlistů",
"crash_page_search_issue": "vyhledali <a href=\"`x`\">existující problémy na GitHubu</a>",
"crash_page_report_issue": "Pokud nepomohlo nic z výše uvedeného, <a href=\"`x`\">otevřete prosím nový problém na GitHubu</a> (pokud možno v angličtině) a zahrňte do zprávy následující text (NEpřekládejte jej):",
"preferences_quality_dash_label": "Preferovaná kvalita videí DASH: ",
"preferences_quality_dash_option_auto": "Automatická",
"preferences_quality_dash_option_best": "Nejlepší",
"preferences_quality_dash_option_worst": "Nejhorší",
"preferences_quality_dash_option_480p": "480p",
"Top enabled: ": "Povoleny nejlepší: ",
"generic_count_seconds_0": "{{count}} sekunda",
"generic_count_seconds_1": "{{count}} sekundy",
"generic_count_seconds_2": "{{count}} sekund",
"preferences_save_player_pos_label": "Uložit pozici přehrávání: ",
"Incorrect password": "Nesprávné heslo",
"View as playlist": "Zobrazit jako playlist",
"View Reddit comments": "Zobrazit komentáře z Redditu",
"No such user": "Uživatel nenalezen",
"Playlist privacy": "Soukromí playlistu",
"Wrong answer": "Špatná odpověď",
"Could not pull trending pages.": "Nepodařilo se získat trendy stránky.",
"Erroneous CAPTCHA": "Chybná CAPTCHA",
"Password is a required field": "Heslo je vyžadované pole",
"preferences_automatic_instance_redirect_label": "Automatické přesměrování instance (fallback na redirect.invidious.io): ",
"Broken? Try another Invidious Instance": "Je něco rozbité? Zkuste jinou instanci Invidious",
"Switch Invidious Instance": "Přepnout instanci Invidious",
"Empty playlist": "Prázdný playlist",
"footer_source_code": "Zdrojový kód",
"relevance": "Relevantnost",
"View YouTube comments": "Zobrazit YouTube komentáře",
"Blacklisted regions: ": "Oblasti na černé listině: ",
"Wrong username or password": "Nesprávné uživatelské jméno nebo heslo",
"Please sign in using 'Log in with Google'": "Přihlaste se prosím pomocí Googlu",
"Password cannot be empty": "Heslo nemůže být prázné",
"preferences_category_misc": "Různá nastavení",
"preferences_show_nick_label": "Zobrazit přezdívku na vrchu: ",
"Whitelisted regions: ": "Oblasti na bílé listině: ",
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Zdravíme! Zdá se, že máte vypnutý JavaScript. Klikněte sem pro zobrazení komentářů - nezapomeňte, že se mohou načítat trochu déle.",
"User ID is a required field": "ID uživatele je vyžadované pole",
"Please log in": "Přihlaste se prosím",
"Invidious Private Feed for `x`": "Soukromý kanál Invidious pro `x`",
"Deleted or invalid channel": "Smazaný nebo neplatný kanál",
"This channel does not exist.": "Tento kanál neexistuje.",
"Hidden field \"token\" is a required field": "Skryté pole \"token\" je vyžadované",
"features": "Funkce",
"Wilson score: ": "Skóre Wilson: ",
"Shared `x`": "Sdíleno `x`",
"Premieres in `x`": "Premiéra za `x`",
"View `x` comments": {
"([^.,0-9]|^)1([^.,0-9]|$)": "Zobrazit `x` komentář",
"": "Zobrazit `x` komentářů"
},
"Unable to log in, make sure two-factor authentication (Authenticator or SMS) is turned on.": "Nepodařilo se přihlásit, ujistěte se, že je povoleno dvoufázové ověřování (autentifikátor nebo SMS).",
"Login failed. This may be because two-factor authentication is not turned on for your account.": "Přihlášení selhalo. Toto se může stát, když není na vašem účtu povolené dvoufázové ověřování.",
"Could not get channel info.": "Nepodařilo se získat informace o kanálu.",
"Could not fetch comments": "Nepodařilo se získat komentáře",
"Could not create mix.": "Nepodařilo se vytvořit mix.",
"Hidden field \"challenge\" is a required field": "Skryté pole \"challenge\" je vyžadované",
"Released under the AGPLv3 on Github.": "Vydáno pod licencí AGPLv3 na GitHubu.",
"Hide replies": "Skrýt odpovědi",
"channel:`x`": "kanál: `x`",
"Load more": "Načíst další",
"Not a playlist.": "Není playlist.",
"Playlist does not exist.": "Playlist neexistuje.",
"Erroneous challenge": "Chybná výzva",
"Premieres `x`": "Premiéra `x`",
"CAPTCHA is a required field": "CAPTCHA je vyžadované pole",
"`x` ago": "Před `x`"
}

View File

@ -141,7 +141,7 @@
"Show less": "Weniger anzeigen",
"Watch on YouTube": "Video auf YouTube ansehen",
"Switch Invidious Instance": "Invidious Instanz wechseln",
"Broken? Try another Invidious Instance": "Funktioniert nicht? Probiere eine andere Invidious Instanz aus",
"Broken? Try another Invidious Instance": "Kaputt? Versuche eine andere Invidious Instanz",
"Hide annotations": "Anmerkungen ausblenden",
"Show annotations": "Anmerkungen anzeigen",
"Genre: ": "Genre: ",
@ -346,7 +346,7 @@
"channel": "Kanal",
"playlist": "Wiedergabeliste",
"movie": "Film",
"show": "Anzeigen",
"show": "anzeigen",
"hd": "HD",
"subtitles": "Untertitel / CC",
"creative_commons": "Creative Commons",
@ -388,7 +388,7 @@
"Video unavailable": "Video nicht verfügbar",
"user_created_playlists": "`x` Wiedergabelisten erstellt",
"user_saved_playlists": "`x` Wiedergabelisten gespeichert",
"preferences_save_player_pos_label": "Aktuelle Position speichern: ",
"preferences_save_player_pos_label": "Aktuelle Position im Video speichern: ",
"360": "360°",
"preferences_quality_dash_option_best": "Höchste",
"preferences_quality_dash_option_worst": "Niedrigste",
@ -398,5 +398,42 @@
"none": "keine",
"videoinfo_started_streaming_x_ago": "Stream begann vor `x`",
"videoinfo_watch_on_youTube": "Auf YouTube ansehen",
"preferences_quality_dash_label": "Bevorzugte DASH-Videoqualität: "
"preferences_quality_dash_label": "Bevorzugte DASH-Videoqualität: ",
"generic_subscribers_count": "{{count}} Abonnent",
"generic_subscribers_count_plural": "{{count}} Abonnenten",
"generic_videos_count": "{{count}} Video",
"generic_videos_count_plural": "{{count}} Videos",
"subscriptions_unseen_notifs_count": "{{count}} ungesehene Benachrichtung",
"subscriptions_unseen_notifs_count_plural": "{{count}} ungesehene Benachrichtungen",
"crash_page_refresh": "Versucht haben, <a href=\"`x`\">die Seite neu zu laden</a>",
"comments_view_x_replies": "{{count}} Antwort anzeigen",
"comments_view_x_replies_plural": "{{count}} Antworten anzeigen",
"generic_count_years": "{{count}} Jahr",
"generic_count_years_plural": "{{count}} Jahre",
"generic_count_weeks": "{{count}} Woche",
"generic_count_weeks_plural": "{{count}} Wochen",
"generic_count_days": "{{count}} Tag",
"generic_count_days_plural": "{{count}} Tage",
"crash_page_before_reporting": "Bevor Sie einen Bug melden, stellen Sie sicher, dass Sie:",
"crash_page_switch_instance": "Eine <a href=\"`x`\">andere Instanz</a> versucht haben",
"generic_count_hours": "{{count}} Stunde",
"generic_count_hours_plural": "{{count}} Stunden",
"generic_count_minutes": "{{count}} Minute",
"generic_count_minutes_plural": "{{count}} Minuten",
"crash_page_read_the_faq": "Das <a href=\"`x`\">FAQ</a> gelesen haben",
"crash_page_search_issue": "Nach <a href=\"`x`\">bereits gemeldeten Bugs auf Github</a> gesucht haben",
"crash_page_report_issue": "Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffnen Sie bitte ein neues Problem (issue) auf Github</a> (vorzugsweise auf Englisch) und fügen Sie den folgenden Text in Ihre Nachricht ein (bitte übersetzen Sie diesen Text NICHT):",
"generic_views_count": "{{count}} Aufruf",
"generic_views_count_plural": "{{count}} Aufrufe",
"generic_count_seconds": "{{count}} Sekunde",
"generic_count_seconds_plural": "{{count}} Sekunden",
"generic_subscriptions_count": "{{count}} Abo",
"generic_subscriptions_count_plural": "{{count}} Abos",
"tokens_count": "{{count}} Token",
"tokens_count_plural": "{{count}} Tokens",
"comments_points_count": "{{count}} Punkt",
"comments_points_count_plural": "{{count}} Punkte",
"crash_page_you_found_a_bug": "Anscheinend haben Sie einen Fehler in Invidious gefunden!",
"generic_count_months": "{{count}} Monat",
"generic_count_months_plural": "{{count}} Monate"
}

View File

@ -448,5 +448,6 @@
"none": "κανένα",
"videoinfo_youTube_embed_link": "Ενσωμάτωση",
"videoinfo_invidious_embed_link": "Σύνδεσμος Ενσωμάτωσης",
"show": "Μπάρα προόδου διαβάσματος"
"show": "Μπάρα προόδου διαβάσματος",
"preferences_watch_history_label": "Ενεργοποίηση ιστορικού παρακολούθησης: "
}

View File

@ -459,7 +459,7 @@
"crash_page_before_reporting": "Before reporting a bug, make sure that you have:",
"crash_page_refresh": "tried to <a href=\"`x`\">refresh the page</a>",
"crash_page_switch_instance": "tried to <a href=\"`x`\">use another instance</a>",
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frenquently Asked Questions (FAQ)</a>",
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frequently Asked Questions (FAQ)</a>",
"crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on Github</a>",
"crash_page_report_issue": "If none of the above helped, please <a href=\"`x`\">open a new issue on GitHub</a> (preferably in English) and include the following text in your message (do NOT translate that text):"
}

View File

@ -196,7 +196,7 @@
"Hidden field \"token\" is a required field": "El campo oculto «símbolo» es un campo obligatorio",
"Erroneous challenge": "Desafío no válido",
"Erroneous token": "Símbolo no válido",
"No such user": "Usuario no válido",
"No such user": "Usuario no existe",
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",
"English": "Inglés",
"English (auto-generated)": "Inglés (generados automáticamente)",
@ -358,7 +358,7 @@
"filter": "filtro",
"Current version: ": "Versión actual: ",
"next_steps_error_message": "Después de lo cual deberías intentar: ",
"next_steps_error_message_refresh": "Recargar",
"next_steps_error_message_refresh": "Recargar la página",
"next_steps_error_message_go_to_youtube": "Ir a YouTube",
"short": "Corto (< 4 minutos)",
"long": "Largo (> 20 minutos)",

View File

@ -21,15 +21,15 @@
"No": "Ei",
"Import and Export Data": "Tuo ja vie tietoja",
"Import": "Tuo",
"Import Invidious data": "Tuo Invidious-tietoja",
"Import YouTube subscriptions": "Tuo YouTube-tilaukset",
"Import Invidious data": "Tuo Invidiousin JSON-tietoja",
"Import YouTube subscriptions": "Tuo YouTube/OPML-tilaukset",
"Import FreeTube subscriptions (.db)": "Tuo FreeTube-tilaukset (.db)",
"Import NewPipe subscriptions (.json)": "Tuo NewPipe-tilaukset (.json)",
"Import NewPipe data (.zip)": "Tuo NewPipe-tietoja (.zip)",
"Export": "Vie",
"Export subscriptions as OPML": "Vie tilaukset OPML-muodossa",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Vie tilaukset OPML-muodossa (NewPipe & FreeTube)",
"Export data as JSON": "Vie data JSON-muodossa",
"Export data as JSON": "Vie Invidious-data JSON-muodossa",
"Delete account?": "Poista tili?",
"History": "Historia",
"An alternative front-end to YouTube": "Vaihtoehtoinen front-end YouTubelle",
@ -66,7 +66,7 @@
"preferences_related_videos_label": "Näytä aiheeseen liittyviä videoita: ",
"preferences_annotations_label": "Näytä huomautukset oletuksena: ",
"preferences_extend_desc_label": "Laajenna automaattisesti videon kuvausta: ",
"preferences_vr_mode_label": "Interaktiiviset 360-asteiset videot: ",
"preferences_vr_mode_label": "Interaktiiviset 360-asteiset videot (vaatii WebGL:n): ",
"preferences_category_visual": "Visuaaliset asetukset",
"preferences_player_style_label": "Soittimen tyyli: ",
"Dark mode: ": "Tumma tila: ",
@ -437,5 +437,29 @@
"long": "Pitkä (> 20 minuuttia)",
"footer_documentation": "Dokumentaatio",
"footer_original_source_code": "Alkuperäinen lähdekoodi",
"footer_modfied_source_code": "Muokattu lähdekoodi"
"footer_modfied_source_code": "Muokattu lähdekoodi",
"Japanese (auto-generated)": "Japani (automaattisesti luotu)",
"German (auto-generated)": "Saksa (automaattisesti luotu)",
"Portuguese (auto-generated)": "Portugali (automaattisesti luotu)",
"Russian (auto-generated)": "Venäjä (automaattisesti luotu)",
"preferences_watch_history_label": "Ota katseluhistoria käyttöön: ",
"English (United Kingdom)": "Englanti (Iso-Britannia)",
"English (United States)": "Englanti (Yhdysvallat)",
"Cantonese (Hong Kong)": "Kantoninkiina (Hong Kong)",
"Chinese": "Kiina",
"Chinese (China)": "Kiina (Kiina)",
"Chinese (Hong Kong)": "Kiina (Hong Kong)",
"Chinese (Taiwan)": "Kiina (Taiwan)",
"Dutch (auto-generated)": "Hollanti (automaattisesti luotu)",
"French (auto-generated)": "Ranska (automaattisesti luotu)",
"Indonesian (auto-generated)": "Indonesia (automaattisesti luotu)",
"Interlingue": "Interlingue",
"Italian (auto-generated)": "Italia (automaattisesti luotu)",
"Korean (auto-generated)": "Korea (automaattisesti luotu)",
"Portuguese (Brazil)": "Portugali (Brasilia)",
"Spanish (auto-generated)": "Espanja (automaattisesti luotu)",
"Spanish (Mexico)": "Espanja (Meksiko)",
"Spanish (Spain)": "Espanja (Espanja)",
"Turkish (auto-generated)": "Turkki (automaattisesti luotu)",
"Vietnamese (auto-generated)": "Vietnam (automaattisesti luotu)"
}

View File

@ -88,7 +88,7 @@
"channel name": "ime kanala",
"channel name - reverse": "ime kanala obrnuto",
"Only show latest video from channel: ": "Prikaži samo najnovija videa kanala: ",
"Only show latest unwatched video from channel: ": "Prikaži samo najnovija nepogledana videa kanala: ",
"Only show latest unwatched video from channel: ": "Prikaži samo najnovija nepogledana videa od kanala: ",
"preferences_unseen_only_label": "Prikaži samo nepogledane: ",
"preferences_notifications_only_label": "Prikaži samo obavijesti (ako ih ima): ",
"Enable web notifications": "Aktiviraj web-obavijesti",
@ -476,5 +476,6 @@
"Chinese (Hong Kong)": "Kineski (Hong Kong)",
"Korean (auto-generated)": "Korejski (automatski generiran)",
"Portuguese (auto-generated)": "Portugalski (automatski generiran)",
"Spanish (auto-generated)": "Španjolski (automatski generiran)"
"Spanish (auto-generated)": "Španjolski (automatski generiran)",
"preferences_watch_history_label": "Aktiviraj povijest gledanja: "
}

View File

@ -390,7 +390,41 @@
"preferences_quality_dash_option_best": "Migliore",
"preferences_quality_dash_option_worst": "Peggiore",
"invidious": "Invidious",
"preferences_quality_dash_label": "Qualità video DASH preferita ",
"preferences_quality_dash_label": "Qualità video DASH preferita: ",
"preferences_quality_option_hd720": "HD720",
"preferences_quality_dash_option_auto": "Automatica"
"preferences_quality_dash_option_auto": "Automatica",
"videoinfo_watch_on_youTube": "Guarda su YouTube",
"preferences_extend_desc_label": "Espandi automaticamente la descrizione del video: ",
"preferences_vr_mode_label": "Video interattivi a 360 gradi: ",
"Show less": "Mostra di meno",
"Switch Invidious Instance": "Cambia istanza Invidious",
"next_steps_error_message_go_to_youtube": "Andare su YouTube",
"footer_documentation": "Documentazione",
"footer_original_source_code": "Codice sorgente originale",
"footer_modfied_source_code": "Codice sorgente modificato",
"none": "nessuno",
"videoinfo_started_streaming_x_ago": "Ha iniziato a trasmettere `x` fa",
"download_subtitles": "Sottotitoli - `x` (.vtt)",
"user_saved_playlists": "playlist salvate da `x`",
"preferences_automatic_instance_redirect_label": "Reindirizzamento automatico dell'istanza (ripiego su redirect.invidious.io): ",
"Video unavailable": "Video non disponibile",
"preferences_show_nick_label": "Mostra nickname in alto: ",
"short": "Corto (< 4 minuti)",
"videoinfo_youTube_embed_link": "Incorpora",
"videoinfo_invidious_embed_link": "Incorpora collegamento",
"user_created_playlists": "playlist create da `x`",
"preferences_save_player_pos_label": "Memorizza il minutaggio raggiunto dal video: ",
"purchased": "Acquistato",
"preferences_quality_option_dash": "DASH (qualità adattiva)",
"preferences_region_label": "Nazione del contenuto: ",
"preferences_category_misc": "Preferenze varie",
"show": "Serie",
"long": "Lungo (> 20 minuti)",
"next_steps_error_message": "Dopodiché dovresti provare a: ",
"next_steps_error_message_refresh": "Aggiornare",
"footer_donate_page": "Dona",
"footer_source_code": "Codice sorgente",
"adminprefs_modified_source_code_url_label": "Link per il repository del codice sorgente modificato",
"Show more": "Mostra di più",
"Broken? Try another Invidious Instance": "Non funzionante? Prova unaltra istanza Invidious"
}

View File

@ -26,15 +26,15 @@
"No": "いいえ",
"Import and Export Data": "データのインポートとエクスポート",
"Import": "インポート",
"Import Invidious data": "Invidious データをインポート",
"Import YouTube subscriptions": "YouTube 登録チャンネルをインポート",
"Import Invidious data": "Invidious JSONデータをインポート",
"Import YouTube subscriptions": "YouTube/OPML 登録チャンネルをインポート",
"Import FreeTube subscriptions (.db)": "FreeTube 登録チャンネルをインポート (.db)",
"Import NewPipe subscriptions (.json)": "NewPipe 登録チャンネルをインポート (.json)",
"Import NewPipe data (.zip)": "NewPipe データをインポート (.zip)",
"Export": "エクスポート",
"Export subscriptions as OPML": "登録チャンネルを OPML でエクスポート",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "登録チャンネルを OPML でエクスポート (NewPipe & FreeTube 用)",
"Export data as JSON": "データを JSON でエクスポート",
"Export data as JSON": "Invidious のデータを JSON でエクスポート",
"Delete account?": "アカウントを削除しますか?",
"History": "履歴",
"An alternative front-end to YouTube": "YouTube 向けの代用フロントエンド",
@ -71,7 +71,7 @@
"preferences_related_videos_label": "関連動画を表示: ",
"preferences_annotations_label": "デフォルトでアノテーションを表示: ",
"preferences_extend_desc_label": "動画の説明文を自動的に拡張: ",
"preferences_vr_mode_label": "対話的な360°動画: ",
"preferences_vr_mode_label": "対話的な360°動画 (WebGL が必要): ",
"preferences_category_visual": "外観設定",
"preferences_player_style_label": "プレイヤースタイル: ",
"Dark mode: ": "ダークモード: ",
@ -411,5 +411,28 @@
"videoinfo_started_streaming_x_ago": "`x`分前に配信を開始",
"videoinfo_watch_on_youTube": "YouTube上で見る",
"user_created_playlists": "`x`が作成したプレイリスト",
"Video unavailable": "ビデオは利用できません"
"Video unavailable": "ビデオは利用できません",
"Chinese": "中国語",
"Chinese (Taiwan)": "中国語 (台湾)",
"Korean (auto-generated)": "韓国語 (自動生成)",
"Portuguese (auto-generated)": "ポルトガル語 (自動生成)",
"Turkish (auto-generated)": "トルコ語 (自動生成)",
"English (United Kingdom)": "英語 (イギリス)",
"Cantonese (Hong Kong)": "広東語 (香港)",
"Chinese (China)": "中国語 (中国)",
"Chinese (Hong Kong)": "中国語 (香港)",
"Dutch (auto-generated)": "オランダ語 (自動生成)",
"French (auto-generated)": "フランス語 (自動生成)",
"German (auto-generated)": "ドイツ語 (自動生成)",
"Indonesian (auto-generated)": "インドネシア語 (自動生成)",
"Italian (auto-generated)": "イタリア語 (自動生成)",
"Japanese (auto-generated)": "日本語 (自動生成)",
"Interlingue": "インターリング",
"Portuguese (Brazil)": "ポルトガル語 (ブラジル)",
"Russian (auto-generated)": "ロシア語 (自動生成)",
"Spanish (auto-generated)": "スペイン語 (自動生成)",
"Spanish (Mexico)": "スペイン語 (メキシコ)",
"Spanish (Spain)": "スペイン語 (スペイン)",
"Vietnamese (auto-generated)": "ベトナム語 (自動生成)",
"360": "360°"
}

View File

@ -369,5 +369,8 @@
"footer_modfied_source_code": "Pakeistas pirminis kodas",
"footer_donate_page": "Paaukoti",
"preferences_region_label": "Turinio šalis: ",
"preferences_quality_dash_label": "Pageidaujama DASH vaizdo kokybė: "
"preferences_quality_dash_label": "Pageidaujama DASH vaizdo kokybė: ",
"preferences_quality_dash_option_best": "Geriausia",
"preferences_quality_dash_option_worst": "Blogiausia",
"preferences_quality_dash_option_auto": "Automatinis"
}

View File

@ -476,5 +476,6 @@
"360": "360°",
"Video unavailable": "Видео недоступно",
"preferences_save_player_pos_label": "Запоминать позицию: ",
"preferences_region_label": "Страна: "
"preferences_region_label": "Страна: ",
"preferences_watch_history_label": "Включить историю просмотров "
}

View File

@ -327,8 +327,8 @@
"Videos": "Videor",
"Playlists": "Spellistor",
"Community": "Gemenskap",
"relevance": "relevans",
"rating": "rankning",
"relevance": "Relevans",
"rating": "Rankning",
"date": "datum",
"views": "visningar",
"content_type": "Typ",

View File

@ -27,6 +27,7 @@ require "compress/zip"
require "protodec/utils"
require "./invidious/database/*"
require "./invidious/database/migrations/*"
require "./invidious/helpers/*"
require "./invidious/yt_backend/*"
require "./invidious/frontend/*"
@ -102,6 +103,10 @@ Kemal.config.extra_options do |parser|
puts SOFTWARE.to_pretty_json
exit
end
parser.on("--migrate", "Run any migrations (beta, use at your own risk!!") do
Invidious::Database::Migrator.new(PG_DB).migrate
exit
end
end
Kemal::CLI.new ARGV

View File

@ -0,0 +1,38 @@
abstract class Invidious::Database::Migration
macro inherited
Migrator.migrations << self
end
@@version : Int64?
def self.version(version : Int32 | Int64)
@@version = version.to_i64
end
getter? completed = false
def initialize(@db : DB::Database)
end
abstract def up(conn : DB::Connection)
def migrate
# migrator already ignores completed migrations
# but this is an extra check to make sure a migration doesn't run twice
return if completed?
@db.transaction do |txn|
up(txn.connection)
track(txn.connection)
@completed = true
end
end
def version : Int64
@@version.not_nil!
end
private def track(conn : DB::Connection)
conn.exec("INSERT INTO #{Migrator::MIGRATIONS_TABLE} (version) VALUES ($1)", version)
end
end

View File

@ -0,0 +1,30 @@
module Invidious::Database::Migrations
class CreateChannelsTable < Migration
version 1
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.channels
(
id text NOT NULL,
author text,
updated timestamp with time zone,
deleted boolean,
subscribed timestamp with time zone,
CONSTRAINT channels_id_key UNIQUE (id)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.channels TO current_user;
SQL
conn.exec <<-SQL
CREATE INDEX IF NOT EXISTS channels_id_idx
ON public.channels
USING btree
(id COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,28 @@
module Invidious::Database::Migrations
class CreateVideosTable < Migration
version 2
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE UNLOGGED TABLE IF NOT EXISTS public.videos
(
id text NOT NULL,
info text,
updated timestamp with time zone,
CONSTRAINT videos_pkey PRIMARY KEY (id)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.videos TO current_user;
SQL
conn.exec <<-SQL
CREATE UNIQUE INDEX IF NOT EXISTS id_idx
ON public.videos
USING btree
(id COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,35 @@
module Invidious::Database::Migrations
class CreateChannelVideosTable < Migration
version 3
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.channel_videos
(
id text NOT NULL,
title text,
published timestamp with time zone,
updated timestamp with time zone,
ucid text,
author text,
length_seconds integer,
live_now boolean,
premiere_timestamp timestamp with time zone,
views bigint,
CONSTRAINT channel_videos_id_key UNIQUE (id)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.channel_videos TO current_user;
SQL
conn.exec <<-SQL
CREATE INDEX IF NOT EXISTS channel_videos_ucid_idx
ON public.channel_videos
USING btree
(ucid COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,34 @@
module Invidious::Database::Migrations
class CreateUsersTable < Migration
version 4
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.users
(
updated timestamp with time zone,
notifications text[],
subscriptions text[],
email text NOT NULL,
preferences text,
password text,
token text,
watched text[],
feed_needs_update boolean,
CONSTRAINT users_email_key UNIQUE (email)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.users TO current_user;
SQL
conn.exec <<-SQL
CREATE UNIQUE INDEX IF NOT EXISTS email_unique_idx
ON public.users
USING btree
(lower(email) COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,28 @@
module Invidious::Database::Migrations
class CreateSessionIdsTable < Migration
version 5
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.session_ids
(
id text NOT NULL,
email text,
issued timestamp with time zone,
CONSTRAINT session_ids_pkey PRIMARY KEY (id)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.session_ids TO current_user;
SQL
conn.exec <<-SQL
CREATE INDEX IF NOT EXISTS session_ids_id_idx
ON public.session_ids
USING btree
(id COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,27 @@
module Invidious::Database::Migrations
class CreateNoncesTable < Migration
version 6
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.nonces
(
nonce text,
expire timestamp with time zone,
CONSTRAINT nonces_id_key UNIQUE (nonce)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.nonces TO current_user;
SQL
conn.exec <<-SQL
CREATE INDEX IF NOT EXISTS nonces_nonce_idx
ON public.nonces
USING btree
(nonce COLLATE pg_catalog."default");
SQL
end
end
end

View File

@ -0,0 +1,20 @@
module Invidious::Database::Migrations
class CreateAnnotationsTable < Migration
version 7
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.annotations
(
id text NOT NULL,
annotations xml,
CONSTRAINT annotations_id_key UNIQUE (id)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.annotations TO current_user;
SQL
end
end
end

View File

@ -0,0 +1,50 @@
module Invidious::Database::Migrations
class CreatePlaylistsTable < Migration
version 8
def up(conn : DB::Connection)
if !privacy_type_exists?(conn)
conn.exec <<-SQL
CREATE TYPE public.privacy AS ENUM
(
'Public',
'Unlisted',
'Private'
);
SQL
end
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.playlists
(
title text,
id text primary key,
author text,
description text,
video_count integer,
created timestamptz,
updated timestamptz,
privacy privacy,
index int8[]
);
SQL
conn.exec <<-SQL
GRANT ALL ON public.playlists TO current_user;
SQL
end
private def privacy_type_exists?(conn : DB::Connection) : Bool
request = <<-SQL
SELECT 1 AS one
FROM pg_type
INNER JOIN pg_namespace ON pg_namespace.oid = pg_type.typnamespace
WHERE pg_namespace.nspname = 'public'
AND pg_type.typname = 'privacy'
LIMIT 1;
SQL
!conn.query_one?(request, as: Int32).nil?
end
end
end

View File

@ -0,0 +1,27 @@
module Invidious::Database::Migrations
class CreatePlaylistVideosTable < Migration
version 9
def up(conn : DB::Connection)
conn.exec <<-SQL
CREATE TABLE IF NOT EXISTS public.playlist_videos
(
title text,
id text,
author text,
ucid text,
length_seconds integer,
published timestamptz,
plid text references playlists(id),
index int8,
live_now boolean,
PRIMARY KEY (index,plid)
);
SQL
conn.exec <<-SQL
GRANT ALL ON TABLE public.playlist_videos TO current_user;
SQL
end
end
end

View File

@ -0,0 +1,11 @@
module Invidious::Database::Migrations
class MakeVideosUnlogged < Migration
version 10
def up(conn : DB::Connection)
conn.exec <<-SQL
ALTER TABLE public.videos SET UNLOGGED;
SQL
end
end
end

View File

@ -0,0 +1,49 @@
class Invidious::Database::Migrator
MIGRATIONS_TABLE = "public.invidious_migrations"
class_getter migrations = [] of Invidious::Database::Migration.class
def initialize(@db : DB::Database)
end
def migrate
versions = load_versions
ran_migration = false
load_migrations.sort_by(&.version)
.each do |migration|
next if versions.includes?(migration.version)
puts "Running migration: #{migration.class.name}"
migration.migrate
ran_migration = true
end
puts "No migrations to run." unless ran_migration
end
def pending_migrations? : Bool
versions = load_versions
load_migrations.sort_by(&.version)
.any? { |migration| !versions.includes?(migration.version) }
end
private def load_migrations : Array(Invidious::Database::Migration)
self.class.migrations.map(&.new(@db))
end
private def load_versions : Array(Int64)
create_migrations_table
@db.query_all("SELECT version FROM #{MIGRATIONS_TABLE}", as: Int64)
end
private def create_migrations_table
@db.exec <<-SQL
CREATE TABLE IF NOT EXISTS #{MIGRATIONS_TABLE} (
id bigserial PRIMARY KEY,
version bigint NOT NULL
)
SQL
end
end

View File

@ -43,20 +43,20 @@ module Invidious::Routes::API::V1::Search
end
def self.search_suggestions(env)
locale = env.get("preferences").as(Preferences).locale
region = env.params.query["region"]?
preferences = env.get("preferences").as(Preferences)
region = env.params.query["region"]? || preferences.region
env.response.content_type = "application/json"
query = env.params.query["q"]?
query ||= ""
query = env.params.query["q"]? || ""
begin
headers = HTTP::Headers{":authority" => "suggestqueries.google.com"}
response = YT_POOL.client &.get("/complete/search?hl=en&gl=#{region}&client=youtube&ds=yt&q=#{URI.encode_www_form(query)}&callback=suggestCallback", headers).body
client = HTTP::Client.new("suggestqueries-clients6.youtube.com")
url = "/complete/search?client=youtube&hl=en&gl=#{region}&q=#{URI.encode_www_form(query)}&xssi=t&gs_ri=youtube&ds=yt"
body = response[35..-2]
body = JSON.parse(body).as_a
response = client.get(url).body
body = JSON.parse(response[5..-1]).as_a
suggestions = body[1].as_a[0..-2]
JSON.build do |json|