mirror of
https://github.com/sct/overseerr.git
synced 2025-12-27 08:45:06 +01:00
* feat(pushover): attach image to pushover notification payload (#3701) * fix: api language query parameter (#3720) * docs: add j0srisk as a contributor for code (#3745) [skip ci] * docs: update README.md * docs: update .all-contributorsrc --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * feat(tooltip): add tooltip to display exact time on date hover (#3773) Co-authored-by: Loetwiek <lodommerholtcm@gmail.com> * docs: add Loetwiek as a contributor for code (#3776) [skip ci] * docs: update README.md * docs: update .all-contributorsrc --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * fix(ui): ensure title fits into the `view collection` box (#3696) * fix(docs): correct openapi docs minor issues (#3648) * docs: add Fuochi as a contributor for doc (#3826) Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * feat: translations update from Hosted Weblate (#3597) * feat(lang): translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1234 of 1234 strings) feat(lang): translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (1232 of 1234 strings) Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (German) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (German) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de> Co-authored-by: Thomas Schöneberg <ta.schoeneberg@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Danish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Danish) Currently translated at 100.0% (1236 of 1236 strings) feat(lang): translated using Weblate (Danish) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Anders Ecklon <aecklon@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Kenneth Hansen <erathor@live.dk> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Greek) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Greek) Currently translated at 100.0% (1236 of 1236 strings) Co-authored-by: BeardedWatermelon <BeardedWatermelon@users.noreply.hosted.weblate.org> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/el/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Russian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Russian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Russian) Currently translated at 99.5% (1234 of 1240 strings) feat(lang): translated using Weblate (Russian) Currently translated at 100.0% (1234 of 1234 strings) feat(lang): translated using Weblate (Russian) Currently translated at 100.0% (1234 of 1234 strings) feat(lang): translated using Weblate (Russian) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: SoundwaveUwU <SoundwaveUwU@users.noreply.hosted.weblate.org> Co-authored-by: SoundwaveUwU <noreply@1000-7.space> Co-authored-by: Димитър Мазнеков (Topper) <d.maznekov@gmail.com> Co-authored-by: Кирилл Тюрин <1337soundwave1337@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ru/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Romanian) Currently translated at 37.1% (461 of 1240 strings) feat(lang): translated using Weblate (Romanian) Currently translated at 37.0% (459 of 1240 strings) feat(lang): translated using Weblate (Romanian) Currently translated at 34.8% (432 of 1240 strings) Co-authored-by: Don Cezar <goldie.czr@gmail.com> Co-authored-by: Dragos <themsk@yahoo.com> Co-authored-by: Eduard Oancea <uberfly@420blaze.it> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ro/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Bulgarian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Bulgarian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Bulgarian) Currently translated at 57.4% (712 of 1240 strings) feat(lang): translated using Weblate (Bulgarian) Currently translated at 13.2% (164 of 1240 strings) feat(lang): translated using Weblate (Bulgarian) Currently translated at 4.8% (60 of 1240 strings) feat(lang): added translation using Weblate (Bulgarian) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: sct <sctsnipe@gmail.com> Co-authored-by: Димитър Мазнеков (Topper) <d.maznekov@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/bg/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 99.1% (1230 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 99.1% (1230 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 99.1% (1230 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 97.9% (1215 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 82.0% (1017 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 72.9% (905 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 72.9% (905 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 71.3% (885 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 64.9% (805 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 64.4% (799 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 63.8% (792 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 63.7% (791 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 57.5% (714 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 49.9% (619 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 35.9% (446 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 35.9% (446 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 32.1% (399 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 24.6% (306 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 18.9% (235 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 17.5% (217 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 17.3% (215 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 8.0% (100 of 1240 strings) feat(lang): translated using Weblate (Ukrainian) Currently translated at 3.3% (41 of 1240 strings) feat(lang): added translation using Weblate (Ukrainian) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Michael Michael <michaelvelosk@gmail.com> Co-authored-by: sct <sctsnipe@gmail.com> Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/uk/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Catalan) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Catalan) Currently translated at 100.0% (1240 of 1240 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: dtalens <databio@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Czech) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Czech) Currently translated at 99.6% (1236 of 1240 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Karel Krýda <karel.kryda@gmail.com> Co-authored-by: Smexhy <roman.bartik@icloud.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Croatian) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.8% (1238 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.8% (1238 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.6% (1236 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.5% (1235 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.5% (1235 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 99.1% (1230 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 97.5% (1210 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 95.5% (1185 of 1240 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 95.6% (1182 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 95.6% (1182 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 95.2% (1177 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 95.2% (1177 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 94.3% (1166 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 91.7% (1134 of 1236 strings) feat(lang): translated using Weblate (Croatian) Currently translated at 91.7% (1134 of 1236 strings) Co-authored-by: Bruno Ševčenko <bs3vcenk@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Milo Ivir <mail@milotype.de> Co-authored-by: Stjepan <stjepstjepanovic@gmail.com> Co-authored-by: lpispek <lpispek@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Hungarian) Currently translated at 91.3% (1133 of 1240 strings) feat(lang): translated using Weblate (Hungarian) Currently translated at 89.3% (1108 of 1240 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Levente Szajkó <leviko112@gmail.com> Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Hebrew) Currently translated at 13.9% (172 of 1236 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: osh <osh@osh.cc> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/he/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Polish) Currently translated at 99.1% (1225 of 1236 strings) Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pl/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Italian) Currently translated at 92.8% (1148 of 1236 strings) Co-authored-by: Francesco <francy.ammirati@hotmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Arabic) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Arabic) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Arabic) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Fhd-pro <juve.11@msn.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ar/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Dutch) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Dutch) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Kobe <kobaubarr@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Spanish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Spanish) Currently translated at 100.0% (1236 of 1236 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: gallegonovato <fran-carro@hotmail.es> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (French) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (French) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (French) Currently translated at 100.0% (1236 of 1236 strings) feat(lang): translated using Weblate (French) Currently translated at 99.9% (1235 of 1236 strings) feat(lang): translated using Weblate (French) Currently translated at 99.9% (1235 of 1236 strings) Co-authored-by: Baptiste <baptiste.nee@me.com> Co-authored-by: Dimitri <dimitridroeck@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Maxime Lafarie <maxime.lafarie@gmail.com> Co-authored-by: Miguel <mig.mllr@gmail.com> Co-authored-by: asurare <jonathan.biteau16@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Swedish) Currently translated at 100.0% (1236 of 1236 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Per Erik <urbanlolface@gmail.com> Co-authored-by: Shjosan <shjosan@kakmix.co> Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Finnish) Currently translated at 2.6% (33 of 1240 strings) feat(lang): added translation using Weblate (Finnish) Co-authored-by: Eero Konttaniemi <eero.konttaniemi@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: sct <sctsnipe@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fi/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Serbian) Currently translated at 50.8% (630 of 1240 strings) Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Milan Smudja <smudja@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Korean) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Developer J <jshsakura@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ko/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1240 of 1240 strings) feat(lang): translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (1234 of 1234 strings) Co-authored-by: Haohao Zhang <hyacz@foxmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: lkw123 <lkw20010211@gmail.com> Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/ Translation: Overseerr/Overseerr Frontend --------- Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com> Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de> Co-authored-by: Thomas Schöneberg <ta.schoeneberg@gmail.com> Co-authored-by: Anders Ecklon <aecklon@gmail.com> Co-authored-by: Kenneth Hansen <erathor@live.dk> Co-authored-by: BeardedWatermelon <BeardedWatermelon@users.noreply.hosted.weblate.org> Co-authored-by: SoundwaveUwU <SoundwaveUwU@users.noreply.hosted.weblate.org> Co-authored-by: SoundwaveUwU <noreply@1000-7.space> Co-authored-by: Димитър Мазнеков (Topper) <d.maznekov@gmail.com> Co-authored-by: Кирилл Тюрин <1337soundwave1337@gmail.com> Co-authored-by: Don Cezar <goldie.czr@gmail.com> Co-authored-by: Dragos <themsk@yahoo.com> Co-authored-by: Eduard Oancea <uberfly@420blaze.it> Co-authored-by: sct <sctsnipe@gmail.com> Co-authored-by: Michael Michael <michaelvelosk@gmail.com> Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com> Co-authored-by: dtalens <databio@gmail.com> Co-authored-by: Karel Krýda <karel.kryda@gmail.com> Co-authored-by: Smexhy <roman.bartik@icloud.com> Co-authored-by: Bruno Ševčenko <bs3vcenk@gmail.com> Co-authored-by: Milo Ivir <mail@milotype.de> Co-authored-by: Stjepan <stjepstjepanovic@gmail.com> Co-authored-by: lpispek <lpispek@gmail.com> Co-authored-by: Levente Szajkó <leviko112@gmail.com> Co-authored-by: osh <osh@osh.cc> Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com> Co-authored-by: Francesco <francy.ammirati@hotmail.com> Co-authored-by: Fhd-pro <juve.11@msn.com> Co-authored-by: Kobe <kobaubarr@gmail.com> Co-authored-by: gallegonovato <fran-carro@hotmail.es> Co-authored-by: Baptiste <baptiste.nee@me.com> Co-authored-by: Dimitri <dimitridroeck@gmail.com> Co-authored-by: Maxime Lafarie <maxime.lafarie@gmail.com> Co-authored-by: Miguel <mig.mllr@gmail.com> Co-authored-by: asurare <jonathan.biteau16@gmail.com> Co-authored-by: Per Erik <urbanlolface@gmail.com> Co-authored-by: Shjosan <shjosan@kakmix.co> Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl> Co-authored-by: Eero Konttaniemi <eero.konttaniemi@gmail.com> Co-authored-by: Milan Smudja <smudja@gmail.com> Co-authored-by: Developer J <jshsakura@gmail.com> Co-authored-by: Haohao Zhang <hyacz@foxmail.com> Co-authored-by: lkw123 <lkw20010211@gmail.com> * feat(lang): add lang config for Bulgarian, Finnish, Ukrainian, Indonesian, Slovak, Turkish and Maori (#3834) --------- Co-authored-by: Isaac M <masesisaac@gmail.com> Co-authored-by: Joseph Risk <j0srisk@gmail.com> Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> Co-authored-by: Loetwiek <79059734+Loetwiek@users.noreply.github.com> Co-authored-by: Loetwiek <lodommerholtcm@gmail.com> Co-authored-by: Fuochi <ffuochi@hotmail.com> Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com> Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de> Co-authored-by: Thomas Schöneberg <ta.schoeneberg@gmail.com> Co-authored-by: Anders Ecklon <aecklon@gmail.com> Co-authored-by: Kenneth Hansen <erathor@live.dk> Co-authored-by: BeardedWatermelon <BeardedWatermelon@users.noreply.hosted.weblate.org> Co-authored-by: SoundwaveUwU <SoundwaveUwU@users.noreply.hosted.weblate.org> Co-authored-by: SoundwaveUwU <noreply@1000-7.space> Co-authored-by: Димитър Мазнеков (Topper) <d.maznekov@gmail.com> Co-authored-by: Кирилл Тюрин <1337soundwave1337@gmail.com> Co-authored-by: Don Cezar <goldie.czr@gmail.com> Co-authored-by: Dragos <themsk@yahoo.com> Co-authored-by: Eduard Oancea <uberfly@420blaze.it> Co-authored-by: sct <sctsnipe@gmail.com> Co-authored-by: Michael Michael <michaelvelosk@gmail.com> Co-authored-by: Сергій <sergiy.goncharuk.1@gmail.com> Co-authored-by: dtalens <databio@gmail.com> Co-authored-by: Karel Krýda <karel.kryda@gmail.com> Co-authored-by: Smexhy <roman.bartik@icloud.com> Co-authored-by: Bruno Ševčenko <bs3vcenk@gmail.com> Co-authored-by: Milo Ivir <mail@milotype.de> Co-authored-by: Stjepan <stjepstjepanovic@gmail.com> Co-authored-by: lpispek <lpispek@gmail.com> Co-authored-by: Levente Szajkó <leviko112@gmail.com> Co-authored-by: osh <osh@osh.cc> Co-authored-by: Eryk Michalak <gnu.ewm@protonmail.com> Co-authored-by: Francesco <francy.ammirati@hotmail.com> Co-authored-by: Fhd-pro <juve.11@msn.com> Co-authored-by: Kobe <kobaubarr@gmail.com> Co-authored-by: gallegonovato <fran-carro@hotmail.es> Co-authored-by: Baptiste <baptiste.nee@me.com> Co-authored-by: Dimitri <dimitridroeck@gmail.com> Co-authored-by: Maxime Lafarie <maxime.lafarie@gmail.com> Co-authored-by: Miguel <mig.mllr@gmail.com> Co-authored-by: asurare <jonathan.biteau16@gmail.com> Co-authored-by: Per Erik <urbanlolface@gmail.com> Co-authored-by: Shjosan <shjosan@kakmix.co> Co-authored-by: bittin1ddc447d824349b2 <bittin@reimu.nl> Co-authored-by: Eero Konttaniemi <eero.konttaniemi@gmail.com> Co-authored-by: Milan Smudja <smudja@gmail.com> Co-authored-by: Developer J <jshsakura@gmail.com> Co-authored-by: Haohao Zhang <hyacz@foxmail.com> Co-authored-by: lkw123 <lkw20010211@gmail.com> Co-authored-by: Jordan Jones <me@jjones.tech>
399 lines
11 KiB
TypeScript
399 lines
11 KiB
TypeScript
import GithubAPI from '@server/api/github';
|
|
import PushoverAPI from '@server/api/pushover';
|
|
import TheMovieDb from '@server/api/themoviedb';
|
|
import type {
|
|
TmdbMovieResult,
|
|
TmdbTvResult,
|
|
} from '@server/api/themoviedb/interfaces';
|
|
import { getRepository } from '@server/datasource';
|
|
import DiscoverSlider from '@server/entity/DiscoverSlider';
|
|
import type { StatusResponse } from '@server/interfaces/api/settingsInterfaces';
|
|
import { Permission } from '@server/lib/permissions';
|
|
import { getSettings } from '@server/lib/settings';
|
|
import logger from '@server/logger';
|
|
import { checkUser, isAuthenticated } from '@server/middleware/auth';
|
|
import { mapWatchProviderDetails } from '@server/models/common';
|
|
import { mapProductionCompany } from '@server/models/Movie';
|
|
import { mapNetwork } from '@server/models/Tv';
|
|
import settingsRoutes from '@server/routes/settings';
|
|
import watchlistRoutes from '@server/routes/watchlist';
|
|
import { appDataPath, appDataStatus } from '@server/utils/appDataVolume';
|
|
import { getAppVersion, getCommitTag } from '@server/utils/appVersion';
|
|
import restartFlag from '@server/utils/restartFlag';
|
|
import { isPerson } from '@server/utils/typeHelpers';
|
|
import { Router } from 'express';
|
|
import authRoutes from './auth';
|
|
import collectionRoutes from './collection';
|
|
import discoverRoutes, { createTmdbWithRegionLanguage } from './discover';
|
|
import issueRoutes from './issue';
|
|
import issueCommentRoutes from './issueComment';
|
|
import mediaRoutes from './media';
|
|
import movieRoutes from './movie';
|
|
import personRoutes from './person';
|
|
import requestRoutes from './request';
|
|
import searchRoutes from './search';
|
|
import serviceRoutes from './service';
|
|
import tvRoutes from './tv';
|
|
import user from './user';
|
|
|
|
const router = Router();
|
|
|
|
router.use(checkUser);
|
|
|
|
router.get<unknown, StatusResponse>('/status', async (req, res) => {
|
|
const githubApi = new GithubAPI();
|
|
|
|
const currentVersion = getAppVersion();
|
|
const commitTag = getCommitTag();
|
|
let updateAvailable = false;
|
|
let commitsBehind = 0;
|
|
|
|
if (currentVersion.startsWith('develop-') && commitTag !== 'local') {
|
|
const commits = await githubApi.getOverseerrCommits();
|
|
|
|
if (commits.length) {
|
|
const filteredCommits = commits.filter(
|
|
(commit) => !commit.commit.message.includes('[skip ci]')
|
|
);
|
|
if (filteredCommits[0].sha !== commitTag) {
|
|
updateAvailable = true;
|
|
}
|
|
|
|
const commitIndex = filteredCommits.findIndex(
|
|
(commit) => commit.sha === commitTag
|
|
);
|
|
|
|
if (updateAvailable) {
|
|
commitsBehind = commitIndex;
|
|
}
|
|
}
|
|
} else if (commitTag !== 'local') {
|
|
const releases = await githubApi.getOverseerrReleases();
|
|
|
|
if (releases.length) {
|
|
const latestVersion = releases[0];
|
|
|
|
if (!latestVersion.name.includes(currentVersion)) {
|
|
updateAvailable = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return res.status(200).json({
|
|
version: getAppVersion(),
|
|
commitTag: getCommitTag(),
|
|
updateAvailable,
|
|
commitsBehind,
|
|
restartRequired: restartFlag.isSet(),
|
|
});
|
|
});
|
|
|
|
router.get('/status/appdata', (_req, res) => {
|
|
return res.status(200).json({
|
|
appData: appDataStatus(),
|
|
appDataPath: appDataPath(),
|
|
});
|
|
});
|
|
|
|
router.use('/user', isAuthenticated(), user);
|
|
router.get('/settings/public', async (req, res) => {
|
|
const settings = getSettings();
|
|
|
|
if (!(req.user?.settings?.notificationTypes.webpush ?? true)) {
|
|
return res
|
|
.status(200)
|
|
.json({ ...settings.fullPublicSettings, enablePushRegistration: false });
|
|
} else {
|
|
return res.status(200).json(settings.fullPublicSettings);
|
|
}
|
|
});
|
|
router.get('/settings/discover', isAuthenticated(), async (_req, res) => {
|
|
const sliderRepository = getRepository(DiscoverSlider);
|
|
|
|
const sliders = await sliderRepository.find({ order: { order: 'ASC' } });
|
|
|
|
return res.json(sliders);
|
|
});
|
|
router.get(
|
|
'/settings/notifications/pushover/sounds',
|
|
isAuthenticated(),
|
|
async (req, res, next) => {
|
|
const pushoverApi = new PushoverAPI();
|
|
|
|
try {
|
|
if (!req.query.token) {
|
|
throw new Error('Pushover application token missing from request');
|
|
}
|
|
|
|
const sounds = await pushoverApi.getSounds(req.query.token as string);
|
|
res.status(200).json(sounds);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving Pushover sounds', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve Pushover sounds.',
|
|
});
|
|
}
|
|
}
|
|
);
|
|
router.use('/settings', isAuthenticated(Permission.ADMIN), settingsRoutes);
|
|
router.use('/search', isAuthenticated(), searchRoutes);
|
|
router.use('/discover', isAuthenticated(), discoverRoutes);
|
|
router.use('/request', isAuthenticated(), requestRoutes);
|
|
router.use('/watchlist', isAuthenticated(), watchlistRoutes);
|
|
router.use('/movie', isAuthenticated(), movieRoutes);
|
|
router.use('/tv', isAuthenticated(), tvRoutes);
|
|
router.use('/media', isAuthenticated(), mediaRoutes);
|
|
router.use('/person', isAuthenticated(), personRoutes);
|
|
router.use('/collection', isAuthenticated(), collectionRoutes);
|
|
router.use('/service', isAuthenticated(), serviceRoutes);
|
|
router.use('/issue', isAuthenticated(), issueRoutes);
|
|
router.use('/issueComment', isAuthenticated(), issueCommentRoutes);
|
|
router.use('/auth', authRoutes);
|
|
|
|
router.get('/regions', isAuthenticated(), async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const regions = await tmdb.getRegions();
|
|
|
|
return res.status(200).json(regions);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving regions', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve regions.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/languages', isAuthenticated(), async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const languages = await tmdb.getLanguages();
|
|
|
|
return res.status(200).json(languages);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving languages', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve languages.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get<{ id: string }>('/studio/:id', async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const studio = await tmdb.getStudio(Number(req.params.id));
|
|
|
|
return res.status(200).json(mapProductionCompany(studio));
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving studio', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
studioId: req.params.id,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve studio.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get<{ id: string }>('/network/:id', async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const network = await tmdb.getNetwork(Number(req.params.id));
|
|
|
|
return res.status(200).json(mapNetwork(network));
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving network', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
networkId: req.params.id,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve network.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/genres/movie', isAuthenticated(), async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const genres = await tmdb.getMovieGenres({
|
|
language: (req.query.language as string) ?? req.locale,
|
|
});
|
|
|
|
return res.status(200).json(genres);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving movie genres', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve movie genres.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/genres/tv', isAuthenticated(), async (req, res, next) => {
|
|
const tmdb = new TheMovieDb();
|
|
|
|
try {
|
|
const genres = await tmdb.getTvGenres({
|
|
language: (req.query.language as string) ?? req.locale,
|
|
});
|
|
|
|
return res.status(200).json(genres);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving series genres', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve series genres.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/backdrops', async (req, res, next) => {
|
|
const tmdb = createTmdbWithRegionLanguage();
|
|
|
|
try {
|
|
const data = (
|
|
await tmdb.getAllTrending({
|
|
page: 1,
|
|
timeWindow: 'week',
|
|
})
|
|
).results.filter((result) => !isPerson(result)) as (
|
|
| TmdbMovieResult
|
|
| TmdbTvResult
|
|
)[];
|
|
|
|
return res
|
|
.status(200)
|
|
.json(
|
|
data
|
|
.map((result) => result.backdrop_path)
|
|
.filter((backdropPath) => !!backdropPath)
|
|
);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving backdrops', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve backdrops.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/keyword/:keywordId', async (req, res, next) => {
|
|
const tmdb = createTmdbWithRegionLanguage();
|
|
|
|
try {
|
|
const result = await tmdb.getKeywordDetails({
|
|
keywordId: Number(req.params.keywordId),
|
|
});
|
|
|
|
return res.status(200).json(result);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving keyword data', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve keyword data.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/watchproviders/regions', async (req, res, next) => {
|
|
const tmdb = createTmdbWithRegionLanguage();
|
|
|
|
try {
|
|
const result = await tmdb.getAvailableWatchProviderRegions({});
|
|
return res.status(200).json(result);
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving watch provider regions', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve watch provider regions.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/watchproviders/movies', async (req, res, next) => {
|
|
const tmdb = createTmdbWithRegionLanguage();
|
|
|
|
try {
|
|
const result = await tmdb.getMovieWatchProviders({
|
|
watchRegion: req.query.watchRegion as string,
|
|
});
|
|
|
|
return res.status(200).json(mapWatchProviderDetails(result));
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving movie watch providers', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve movie watch providers.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/watchproviders/tv', async (req, res, next) => {
|
|
const tmdb = createTmdbWithRegionLanguage();
|
|
|
|
try {
|
|
const result = await tmdb.getTvWatchProviders({
|
|
watchRegion: req.query.watchRegion as string,
|
|
});
|
|
|
|
return res.status(200).json(mapWatchProviderDetails(result));
|
|
} catch (e) {
|
|
logger.debug('Something went wrong retrieving tv watch providers', {
|
|
label: 'API',
|
|
errorMessage: e.message,
|
|
});
|
|
return next({
|
|
status: 500,
|
|
message: 'Unable to retrieve tv watch providers.',
|
|
});
|
|
}
|
|
});
|
|
|
|
router.get('/', (_req, res) => {
|
|
return res.status(200).json({
|
|
api: 'Overseerr API',
|
|
version: '1.0',
|
|
});
|
|
});
|
|
|
|
export default router;
|