Compare commits

...

602 Commits

Author SHA1 Message Date
fallenbagel
e48f998a2b fix: nullable type for jellyfinMediaId(4k)
The jellyfinMediaId(4k) properties were inferred as string | undefined, causing them to be set to
undefined when assigning null. This prevented the media from being saved correctly to the SQLite
database, as it doesn't accept undefined values. This resolves the availabilitySync job issue where
the "play on" button wasn't being removed for all media server types.

fix #668
2024-03-31 16:03:02 +05:00
Danish Humair
010df62776 feat: check if first jellyfin user is admin (#635)
* feat: merge check if first jellyfin user is admin

re #610

* refactor(i18n): extract admin error message into en locale

---------

Co-authored-by: fallenbagel <98979876+Fallenbagel@users.noreply.github.com>
2024-03-30 05:53:14 +05:00
Fallenbagel
530be4272c fix(jellyfinscanner): conditionally assign the jellyfinMediaId and jellyfinMediaId4k (#686)
Previously `jellyfinMediaId4k` was being assigned even if 4k server was not setup or even if 4k
content were not present. This fixes it by conditionally assigning the jellyfinMediaId and
JellyfinMediaId4k

fix #681
2024-03-14 03:11:53 +05:00
Fallenbagel
c2e87714b4 fix(embyauth): remove the accidentally added mediaServerType change code from another PR (#684)
Accidentally added the mediaServerType change code from another feature branch/PR during the auth
logic refactor that broke emby logins.
2024-03-14 01:08:09 +05:00
Gauvino
eee9a025d2 fix: typos on readme (#655)
* Fix typo

* Apply suggestions

* Apply suggestions

---------

Co-authored-by: Fallenbagel <98979876+Fallenbagel@users.noreply.github.com>
2024-02-23 12:57:57 +05:00
allcontributors[bot]
aed011a557 docs: add trackmastersteve as a contributor for doc (#665)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2024-02-23 09:39:53 +05:00
Stephen Harris
ea47dd3571 Fixed a typo (#654)
Just a simple typo fix.
2024-02-23 09:38:45 +05:00
Fallenbagel
4c9013729e refactor: jellyfin authentication and add gravatar for missing avatars of jellyfin users (#664)
* refactor: jellyfin authentication

This refactor standardizes the authentication approach in Jellyfin to mirror the method employed in
Plex authentication for consistency

* feat: use gravatar for jellyfin users' with missing jellyfin avatars
2024-02-23 09:38:18 +05:00
Fallenbagel
3eb1bb3d8f feat(job): media availability support for jellyfin/emby (#522)
* feat(job): media availability support for jellyfin/emby

This refactors the media availability job to support jellyfin/emby for media removal automatically.
Needs further testing on 4k items (as I have not yet tested with 4k), however, non-4k items work as
intended.

fix #406, fix #193, fix #516, fix #362, fix #84

* fix(availabilitysync): use the correct 4k jellyfinMediaId

* fix: season mapping for plex

Fixes a bug introduced with this PR where media availability sync job removed the seasons from all
series even when those seasons existed
2024-02-23 07:42:59 +05:00
InvalidArgumentException
db84f6529a fix(jellyfin.ts): process virtual seasons if they have non virtual episodes (#639)
All seasons are processed now, but those without any episodes are filtered out again as unavailable.
This fixes in issue where jellyfin reports all seasons as virtual
2024-02-01 16:10:06 +05:00
Fallenbagel
4f81788386 Merge pull request #640 from Fallenbagel/all-contributors/add-Danish-H
docs: add Danish-H as a contributor for code
2024-01-29 00:54:02 +05:00
allcontributors[bot]
72d3f9b908 docs: update .all-contributorsrc [skip ci] 2024-01-28 19:53:51 +00:00
allcontributors[bot]
333ffed7f0 docs: update README.md [skip ci] 2024-01-28 19:53:50 +00:00
Fallenbagel
8641a26771 Merge pull request #636 from Danish-H/feature-letterboxd-links
feat: added Letterboxd links for the external link blocks for movies
2024-01-29 00:53:29 +05:00
Fallenbagel
7329524868 Merge pull request #638 from Fallenbagel/all-contributors/add-aleksasiriski
docs: add aleksasiriski as a contributor for infra
2024-01-28 01:10:56 +05:00
allcontributors[bot]
908dcb487a docs: update .all-contributorsrc [skip ci] 2024-01-27 20:10:44 +00:00
allcontributors[bot]
d486d58d3d docs: update README.md [skip ci] 2024-01-27 20:10:43 +00:00
Fallenbagel
d8b08f4c6b Merge pull request #637 from aleksasiriski/patch-1
ci(preview): added arm support for preview tags
2024-01-28 00:50:23 +05:00
Aleksa Siriški
a48a337e0f ci(preview): added arm support for preview tags 2024-01-27 16:58:35 +01:00
Danish Humair
981f5e679c feat: added Letterboxd links for the external link blocks for movies 2024-01-27 03:25:03 +05:00
Fallenbagel
7af193b8f6 docs: fix weblate link 2024-01-13 22:05:03 +05:00
Fallenbagel
6040e16645 update discord badge 2024-01-04 02:02:16 +05:00
Fallenbagel
3877301fc8 add translation percentage badge 2024-01-04 02:00:49 +05:00
Fallenbagel
092a1458a4 move weblate details to contributing.md 2024-01-03 14:25:23 +05:00
Fallenbagel
1c68111b12 update weblate link 2024-01-03 14:24:45 +05:00
Fallenbagel
0e777ddb1e Merge pull request #612 from Fallenbagel/feat-readme-weblate
Add more badges and weblate status
2024-01-03 14:20:29 +05:00
Fallenbagel
52c689b080 Merge pull request #613 from Fallenbagel/all-contributors/add-xeruf
docs: add xeruf as a contributor for doc
2024-01-03 14:12:32 +05:00
allcontributors[bot]
1a11f085ba docs: update .all-contributorsrc [skip ci] 2024-01-03 09:12:19 +00:00
allcontributors[bot]
c0234582a6 docs: update README.md [skip ci] 2024-01-03 09:12:18 +00:00
Fallenbagel
fd958d6347 Merge pull request #611 from xeruf/patch-1
Link related projects in README.md
2024-01-03 14:10:17 +05:00
Fallenbagel
6586db52dc Add more badges and weblate status 2024-01-03 14:04:17 +05:00
Janek
a41cb8b004 Link related projects in README.md 2024-01-03 07:39:48 +01:00
Fallenbagel
de66222e7a Merge pull request #590 from Fallenbagel/all-contributors/add-mdll23
docs: add mdll23 as a contributor for translation
2023-12-03 21:04:28 +05:00
allcontributors[bot]
eb790cb466 docs: update .all-contributorsrc [skip ci] 2023-12-03 16:03:26 +00:00
allcontributors[bot]
0680931332 docs: update README.md [skip ci] 2023-12-03 16:03:26 +00:00
Fallenbagel
ff2821471e Merge pull request #589 from mdll23/develop
fix: translation de.json
2023-12-03 21:02:59 +05:00
mdll23
e032c02f5f fix: fix german translation for "components.Discover.FilterSlideover.tmdbuservotecount" 2023-12-03 15:13:19 +01:00
Fallenbagel
f8c4def229 Merge pull request #565 from notquitenothing/custom-jellyfin-password-reset
feat: Custom jellyfin password reset setting
2023-11-30 14:08:20 +05:00
fallenbagel
a0415e7b6b Merge branch 'develop' into custom-jellyfin-password-reset 2023-11-30 09:26:14 +05:00
fallenbagel
b5f672785a docs: reverted two unrelated files to its develop branch state 2023-11-30 09:25:34 +05:00
Fallenbagel
770d788fd7 Merge pull request #577 from Fallenbagel/fix-set-defaultValue-seasonFoldersInSonarr
fix: disable seasonfolder option in sonarr for jellyfin/Emby users
2023-11-30 09:04:46 +05:00
Fallenbagel
c58261c841 Merge pull request #578 from Fallenbagel/refactor-jellyfin-scan-job
refactor: jellyfin scan jobs moved from server/jobs to server/libs/scanners
2023-11-27 15:05:02 +05:00
fallenbagel
ccfcdea1f6 refactor: clean out commented code 2023-11-27 14:11:10 +05:00
fallenbagel
8ec8f2ac57 fix: disable seasonfolder option in sonarr for jellyfin/Emby users
This disables seasonfolder option in sonarr for jellyfin/emby users as physical seasonFolders are
necessary as virtualFolders are ignored since #126

fix #575
2023-11-27 13:58:46 +05:00
fallenbagel
91f97f96ab refactor: jellyfin scan jobs moved from server/jobs to server/libs/scanners 2023-11-27 11:09:45 +05:00
Fallenbagel
f4051a1e5d Merge pull request #572 from Fallenbagel/fix-filterSlideOver-datepicker
fix: correct width issue in datepicker of filterSliderOver
2023-11-19 18:47:49 +05:00
fallenbagel
f564cddff4 fix: correct width issue in datepicker of filterSliderOver
This commit addresses a rendering issue with the date picker component.
The problem was traced back to a misconfiguration in the tailwindcss settings, resulting in an
incorrect width for the popup.

fix #415
2023-11-19 18:08:06 +05:00
Fallenbagel
cfcce6acf0 Merge pull request #571 from Fallenbagel/fix-local-watchlist-page-item-removal
fix: ensure watchlist updates are immediately reflected
2023-11-19 16:47:45 +05:00
fallenbagel
b85d7f37b9 fix: ensure watchlist updates are immediately reflected
This fix addresses an issue on the Watchlist page where changes to the watchlist were not
immediately reflected. Previously, after removing an item from the watchlist, the update
required a full page reload or revalidating upon focusing the window or tab. With this fix,
the watchlist now correctly mutates and updates in real-time, providing a seamless user
experience.
2023-11-19 16:33:02 +05:00
Fallenbagel
97396c2f57 Merge pull request #568 from Fallenbagel/fix-local-watchlist-page-item-removal
fix(watchlist): added missing prop for watchlist item removal button in watchlist page
2023-11-18 06:29:25 +05:00
fallenbagel
a0ec992028 fix(watchlist): added missing prop for watchlist item removal button in watchlist page
This fix resolves a Watchlist page bug where the isAddedToWatchlist prop was missing.
Without this prop, the removal button for watchlist items was absent. In this fix, the
isAddedToWatchlist prop is re-added and set to true, allowing users to remove items from
their local watchlist directly on the Watchlist page.
2023-11-18 06:13:27 +05:00
Derek Paschal
0dfe050ba1 Fixing code formatting, prettier 2023-11-15 06:59:02 -06:00
Derek Paschal
13dd3cad54 Making the new setting optional 2023-11-14 08:51:29 -06:00
Derek Paschal
ce9802d5d4 Adding Jellyfin Setting for Custom "Forgot Password" URL
Adding Jellyfin Setting for Custom "Forgot Password" URL.  Useful in cases where you are using a custom authentication provider such as the LDAP plugin, Authelia, lldap, or any other external auth scheme with its own password reset page.
2023-11-14 08:20:28 -06:00
Fallenbagel
4005397f3d Merge pull request #564 from Fallenbagel/all-contributors/add-athphane
docs: add athphane as a contributor for doc
2023-11-11 14:43:44 +05:00
allcontributors[bot]
a67e4dbb80 docs: update .all-contributorsrc [skip ci] 2023-11-11 09:43:19 +00:00
allcontributors[bot]
cf5cf3f9ca docs: update README.md [skip ci] 2023-11-11 09:43:18 +00:00
Fallenbagel
8ae4391f37 Merge pull request #563 from athphane/update-github-templates
update .github folder templates
2023-11-11 14:41:41 +05:00
Athfan Khaleel
bfd77e271a update .github folder templates 2023-11-11 14:37:34 +05:00
fallenbagel
d90fc2de1c ci: github repository container lowercase tag 2023-11-08 13:58:09 +05:00
fallenbagel
3b67d6b0e8 build: revert the hardcoded tag 2023-11-08 13:44:37 +05:00
fallenbagel
38348accb0 ci(build): hard-coded repository owner name for lowercase naming 2023-11-08 11:46:42 +05:00
fallenbagel
be335c39be ci(build): implement github repository container images
fix #370
2023-11-08 04:57:20 +05:00
Fallenbagel
c25c5cae38 Merge pull request #559 from Fallenbagel/Fallenbagel-patch-1
Add more detailed installation instructions
2023-11-08 04:38:46 +05:00
Fallenbagel
2e059cefc0 Update README.md 2023-11-08 04:28:36 +05:00
Fallenbagel
e540b58f73 Add more detailed installation instructions 2023-11-08 04:16:34 +05:00
Fallenbagel
22b548bad2 Merge pull request #558 from Fallenbagel/all-contributors/add-Br33ce
docs: add Br33ce as a contributor for translation
2023-11-08 03:42:57 +05:00
allcontributors[bot]
c4adbdb3a8 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:42:49 +00:00
allcontributors[bot]
e5d565b435 docs: update README.md [skip ci] 2023-11-07 22:42:48 +00:00
Fallenbagel
5c531011be Merge pull request #557 from Fallenbagel/all-contributors/add-RickLuiken
docs: add RickLuiken as a contributor for code
2023-11-08 03:42:16 +05:00
allcontributors[bot]
f2b1fd24c2 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:42:07 +00:00
allcontributors[bot]
4be95fade4 docs: update README.md [skip ci] 2023-11-07 22:42:06 +00:00
Fallenbagel
d02f5b0090 Merge pull request #556 from Fallenbagel/all-contributors/add-SirMartin
docs: add SirMartin as a contributor for doc
2023-11-08 03:41:37 +05:00
allcontributors[bot]
d5f2034e69 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:41:27 +00:00
allcontributors[bot]
9059f15291 docs: update README.md [skip ci] 2023-11-07 22:41:26 +00:00
Fallenbagel
b168d04fe6 Merge pull request #555 from Fallenbagel/all-contributors/add-EthanArmbrust
docs: add EthanArmbrust as a contributor for code
2023-11-08 03:40:15 +05:00
allcontributors[bot]
9a51c5b47b docs: update .all-contributorsrc [skip ci] 2023-11-07 22:40:05 +00:00
allcontributors[bot]
ab8efc91d5 docs: update README.md [skip ci] 2023-11-07 22:40:04 +00:00
Fallenbagel
c115f813e5 Merge pull request #554 from Fallenbagel/all-contributors/add-Gauvino
docs: add Gauvino as a contributor for translation
2023-11-08 03:39:29 +05:00
allcontributors[bot]
8967bb9f90 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:39:20 +00:00
allcontributors[bot]
b316b9984d docs: update README.md [skip ci] 2023-11-07 22:39:19 +00:00
Fallenbagel
605a1de98f Merge pull request #553 from Fallenbagel/all-contributors/add-davidfdezalcoba
docs: add davidfdezalcoba as a contributor for code
2023-11-08 03:38:46 +05:00
allcontributors[bot]
74d84a1cad docs: update .all-contributorsrc [skip ci] 2023-11-07 22:38:37 +00:00
allcontributors[bot]
8a7f39994f docs: update README.md [skip ci] 2023-11-07 22:38:36 +00:00
Fallenbagel
6e47834de0 Merge pull request #552 from Fallenbagel/all-contributors/add-d-fendrich
docs: add d-fendrich as a contributor for translation
2023-11-08 03:37:54 +05:00
allcontributors[bot]
14aafbe1d6 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:37:43 +00:00
allcontributors[bot]
445604a615 docs: update README.md [skip ci] 2023-11-07 22:37:42 +00:00
Fallenbagel
fa28f05263 Merge pull request #551 from Fallenbagel/all-contributors/add-jeaboswell
docs: add jeaboswell as a contributor for code
2023-11-08 03:36:57 +05:00
allcontributors[bot]
fd5338167a docs: update .all-contributorsrc [skip ci] 2023-11-07 22:36:47 +00:00
allcontributors[bot]
81b5e8afbd docs: update README.md [skip ci] 2023-11-07 22:36:46 +00:00
Fallenbagel
4fe4e377a6 Merge pull request #550 from Fallenbagel/all-contributors/add-yalagin
docs: add yalagin as a contributor for code
2023-11-08 03:35:59 +05:00
allcontributors[bot]
87a59651b2 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:35:50 +00:00
allcontributors[bot]
3a680c47b6 docs: update README.md [skip ci] 2023-11-07 22:35:49 +00:00
Fallenbagel
44444402a9 Merge pull request #549 from Fallenbagel/all-contributors/add-Pikachu920
docs: add Pikachu920 as a contributor for code
2023-11-08 03:35:14 +05:00
allcontributors[bot]
9140b8d98c docs: update .all-contributorsrc [skip ci] 2023-11-07 22:35:06 +00:00
allcontributors[bot]
2e20fbae1b docs: update README.md [skip ci] 2023-11-07 22:35:05 +00:00
Fallenbagel
6c0d75759f Merge pull request #548 from Fallenbagel/all-contributors/add-GeoffreyCoulaud
docs: add GeoffreyCoulaud as a contributor for translation
2023-11-08 03:34:21 +05:00
allcontributors[bot]
f483062d0e docs: update .all-contributorsrc [skip ci] 2023-11-07 22:34:11 +00:00
allcontributors[bot]
a7cf87f266 docs: update README.md [skip ci] 2023-11-07 22:34:10 +00:00
Fallenbagel
8ef7ec40ae Merge pull request #547 from Fallenbagel/all-contributors/add-andrey4korop
docs: add andrey4korop as a contributor for code, and translation
2023-11-08 03:33:32 +05:00
allcontributors[bot]
3b74002f25 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:33:23 +00:00
allcontributors[bot]
2b1427108c docs: update README.md [skip ci] 2023-11-07 22:33:22 +00:00
Fallenbagel
68b2388205 Merge pull request #546 from Fallenbagel/all-contributors/add-DimitriDR
docs: add DimitriDR as a contributor for translation
2023-11-08 03:32:44 +05:00
allcontributors[bot]
b20c334941 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:32:35 +00:00
allcontributors[bot]
9f2ee0beeb docs: update README.md [skip ci] 2023-11-07 22:32:34 +00:00
Fallenbagel
24a3ee1e77 Merge pull request #545 from Fallenbagel/all-contributors/add-CheChu10
docs: add CheChu10 as a contributor for translation
2023-11-08 03:31:48 +05:00
allcontributors[bot]
510a564a57 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:31:39 +00:00
allcontributors[bot]
6540ba7226 docs: update README.md [skip ci] 2023-11-07 22:31:38 +00:00
Fallenbagel
3291cd08dd Merge pull request #544 from Fallenbagel/all-contributors/add-undone37
docs: add undone37 as a contributor for translation
2023-11-08 03:31:09 +05:00
allcontributors[bot]
a08512ff71 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:30:57 +00:00
allcontributors[bot]
345c67c750 docs: update README.md [skip ci] 2023-11-07 22:30:56 +00:00
Fallenbagel
bff97d2a70 Merge pull request #543 from Fallenbagel/all-contributors/add-darmiel
docs: add darmiel as a contributor for code
2023-11-08 03:29:19 +05:00
allcontributors[bot]
62c289bd65 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:29:10 +00:00
allcontributors[bot]
21cc64eee4 docs: update README.md [skip ci] 2023-11-07 22:29:09 +00:00
Fallenbagel
4a759e64fd Merge pull request #542 from Fallenbagel/all-contributors/add-dd060606
docs: add dd060606 as a contributor for code
2023-11-08 03:27:22 +05:00
allcontributors[bot]
f5122ec652 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:27:07 +00:00
allcontributors[bot]
e9fafeaef8 docs: update README.md [skip ci] 2023-11-07 22:27:06 +00:00
Fallenbagel
8e2c6edd42 Merge pull request #541 from Fallenbagel/all-contributors/add-Smexhy
docs: add Smexhy as a contributor for translation
2023-11-08 03:26:16 +05:00
allcontributors[bot]
532f2882da docs: update .all-contributorsrc [skip ci] 2023-11-07 22:26:06 +00:00
allcontributors[bot]
9e73eaa5a3 docs: update README.md [skip ci] 2023-11-07 22:26:05 +00:00
Fallenbagel
8ef2815b44 Merge pull request #540 from Fallenbagel/all-contributors/add-NicolaiVdS
docs: add NicolaiVdS as a contributor for code
2023-11-08 03:24:42 +05:00
allcontributors[bot]
63d4ab958a docs: update .all-contributorsrc [skip ci] 2023-11-07 22:24:28 +00:00
allcontributors[bot]
b031b58598 docs: update README.md [skip ci] 2023-11-07 22:24:27 +00:00
Fallenbagel
bdd45231e1 Merge pull request #539 from Fallenbagel/all-contributors/add-jab416171
docs: add jab416171 as a contributor for doc
2023-11-08 03:23:16 +05:00
allcontributors[bot]
a38db77c8e docs: update .all-contributorsrc [skip ci] 2023-11-07 22:23:06 +00:00
allcontributors[bot]
21fa447da6 docs: update README.md [skip ci] 2023-11-07 22:23:05 +00:00
Fallenbagel
87bd130420 Merge pull request #538 from Fallenbagel/all-contributors/add-CyferShepard
docs: add CyferShepard as a contributor for code
2023-11-08 03:21:46 +05:00
allcontributors[bot]
9a9ec41d92 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:21:37 +00:00
allcontributors[bot]
e81a305f4d docs: update README.md [skip ci] 2023-11-07 22:21:36 +00:00
Fallenbagel
144980136e Merge pull request #537 from Fallenbagel/all-contributors/add-sambartik
docs: add sambartik as a contributor for code
2023-11-08 03:20:50 +05:00
allcontributors[bot]
f6e90de708 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:20:41 +00:00
allcontributors[bot]
95636c4825 docs: update README.md [skip ci] 2023-11-07 22:20:40 +00:00
Fallenbagel
aa05235392 Merge pull request #536 from Fallenbagel/all-contributors/add-boring-dragon
docs: add boring-dragon as a contributor for code
2023-11-08 03:19:59 +05:00
allcontributors[bot]
84bfc5c363 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:19:46 +00:00
allcontributors[bot]
2f2427f125 docs: update README.md [skip ci] 2023-11-07 22:19:45 +00:00
Fallenbagel
1ac2a2a909 Merge pull request #535 from Fallenbagel/all-contributors/add-jsl9208
docs: add jsl9208 as a contributor for code
2023-11-08 03:18:41 +05:00
allcontributors[bot]
44e368cb1b docs: update .all-contributorsrc [skip ci] 2023-11-07 22:18:02 +00:00
allcontributors[bot]
9bf20b76fa docs: update README.md [skip ci] 2023-11-07 22:18:01 +00:00
Fallenbagel
2a7128c390 Merge pull request #534 from Fallenbagel/all-contributors/add-Jumail
docs: add Jumail as a contributor for review
2023-11-08 03:15:53 +05:00
allcontributors[bot]
8e93d351fd docs: update .all-contributorsrc [skip ci] 2023-11-07 22:15:35 +00:00
allcontributors[bot]
4acec9aeb9 docs: update README.md [skip ci] 2023-11-07 22:15:34 +00:00
Fallenbagel
51b655e364 Merge pull request #532 from Fallenbagel/all-contributors/add-notfakie
docs: add notfakie as a contributor for code
2023-11-08 03:14:20 +05:00
allcontributors[bot]
f658e5ee66 docs: update .all-contributorsrc [skip ci] 2023-11-07 22:11:42 +00:00
allcontributors[bot]
9021e60d11 docs: update README.md [skip ci] 2023-11-07 22:11:41 +00:00
fallenbagel
df510820fa chore: [skip ci] added skipCi to all-contributorsrc temporarily 2023-11-08 03:09:07 +05:00
Fallenbagel
26f90b0d7f Merge pull request #531 from Fallenbagel/all-contributors/add-seanzhang98
docs: add seanzhang98 as a contributor for translation, and code
2023-11-08 03:08:26 +05:00
allcontributors[bot]
d7ba80d502 docs: update .all-contributorsrc 2023-11-07 22:07:29 +00:00
allcontributors[bot]
96e90c1e7e docs: update README.md 2023-11-07 22:07:28 +00:00
Fallenbagel
559b7ff018 Merge pull request #530 from Fallenbagel/all-contributors/add-Fallenbagel
docs: add Fallenbagel as a contributor for code, and maintenance
2023-11-08 02:55:09 +05:00
allcontributors[bot]
dd08f5e7cf docs: update .all-contributorsrc 2023-11-07 21:54:24 +00:00
allcontributors[bot]
0730e17932 docs: update README.md 2023-11-07 21:54:23 +00:00
fallenbagel
a32307e6cf docs: [skip ci] removed contributor block so all-contributors can handle it 2023-11-08 02:51:26 +05:00
fallenbagel
f9bd02553c docs: [skip ci] add in current project allcontributors only
As allcontributors bot does not support having two lists of allcontributors seperately,
unfortunately had to remove upstream contributors from the .all-contributorsrc. However, they will
be added manually by @Fallenbagel to the README.md
2023-11-08 02:39:46 +05:00
fallenbagel
d039e87da4 docs: update README to accomodate both upstream and downstream contributor list seperately 2023-11-08 02:27:30 +05:00
fallenbagel
4347728a1b docs: [skip ci] change contributor settings to add both upstream and downstream contributors
This commit changes the contributorrc for allcontributors bot so we can add both overseerr and
jellyseerr contributors to the list
2023-11-08 02:16:18 +05:00
Fallenbagel
68f7f397d3 Merge pull request #527 from Fallenbagel/fix-local-watchlists
fix(watchlist): discover local watchlist item display and profile local watchlist slider visibility
2023-11-08 01:34:04 +05:00
fallenbagel
8c82a61450 fix: fix the translations for watchlist permissions and userSettings page 2023-11-08 01:24:18 +05:00
fallenbagel
67bde68596 refactor: cleans up local watchlist logic and fixes translation extractions 2023-11-08 01:04:20 +05:00
fallenbagel
3cb9494e62 fix(watchlist): discover local watchlist item display and profile local watchlist slider visibility
Previously when you expand the `Your Watchlist` slider from the discover page to see all your
watchlist items, you only see the first 20 items. This commit fixes that so you can see all your
local watchlist items when you expand that slider. In addition, this commit also fixes the visiblity
of profile watchlist slider for local watchlists
2023-11-08 00:41:28 +05:00
fallenbagel
f92231850c build(snap): remove rm .gitbook.yaml line to fix snap builds 2023-11-07 05:34:19 +05:00
fallenbagel
8f9d3f7fbd build(snap): add frozen-lockfile and increase network timeout for yarn install 2023-11-07 05:24:50 +05:00
fallenbagel
2b7dab2765 build(snap): add yarn install before yarn build 2023-11-07 05:21:15 +05:00
fallenbagel
9ac56a4057 build(snap): use nil package and try to setup node in override-build step 2023-11-07 05:17:39 +05:00
fallenbagel
e8ee6f9e32 build(snap): fix path for the build-environment 2023-11-07 05:07:55 +05:00
fallenbagel
9348cdfd01 build(snap): changes node-js plugin to npm plugin for Core20
In an attempt to fix version compatibility of `GLIBC_2.28` base was upgraded from core18 to core20.
Node-js plugin was deprecated for core20 and instead npm plugin has to be used. As npm plugin cannot
specify the package manager to use, yarn is now installed globally during the override-build phase.
2023-11-07 04:58:28 +05:00
fallenbagel
40c739c5a4 ci(build): changes the base of the snap build to fix compatibility issues with GLIBC version
Changes base to core20 in an attempt to fix the error `node: /lib/x86_64-linux-gnu/libc.so.6:
version `GLIBC_2.28' not found (required by node)` during snap builds
2023-11-07 04:42:36 +05:00
Fallenbagel
364fb46805 Merge pull request #526 from Fallenbagel/fix-forget-password-button
fix(jellyfinlogin): use externalHostname if set for forgetpassword link
2023-11-07 04:26:11 +05:00
fallenbagel
405f6bbb7f fix(jellyfinlogin): use externalHostname if set for forgetpassword link
Implemented dynamic URL generation for the 'Forgot Password' feature. If jellyfin external hostname
is set, the URL is generated based on it; otherwise, jellyfin hostname is used as the base URL. The
URL includes additional parameters to handle emby support.

fix #199, fix #424, re #212
2023-11-07 04:13:19 +05:00
Fallenbagel
9a7a98b75e Merge pull request #525 from Fallenbagel/fix-ukranian-lang-code
fix(langcode): fixes the ukranian language code
2023-11-07 03:37:00 +05:00
fallenbagel
dc67aaaf53 fix(langcode): fixes the ukranian language code
This changes the ukranian language code from ua to uk to fit to ISO 639-1 format that the tmdb api
uses.

fix #504
2023-11-07 02:37:12 +05:00
Fallenbagel
31bc6ca612 Merge pull request #524 from Fallenbagel/fix-library-sync-for-ldap-support
revert(jellyfinapi): reverts #450 as it broke library sync support for local accounts using LDAP
2023-11-07 02:09:41 +05:00
fallenbagel
b5acc09ba9 revert(jellyfinapi): reverts #450 as it broke library sync support for local accounts using LDAP
Reverted #450 which addressed the issue where the automatic grouping enabled libraries were not
functioning correctly. The previous fix inadvertently caused a bug for Jellyfin LDAP users,
preventing library syncing with a 401 error. Reverting this change temporarily until support for
automatic library grouping can be re-implemented

fix #489
2023-11-07 01:47:54 +05:00
fallenbagel
506ea92826 chore(translations): fixed watchlist translation so its generic for all media servers 2023-11-07 01:39:29 +05:00
fallenbagel
200d47bb43 Merge remote-tracking branch 'upstream/develop' into develop 2023-11-06 17:41:40 +05:00
Ryan Cohen
be047427df build: correct node version in snapcraft (#3678) 2023-11-06 20:43:03 +09:00
Ryan Cohen
e297d25603 build: add global node-gyp for arm (#3676) 2023-11-06 18:56:57 +09:00
Ryan Cohen
89287af096 build: use node 18 (#3675) 2023-11-06 18:48:02 +09:00
Ryan Cohen
3a593d9d76 build: update docker ubuntu images to 22.04 (#3671) 2023-11-05 22:40:03 +09:00
Fallenbagel
10737dd4ec Too many jellyfishes 2023-11-05 17:51:10 +05:00
Fallenbagel
7c03b831f5 update emoji for jellyseerr contributor 2023-11-05 17:50:04 +05:00
fallenbagel
cdf1e1ecc7 docs: adds jellyseerr commit links
Adds jellyseerr commit links to Fallenbagel. TODO: add other contributors of jellyseerr into the
list
2023-11-05 17:37:23 +05:00
fallenbagel
b9c0d5f46e Merge remote-tracking branch 'upstream/develop' into develop 2023-11-05 17:29:23 +05:00
Ryan Cohen
a45fc86032 build: do not link python for arm (#3670) 2023-11-05 20:43:58 +09:00
Ryan Cohen
59dabed380 build: update node to 20.9 (#3668) 2023-11-05 19:18:21 +09:00
Ryan Cohen
b40ba07a4d fix: request watchlist items sequentially to prevent bypassing quota (#3667) 2023-11-05 10:39:22 +09:00
allcontributors[bot]
246887efa1 docs: add RemiRigal as a contributor for code (#3653) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-10-19 17:55:24 +09:00
Brandon Cohen
28a2c50495 fix: resolved issue with region selector and all regions value (#3652) 2023-10-19 16:46:54 +09:00
RemiRigal
c84ca43074 feat: update SameSite policy of session cookie to Lax (#3650)
* update session cookie samesite policy to lax

* set cookie samesite policy based on csrf protection setting
2023-10-18 15:05:22 +00:00
TheCatLady
e2771a3011 chore: specify files/directories to exclude from git archives (#2184)
Co-authored-by: Danshil Kokil Mungur <me@danshilm.com>
2023-10-16 17:02:01 +00:00
TheCatLady
3ea5076053 feat(notif): add Pushover sound options (#2403)
Co-authored-by: Danshil Kokil Mungur <me@danshilm.com>
2023-10-15 23:05:36 +04:00
fallenbagel
bd65f940e3 Merge remote-tracking branch 'upstream/develop' into develop 2023-09-28 06:26:45 +05:00
Brandon Cohen
7bdd25e5a4 feat: standard series type selector (#3628)
* feat: added a standard series type selector

* fix: moved series type property to correct interface
2023-09-27 12:38:49 +00:00
Fallenbagel
f6286359cf feat: select default seriesType for anime (#3627)
* feat: select default seriesType for anime

Added flexibility to set default anime series type in service settings. Now you can choose
'standard' for anime if you prefer it, making it easier to use features like searching for season
packs on Sonarr.

fix #3626

* feat: extracted translations
2023-09-27 14:02:42 +09:00
Fallenbagel
ac7fe1baf0 Merge pull request #493 from Br33ce/german-translation
Update de.json
2023-09-26 20:31:48 +05:00
Br33ce
9c895f26e3 Update de.json
Added a german translation for 
  "components.Discover.RecentlyAddedSlider.recentlyAdded": "Recently Added",
2023-09-26 16:28:10 +02:00
Fallenbagel
591533f850 Merge pull request #483 from RickLuiken/fix-radarr-sonarr-permissions
Fix permissions on ManageSliderOver
2023-09-20 16:41:04 +05:00
Rick Luiken
127897b9d7 style: fix prettier errors 2023-09-20 10:35:14 +02:00
Ryan Cohen
92507359b4 feat: add ko language (#3619) 2023-09-19 10:29:53 +09:00
Rick Luiken
ca4c4440ae Fix permissions on ManageSliderOver
Previously, would cause a 403 error when a non-admin user opened a movie/series page
2023-09-17 17:32:15 +02:00
Fallenbagel
eb4306a2b8 Merge pull request #479 from SirMartin/patch-1
named service inside docker-compose.yml
2023-09-14 14:58:03 +05:00
Eduardo
baa847330d named service inside docker-compose.yml 2023-09-14 09:40:00 +02:00
Fallenbagel
39372d2182 Merge pull request #441 from d-fendrich/fix/jellyfin-translation
Translation key fix for Jellyfin jobs
2023-09-14 05:52:08 +05:00
Ryan Cohen
c484810f96 feat: add tooltips to tautulli avatars (#3601) 2023-08-31 08:35:45 +09:00
Jean Beauchamp
0c39057ca5 feat: add Peacock to Network Slider (#3545) 2023-08-25 10:54:42 +04:00
Daniel Fendrich
28d6e5f5ce Merge remote-tracking branch 'upstream/develop' into fix/jellyfin-translation 2023-08-24 19:26:42 +02:00
Weblate (bot)
e62a078298 feat: translations update from Hosted Weblate (#3258)
* feat(lang): translated using Weblate (Korean)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 11.2% (139 of 1233 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 11.3% (139 of 1226 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 7.8% (96 of 1226 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 7.4% (91 of 1226 strings)

feat(lang): translated using Weblate (Korean)

Currently translated at 1.7% (21 of 1226 strings)

feat(lang): added translation using Weblate (Korean)

Co-authored-by: Developer J <jshsakura@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: sct <sctsnipe@gmail.com>
Co-authored-by: 김상구 (Studio) <spair0039@gmail.com>
Co-authored-by: 최효근 <gyrms7532@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ko/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Greek)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Greek)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Greek)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Greek)

Currently translated at 100.0% (1233 of 1233 strings)

Co-authored-by: BeardedWatermelon <periklis.karantonis@gmail.com>
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 (Serbian)

Currently translated at 49.7% (608 of 1222 strings)

Co-authored-by: Dzonkins <nikoladjordjevic.ns@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1228 of 1228 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 100.0% (1222 of 1222 strings)

Co-authored-by: Angel <adelpozoman@gmail.com>
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 (Romanian)

Currently translated at 33.0% (408 of 1234 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 29.7% (367 of 1234 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 27.9% (345 of 1234 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 27.8% (344 of 1233 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 27.6% (339 of 1226 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 27.4% (337 of 1226 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 22.8% (279 of 1223 strings)

Co-authored-by: Bunduc Dragos <bunduc.dragos@gmail.com>
Co-authored-by: DragoPrime <emperordrago@gmail.com>
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 (Russian)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Russian)

Currently translated at 87.4% (1069 of 1223 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kirill Zhukov <siper13@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ru/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1222 of 1222 strings)

Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: Emil Nymann <ens@hiper.dk>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hungarian)

Currently translated at 86.3% (1055 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: ZsiGiT <zsigit@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Dutch)

Currently translated at 99.4% (1226 of 1233 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1222 of 1222 strings)

Co-authored-by: Bas <bashankamp+weblate@gmail.com>
Co-authored-by: COTMO <moermantom1@gmail.com>
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 (Portuguese (Brazil))

Currently translated at 99.6% (1229 of 1233 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1228 of 1228 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (1213 of 1222 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.1% (1212 of 1222 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.1% (1212 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mateus <mateusbernardo@protonmail.com>
Co-authored-by: Rafael Vieira <rafaelvieiras@pm.me>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Czech)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 99.7% (1223 of 1226 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 96.4% (1179 of 1222 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 89.1% (1090 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Marek <marek@pavelka.xyz>
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 (Arabic)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1233 of 1233 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 (Portuguese (Portugal))

Currently translated at 100.0% (1222 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 99.9% (1233 of 1234 strings)

feat(lang): translated using Weblate (German)

Currently translated at 99.5% (1228 of 1234 strings)

feat(lang): translated using Weblate (German)

Currently translated at 99.5% (1227 of 1233 strings)

feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (German)

Currently translated at 95.9% (1172 of 1222 strings)

feat(lang): translated using Weblate (German)

Currently translated at 95.9% (1172 of 1222 strings)

feat(lang): translated using Weblate (German)

Currently translated at 94.7% (1158 of 1222 strings)

Co-authored-by: Ben <ben.david.wallner@gmail.com>
Co-authored-by: Furkan Çakar <cakar.55.furkan@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Juli <snowjuli@protonmail.com>
Co-authored-by: Leo Schultheiss <leoschultheiss@yahoo.de>
Co-authored-by: inkarnation <94744834+inkarnation@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 99.6% (1229 of 1233 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1228 of 1228 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 90.0% (1104 of 1226 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 90.0% (1101 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Topfield99 <timmiesonne@live.se>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Lithuanian)

Currently translated at 58.7% (725 of 1233 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 58.6% (719 of 1226 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 51.0% (624 of 1222 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 43.9% (537 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: PovilasID <povilas.sidaravicius@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/lt/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 99.5% (1217 of 1223 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 99.4% (1216 of 1223 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 98.6% (1207 of 1223 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 97.2% (1189 of 1223 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 94.3% (1154 of 1223 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Maite Guix <maite.guix@gmail.com>
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 (Croatian)

Currently translated at 89.9% (1103 of 1226 strings)

Co-authored-by: Bruno Ševčenko <bs3vcenk@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Italian)

Currently translated at 92.2% (1138 of 1233 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 88.5% (1092 of 1233 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 85.8% (1058 of 1233 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 86.0% (1052 of 1223 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 83.2% (1017 of 1222 strings)

Co-authored-by: Francesco <francy.ammirati@hotmail.com>
Co-authored-by: Gian Marco Cinalli <gm.cinalli@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mirco Cau <mircocau@gmail.com>
Co-authored-by: eggermn <egger.mn@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1226 of 1226 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.9% (1225 of 1226 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.9% (1225 of 1226 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (1224 of 1226 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.9% (1223 of 1224 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 98.0% (1198 of 1222 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 96.7% (1182 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Jassy lin <linjiaxinme@gmail.com>
Co-authored-by: anpplex <anpplex@gmail.com>
Co-authored-by: kx <yoboy.rox@gmail.com>
Co-authored-by: lkw123 <lkw20010211@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1234 of 1234 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1233 of 1233 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.9% (1225 of 1226 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1224 of 1224 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1223 of 1223 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.5% (1216 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.5% (1216 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.5% (1216 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1222 of 1222 strings)

Co-authored-by: Hordo <hordocast@mailo.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Maxent <rouaultmaxent@gmail.com>
Co-authored-by: Rémi Guerrero <remidu34070@hotmail.fr>
Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Symness <simon@frayssines.fr>
Co-authored-by: Valentin <droidente@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.7% (1219 of 1222 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 89.6% (1095 of 1222 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: 주서현 <adan.89lion@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

---------

Co-authored-by: Developer J <jshsakura@gmail.com>
Co-authored-by: sct <sctsnipe@gmail.com>
Co-authored-by: 김상구 (Studio) <spair0039@gmail.com>
Co-authored-by: 최효근 <gyrms7532@gmail.com>
Co-authored-by: BeardedWatermelon <periklis.karantonis@gmail.com>
Co-authored-by: Dzonkins <nikoladjordjevic.ns@gmail.com>
Co-authored-by: Angel <adelpozoman@gmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Bunduc Dragos <bunduc.dragos@gmail.com>
Co-authored-by: DragoPrime <emperordrago@gmail.com>
Co-authored-by: Kirill Zhukov <siper13@gmail.com>
Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: Emil Nymann <ens@hiper.dk>
Co-authored-by: ZsiGiT <zsigit@gmail.com>
Co-authored-by: Bas <bashankamp+weblate@gmail.com>
Co-authored-by: COTMO <moermantom1@gmail.com>
Co-authored-by: Kobe <kobaubarr@gmail.com>
Co-authored-by: Mateus <mateusbernardo@protonmail.com>
Co-authored-by: Rafael Vieira <rafaelvieiras@pm.me>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Co-authored-by: Marek <marek@pavelka.xyz>
Co-authored-by: Smexhy <roman.bartik@icloud.com>
Co-authored-by: Fhd-pro <juve.11@msn.com>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Ben <ben.david.wallner@gmail.com>
Co-authored-by: Furkan Çakar <cakar.55.furkan@gmail.com>
Co-authored-by: Juli <snowjuli@protonmail.com>
Co-authored-by: Leo Schultheiss <leoschultheiss@yahoo.de>
Co-authored-by: inkarnation <94744834+inkarnation@users.noreply.github.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Topfield99 <timmiesonne@live.se>
Co-authored-by: PovilasID <povilas.sidaravicius@gmail.com>
Co-authored-by: Maite Guix <maite.guix@gmail.com>
Co-authored-by: dtalens <databio@gmail.com>
Co-authored-by: Bruno Ševčenko <bs3vcenk@gmail.com>
Co-authored-by: Francesco <francy.ammirati@hotmail.com>
Co-authored-by: Gian Marco Cinalli <gm.cinalli@gmail.com>
Co-authored-by: Mirco Cau <mircocau@gmail.com>
Co-authored-by: eggermn <egger.mn@gmail.com>
Co-authored-by: Jassy lin <linjiaxinme@gmail.com>
Co-authored-by: anpplex <anpplex@gmail.com>
Co-authored-by: kx <yoboy.rox@gmail.com>
Co-authored-by: lkw123 <lkw20010211@gmail.com>
Co-authored-by: Hordo <hordocast@mailo.com>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Maxent <rouaultmaxent@gmail.com>
Co-authored-by: Rémi Guerrero <remidu34070@hotmail.fr>
Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Symness <simon@frayssines.fr>
Co-authored-by: Valentin <droidente@gmail.com>
Co-authored-by: 주서현 <adan.89lion@gmail.com>
2023-08-24 20:14:19 +09:00
Uruk
3fd016808b Fix translation on fr.json (#446)
* Fix sidebar name

* Update fr.json

* Update fr.json

* added missing line

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* fix watchlist

* Update fr.json

* Fix plural

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json

* Update fr.json
2023-08-21 13:52:09 +05:00
Fallenbagel
b7282ce990 Merge pull request #450 from EthanArmbrust/libview
fix(server/api/jellyfin.ts): use /Library/VirtualFolders Jellyfin API call to fetch Jellyfin libs
2023-08-11 20:52:01 +05:00
Ethan Armbrust
8685f5796a fix(server/api/jellyfin.ts): use /Library/VirtualFolders Jellyfin API call to fetch Jellyfin libs
use /Library/VirtualFolders Jellyfin API call to fetch Jellyfin libraries, instead of relying on
user's view

fix #256
2023-08-10 18:10:29 -04:00
Fallenbagel
acc230fd20 Merge pull request #449 from davidfdezalcoba/fix-repeat-notifications-4k
fix: repeat notifications for available 4k media
2023-08-10 12:58:58 +05:00
jellyfin
30361f2ab7 fix: repeat notifications for available 4k media 2023-08-09 10:57:58 +02:00
fallenbagel
6a8406b5e3 Merge remote-tracking branch 'upstream/develop' into develop 2023-08-07 11:05:47 +05:00
Fallenbagel
7980212bee Merge pull request #444 from davidfdezalcoba/fix-repeat-notifications
fix: multiple notifications for available media
2023-08-07 01:48:43 +05:00
Ryan Cohen
317110855e ci: remove docker caching to save space after build (#3574) 2023-08-06 16:15:03 +09:00
David Fernandez Alcoba
048fa967f2 fix: multiple notifications for available media 2023-08-05 11:56:07 +02:00
TheCatLady
f7b4dfcac4 fix(tautulli): only test connection if hostname is defined (#3573) 2023-08-05 08:26:03 +09:00
allcontributors[bot]
a686d31e4d docs: add nemchik as a contributor for code (#3565) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-07-28 23:42:29 +09:00
Eric Nemchik
cb63bf217b fix: Include all defaults in payload (#3538)
* fix: Include all defaults in payload

* style(src/components/settings/notifications/notificationswebhook/index.tsx): prettier format

format changes from previous commit using prettier. line length requirement now met.

* fix(server/lib/settings.ts): update default settings for first install
2023-07-28 23:41:52 +09:00
Daniel Fendrich
7eed23637d fix(i18n): fixed jellyfin jobs 2023-07-28 15:53:03 +02:00
allcontributors[bot]
46e21c4e3e docs: add marcofaggian as a contributor for code (#3563) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-07-28 20:52:03 +09:00
Marco Faggian
b4191f9c65 feat(rating): added IMDB Radarr proxy (#3496)
* feat(rating): added imdb radarr proxy

Signed-off-by: marcofaggian <m@marcofaggian.com>

* refactor(rating/imdb): rm export unused interfaces

Signed-off-by: marcofaggian <m@marcofaggian.com>

* docs(rating/imdb): rt to imdb

Signed-off-by: marcofaggian <m@marcofaggian.com>

* refactor(rating/imdb): specified error message

Signed-off-by: marcofaggian <m@marcofaggian.com>

* refactor(rating/imdb): rm line break

Signed-off-by: marcofaggian <m@marcofaggian.com>

* refactor(rating): conform to types patter

Signed-off-by: marcofaggian <m@marcofaggian.com>

* chore(rating/imdb): added line to translation file

Signed-off-by: marcofaggian <m@marcofaggian.com>

* feat(rating/imdb): ratings to ratingscombined

Signed-off-by: marcofaggian <m@marcofaggian.com>

* fix(rating/imdb): reinstating ratings route

Signed-off-by: marcofaggian <m@marcofaggian.com>

* docs(ratings): openapi ratings

Signed-off-by: marcofaggian <m@marcofaggian.com>

* chore(ratings): undo openapi ratings apex

Signed-off-by: marcofaggian <m@marcofaggian.com>

---------

Signed-off-by: marcofaggian <m@marcofaggian.com>
2023-07-28 20:51:19 +09:00
Brandon Cohen
83b008c839 fix: handle issue causing incorrect media to change to unknown (#3516)
* fix: handle issue causing incorrect media to change back to unknown

* fix: prevent start if plex client is unavailable

* fix: initialize radarr and sonarr clients before the scan starts

* fix: compensate for multiple *arr servers

* fix: added a more reliable season lookup

* refactor: modified tuples to increase code readability
2023-07-24 15:33:12 +09:00
allcontributors[bot]
68c7b3650e docs: add scorp200 as a contributor for code (#3555) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-07-18 05:17:07 +00:00
Anton K. (ai Doge)
2816c66300 fix: resolved user access check issue (#3551)
* fix: importing friends

update checkUserAccess to use getUsers

* refactor(server/api/plextv.ts): clean up

removed unused getFriends function, and its interface.
renamed friends variable.
2023-07-18 01:03:52 -04:00
TheCatLady
01de972a8f fix(statusbadge): handle missing season/episode number (#3526) 2023-06-29 12:34:10 -04:00
Fallenbagel
da2d8fe35b fix typo in the safe directory 2023-06-25 20:41:46 +05:00
Brandon Cohen
a761b7dd35 fix: resolved issue with create slider causing incorrect form submission (#3514) 2023-06-21 17:18:50 +00:00
Fallenbagel
4f89286fa8 Merge pull request #357 from Pikachu920/develop
Clarify email address field during setup
2023-06-15 04:21:38 +05:00
Brandon Cohen
d0836ce0ef fix: improved handling of edge case that could cause availability sync to fail (#3497) 2023-06-14 14:43:08 +09:00
Fallenbagel
4740476c9a Merge pull request #398 from jeaboswell/feature-change-jellyfin-ip
feat(settings): add internal url to jellyfin settings form
2023-06-14 05:26:36 +05:00
Fallenbagel
c167d3ac38 test(cypress): fix broken cypress test 2023-06-14 05:12:48 +05:00
Ryan Cohen
2c3f533076 fix: adjust the plex watchlist sync schedule to have fuzziness (#3502)
also fixes the schedule making it uneditable
2023-06-13 23:15:54 +09:00
Fallenbagel
55baca57c1 Merge branch 'develop' into feature-change-jellyfin-ip 2023-06-13 05:38:41 +05:00
Fallenbagel
0b797964a8 docs(locale): extract locales 2023-06-13 05:32:22 +05:00
Brandon Cohen
c1a47bd9de fix(ui): corrected issues icon color (#3498) 2023-06-12 17:35:01 +09:00
Fallenbagel
030cbc535a Merge pull request #403 from Fallenbagel/fix-log-format-jellyfin-auth
fix(logs): jellyfin auth error now has the severity `warn` consistent with local login
2023-06-12 01:42:04 +05:00
Fallenbagel
b0fd0f59c4 Merge pull request #404 from Fallenbagel/add-translations
feat: translations update
2023-06-11 20:01:54 +05:00
Fallenbagel
47287c3688 feat: translations update
fix #381
2023-06-11 07:52:39 +05:00
Fallenbagel
cc041b5e0a fix(logs): jellyfin auth error now has the severity warn consistent with local login
fix #224
2023-06-11 07:26:45 +05:00
Fallenbagel
b4c74de7b3 style: added more clarity to the tooltip message
Previous commits wordings made it sound like it NEEDS to be unrelated to the mediaserver instance.
However, it can be any valid address
2023-06-11 07:06:39 +05:00
Fallenbagel
9daceb7017 style: offsetted the info icon and increased clarity in the tooltip message 2023-06-11 06:54:37 +05:00
Fallenbagel
ff7f9725f8 Merge remote-tracking branch 'upstream/develop' into develop 2023-06-11 06:44:07 +05:00
Fallenbagel
cd7930eef9 feat(tooltip): email tooltip now appears when hovered over info icon 2023-06-11 06:36:51 +05:00
allcontributors[bot]
24d94ef6fd docs: add Fallenbagel as a contributor for code (#3493) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-06-11 10:15:55 +09:00
Fallenbagel
04fbd00d4a fix: fixes RT ratings for tv shows (#3492)
fix #3491
2023-06-11 10:14:14 +09:00
Fallenbagel
33ec4436fb fix: external url regex is now consistent with internal url 2023-06-11 05:43:02 +05:00
Fallenbagel
e848386d10 fix: fix regex for internal url to use a more effecient one 2023-06-11 05:15:26 +05:00
Fallenbagel
235cee1d28 ci: use self-hosted github runner
Changed to using self-hosted github runner as the free tier one was crashing due to low storage
space when pushing cache
2023-06-10 21:57:01 +05:00
Fallenbagel
8d4943997e ci: temporarily clean cache to fix docker builds 2023-06-10 10:23:20 +05:00
Fallenbagel
2ab814574c ci(snap): possible fix for dubious ownership error for snap builds 2023-06-10 05:17:01 +05:00
Fallenbagel
c6b2dd3728 ci: fix CODEOWNERS file containing errors 2023-06-10 05:06:22 +05:00
Fallenbagel
825fa75ee2 Merge upstream/develop 2023-06-10 04:58:15 +05:00
allcontributors[bot]
21231186d1 docs: add andrew-kennedy as a contributor for code (#3489) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-06-09 23:20:02 +00:00
Andrew Kennedy
48f76662d5 fix: make a (shallow) copy of radarr/sonarr tags into a request before adding user tags (#3485)
* Make a (shallow) copy of radarr/sonarr tags into a request before adding user tags

* Undo random formatting changes

* more undoing formatting changes

* Fix undefined case.

* Prettier format
2023-06-09 18:46:04 -04:00
Fallenbagel
4920670495 Merge pull request #397 from jeaboswell/feature-emby-icons
Emby Link Icon
2023-06-06 19:22:40 +05:00
Jesse Boswell
0a30cd356d feat(settings): add internal url to jellyfin settings form
re #194
2023-06-05 23:05:54 -05:00
Jesse Boswell
1fe4bb8a04 fix(ui): Make play symbol white 2023-06-05 18:44:42 -05:00
Fallenbagel
21c1bbec90 Merge pull request #374 from yalagin/add-watchlist
feat(watchlist): Add media to watchlist
2023-06-06 03:13:34 +05:00
Jesse Boswell
ad69d6715e fix(ui): Resize Emby icon and add margins 2023-06-05 13:21:00 -05:00
Jesse Boswell
46cd4d01d9 fix: externalLinkBlock 2023-06-05 12:10:25 -05:00
Jesse Boswell
672061cd64 feat(src/components/externallinkblock/index.tsx): support Emby icon
Display the Emby icon instead of Jellyfin when mediaserver type is Emby
2023-06-05 10:59:32 -05:00
allcontributors[bot]
df332cec84 docs: add SalmanTariq as a contributor for code (#3478)
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-06-01 00:24:05 +00:00
Salman Tariq
d7fa35e066 fix(genreselector): fix searching in Genre filter (#3468) 2023-05-31 21:53:50 +00:00
Ryan Cohen
f33eb862fd chore: update codeowners (#3474) [skip ci] 2023-05-29 11:36:26 +09:00
allcontributors[bot]
0a007ca805 docs: add IzaacJ as a contributor for code (#3473) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-05-29 11:32:08 +09:00
Izaac Brånn
24f268b6cb feat: auto tagging requested media with username (#3338)
* feat: auto tagging requested media with username

Relating to discussion: https://github.com/sct/overseerr/discussions/3313

Adding an option to the Radarr and Sonarr service to enable automatic tagging
with the username requesting the media.

Current format, to reduce tag clutter if a user changes displayname:

`[user.id] - [user.displayName]`

* fix: modified new secondary tip language

---------

Co-authored-by: Brandon Cohen <brandon@z3hn.dev>
2023-05-29 02:29:36 +00:00
Yalagin
03316c642d fix(watchlist): add validation for creation request 2023-05-15 23:25:32 +07:00
allcontributors[bot]
b8e3c07c47 docs: add SMores as a contributor for code (#3455) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-05-13 09:35:51 +09:00
Shane Friedman
aa84977680 feat(discover): support filtering by tmdb user vote count on discover page (#3407) 2023-05-13 00:23:14 +00:00
Brandon Cohen
e051b1dfea fix: correctly load series fallback modal with sonarr v4 (#3451) 2023-05-11 04:43:11 +00:00
Brandon Cohen
c27f96096a fix: lock body scroll when using webkit (#3399) 2023-05-11 04:27:45 +00:00
Brandon Cohen
4bd87647d0 fix: corrected initial fallback data load on details page (#3395) 2023-05-11 04:16:50 +00:00
Brandon Cohen
c1e10338c1 refactor: pull to refresh (#3391)
* refactor: decoupled PTR by removing import and creating new touch logic

* fix: overscroll behavior on mobile is now prevented on the y axis

* feat: added shadow effects to icon

* fix: modified cypress test

* fix: added better scroll lock functionality

* fix: hide icon if scroll value is negative

* fix: changed to allow usage on all touch devices
2023-05-11 11:59:12 +09:00
allcontributors[bot]
cd1cacad55 docs: add Zebebles as a contributor for code (#3453) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-05-11 10:45:54 +09:00
Zeb Muller
ac77b037d5 fix: error deleting users with over 1000 requests (#3376)
Break-up request removal into groups of 1000 requests to be removed at a time.
2023-05-11 10:45:23 +09:00
allcontributors[bot]
10eb69a7dc docs: add Alexays as a contributor for code (#3452) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-05-11 09:59:15 +09:00
Alex
70b1540ae2 fix: handle search results with collections (#3393)
* feat: handle search collection

* Update server/utils/typeHelpers.ts

Co-authored-by: Danshil Kokil Mungur <danshil.mungur@gmail.com>

* fix: modified title card to show collection instead of movies

---------

Co-authored-by: Danshil Kokil Mungur <danshil.mungur@gmail.com>
Co-authored-by: Brandon <cohbrandon@gmail.com>
2023-05-11 09:58:16 +09:00
Brandon Cohen
7522aa3174 fix: availability sync file detection (#3371)
* fix: added extra check for unmonitored movies in radarr

* feat: created new radarr/sonarr routes  to grab existing series data

* refactor: updated job routes to check by external service id

* fix: season check will now also look at episode file count
2023-05-11 09:36:12 +09:00
Brandon Cohen
77a33cb74d fix(ui): corrected mobile menu spacing in collection details (#3432) 2023-05-04 22:08:22 +04:00
Yalagin
c08897bdc1 fix(watchlist): fix github code scanning 2023-05-04 22:36:36 +07:00
Yalagin
469f64d484 test(watchlist): fix broken test 2023-05-02 21:13:18 +07:00
Yalagin
b7e3d285ed feat(watchlist): add translation for en 2023-04-27 22:46:46 +07:00
Yalagin
5f1c10d50a feat(add watchlist): adding midding functionality from overserr
feat(add watchlist): adding missing functionality from overserr
2023-04-27 22:27:23 +07:00
Pikachu920
9637c3f4ab Merge remote-tracking branch 'origin/develop' into develop 2023-03-25 10:22:56 -05:00
Pikachu920
a15c85cbd1 Add helper text to email address field in setup 2023-03-25 10:22:30 -05:00
Fallenbagel
53f6a890b9 Merge pull request #356 from GeoffreyCoulaud/geoffrey-fix
Fixed french locale: using "de " instead of "d'" before Jellyseerr
2023-03-25 16:43:51 +05:00
GeoffreyCoulaud
7dbe6f61d0 Fixed d' before Jellyseerr 2023-03-25 00:49:59 +01:00
Fallenbagel
fd460df243 Merge pull request #348 from Fallenbagel/temp-disable-media-availability
fix: disable availability sync temporarily
2023-03-18 04:26:14 +05:00
Fallenbagel
2e5cf22626 fix: disable availability sync temporarily
This PR disables availability sync temporarily as the current one does not have jellyfin/emby sync
ported into it. This would ensure that jellyseerr does not bug out and start removing availability
from media despite it being available on jellyfin/emby/*arr as well as their requests.
2023-03-18 04:08:54 +05:00
Fallenbagel
092d639dd9 Merge pull request #347 from Fallenbagel/temp-fix-display-specials-within-season
fix(jellyfin sync): temporary workaround fix for jellyfin scan when display specials within season
2023-03-18 03:43:06 +05:00
Fallenbagel
fc1f3202e8 Merge pull request #338 from Fallenbagel/fix-4k-detection-series
fixes 4k detection of series
2023-03-18 03:42:48 +05:00
Fallenbagel
3bf04f2abd refactor: refactored 4k detection fix to be more consistent with how movie logic works 2023-03-17 04:32:27 +05:00
Fallenbagel
38fb66d31e fix(jellyfin scan): temporary workaround fix for jellyfin scan when display specials within season
Currently when display specials within season is enabled, it increases the indexed episode count of
the season. This is a problem due to the way our jellyfin sync works as it requires total standard
episodes to be equal to season episode count for the `AVAILABLE` badge for that season. However,
when the display specials within season is enabled, the scan sets that season as `PARTIALLY
AVAILABLE`. This workaround fixes this behaviour. In addition, this fix **might** also fix the
recurring availability notifications (recurring notifications might be occurring due to the scan
initially setting the season as available, thus the series is set as available and sends the
notification, but then it sets the season as partially available due to the aforementioned sync flow
until next scan and repeats.)

fix #215 #176 #246
2023-03-17 04:19:16 +05:00
Fallenbagel
8b3801539e Merge pull request #321 from andrey4korop/Lang_changes
Update Ukrainian language
2023-03-09 03:43:13 +05:00
Fallenbagel
101ffae641 style: ran prettier on ua locale 2023-03-04 01:17:26 +05:00
Fallenbagel
bc9017f54d fix: add better checks on 4k detection of series 2023-03-04 00:54:21 +05:00
Fallenbagel
b90dedfafc fix merge conflict lines which were present during last merge 2023-03-02 19:32:34 +05:00
Brandon Cohen
a4d07f5afa fix(ui): corrected default badge hover opacity (#3369) 2023-03-02 08:21:55 -05:00
renovate[bot]
f5191aded6 fix(deps): update all non-major dependencies (#3223)
* chore(deps): update all non-major dependencies

* fix: resolve same express-session types for connect-typeorm

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
2023-03-01 11:59:06 -05:00
Brandon Cohen
2520d8f739 feat: adds streaming services custom slider (#3361)
* feat: adding streaming services as a slider is now an option

* fix: truncated slider titles on mobile
2023-02-28 13:36:28 +09:00
Fallenbagel
ee23de6d2f Merge remote-tracking branch 'upstream/develop' into develop 2023-02-28 03:28:36 +05:00
allcontributors[bot]
04980f93ab docs: add jariz as a contributor for code (#3357) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-02-24 19:47:36 +09:00
allcontributors[bot]
2a3213d706 docs: add Nimelrian as a contributor for code (#3356) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-02-24 19:46:46 +09:00
Brandon Cohen
c36a4ba2b8 fix: logger was set to info for the wrong logs (#3354) 2023-02-24 07:29:42 +00:00
Brandon Cohen
ae3818304b feat: availability sync rework (#3219)
* feat: add availability synchronization job

fix #377

* fix: feedback on PR

* perf: use pagination for Media Availability Synchronization job

The original approach loaded all media items from the database at once. With large libraries, this
could lead to performance issues. We're now using a paginated approach with a page size of 50.

* feat: updated the availability sync to work with 4k

* fix: corrected detection of media in plex

* refactor: code cleanup and minimized unnecessary calls

* fix: if media is not found, media check will continue

* fix: if non-4k or 4k show media is updated, seasons and request is now properly updated

* refactor: consolidated media updater into one function

* fix: season requests are now removed if season has been deleted

* refactor: removed joincolumn

* fix: makes sure we will always check radarr/sonarr to see if media exists

* fix: media will now only be updated to unavailable and deletion will be prevented

* fix: changed types in Media entity

* fix: prevent season deletion in preference of setting season to unknown

---------

Co-authored-by: Jari Zwarts <jari@oberon.nl>
Co-authored-by: Sebastian Kappen <sebastian@kappen.dev>
2023-02-24 05:28:22 +00:00
Danshil Kokil Mungur
b3882de893 fix(ui): hide search bar behind slideover when opened (#3348) 2023-02-24 02:03:01 +00:00
Danshil Kokil Mungur
af880a6c83 fix(watchlist): correctly load more than 20 watchlist items (#3351)
* fix(discover): correctly load additional watchlist items pages

* chore(discover): remove unused params types
2023-02-24 00:40:01 +00:00
Danshil Kokil Mungur
eb5502a16f fix(ui): prevent title cards from flickering when quickly hovering across them (#3349)
* fix(ui): remove opacity classes from transition enter and leave props

The flickering was caused by the opacity classes in the `leave` prop to take effect as the
transition ends; when the `leaveTo` prop classes are no longer applied, but the `leave` prop classes
are still applied.

* fix(ui): resolve transition issues for all components

1. Remove opacity classes from `enter` and `leave` props
2. Fix some class name typos
3. Remove transform classes since those are automatically applied as from TailwindCSS v3.0
4. Narrow down `transition` classes to only the properties being transitioned in Transition components
2023-02-24 00:27:26 +09:00
Danshil Kokil Mungur
50f06dabbf fix(ui): hide mini status badge if non-4K media status is unknown (#3346) 2023-02-20 10:54:06 +09:00
Fallenbagel
ddbc377d79 Merge pull request #182 from dd060606/features/deleteMediaFile
feat: button to remove a movie from Radarr/Sonarr
2023-02-19 02:59:28 +05:00
Brandon Cohen
1e2c6f46ab fix: added a refresh interval if download status is in progress (#3275)
* fix: added a refresh interval if download status is in progress

* refactor: switched to a function instead of useEffect

* feat: added editable download sync schedule
2023-02-15 19:16:13 +04:00
Owen Voke
dd1378cef5 chore(api): update descriptions for API endpoints (#3341) 2023-02-15 00:40:51 +04:00
allcontributors[bot]
e684456bba docs: add owenvoke as a contributor for code (#3340) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-02-14 14:53:35 +09:00
Owen Voke
6bd3f015d6 fix: remove unnecessary parenthesis from api key generation (#3336) 2023-02-14 14:52:26 +09:00
dd060606
7bd4c4d1d4 Merge branch 'develop' into features/deleteMediaFile 2023-02-13 08:58:53 +01:00
dd060606
3005e577d7 style(src/components/manageslideover/index.tsx): fix code style issues 2023-02-13 08:33:23 +01:00
allcontributors[bot]
2d97be0d6c docs: add lunks as a contributor for code (#3334) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-02-12 20:05:59 +09:00
Pedro Nascimento
966639df43 perf(imageproxy): do not set cookies to image proxy so CDNs can cache images (#3332)
CDNs such as Cloudflare bypass their cache if cookies are set in the response.
clearCookies
middleware removes the header before imageproxy serves the image.
2023-02-12 20:05:29 +09:00
Brandon Cohen
33e7691b94 feat: full title of download item on hover with tooltip (#3296)
Co-authored-by: Ryan Cohen <ryan@sct.dev>
2023-02-11 10:30:53 +00:00
Danshil Kokil Mungur
d7b83d22ce fix(build): increase threshold for amount of data to be fetched when SSR'ing (#3320)
Co-authored-by: Ryan Cohen <ryan@sct.dev>
2023-02-11 09:36:31 +00:00
Ryan Cohen
b6eac0f364 test: change custom keyword for slider creation (#3333) 2023-02-11 17:18:30 +09:00
Fallenbagel
572a7db4aa Merge pull request #297 from DimitriDR/develop
French I18n update
2023-02-04 03:27:06 +05:00
andrey
862cd2d6ac Update Ukrainian language 2023-02-02 19:04:29 +02:00
Fallenbagel
6f23abaa6d Merge pull request #298 from andrey4korop/develop
Add Ukrainian language
2023-02-01 21:15:23 +05:00
andrey
81518df89a Merge remote-tracking branch 'o/develop' into develop 2023-02-01 16:20:04 +02:00
Fallenbagel
604335a16d ci(release): fix previous merge that changed discord notification run-on to self-hosted [skip ci] 2023-02-01 08:52:28 +05:00
Fallenbagel
78ccea94bd Merge pull request #318 from Fallenbagel/CHANGELOG-ignore-prettier
chore(prettier): ignore CHANGELOG by prettier
2023-01-31 03:50:53 +05:00
Fallenbagel
a487ab4506 chore(prettier): ignore CHANGELOG by prettier
When changelog is generated by semantic bot, it keeps failing the prettier format check. So this
ignores it
2023-01-31 03:40:47 +05:00
Ryan Cohen
c93467b3ac fix(snapcraft): use the correct config folder for image cache (#3302) 2023-01-31 01:31:39 +09:00
Fallenbagel
c709e8596a Merge pull request #314 from Fallenbagel/upstream-fix
Merge upstream hotfix
2023-01-30 04:41:37 +05:00
Fallenbagel
26e49e73a5 Merge remote-tracking branch 'upstream/develop' into develop 2023-01-30 04:27:34 +05:00
Ryan Cohen
d954328911 fix(ui): correct range slider styling in chrome (#3299) 2023-01-29 20:32:25 +09:00
Brandon Cohen
3e43586acc fix(ui): air date will use UTC for timezone (#3297) 2023-01-29 16:43:54 +09:00
Ryan Cohen
7040da1334 fix(ui): show 5 icons when possible on mobile menu (#3298) 2023-01-29 16:27:09 +09:00
Ryan Cohen
9d10e6a88c fix(ui): style range thumbs correctly for firefox (#3294) 2023-01-29 13:27:33 +09:00
Fallenbagel
4c22a71cdf Merge pull request #311 from Fallenbagel/upstream
Merge 'upstream/develop' into develop
2023-01-28 05:22:42 +05:00
Fallenbagel
b9e7933e09 docs(readme): revert to original README 2023-01-28 05:04:33 +05:00
Fallenbagel
2508b4340f refactor: updated the heroicons used in jellyfin settings/email warning 2023-01-28 04:44:46 +05:00
Fallenbagel
e1f67ad8ba Merge 'overseerr/develop' into develop 2023-01-28 03:40:12 +05:00
Fallenbagel
91abdb2ba5 Remove Zone.Identfier [skip ci] 2023-01-28 03:33:22 +05:00
Brandon Cohen
8942eb8b7c fix: pass in library type when scanning recently added items (#3287) 2023-01-27 21:53:46 +09:00
notfakie
ad3d922440 Merge remote-tracking branch 'overseerr/develop' into develop 2023-01-27 17:55:55 +13:00
Danshil Kokil Mungur
51b05cd8fb fix(build): update usage of publish snap action (#3272)
* fix(build): use env variable to login with snapcraft 7

* refactor(build): replace deprecated set-output command in GHA

* fix(build): use correct environment variable for output

* style(build): run prettier
2023-01-27 09:48:40 +09:00
Brandon Cohen
374c78c989 fix(ui): series first air date sorting (#3283) 2023-01-26 22:22:38 +00:00
Brandon Cohen
507693881b fix: multiple genre filtering now works (#3282) 2023-01-26 14:10:02 -08:00
Ryan Cohen
f4a22dc437 fix: correctly check mobile menu permissions (#3271) 2023-01-25 18:49:01 +09:00
Ryan Cohen
5d1c6f7065 fix: create shared class to add bottom spacing (#3269) 2023-01-24 19:30:38 +09:00
Ryan Cohen
3db010b9ea fix: correct issue detail bottom padding on mobile displays (#3268) 2023-01-24 14:54:58 +09:00
TheCatLady
fd219717c0 fix: issues with issues (#3267)
* fix: issues with issues

* fix: don't notify on user closing/reopening own issue

* fix: only show close/reopen buttons for OP and admins
2023-01-24 02:58:56 +00:00
Brandon Cohen
d328485161 fix: arrow icons were misplaced on mobile in slider edit (#3260) 2023-01-20 14:46:29 +00:00
Brandon Cohen
da00d454e1 feat: discover slider edit arrow buttons for reordering (#3259) 2023-01-20 06:20:05 +00:00
Danshil Kokil Mungur
d7bfc73727 docs(installation): add PORT env variable to example commands (#3254) [skip ci]
* docs(installation): add PORT env variable to Docker CLI & Docker Compose examples

* docs(installation): fix typo

* docs(installation): clarify hint about named volumes for windows installation example
2023-01-20 02:39:24 +09:00
Weblate (bot)
5940ff7f5f feat: translations update from Hosted Weblate (#3218)
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.5% (1217 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.4% (1215 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.4% (1215 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.2% (1213 of 1222 strings)

feat(lang): translated using Weblate (French)

Currently translated at 98.6% (1203 of 1219 strings)

feat(lang): translated using Weblate (French)

Currently translated at 92.6% (1130 of 1219 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (French)

Currently translated at 96.0% (1132 of 1179 strings)

feat(lang): translated using Weblate (French)

Currently translated at 95.9% (1131 of 1179 strings)

Co-authored-by: Dimitri <dimitridroeck@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Uruk <uruknarb20@gmail.com>
Co-authored-by: slundi <slundi@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Spanish)

Currently translated at 85.5% (1045 of 1222 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Angel <adelpozoman@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Polish)

Currently translated at 100.0% (1222 of 1222 strings)

feat(lang): translated using Weblate (Polish)

Currently translated at 93.6% (1144 of 1222 strings)

feat(lang): translated using Weblate (Polish)

Currently translated at 90.6% (1105 of 1219 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Patryk <byakurau1@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pl/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1219 of 1219 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 96.9% (1182 of 1219 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1179 of 1179 strings)

Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 94.0% (1105 of 1175 strings)

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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1219 of 1219 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Dutch)

Currently translated at 95.5% (1126 of 1179 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 93.8% (1107 of 1179 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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 94.6% (1154 of 1219 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1175 of 1175 strings)

Co-authored-by: Ben <ben.david.wallner@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 94.7% (1113 of 1175 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hindi)

Currently translated at 11.8% (145 of 1222 strings)

feat(lang): translated using Weblate (Hindi)

Currently translated at 9.4% (115 of 1222 strings)

feat(lang): translated using Weblate (Hindi)

Currently translated at 9.1% (112 of 1222 strings)

feat(lang): translated using Weblate (Hindi)

Currently translated at 9.1% (112 of 1222 strings)

feat(lang): translated using Weblate (Hindi)

Currently translated at 2.7% (33 of 1222 strings)

Co-authored-by: Gaurang Goel <gaurang7goel+hosted@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Ishan Jindal <jindal25ishan@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hi/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Albanian)

Currently translated at 97.1% (1142 of 1175 strings)

Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Dimitri <dimitridroeck@gmail.com>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Sulli <susu.leduc@gmail.com>
Co-authored-by: Uruk <uruknarb20@gmail.com>
Co-authored-by: slundi <slundi@gmail.com>
Co-authored-by: Angel <adelpozoman@gmail.com>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: lkw123 <lkw20010211@gmail.com>
Co-authored-by: Kobe <kobaubarr@gmail.com>
Co-authored-by: Ben <ben.david.wallner@gmail.com>
Co-authored-by: exentler <gurandsrud@gmail.com>
Co-authored-by: Gaurang Goel <gaurang7goel+hosted@gmail.com>
Co-authored-by: Ishan Jindal <jindal25ishan@gmail.com>
Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
2023-01-19 21:53:44 +09:00
Ryan Cohen
fcbca1722f feat: new mobile menu (#3251) 2023-01-17 18:00:15 +09:00
Ryan Cohen
19370f856c chore: add holopin config (#3250) [skip ci] 2023-01-17 10:36:00 +09:00
Ryan Cohen
154f3e72ef fix: correctly restore selected streaming service filters (#3249) 2023-01-16 21:34:47 +09:00
Ryan Cohen
6fd11cf425 fix: correct grid sizing for webkit on streaming services (#3248) 2023-01-16 21:04:55 +09:00
Ryan Cohen
1154156459 feat: add streaming services filter (#3247)
* feat: add streaming services filter

* fix: count watch region/provider as one filter
2023-01-16 17:05:21 +09:00
Danshil Kokil Mungur
cb650745f6 fix(request): mark request as approved if media is already available when retrying failed request (#3244) 2023-01-15 11:32:38 +04:00
Brandon Cohen
3aefddd488 fix: screen would zoom on mobile if date picker input was selected (#3241) 2023-01-14 11:40:39 +09:00
allcontributors[bot]
1bf0103422 docs: add aedelbro as a contributor for code (#3240) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-01-14 10:11:30 +09:00
aedelbro
a672b324ec feat(ui): add episode number to front of episode name in season details (#3086) 2023-01-14 01:10:38 +00:00
Brandon Cohen
a343f8ad91 fix: prevent double encode if we are on /search endpoint (#3238) 2023-01-13 23:21:54 +00:00
Fallenbagel
7a69cb35f8 Merge pull request #296 from CheChu10/patch-2
Update Spanish translations
2023-01-14 00:01:31 +05:00
Ryan Cohen
c2a1a20a3b fix: include new package calendar css in build (#3235) 2023-01-13 20:42:03 +09:00
Ryan Cohen
dd00e48f59 feat: discover overhaul (filters!) (#3232) 2023-01-13 16:54:35 +09:00
Danshil Kokil Mungur
b5157010c4 fix(request): approve request when retrying request (#3234)
chore(request): clarify comment
2023-01-12 16:34:53 +09:00
andrey
812fb2f087 Add Ukrainian language 2023-01-11 04:09:48 +02:00
renovate[bot]
7b6db50ae5 fix(deps): update dependency swr to v2 (#3212)
* fix(deps): update dependency swr to v2

* fix: correct type import for swr

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
2023-01-09 16:28:15 +09:00
Ryan Cohen
3ba6df1a41 fix: correct checkbox position (again) for slider edits (#3227) 2023-01-09 15:15:26 +09:00
Ryan Cohen
2eebb7fd39 fix: restore border to ghost button and fix discover slider visibility toggle position (#3226) 2023-01-08 09:18:08 +09:00
Dimitri
c60667ba63 Readding file because Windows didn't want to. 2023-01-08 00:13:27 +01:00
Dimitri
7d6831483a Are you ready for a miracle? 2023-01-08 00:10:48 +01:00
Dimitri
58c5c27929 Delete preview.jpg:Zone.Identifier 2023-01-07 23:33:21 +01:00
Fallenbagel
f5c7a4fa97 Merge pull request #295 from undone37/patch-1
Updated German Translations
2023-01-08 00:34:27 +05:00
Chechu
50e85c975a Prettier fixed 2023-01-07 19:31:50 +01:00
Ryan Cohen
62e2de70bf fix: correct spacing between sliders (#3225) 2023-01-08 00:35:08 +09:00
Ryan Cohen
0683f4f000 refactor: redesign discover customization buttons (#3224) 2023-01-08 00:12:31 +09:00
Chechu García
b1bd569335 Update es.json
Added some missing Spanish translations and fixed a spelling mistake.
Ordered by JSON Keys.
2023-01-07 09:15:28 +00:00
undone37
a49ea92692 style(i18n german translation): fixed Prettier formatting issue of German translation file 2023-01-06 20:02:56 +01:00
Ryan Cohen
d23b2132de fix: improve small screen layout for discover editing (#3221) 2023-01-07 01:12:19 +09:00
Ryan Cohen
8bd10b5bf3 feat: discover inline customization (#3220) 2023-01-06 21:03:09 +09:00
undone37
08c9085f0d Updated German Translations
Added missing German translations and fixed some spelling mistakes.
Changed some German translations to match informal address of user.
Unification of wordings like "Episoden" and "Folgen".
2023-01-06 11:10:13 +01:00
Weblate (bot)
0d8b390b67 feat(lang): translations update from Hosted Weblate (#3030)
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Spanish)

Currently translated at 84.8% (955 of 1125 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Joseph Valderrama Palacios <jvalderrama.es@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Romanian)

Currently translated at 23.3% (263 of 1125 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 23.3% (263 of 1125 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 21.6% (243 of 1125 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 17.6% (199 of 1125 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 10.9% (123 of 1125 strings)

Co-authored-by: DragoPrime <emperordrago@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Sergiu Pahontu <pahontusergiu@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ro/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Polish)

Currently translated at 100.0% (1129 of 1129 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Patryk <byakurau1@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pl/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Russian)

Currently translated at 87.7% (987 of 1125 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Sergey Moiseev <ty4ko@bk.ru>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ru/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Portuguese (Portugal))

Currently translated at 98.0% (1103 of 1125 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: ssantos <ssantos@web.de>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Danish)

Currently translated at 100.0% (1125 of 1125 strings)

Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.7% (1126 of 1129 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.5% (1120 of 1125 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1120 of 1120 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1120 of 1120 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1120 of 1120 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.8% (1118 of 1120 strings)

Co-authored-by: Eric <hamburger1024@mailbox.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: lkw123 <2020393267@qq.com>
Co-authored-by: lkw123 <lkw20010211@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Hungarian)

Currently translated at 96.7% (1083 of 1119 strings)

feat(lang): translated using Weblate (Hungarian)

Currently translated at 94.3% (1056 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1129 of 1129 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 99.9% (1124 of 1125 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1120 of 1120 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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Czech)

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Smexhy <roman.bartik@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1120 of 1120 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 98.0% (1152 of 1175 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1129 of 1129 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Squizzy911 <tobias.mueller1210@gmail.com>
Co-authored-by: inkarnation <94744834+inkarnation@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (1120 of 1120 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 95.0% (1069 of 1125 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 94.0% (1058 of 1125 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 93.8% (1050 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Micke Nilsson <mikni@proton.me>
Co-authored-by: Mikael Nilsson <mikni@proton.me>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hebrew)

Currently translated at 12.1% (137 of 1125 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Izik Avinoam <izik.avi@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/he/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1120 of 1120 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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Croatian)

Currently translated at 100.0% (1129 of 1129 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 99.9% (1124 of 1125 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 100.0% (1120 of 1120 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 100.0% (1119 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 98.3% (1100 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 96.9% (1085 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 96.0% (1075 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 95.3% (1067 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 95.3% (1067 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: lpispek <lpispek@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Albanian)

Currently translated at 100.0% (1125 of 1125 strings)

feat(lang): translated using Weblate (Albanian)

Currently translated at 99.5% (1120 of 1125 strings)

feat(lang): translated using Weblate (Albanian)

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Joseph Valderrama Palacios <jvalderrama.es@gmail.com>
Co-authored-by: DragoPrime <emperordrago@gmail.com>
Co-authored-by: Sergiu Pahontu <pahontusergiu@gmail.com>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: Sergey Moiseev <ty4ko@bk.ru>
Co-authored-by: ssantos <ssantos@web.de>
Co-authored-by: Anders Ecklon <aecklon@gmail.com>
Co-authored-by: Eric <hamburger1024@mailbox.org>
Co-authored-by: lkw123 <2020393267@qq.com>
Co-authored-by: lkw123 <lkw20010211@gmail.com>
Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de>
Co-authored-by: Kobe <kobaubarr@gmail.com>
Co-authored-by: Smexhy <roman.bartik@icloud.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Squizzy911 <tobias.mueller1210@gmail.com>
Co-authored-by: inkarnation <94744834+inkarnation@users.noreply.github.com>
Co-authored-by: exentler <gurandsrud@gmail.com>
Co-authored-by: Micke Nilsson <mikni@proton.me>
Co-authored-by: Shjosan <shjosan@kakmix.co>
Co-authored-by: Izik Avinoam <izik.avi@gmail.com>
Co-authored-by: dtalens <databio@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
Co-authored-by: lpispek <lpispek@gmail.com>
Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
2023-01-05 13:57:43 +09:00
renovate[bot]
19b4dc424f chore(deps): update all non-major dependencies (#3195) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-05 13:35:13 +09:00
renovate[bot]
7fef48df63 chore(deps): update dependency lint-staged to v13 (#2931) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-05 13:25:24 +09:00
allcontributors[bot]
8220ea55ae docs: add ceptonit as a contributor for doc (#3211) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2023-01-05 13:19:25 +09:00
ceptonit
4de4a1a52c docs: removed 'available' from /request/{requestId}/{status} endpoint (#3098) [skip ci] 2023-01-05 04:18:05 +00:00
Ryan Cohen
042a1a950f fix: update StatusBadgeMini to shrink on title cards (and remove ring) (#3210) 2023-01-05 12:09:08 +09:00
renovate[bot]
421029ebab fix(deps): update dependency axios to v1 (#3202)
* fix(deps): update dependency axios to v1

* fix: deal with possibly undefined headers from axios

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
2023-01-05 11:05:46 +09:00
Ryan Cohen
4e9be7a3f7 fix: correct link to correct keyword results for series (#3208) 2023-01-05 10:30:05 +09:00
Fallenbagel
af4a3b4279 Merge remote-tracking branch 'notfakie/develop' into develop 2023-01-05 03:47:35 +05:00
Fallenbagel
5ce59cc2ee Revert to develop version [skip ci] 2023-01-05 03:45:57 +05:00
Fallenbagel
ff2fa66002 Merge pull request #291 from Fallenbagel/main
Merge origin/main to develop
2023-01-05 03:38:47 +05:00
Fallenbagel
9388a1e61c docs: fix CHANGELOG formatting issue 2023-01-05 02:51:45 +05:00
Fallenbagel
b44a1b4a99 Remove CHANGELOG from origin/develop [skip ci] 2023-01-05 02:46:59 +05:00
Fallenbagel
6f73dbc36a Fix snap stable builds 2023-01-05 02:26:23 +05:00
Ryan Cohen
9d3446d370 fix: restore status badges on titles on actors page when hide available media enabled (#3206) 2023-01-04 17:29:48 +09:00
Ryan Cohen
2f680b4cec refactor: update titlecard to use StatusBadgeMini (#3205) 2023-01-04 16:40:21 +09:00
Brandon Cohen
2179637d43 fix: series displayed an empty season with series list/request modal (#3147)
* fix: series would show an empty season on season list or tv request modal

* fix: request more would show even if all requestable seasons are already requested

* fix: will check if request or season length is longer
2023-01-04 05:48:21 +00:00
Ryan Cohen
e084649878 feat: add keywords to movie/series detail pages (#3204) 2023-01-04 14:19:51 +09:00
renovate[bot]
edf5010659 chore(deps): update dependency cypress to v12 (#3197) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-04 10:43:02 +09:00
Ryan Cohen
93afead92e fix: convert genre/studio to string in create slider (#3201)
* fix: convert genre/studio to string in create slider

* fix: fix typo in variable name for i18n message
2023-01-04 10:42:30 +09:00
renovate[bot]
dd48d59b20 fix(deps): update dependency @heroicons/react to v2 (#2970)
* fix(deps): update dependency @heroicons/react to v2

* fix: update imports and fix icon name changes for heroicons

* fix: also update MiniStatusBadge to use new check icon

* fix: update last place with old import

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
2023-01-04 01:06:02 +00:00
renovate[bot]
c4b16abc62 fix(deps): pin dependency @headlessui/react to 1.7.7 (#3194) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-03 22:08:29 +09:00
renovate[bot]
1a95d423f2 chore(deps): update all non-major dependencies (#2926)
* chore(deps): update all non-major dependencies

* fix: correct breaking changes

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
2023-01-03 22:06:07 +09:00
Ryan Cohen
cd3574851a feat: add discover customization (#3182) 2023-01-03 16:04:28 +09:00
semantic-release-bot
299f65c597 chore(release): 1.3.0 2023-01-02 00:14:11 +00:00
Fallenbagel
6021d1e336 Merge pull request #285 from Fallenbagel/prepare-for-next-version
Merge origin/develop to prepare for next release
2023-01-02 05:11:37 +05:00
Fallenbagel
3ce1ef350e docs: merge CHANGELOG.md of develop with main to fix format issue 2023-01-02 05:01:13 +05:00
Fallenbagel
06c91744f3 Merge branch 'develop' 2023-01-02 04:44:05 +05:00
Ryan Cohen
f14d9407d8 chore: update to use github codeql (#3191) [skip ci] 2022-12-30 11:38:08 +09:00
Brandon Cohen
68223f4b1e fix: add bg-opacity to in-progress status badges (#3190) 2022-12-30 11:36:47 +09:00
Ryan Cohen
76335ec8d3 refactor: update mini status icons on titlecard to match badge colors (#3188) 2022-12-29 23:10:23 +09:00
notfakie
2714cbcefd Merge remote-tracking branch 'overseerr/develop' into develop 2022-12-29 13:37:07 +13:00
Brandon Cohen
3309f77aa4 fix: added download status and title to request card/item error components (#3186) 2022-12-28 05:57:11 +00:00
Brandon Cohen
6face8cc45 fix: tooltip shows properly if not in progress (#3185) 2022-12-27 15:17:32 +00:00
Brandon Cohen
27feeea691 fix: changed overflow scroll to only if necessary (#3184) 2022-12-27 13:54:17 +09:00
Brandon Cohen
03853a1b91 feat(ui): request card progress bar (#3123) 2022-12-27 02:13:57 +00:00
Ryan Cohen
357cab87ac fix(experimental): use new RT API (sorta) (#3179) 2022-12-26 16:42:08 +09:00
Fallenbagel
d18e3d185f Merge pull request #277 from Fallenbagel/updatereadme
docs: update current features and add emphasis on the pre-requisites
2022-12-17 17:40:31 +05:00
Fallenbagel
e222463a63 docs: update current features and add emphasis on the pre-requisites [skip ci] 2022-12-17 06:02:06 +05:00
Fallenbagel
03b9bda287 Merge pull request #276 from Fallenbagel/fix-issue-#254
fix(ui): adds mediaServerName to statusBadge and manageSlideOver
2022-12-17 05:38:21 +05:00
Fallenbagel
7e20c7cb78 fix(locale): fix the duplicated wording in the Clear Media Warning message
Fixes the duplicated wording in the clear media warning message of manageSlideOver that was
introduced in previous commit
2022-12-17 05:10:11 +05:00
Fallenbagel
d0cdce9e90 fix(ui): adds mediaServerName to statusBadge and manageSlideOver
Adds mediaServerName to statusBadge and manageSlideOver to indicate the type of mediaServer that is
connected to jellyseerr

fix #254
2022-12-17 05:02:47 +05:00
Fallenbagel
113b09bf2b Merge pull request #275 from Fallenbagel/support-mixed-libraries
feat(api): adds support for Mixed Libraries
2022-12-17 04:27:46 +05:00
Fallenbagel
b16f192b92 Merge pull request #274 from Fallenbagel/pr269
Merge upstream "origin/develop"
2022-12-16 22:26:21 +05:00
Fallenbagel
d9ca3c6e52 fix(api): ignore Music,Books,Photos,MusicVideo libraries
Ignores libraries other than tvshows,movies,others
2022-12-16 20:19:03 +05:00
Fallenbagel
ba82ecec5c feat(api): adds support for Mixed Libraries
Adds support for mixed libraries with movies and show types

fix #95
2022-12-16 16:23:32 +05:00
Fallenbagel
c052a2455c Merge remote-tracking branch 'origin/develop' into pr269 2022-12-16 13:01:07 +05:00
Fallenbagel
2d99a8b03c fix character length of summary for snaps 2022-12-16 12:34:59 +05:00
Fallenbagel
7434c0cf2f fix formatting snapcraft 2022-12-16 12:22:22 +05:00
notfakie
afcb096f49 Merge remote-tracking branch 'overseerr/develop' into develop 2022-12-16 19:58:33 +13:00
Fallenbagel
9dc11cedbf Merge pull request #272 from Fallenbagel/prepare-snap-builds [skip ci]
Prepare snap builds [skip ci]
2022-12-16 03:01:31 +05:00
Fallenbagel
22aab783d4 Prepare snap builds [skip ci] 2022-12-16 02:41:05 +05:00
Fallenbagel
a2babb83ad Merge pull request #263 from darmiel/fix/combined-episodes
fix: count combined episodes
2022-12-06 17:35:02 +05:00
allcontributors[bot]
76a7ceb758 docs: add s0up4200 as a contributor for doc (#3153) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-12-06 12:49:19 +04:00
soup
9688acaa87 chore(docs): fix typo in fail2ban article (#3139) [skip ci] 2022-12-06 12:35:09 +04:00
darmiel
64339e5f03 fix: count combined episodes
Jellyfin allows combined episodes, like `S01E01-E02`,
but seasons containing such episodes are only recognized
as `Partially Available`. This commit should fix that.
2022-12-04 00:36:01 +01:00
Fallenbagel
1ceea3dcca Merge pull request #262 from Fallenbagel/change-cypress-projectid
test(cypress): change cypress projectId
2022-12-03 17:10:42 +05:00
Fallenbagel
e3c3283603 test(cypress): change cypress projectId
Change cypress projectId to jellyseerr's project id
2022-12-03 17:07:36 +05:00
Fallenbagel
4ac02d3aac docs(readme): fixed the formatting of README.md
Fixed the formatting of README.md that was causing issues with the formatting check workflow
2022-12-03 16:15:14 +05:00
Fallenbagel
8eacfe045f Add information about unsupported types
Added information about unsupported libraries and automatic grouping
2022-11-24 06:06:35 +05:00
Ryan Cohen
15e246929b fix(api): handle auth for accounts where the plex id may have been set to null (#3125)
also made some changes to hopefully alleviate this issue from happening at all in the future
2022-11-20 19:07:32 +09:00
Fallenbagel
c1424634fb fix the git clone url 2022-11-02 03:31:47 +05:00
Brandon Cohen
07ec3efbca fix: improved PTR scrolling performance (#3095) 2022-11-01 14:24:10 +09:00
Fallenbagel
9b07b10901 style(readme): fix formatting of README.md 2022-10-26 08:43:08 +05:00
Fallenbagel
b1e9cdbea2 add in minimum version needed for nodejs 2022-10-25 03:53:50 +05:00
Fallenbagel
9aee630392 update instructions to include steps for stable version 2022-10-25 03:47:08 +05:00
Fallenbagel
6b50f77624 update windows instructions
Replaced `yarn` with `npm` in the installation of `win-node-env`
2022-10-25 03:45:07 +05:00
Fallenbagel
16f1c286c4 Add detailed native installation instructions 2022-10-25 03:42:46 +05:00
TheCatLady
64aab6dd82 feat(lang): add Croatian display language (#3041) 2022-10-19 00:40:03 +00:00
allcontributors[bot]
144bb84bdc docs: add Eclipseop as a contributor for code (#3087) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-10-19 09:29:07 +09:00
Mackenzie
76260f9b22 build: update semantic-release to use proper arg for git sha (#3075) 2022-10-18 23:18:48 +00:00
Ryan Cohen
500cd1f872 feat: custom image proxy (#3056) 2022-10-18 14:40:24 +09:00
semantic-release-bot
9252817b58 chore(release): 1.2.1 2022-10-18 02:24:18 +00:00
Fallenbagel
a66925067d Merge pull request #242 from Fallenbagel/develop
Merge origin/develop
2022-10-18 07:21:19 +05:00
Fallenbagel
d037d178aa Merge pull request #240 from sambartik/revert-230-fix-jellyfin-emby-links
Fix jellyfin external url basepath being ignored
2022-10-16 04:24:25 +05:00
Fallenbagel
ab09664d41 fix(backend): fix jellyfinHost to not be undefined
Fix jellyfinHost so its not being treated as null or undefined

fix #237
2022-10-16 03:50:22 +05:00
Brandon Cohen
bfe56c3470 fix: added deep links to issues and status badges (#3065) 2022-10-15 05:39:33 +00:00
TheCatLady
1dfa9431a9 fix: update API docs to allow 'all' seasons value (#3073) 2022-10-15 08:31:50 +09:00
Samuel Bartík
0faae20bac Fix jellyfin external url basepath being ignored 2022-10-13 23:24:09 +02:00
Samuel Bartík
5b10da4073 Revert "fix(backend): fixes Jellyfin/Emby links if server is initially setup with a trailing /" 2022-10-13 23:08:20 +02:00
semantic-release-bot
6049edffca chore(release): 1.2.0 2022-10-12 13:34:54 +00:00
Fallenbagel
f27200c8c1 Merge pull request #235 from Fallenbagel/prepare-for-next-version
Merge origin/develop
2022-10-12 18:27:14 +05:00
Fallenbagel
613ebb95d2 Merge origin/develop 2022-10-12 00:15:50 +05:00
Fallenbagel
15c79e03a5 Merge pull request #234 from Fallenbagel/merge-upstream
Merge upstream develop
2022-10-12 00:07:57 +05:00
Fallenbagel
ed95b0af25 Merge upstream develop 2022-10-11 23:13:31 +05:00
Danshil Kokil Mungur
f5c2fc1c20 fix(ui): minor fixes (#3036)
* fix(ui): hide available media on person page

* fix(ui): set correct label for image cache settings

* fix(ui): disable status badge tooltip for collections

* fix(ui): replace empty space when no episodes in season

* fix: suggested changes

* fix(jobs): set watchlist sync to short interval

* chore: run i18n:extract

* fix: suggested changes
2022-10-04 12:03:24 +09:00
Fallenbagel
3ba69f9a74 Merge pull request #230 from Fallenbagel/fix-jellyfin-emby-links
fix(backend): fixes Jellyfin/Emby links if server is initially setup with a trailing /
2022-09-29 08:34:26 +05:00
dd060606
bcd2bb7c96 fix: lint issues 2022-09-28 15:55:56 +02:00
Fallenbagel
66357019f0 fix(backend): fixes Jellyfin/Emby links if server is initially setup with a trailing /
Fixes #168 and #220
2022-09-26 10:17:18 +05:00
Brandon Cohen
21d20fdfd6 fix: sidebar close button placement when using PWA (#3045) 2022-09-23 17:54:17 +09:00
JonnyWong16
cf96db90ad docs(proxy): update sub_filter for subfolder (#3046) [skip ci]
The updated `next.js` dependency has a new regex match in the code for `/^\/_next\/data\//`.

This `sub_filter` creates invalid regex `/^\/overseerr/_next\/data\//`
```nginx
    sub_filter '/_next' '/$app/_next';
```
It needs to be updated to substitute the correct the regex `/^\/overseerr\/_next\/data\//`
```nginx
    sub_filter '\/_next' '\/$app\/_next';
    sub_filter '/_next' '/$app/_next';
```
2022-09-22 18:16:08 +00:00
Ryan Cohen
430b1ab871 fix: remove backdrop-blur class from warning buttons (#3037) 2022-09-20 18:18:25 +09:00
Danshil Kokil Mungur
7404d68143 fix(ui): hide null dates in episodes list (#3035) 2022-09-19 16:11:16 +00:00
Weblate (bot)
16cb53f703 feat(lang): translations update from Hosted Weblate (#3026)
* feat(lang): translated using Weblate (Swedish)

Currently translated at 91.8% (1028 of 1119 strings)

Co-authored-by: Johan Ruda <johan.ruda@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hungarian)

Currently translated at 89.7% (1004 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
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 (Dutch)

Currently translated at 100.0% (1119 of 1119 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 (Croatian)

Currently translated at 23.3% (261 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Milo Ivir <mail@milotype.de>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Johan Ruda <johan.ruda@gmail.com>
Co-authored-by: Nandor Rusz <nandor.rusz@vodafone.de>
Co-authored-by: Kobe <kobaubarr@gmail.com>
Co-authored-by: Milo Ivir <mail@milotype.de>
2022-09-18 21:07:58 -07:00
Brandon Cohen
407af32d32 fix: new status indicators added to series list on mobile (#3024)
* fix: new status indicators added to series list

* refactor: component will render icons and has updated props
2022-09-17 14:52:51 +09:00
aedelbro
5c01313cc4 fix(ui): remove 'all' badge from request cards (#2992)
if all seasons are requested for a TV show, show each indivdual season badge. This prevents the
admin from needing to open a second tab / navigate to see how many seasons / what seasons have been
requested.
2022-09-16 21:27:45 +00:00
Ryan Cohen
d8da5cbe9d fix(plex): add container-size header to recently added api call (#3023) 2022-09-16 02:01:29 +00:00
dd060606
5a72f5f86e Merge branch 'develop' into features/deleteMediaFile 2022-09-14 14:58:37 +02:00
Weblate (bot)
3d458dd2fd feat(lang): translations update from Hosted Weblate (#3014)
* feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Maite Guix <maite.guix@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 95.6% (1070 of 1119 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 95.6% (1070 of 1119 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 92.3% (1033 of 1119 strings)

Co-authored-by: Eric <hamburger1024@mailbox.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Linyue-GitHub <592746995@qq.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1119 of 1119 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Croatian)

Currently translated at 23.3% (261 of 1119 strings)

feat(lang): translated using Weblate (Croatian)

Currently translated at 18.1% (203 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: lpispek <lpispek@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Maite Guix <maite.guix@gmail.com>
Co-authored-by: Eric <hamburger1024@mailbox.org>
Co-authored-by: Linyue-GitHub <592746995@qq.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: exentler <gurandsrud@gmail.com>
Co-authored-by: lpispek <lpispek@gmail.com>
2022-09-13 23:27:24 +00:00
Brandon Cohen
e486623310 fix: compatibility issue with safari (#3019) 2022-09-14 08:16:55 +09:00
Fallenbagel
e0f9a6e12f Merge pull request #219 from notfakie/develop
Remove failing ci job & update with upstream & fix play on button
2022-09-13 02:31:42 +05:00
notfakie
05139717d1 Merge remote-tracking branch 'overseerr/develop' into develop 2022-09-12 19:19:57 +12:00
renovate[bot]
f20ba3fc2e fix(deps): pin dependency cronstrue to 2.11.0 (#3018) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-12 13:11:21 +09:00
Danshil Kokil Mungur
30141f76e0 feat(logs): add search filter (#2505)
* feat(logs): add search filter

* refactor(logs): move loading spinner inside log viewer

Inputting text in the search bar on the logs page would refresh the page
losing focus on the search bar.
This moves the loading spinner inside the log viewer, so that it is not
as disruptive as it would

* fix(logs): escape string for search filter

* chore: rebase

* fix(logs): suggested changes
2022-09-12 02:21:16 +00:00
Brandon Cohen
87825a0e05 feat: pull down to refresh (#2908)
* feat: pull down to refresh functionality

Custom pull down to refresh added to replace the default browser pull down to refresh. This will
allow you to manually reload the page if you are using it as a PWA.

* test: update test to check api call correctly

changed api call for test and made sure it pulls down all the way to trigger refresh

* fix: changed positioning of pull to refresh

Refresh indicator now has absolute positioning and will prevent the top edge from pulling down.
2022-09-12 02:07:37 +00:00
Danshil Kokil Mungur
99fc9a2da0 feat(jobs): show current job frequency in edit modal (#3008)
* fix(jobs): reset job schedule edit modal values when closed

* feat(jobs): show job's current frequency

* fix(jobs): reset job schedule edit modal values when cancelled

* chore: rebase

* refactor(jobs): use reducer instead of several react states

* fix(jobs): reset modal state when opening instead of closing the modal

This prevents the modal state from glitching when saving/closing the modal

* feat(jobs): parse job schedule cron string

unavailable locale will fallback to english
2022-09-12 01:14:27 +00:00
notfakie
6dbb99e0b6 fix: only request Tautulli watch data for Plex media servers (to avoid error messages in logs) 2022-09-11 13:47:37 +12:00
notfakie
3b0c0915fb fix: fix play on Jellyfin/Emby button after previous merge 2022-09-11 13:32:13 +12:00
notfakie
5f7e7eef11 fix: remove failing ci job that builds a test copy to a private repo 2022-09-11 13:01:29 +12:00
notfakie
2dd3925e92 Merge remote-tracking branch 'overseerr/develop' into develop 2022-09-11 13:01:09 +12:00
Weblate (bot)
611ceeb5f4 feat(lang): translations update from Hosted Weblate (#3006)
* feat(lang): translated using Weblate (Albanian)

Currently translated at 95.0% (1063 of 1118 strings)

Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Czech)

Currently translated at 100.0% (1118 of 1118 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 94.3% (1055 of 1118 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 94.3% (1055 of 1118 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 88.5% (990 of 1118 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Pollyi <weblate.ntxx4@simplelogin.co>
Co-authored-by: Smexhy <smexhy@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Dutch)

Currently translated at 92.1% (1030 of 1118 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1118 of 1118 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Croatian)

Currently translated at 4.7% (53 of 1118 strings)

feat(lang): added translation using Weblate (Croatian)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: lpispek <lpispek@gmail.com>
Co-authored-by: sct <sctsnipe@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hr/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Pollyi <weblate.ntxx4@simplelogin.co>
Co-authored-by: Smexhy <smexhy@gmail.com>
Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: lpispek <lpispek@gmail.com>
Co-authored-by: sct <sctsnipe@gmail.com>
2022-09-10 14:59:40 -07:00
Fallenbagel
0636ff83a2 Merge pull request #218 from sambartik/merge-english-translations
refactor(en.json): merge translation keys from upstream overseerr
2022-09-08 20:08:39 +05:00
Samuel Bartík
aa005149be refactor(en.json): merge translation keys from upstream overseerr
Also fixes a cypress job error
2022-09-08 16:56:31 +02:00
Fallenbagel
13130188fc Merge pull request #217 from sambartik/fix-dependencies
fix(deps): do not list email-validator as a devDependency
2022-09-07 21:49:16 +05:00
Samuel Bartík
8724058aa5 fix(import statement): import statement 2022-09-07 18:05:59 +02:00
Samuel Bartík
94513425be style: fix formatting 2022-09-07 16:30:45 +02:00
Samuel Bartík
323086db09 refactor: automatic eslint fix 2022-09-07 15:45:08 +02:00
Samuel Bartík
9518cb3635 fix(deps): do not list email-validator as a devDependency
Because it was listed as a devDependency it got removed during a container build process causing module not found error.
2022-09-07 15:14:04 +02:00
Fallenbagel
b66f12a0e1 Merge pull request #216 from notfakie/develop
Merge remote-tracking branch 'overseerr/develop' into 'jellyseerr/develop'
2022-09-07 12:14:27 +05:00
notfakie
e9eba96f5a Merge remote-tracking branch 'overseerr/develop' into develop 2022-09-07 18:24:01 +12:00
Ryan Cohen
14280c5437 fix: scroll restoration (#3005) 2022-09-06 13:27:13 +09:00
Weblate (bot)
867286996b feat(lang): translations update from Hosted Weblate (#2999)
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Serbian)

Currently translated at 54.8% (613 of 1118 strings)

feat(lang): translated using Weblate (Serbian)

Currently translated at 54.8% (613 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: lpispek <lpispek@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1118 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1118 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 92.3% (1033 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Eric <hamburger1024@firemail.cc>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1118 of 1118 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1116 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1117 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (1118 of 1118 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (1119 of 1119 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: lpispek <lpispek@gmail.com>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: dtalens <databio@gmail.com>
Co-authored-by: Eric <hamburger1024@firemail.cc>
Co-authored-by: exentler <gurandsrud@gmail.com>
2022-09-03 10:27:16 -07:00
TheCatLady
03d5e56678 fix(ui): hide 'Recently Added' & 'Recent Requests' sliders when empty (#2190)
* fix(ui): hide 'Recently Added' & 'Recent Requests' sliders when empty

* fix(ui): hide 'errored' sliders too

* fix: type import

* fix: remove unneeded React import

* fix: missing TmdbTitleCard props

* refactor: remove isEmpty param for never-empty sliders

* fix: display empty watchlist message if autorequest enabled

* fix: pr suggestion

* fix(lang): remove no-longer-needed string
2022-08-30 23:51:55 +00:00
TheCatLady
410ad0d4b4 fix: failure to load SearchByNameModal (#3000) 2022-08-31 08:29:41 +09:00
TheCatLady
23f93e311d fix: do not display 'Request More' button if no requestable seasons (#2998) 2022-08-30 19:14:03 +09:00
Weblate (bot)
2950cf4438 feat(lang): translations update from Hosted Weblate (#2971)
* feat(lang): translated using Weblate (Greek)

Currently translated at 68.6% (768 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/el/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Japanese)

Currently translated at 58.3% (653 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ja/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Serbian)

Currently translated at 54.4% (609 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Albanian)

Currently translated at 92.0% (1030 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (French)

Currently translated at 99.1% (1110 of 1119 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.1% (1110 of 1119 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.1% (1110 of 1119 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.1% (1110 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1115 of 1115 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Spanish)

Currently translated at 85.7% (959 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Catalan)

Currently translated at 99.2% (1111 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1115 of 1115 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 92.8% (1035 of 1115 strings)

Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: dtalens <databio@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Czech)

Currently translated at 87.9% (984 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Polish)

Currently translated at 94.7% (1060 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Polish)

Currently translated at 95.5% (1065 of 1115 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Swedish)

Currently translated at 92.7% (1038 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Russian)

Currently translated at 86.9% (973 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ru/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Arabic)

Currently translated at 91.9% (1029 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ar/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Portugal))

Currently translated at 72.0% (806 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Danish)

Currently translated at 91.5% (1025 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 92.4% (1034 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 93.1% (1039 of 1115 strings)

Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hungarian)

Currently translated at 87.9% (984 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Dutch)

Currently translated at 92.1% (1031 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 98.8% (1106 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (1111 of 1115 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 96.0% (1071 of 1115 strings)

Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Italian)

Currently translated at 92.9% (1040 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Italian)

Currently translated at 96.2% (1044 of 1085 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Simone <simoneungaro@hotmail.it>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1117 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1113 of 1115 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.0% (1104 of 1115 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1086 of 1088 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 95.3% (1067 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 99.9% (1118 of 1119 strings)

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 95.8% (1073 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 96.5% (1076 of 1115 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Lithuanian)

Currently translated at 47.9% (537 of 1119 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/lt/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Cleiton Carvalho <cleitonsilvacarvalho@gmail.com>
Co-authored-by: dtalens <databio@gmail.com>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Simone <simoneungaro@hotmail.it>
Co-authored-by: exentler <gurandsrud@gmail.com>
2022-08-29 16:54:33 -07:00
TheCatLady
dbdecb1e0a fix(frontend): only allow 'request as' users w/ request perms (#2991) 2022-08-29 10:33:17 +00:00
renovate[bot]
833f52de56 fix(deps): pin dependency @headlessui/react to v0.0.0-insiders.b301f04 (#2993) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-29 19:22:24 +09:00
Ryan Cohen
889caaa733 refactor: modal redesign and fix for transitions (#2987) 2022-08-29 14:56:04 +09:00
Brandon Cohen
4d56320870 fix: settings log modal when closing (#2985) 2022-08-26 21:38:13 +09:00
Ryan Cohen
1a0053221b fix: clicking outside modal closes modal again (#2984) 2022-08-25 13:28:44 +09:00
Brandon Cohen
b925857dfa fix: username will not show undefined on cancel or delete (#2982) 2022-08-25 01:45:05 +00:00
Ryan Cohen
c4aa08f5f0 fix: correct spacing on season header badges (#2983) 2022-08-25 10:14:16 +09:00
TheCatLady
5d73bc2238 fix: check perms to view watchlist slider on user profile (#2980) 2022-08-25 02:43:25 +04:00
Brandon Cohen
095048d94a fix: issues and login page still had incorrect animations (#2979)
Issues dropdown and the login page transition including the language picker were set as fragments
2022-08-24 13:10:57 -07:00
Brandon Cohen
98028bf2f4 fix: transition animation (#2974)
switched to using headlessui transition instead of react-css-transition due to new version breaking the
animation
2022-08-24 10:18:09 -07:00
renovate[bot]
baf1ea95a3 fix(deps): pin dependency @formatjs/intl-utils to 3.8.4 (#2975) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-24 21:47:39 +09:00
Ryan Cohen
23409e6f2f fix: correct safe margin for slideover (#2977) 2022-08-24 20:57:30 +09:00
TheCatLady
dd28200040 fix: watch data not required to show Tautulli button (#2976) 2022-08-24 15:26:25 +09:00
Ryan Cohen
22360f3b87 refactor: slideover redesign (#2973) 2022-08-24 15:00:04 +09:00
TheCatLady
815d709bcf feat(frontend): a few more tooltips (#2972)
* feat(frontend): a few more tooltips

* feat: add tooltips to status badges
2022-08-24 13:59:26 +09:00
Ryan Cohen
8a2acb7f2b feat: season/episode list on series details (#2967) 2022-08-24 04:09:10 +00:00
Ryan Cohen
67f3a3829e feat: improved user dropdown (#2969) 2022-08-24 01:49:25 +00:00
renovate[bot]
f5e5016ca5 chore(deps): update github actions (major) (#2947)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
2022-08-23 18:32:49 -04:00
Ryan Cohen
6e60a275c7 fix: use fallbackData to prepare user data during SSR (#2968) 2022-08-23 17:36:02 +09:00
Ryan Cohen
3b2633812b fix: use image.tmdb.org for setup/login backdrop images (#2966) 2022-08-23 14:25:20 +09:00
Ryan Cohen
507227aa49 feat: restore option to cache and optimize images locally (#2964) 2022-08-23 01:46:52 +09:00
Weblate (bot)
29ab178fb0 feat(lang): translations update from Hosted Weblate (#2958)
* feat(lang): translated using Weblate (French)

Currently translated at 99.4% (1067 of 1073 strings)

feat(lang): translated using Weblate (French)

Currently translated at 97.1% (1040 of 1071 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (1063 of 1071 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.8% (1083 of 1085 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.6% (1081 of 1085 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1073 of 1073 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.4% (1067 of 1073 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.5% (1066 of 1071 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1073 of 1073 strings)

feat(lang): translated using Weblate (German)

Currently translated at 100.0% (1073 of 1073 strings)

feat(lang): translated using Weblate (German)

Currently translated at 99.6% (1067 of 1071 strings)

Co-authored-by: Ben <ben.david.wallner@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: Mathieu <math_du_88@yahoo.fr>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Ben <ben.david.wallner@gmail.com>
2022-08-22 08:17:31 -07:00
TheCatLady
f5e6b620c1 fix(lang): manage movie -> manage series (#2963) 2022-08-22 06:05:10 +00:00
TheCatLady
0839718806 feat: view other users' watchlists (#2959)
* feat: view other users' watchlists

* test: add cypress tests

* feat(lang): translation keys

* refactor: yarn format

* fix: manage requests perm is parent of view watchlist perm
2022-08-22 05:50:27 +00:00
TheCatLady
950b1712b7 feat(frontend): add more tooltips (#2961)
* feat(frontend): add more tooltips

* fix: remove styling from Tooltip

* refactor: tooltip expects a single child
2022-08-22 14:37:22 +09:00
renovate[bot]
43a9067976 chore(deps): pin dependencies (#2962) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-22 13:36:51 +09:00
Ryan Cohen
c6a133d4e5 refactor: absolute imports with path alias (#2960) [skip ci] 2022-08-22 11:02:46 +09:00
Ryan Cohen
4b855b8114 style: fix organize-imports to work with tailwindcss prettier plugin (#2957) [skip ci] 2022-08-21 10:40:12 +00:00
TheCatLady
6c0fd40877 feat(notif): auto-request notif type (#2956) 2022-08-21 10:26:19 +00:00
Ryan Cohen
301f2bf7ab feat: plex watchlist sync integration (#2885) 2022-08-21 16:33:49 +09:00
allcontributors[bot]
7943e0c339 docs: add miknii as a contributor for translation (#2955) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-21 01:25:12 +00:00
allcontributors[bot]
6ce0aa5b10 docs: add byakurau as a contributor for translation (#2954) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-21 01:14:50 +00:00
Weblate (bot)
a0301e2d83 feat(lang): translations update from Hosted Weblate (#2915)
* feat(lang): translated using Weblate (Greek)

Currently translated at 74.1% (775 of 1045 strings)

feat(lang): translated using Weblate (Greek)

Currently translated at 74.0% (774 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/el/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Japanese)

Currently translated at 62.9% (658 of 1045 strings)

feat(lang): translated using Weblate (Japanese)

Currently translated at 62.9% (658 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ja/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Albanian)

Currently translated at 99.2% (1037 of 1045 strings)

feat(lang): translated using Weblate (Albanian)

Currently translated at 99.1% (1036 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (French)

Currently translated at 99.2% (1037 of 1045 strings)

feat(lang): translated using Weblate (French)

Currently translated at 99.1% (1036 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Spanish)

Currently translated at 92.4% (966 of 1045 strings)

feat(lang): translated using Weblate (Spanish)

Currently translated at 92.3% (965 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/es/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Catalan)

Currently translated at 99.3% (1038 of 1045 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 99.2% (1037 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Czech)

Currently translated at 94.6% (989 of 1045 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 94.5% (988 of 1045 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Polish)

Currently translated at 100.0% (1048 of 1048 strings)

feat(lang): translated using Weblate (Polish)

Currently translated at 100.0% (1045 of 1045 strings)

feat(lang): translated using Weblate (Polish)

Currently translated at 99.2% (1037 of 1045 strings)

feat(lang): translated using Weblate (Polish)

Currently translated at 99.1% (1036 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1045 of 1045 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 99.9% (1044 of 1045 strings)

feat(lang): translated using Weblate (Swedish)

Currently translated at 99.2% (1037 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Mikael Nilsson <mikni@proton.me>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Russian)

Currently translated at 93.7% (980 of 1045 strings)

feat(lang): translated using Weblate (Russian)

Currently translated at 93.6% (979 of 1045 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ru/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Portugal))

Currently translated at 77.7% (813 of 1045 strings)

feat(lang): translated using Weblate (Portuguese (Portugal))

Currently translated at 77.7% (812 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Danish)

Currently translated at 98.7% (1032 of 1045 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 98.6% (1031 of 1045 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 98.2% (1039 of 1058 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 98.1% (1038 of 1058 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.3% (1038 of 1045 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 99.3% (1038 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Hungarian)

Currently translated at 94.8% (991 of 1045 strings)

feat(lang): translated using Weblate (Hungarian)

Currently translated at 94.7% (990 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Dutch)

Currently translated at 99.3% (1038 of 1045 strings)

feat(lang): translated using Weblate (Dutch)

Currently translated at 99.2% (1037 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1058 of 1058 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1058 of 1058 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1050 of 1050 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (1047 of 1048 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1045 of 1045 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Italian)

Currently translated at 99.3% (1038 of 1045 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 99.2% (1037 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1058 of 1058 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1058 of 1058 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1050 of 1050 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1048 of 1048 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1045 of 1045 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (German)

Currently translated at 99.1% (1036 of 1045 strings)

feat(lang): translated using Weblate (German)

Currently translated at 99.0% (1035 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 98.9% (1047 of 1058 strings)

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 97.9% (1036 of 1058 strings)

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 99.3% (1038 of 1045 strings)

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 99.2% (1037 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Patryk <byakurau1@gmail.com>
Co-authored-by: Mikael Nilsson <mikni@proton.me>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Co-authored-by: exentler <gurandsrud@gmail.com>
2022-08-20 16:47:15 -04:00
TheCatLady
9021696cf0 fix(lang): correct capitalization of 'TMDB' (#2953) 2022-08-20 12:23:16 +09:00
TheCatLady
9bc1f89777 fix(frontend): better request/media cards for items without valid TMDb IDs (#2181) 2022-08-20 11:21:53 +09:00
TheCatLady
a12697b061 feat(perms): add new permission for viewing recently added media (#2129)
* feat(perms): add new permission for viewing recently added media

* test: update login test to check for Trending instead of Recently Added

* fix: avoid conflict with new watchlist perms
2022-08-19 20:32:24 +00:00
renovate[bot]
5247f14968 fix(deps): pin dependency react-popper-tooltip to 4.4.2 (#2952) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-19 21:19:14 +09:00
Danshil Kokil Mungur
fd0ff4bd5f chore: remove empty lines from imports section (#2951) [skip ci] 2022-08-19 10:59:27 +00:00
Ryan Cohen
16545eec22 feat: tooltip foundation (#2950)
* feat: add foundation for tooltips

* fix: add lang

* refactor: remove React import where no longer necessary
2022-08-19 19:35:50 +09:00
Brandon Cohen
36d17fed6e feat: user delete modal shows username and requires confirmation (#2779)
The delete user modal will now show the user that is being deleted and the delete button will now
ask you to confirm deletion similar to the delete request button.
2022-08-19 10:21:29 +00:00
TheCatLady
ac34328074 ci: don't lint/test in snap publish workflow (#2948) [skip ci] 2022-08-19 14:38:11 +09:00
Danshil Kokil Mungur
91e0928aa0 feat(ui): revalidate requests slider on discover page (#2818) 2022-08-18 17:07:23 +00:00
renovate[bot]
f836cadd23 chore(deps): update node.js to v16.17 (#2941)
* chore(deps): update node.js to v16.17

* chore(deps): also bump node.js in snapcraft.yaml

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
2022-08-18 20:44:18 +09:00
Ryan Cohen
f4910a1483 build(snap): re-enable snap workflow (#2945)
* build(snap): try re-enabling snap workflow

* build: try adding a safe directory exception?

* build(snap): disable cypress binary install

* build(snap): add yarnrc to force frozen lockfile and timeout arguments

* build(snap): add back in release snap workflow

* build(snap): revert back to only running on dev branch
2022-08-18 19:16:24 +09:00
renovate[bot]
103c4ca49c fix(deps): pin dependencies (#2946) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-18 18:38:52 +09:00
TheCatLady
c143c0b8d2 fix: better ordering of RequestButton options & properly handle failed requests (#2944)
* fix: better ordering of RequestButton options & properly handle failed requests

* fix: appease prettier
2022-08-18 08:30:40 +00:00
Ryan Cohen
e5d8c93ab8 chore(deps): update react to 18 (#2943) 2022-08-18 17:05:58 +09:00
Ryan Cohen
72d7a3477f chore(deps): update dependencies (#2942) 2022-08-18 13:49:07 +09:00
TheCatLady
808fabba9a chore(deps): update renovate config to group node container deps (#2939) [skip ci] 2022-08-18 11:54:08 +09:00
Ryan Cohen
7a5fab35ff build(snap): add architectures to snapcraft.yaml (#2938) [skip ci] 2022-08-18 10:57:40 +09:00
renovate[bot]
17ac5069e5 chore(deps): update github-actions (#2933) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-17 15:04:19 -04:00
renovate[bot]
cfab63c0ca chore(deps): pin dependencies (#2925) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-17 11:52:16 +00:00
Danshil Kokil Mungur
0fa84eae8d build(deps): bump dependencies (#2796) 2022-08-17 20:43:35 +09:00
renovate[bot]
821bb79d83 chore(deps): configure renovate [skip ci]
* chore(deps): add renovate.json

* chore(deps): update renovate.json to add grouping

* chore(deps): update renovate.json to disable major docker updates

* chore(deps): remove dependabot config

* chore(deps): bundle github-action updates

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: sct <ryan@sct.dev>
Co-authored-by: Ryan Cohen <r-cohen@mercari.com>
2022-08-17 18:04:16 +09:00
TheCatLady
233035dbd7 build(docker): downgrade to node 16.16 (#2921) 2022-08-17 13:10:11 +09:00
TheCatLady
114943ae2c build(docker): skip cypress install & bump node version (#2920) 2022-08-17 12:46:03 +09:00
TheCatLady
a6f7b19693 chore(vscode): remove deprecated npm extension from recommendations (#2919) [skip ci] 2022-08-17 09:16:47 +09:00
TheCatLady
3db3044210 feat(lang): add Arabic and Lithuanian display languages (#2916) 2022-08-17 09:15:30 +09:00
allcontributors[bot]
1fcfe93b58 docs: add PovilasID as a contributor for translation (#2918) [skip ci]
* docs: update README.md

* docs: update .all-contributorsrc

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-16 22:12:47 +00:00
allcontributors[bot]
6cb456cb69 docs: add Fhd-pro as a contributor for translation (#2917) [skip ci]
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-16 22:06:08 +00:00
Weblate (bot)
e939dc678e feat(lang): translations update from Hosted Weblate (#2659)
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Japanese)

Currently translated at 63.2% (660 of 1043 strings)

feat(lang): translated using Weblate (Japanese)

Currently translated at 62.4% (651 of 1043 strings)

feat(lang): translated using Weblate (Japanese)

Currently translated at 61.7% (644 of 1043 strings)

feat(lang): translated using Weblate (Japanese)

Currently translated at 50.3% (525 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: T'ai <chivalrousjosh@gmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ja/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Serbian)

Currently translated at 58.8% (614 of 1043 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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sr/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Albanian)

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sq/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (French)

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Rémi Guerrero <remidu34070@hotmail.fr>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/fr/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Romanian)

Currently translated at 3.6% (38 of 1042 strings)

feat(lang): translated using Weblate (Romanian)

Currently translated at 0.8% (9 of 1042 strings)

feat(lang): added translation using Weblate (Romanian)

Co-authored-by: Constantin <bimasakti.ro@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/ro/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Catalan)

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Maite Guix <maite.guix@gmail.com>
Co-authored-by: dtalens <databio@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ca/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Czech)

Currently translated at 95.3% (994 of 1043 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 91.4% (954 of 1043 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 91.4% (954 of 1043 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 91.3% (953 of 1043 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 91.3% (953 of 1043 strings)

feat(lang): translated using Weblate (Czech)

Currently translated at 50.3% (525 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Pollyi <weblate.ntxx4@simplelogin.co>
Co-authored-by: Smexhy <smexhy@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/cs/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Danish)

Currently translated at 99.5% (1037 of 1042 strings)

feat(lang): translated using Weblate (Danish)

Currently translated at 97.6% (1018 of 1042 strings)

Co-authored-by: Daniel Maslygan <danielmaslygan@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/da/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Swedish)

Currently translated at 100.0% (1043 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/sv/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Miniers <m@lk.mk>
Co-authored-by: yzqzss <yzqzss@othing.xyz>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hans/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 100.0% (1042 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 75.6% (788 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 62.7% (654 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 54.6% (569 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 52.9% (552 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 49.6% (517 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 47.0% (490 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 42.5% (443 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 38.1% (398 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 36.8% (384 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 32.7% (341 of 1042 strings)

feat(lang): translated using Weblate (Arabic)

Currently translated at 0.1% (1 of 1042 strings)

feat(lang): added translation using Weblate (Arabic)

Co-authored-by: Fhd-pro <juve.11@msn.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: sct <sctsnipe@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/ar/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Hungarian)

Currently translated at 95.3% (995 of 1043 strings)

feat(lang): translated using Weblate (Hungarian)

Currently translated at 88.3% (921 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Sir Hóksalot <haaax2000@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/hu/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Dutch)

Currently translated at 100.0% (1043 of 1043 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/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 99.6% (1041 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (1043 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Italian)

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Italian)

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Simone <simoneungaro@hotmail.it>
Co-authored-by: Simone Chiavaccini <mazzetta86@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/it/
Translation: Overseerr/Overseerr Frontend

* feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1045 of 1045 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 99.9% (1044 of 1045 strings)

Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1043 of 1043 strings)

feat(lang): translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (1042 of 1042 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: 주서현 <adan.89lion@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/zh_Hant/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (German)

Currently translated at 99.8% (1041 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Samuel Nitzsche <samuel.nitzsche+github@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (1043 of 1043 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: exentler <gurandsrud@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nb_NO/
Translation: Overseerr/Overseerr Frontend

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 52.2% (545 of 1043 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 43.8% (457 of 1043 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 31.8% (332 of 1043 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 28.2% (295 of 1043 strings)

feat(lang): translated using Weblate (Lithuanian)

Currently translated at 25.7% (269 of 1043 strings)

feat(lang): added translation using Weblate (Lithuanian)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: PovilasID <povilas.sidaravicius@gmail.com>
Co-authored-by: sct <sctsnipe@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/lt/
Translation: Overseerr/Overseerr Frontend

* feat(lang): added translation using Weblate (Hindi)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: sct <sctsnipe@gmail.com>

* feat(lang): translated using Weblate (Hebrew)

Currently translated at 0.2% (3 of 1043 strings)

feat(lang): translated using Weblate (Hebrew)

Currently translated at 0.1% (2 of 1043 strings)

feat(lang): added translation using Weblate (Hebrew)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: sct <sctsnipe@gmail.com>
Co-authored-by: tallevi1000 <tal_levi1000@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/he/
Translation: Overseerr/Overseerr Frontend

Co-authored-by: T'ai <chivalrousjosh@gmail.com>
Co-authored-by: TheCatLady <o40yoym9@anonaddy.me>
Co-authored-by: Milan Smudja <smudja@gmail.com>
Co-authored-by: Denis Çerri <deniscerri3@gmail.com>
Co-authored-by: Rémi Guerrero <remidu34070@hotmail.fr>
Co-authored-by: Constantin <bimasakti.ro@gmail.com>
Co-authored-by: sct <sctsnipe@gmail.com>
Co-authored-by: Maite Guix <maite.guix@gmail.com>
Co-authored-by: dtalens <databio@gmail.com>
Co-authored-by: Pollyi <weblate.ntxx4@simplelogin.co>
Co-authored-by: Smexhy <smexhy@gmail.com>
Co-authored-by: Daniel Maslygan <danielmaslygan@gmail.com>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Co-authored-by: Eric <alchemillatruth@purelymail.com>
Co-authored-by: Miniers <m@lk.mk>
Co-authored-by: yzqzss <yzqzss@othing.xyz>
Co-authored-by: Fhd-pro <juve.11@msn.com>
Co-authored-by: Sir Hóksalot <haaax2000@gmail.com>
Co-authored-by: Kobe <kobaubarr@gmail.com>
Co-authored-by: Tijuco <sendtomy@protonmail.com>
Co-authored-by: Simone <simoneungaro@hotmail.it>
Co-authored-by: Simone Chiavaccini <mazzetta86@gmail.com>
Co-authored-by: 주서현 <adan.89lion@gmail.com>
Co-authored-by: Samuel Nitzsche <samuel.nitzsche+github@gmail.com>
Co-authored-by: exentler <gurandsrud@gmail.com>
Co-authored-by: PovilasID <povilas.sidaravicius@gmail.com>
Co-authored-by: tallevi1000 <tal_levi1000@hotmail.com>
2022-08-16 17:28:12 -04:00
TheCatLady
f3e56da3b7 feat: show alert/prompt when settings changes require restart (#2401)
* fix: correct 'StatusChecker' typo

* feat: add restart required check to StatusChecker

* fix(perms): remove MANAGE_SETTINGS permission

* fix: allow alert to be dismissed

* fix(lang): add missing string in SettingsServices

* fix(frontend): fix modal icon border

* fix(frontend): un-dismiss alert if setting reverted not require server restart

* fix(backend): restart flag only needs to track main settings

* fix: rebase issue

* refactor: appease Prettier

* refactor: swap settings badge order

* fix: type import for MainSettings

* test: add cypress test for restart prompt
2022-08-16 16:58:11 +00:00
allcontributors[bot]
70dc4c4b3b docs: add Gylesie as a contributor for code (#2912) [skip ci]
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-16 16:39:35 +00:00
TheCatLady
6428b8d419 fix: log level value should not be case sensitive (#2913) 2022-08-17 01:33:13 +09:00
Gylesie
004e1bb17e fix(api): lookup shows using english title only (#2911)
Fixes most of the time irrelevant lookup list when using localized TMDB metadata. #2801
2022-08-16 11:56:46 -04:00
Ryan Cohen
ebd22ffcea test: add waits in user test (#2907) [skip ci] 2022-08-15 19:50:42 +09:00
Ryan Cohen
22ec058431 test: add cypress foundation (#2903) [skip ci] 2022-08-15 08:34:38 +09:00
dd060606
7d4455ba6b fix: hide remove button when default service is not configured 2022-08-14 12:07:12 +02:00
allcontributors[bot]
db898db9f2 docs: add TheMeanCanEHdian as a contributor for code (#2889) [skip ci]
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-04 16:05:30 +09:00
TheMeanCanEHdian
b33956e6b8 feat: add 20th Century Studios to Studio Slider (#2288)
* Add 20th Century Studios to Studio Sliders

* Remove 20th Century Fox from Studio Sliders

Co-authored-by: TheCatLady <52870424+TheCatLady@users.noreply.github.com>
Co-authored-by: Ryan Cohen <ryan@sct.dev>
2022-08-03 04:13:21 +00:00
Ryan Cohen
f5864b49de refactor: update a few dev deps and convert to using type imports where possible (#2886)
* build: bump deps and add some new eslint rules

* refactor: run eslint --fix on code to convert to type imports where possible
2022-08-03 12:57:51 +09:00
allcontributors[bot]
25eb765f9b docs: add frank-cywong as a contributor for code (#2884) [skip ci]
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-08-03 10:26:02 +09:00
Chun Yeung Wong
9da8461225 fix: update Discord ID regex to include 19 digit IDs (#2860) 2022-08-03 10:24:57 +09:00
Ryan Cohen
aed1409f29 fix(api): add rate limiter to TMDb requests to hopefully deal with 429s (#2881)
fixes #2853
2022-08-02 16:00:34 +09:00
Brandon Cohen
575da306b0 feat: plex deep links for iOS devices (#2680) 2022-08-02 06:41:09 +00:00
Fallenbagel
f4c38fa81f Merge pull request #188 from seanzhang98/develop
Update the translations on zh_Hans.json
2022-07-30 01:52:50 +05:00
Sean
a3b620efb3 Update zh_Hans.json 2022-07-25 14:37:31 +08:00
Sean
054da8e456 Update zh_Hans.json
sync en.json and added translation
2022-07-25 14:32:48 +08:00
Danshil Kokil Mungur
6cd0c9b2c8 fix(api): use correct path param type in openapi spec (#2834) 2022-07-22 15:00:59 -04:00
dd060606
2e7458457e feat: add a button in ManageSlideOver to remove the movie and the file from Radarr/Sonarr 2022-07-22 17:58:33 +02:00
Fallenbagel
b67844a0ee Merge pull request #185 from notfakie/develop
fix: start scheduled jobs on initial admin account setup
2022-07-15 00:16:46 +05:00
notfakie
b08025195e fix: start scheduled jobs on initial admin account setup
issue #170
2022-07-11 17:29:17 +12:00
Fallenbagel
a5cc36c88f Merge pull request #150 from Smexhy/czech-language
feat(language): update czech language
2022-06-24 05:30:57 +05:00
Smexhy
c744e2a9b6 apply review suggestions 2022-06-22 23:59:41 +02:00
Fallenbagel
4a34574a23 Merge pull request #161 from Fallenbagel/Readme-formatting-fix
Readme formatting fix
2022-06-20 23:48:09 +05:00
Fallenbagel
38fc150892 Readme-formatting-fix 2022-06-20 23:47:32 +05:00
Fallenbagel
6e2cf2f80e Merge pull request #148 from Fallenbagel/README-update
docs(readme): added information about upcoming/unique features
2022-06-20 23:46:49 +05:00
Fallenbagel
4ccc956c35 Fixed formatting 2022-06-20 23:45:55 +05:00
Fallenbagel
5af3a7e71b Add in much needed information
upcoming feature explanation and the reason for fork
2022-06-20 22:07:49 +05:00
Smexhy
8619724c65 feat(language): update czech language 2022-06-19 21:03:27 +02:00
Fallenbagel
304b82b594 docs(readme): added information about upcoming/unique features
added information about upcoming/unique features
2022-06-19 23:34:01 +05:00
Danshil Kokil Mungur
a6c1f3f7ce fix(api): ignore filter if unset in media route (#2647)
Co-authored-by: Ryan Cohen <ryan@sct.dev>
2022-05-28 12:48:23 +00:00
allcontributors[bot]
eb5248d8d1 docs: add sambartik as a contributor for code (#2783)
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2022-05-28 19:13:54 +09:00
551 changed files with 39895 additions and 13373 deletions

View File

@@ -4,674 +4,324 @@
],
"imageSize": 100,
"commit": false,
"contributors": [
{
"login": "sct",
"name": "sct",
"avatar_url": "https://avatars1.githubusercontent.com/u/234213?v=4",
"profile": "https://sct.dev",
"contributions": [
"code",
"design",
"ideas"
]
},
{
"login": "azoitos",
"name": "Alex Zoitos",
"avatar_url": "https://avatars2.githubusercontent.com/u/26529049?v=4",
"profile": "https://github.com/azoitos",
"contributions": [
"code"
]
},
{
"login": "OwsleyJr",
"name": "Brandon Cohen",
"avatar_url": "https://avatars3.githubusercontent.com/u/8635678?v=4",
"profile": "https://github.com/OwsleyJr",
"contributions": [
"code",
"doc"
]
},
{
"login": "Ahreluth",
"name": "Ahreluth",
"avatar_url": "https://avatars2.githubusercontent.com/u/75682440?v=4",
"profile": "https://github.com/Ahreluth",
"contributions": [
"translation"
]
},
{
"login": "KovalevArtem",
"name": "KovalevArtem",
"avatar_url": "https://avatars0.githubusercontent.com/u/36500228?v=4",
"profile": "https://github.com/KovalevArtem",
"contributions": [
"translation"
]
},
{
"login": "GiyomuWeb",
"name": "GiyomuWeb",
"avatar_url": "https://avatars0.githubusercontent.com/u/62489209?v=4",
"profile": "https://github.com/GiyomuWeb",
"contributions": [
"translation"
]
},
{
"login": "angrycuban13",
"name": "Angry Cuban",
"avatar_url": "https://avatars3.githubusercontent.com/u/39564898?v=4",
"profile": "https://github.com/angrycuban13",
"contributions": [
"doc"
]
},
{
"login": "jvennik",
"name": "jvennik",
"avatar_url": "https://avatars3.githubusercontent.com/u/6672637?v=4",
"profile": "https://github.com/jvennik",
"contributions": [
"translation"
]
},
{
"login": "darknessgp",
"name": "darknessgp",
"avatar_url": "https://avatars0.githubusercontent.com/u/1521243?v=4",
"profile": "https://github.com/darknessgp",
"contributions": [
"code"
]
},
{
"login": "saltydk",
"name": "salty",
"avatar_url": "https://avatars1.githubusercontent.com/u/6587950?v=4",
"profile": "https://github.com/saltydk",
"contributions": [
"infra"
]
},
{
"login": "Shutruk",
"name": "Shutruk",
"avatar_url": "https://avatars2.githubusercontent.com/u/9198633?v=4",
"profile": "https://github.com/Shutruk",
"contributions": [
"translation"
]
},
{
"login": "krystiancharubin",
"name": "Krystian Charubin",
"avatar_url": "https://avatars2.githubusercontent.com/u/17775600?v=4",
"profile": "https://github.com/krystiancharubin",
"contributions": [
"design"
]
},
{
"login": "kieron",
"name": "Kieron Boswell",
"avatar_url": "https://avatars2.githubusercontent.com/u/8655212?v=4",
"profile": "https://github.com/kieron",
"contributions": [
"code"
]
},
{
"login": "samwiseg0",
"name": "samwiseg0",
"avatar_url": "https://avatars1.githubusercontent.com/u/2241731?v=4",
"profile": "https://github.com/samwiseg0",
"contributions": [
"question",
"infra"
]
},
{
"login": "ecelebi29",
"name": "ecelebi29",
"avatar_url": "https://avatars2.githubusercontent.com/u/8337120?v=4",
"profile": "https://github.com/ecelebi29",
"contributions": [
"code",
"doc"
]
},
{
"login": "mmozeiko",
"name": "Mārtiņš Možeiko",
"avatar_url": "https://avatars3.githubusercontent.com/u/1665010?v=4",
"profile": "https://github.com/mmozeiko",
"contributions": [
"code"
]
},
{
"login": "mazzetta86",
"name": "mazzetta86",
"avatar_url": "https://avatars2.githubusercontent.com/u/45591560?v=4",
"profile": "https://github.com/mazzetta86",
"contributions": [
"translation"
]
},
{
"login": "Panzer1119",
"name": "Paul Hagedorn",
"avatar_url": "https://avatars1.githubusercontent.com/u/23016343?v=4",
"profile": "https://github.com/Panzer1119",
"contributions": [
"translation"
]
},
{
"login": "Shagon94",
"name": "Shagon94",
"avatar_url": "https://avatars3.githubusercontent.com/u/9140783?v=4",
"profile": "https://github.com/Shagon94",
"contributions": [
"translation"
]
},
{
"login": "sebstrgg",
"name": "sebstrgg",
"avatar_url": "https://avatars3.githubusercontent.com/u/27026694?v=4",
"profile": "https://github.com/sebstrgg",
"contributions": [
"translation"
]
},
{
"login": "danshilm",
"name": "Danshil Mungur",
"avatar_url": "https://avatars2.githubusercontent.com/u/20923978?v=4",
"profile": "https://github.com/danshilm",
"contributions": [
"code",
"doc"
]
},
{
"login": "doob187",
"name": "doob187",
"avatar_url": "https://avatars1.githubusercontent.com/u/60312740?v=4",
"profile": "https://github.com/doob187",
"contributions": [
"infra"
]
},
{
"login": "johnpyp",
"name": "johnpyp",
"avatar_url": "https://avatars2.githubusercontent.com/u/20625636?v=4",
"profile": "https://github.com/johnpyp",
"contributions": [
"code"
]
},
{
"login": "ankarhem",
"name": "Jakob Ankarhem",
"avatar_url": "https://avatars1.githubusercontent.com/u/14110063?v=4",
"profile": "https://github.com/ankarhem",
"contributions": [
"doc",
"code",
"translation"
]
},
{
"login": "jayesh100",
"name": "Jayesh",
"avatar_url": "https://avatars1.githubusercontent.com/u/8022175?v=4",
"profile": "https://github.com/jayesh100",
"contributions": [
"code"
]
},
{
"login": "flying-sausages",
"name": "flying-sausages",
"avatar_url": "https://avatars1.githubusercontent.com/u/23618693?v=4",
"profile": "https://github.com/flying-sausages",
"contributions": [
"doc"
]
},
{
"login": "hirenshah",
"name": "hirenshah",
"avatar_url": "https://avatars2.githubusercontent.com/u/418112?v=4",
"profile": "https://github.com/hirenshah",
"contributions": [
"doc"
]
},
{
"login": "TheCatLady",
"name": "TheCatLady",
"avatar_url": "https://avatars0.githubusercontent.com/u/52870424?v=4",
"profile": "https://github.com/TheCatLady",
"contributions": [
"code",
"translation",
"doc"
]
},
{
"login": "chriscpritchard",
"name": "Chris Pritchard",
"avatar_url": "https://avatars1.githubusercontent.com/u/1839074?v=4",
"profile": "https://github.com/chriscpritchard",
"contributions": [
"code",
"doc"
]
},
{
"login": "Tamberlox",
"name": "Tamberlox",
"avatar_url": "https://avatars3.githubusercontent.com/u/56069014?v=4",
"profile": "https://github.com/Tamberlox",
"contributions": [
"translation"
]
},
{
"login": "hmnd",
"name": "David",
"avatar_url": "https://avatars.githubusercontent.com/u/12853597?v=4",
"profile": "https://hmnd.io",
"contributions": [
"code"
]
},
{
"login": "douglasparker",
"name": "Douglas Parker",
"avatar_url": "https://avatars.githubusercontent.com/u/18235822?v=4",
"profile": "https://www.douglas-parker.com",
"contributions": [
"doc"
]
},
{
"login": "dancarter",
"name": "Daniel Carter",
"avatar_url": "https://avatars.githubusercontent.com/u/4387516?v=4",
"profile": "https://github.com/dancarter",
"contributions": [
"code"
]
},
{
"login": "NuroDev",
"name": "nuro",
"avatar_url": "https://avatars.githubusercontent.com/u/4991309?v=4",
"profile": "https://nuro.dev",
"contributions": [
"doc"
]
},
{
"login": "onedr0p",
"name": "ᗪєνιη ᗷυнʟ",
"avatar_url": "https://avatars.githubusercontent.com/u/213795?v=4",
"profile": "https://github.com/onedr0p",
"contributions": [
"infra"
]
},
{
"login": "JonnyWong16",
"name": "JonnyWong16",
"avatar_url": "https://avatars.githubusercontent.com/u/9099342?v=4",
"profile": "https://github.com/JonnyWong16",
"contributions": [
"doc"
]
},
{
"login": "Roxedus",
"name": "Roxedus",
"avatar_url": "https://avatars.githubusercontent.com/u/7110194?v=4",
"profile": "https://github.com/Roxedus",
"contributions": [
"doc"
]
},
{
"login": "WoisWoi",
"name": "WoisWoi",
"avatar_url": "https://avatars.githubusercontent.com/u/75491231?v=4",
"profile": "https://github.com/WoisWoi",
"contributions": [
"translation"
]
},
{
"login": "HubDuck",
"name": "HubDuck",
"avatar_url": "https://avatars.githubusercontent.com/u/77843475?v=4",
"profile": "https://github.com/HubDuck",
"contributions": [
"translation",
"doc"
]
},
{
"login": "costaht",
"name": "costaht",
"avatar_url": "https://avatars.githubusercontent.com/u/50637431?v=4",
"profile": "https://github.com/costaht",
"contributions": [
"doc",
"translation"
]
},
{
"login": "Shjosan",
"name": "Shjosan",
"avatar_url": "https://avatars.githubusercontent.com/u/20847626?v=4",
"profile": "https://github.com/Shjosan",
"contributions": [
"translation"
]
},
{
"login": "kobaubarr",
"name": "kobaubarr",
"avatar_url": "https://avatars.githubusercontent.com/u/28481522?v=4",
"profile": "https://github.com/kobaubarr",
"contributions": [
"translation"
]
},
{
"login": "notorius28",
"name": "Ricardo González",
"avatar_url": "https://avatars.githubusercontent.com/u/1621513?v=4",
"profile": "https://github.com/notorius28",
"contributions": [
"translation"
]
},
{
"login": "Torkiliuz",
"name": "Torkil",
"avatar_url": "https://avatars.githubusercontent.com/u/460764?v=4",
"profile": "http://torkili.uz",
"contributions": [
"translation"
]
},
{
"login": "JagandeepBrar",
"name": "Jagandeep Brar",
"avatar_url": "https://avatars.githubusercontent.com/u/3048295?v=4",
"profile": "https://www.jagandeepbrar.io",
"contributions": [
"doc"
]
},
{
"login": "dtalens",
"name": "dtalens",
"avatar_url": "https://avatars.githubusercontent.com/u/6631832?v=4",
"profile": "http://dtalens.com",
"contributions": [
"translation"
]
},
{
"login": "acortelyou",
"name": "Alex Cortelyou",
"avatar_url": "https://avatars.githubusercontent.com/u/1689668?v=4",
"profile": "https://github.com/acortelyou",
"contributions": [
"code"
]
},
{
"login": "jonocairns",
"name": "Jono Cairns",
"avatar_url": "https://avatars.githubusercontent.com/u/182836?v=4",
"profile": "https://nz.linkedin.com/in/jonocairns",
"contributions": [
"code"
]
},
{
"login": "DJScias",
"name": "DJScias",
"avatar_url": "https://avatars.githubusercontent.com/u/439655?v=4",
"profile": "https://scias.net/",
"contributions": [
"translation"
]
},
{
"login": "Dabu-dot",
"name": "Dabu-dot",
"avatar_url": "https://avatars.githubusercontent.com/u/52525576?v=4",
"profile": "https://github.com/Dabu-dot",
"contributions": [
"translation"
]
},
{
"login": "Jabster28",
"name": "Jabster28",
"avatar_url": "https://avatars.githubusercontent.com/u/29015942?v=4",
"profile": "https://github.com/Jabster28",
"contributions": [
"code"
]
},
{
"login": "littlerooster",
"name": "littlerooster",
"avatar_url": "https://avatars.githubusercontent.com/u/83890654?v=4",
"profile": "https://github.com/littlerooster",
"contributions": [
"translation"
]
},
{
"login": "dphildebrandt",
"name": "Dustin Hildebrandt",
"avatar_url": "https://avatars.githubusercontent.com/u/154459?v=4",
"profile": "https://github.com/dphildebrandt",
"contributions": [
"code"
]
},
{
"login": "Generator",
"name": "Bruno Guerreiro",
"avatar_url": "https://avatars.githubusercontent.com/u/44146?v=4",
"profile": "https://github.com/Generator",
"contributions": [
"translation"
]
},
{
"login": "iceHtwoO",
"name": "Alexander Neuhäuser",
"avatar_url": "https://avatars.githubusercontent.com/u/27020492?v=4",
"profile": "https://github.com/iceHtwoO",
"contributions": [
"translation"
]
},
{
"login": "liviokanone",
"name": "Livio",
"avatar_url": "https://avatars.githubusercontent.com/u/37431541?v=4",
"profile": "http://www.unext.co.jp",
"contributions": [
"design"
]
},
{
"login": "tangentThought",
"name": "tangentThought",
"avatar_url": "https://avatars.githubusercontent.com/u/25516090?v=4",
"profile": "https://github.com/tangentThought",
"contributions": [
"code"
]
},
{
"login": "nicospz",
"name": "Nicolás Espinoza",
"avatar_url": "https://avatars.githubusercontent.com/u/31373060?v=4",
"profile": "https://github.com/nicospz",
"contributions": [
"code"
]
},
{
"login": "sootylunatic",
"name": "sootylunatic",
"avatar_url": "https://avatars.githubusercontent.com/u/36486087?v=4",
"profile": "https://github.com/sootylunatic",
"contributions": [
"translation"
]
},
{
"login": "JoKerIsCraZy",
"name": "JoKerIsCraZy",
"avatar_url": "https://avatars.githubusercontent.com/u/47474211?v=4",
"profile": "https://github.com/JoKerIsCraZy",
"contributions": [
"translation"
]
},
{
"login": "GoByeBye",
"name": "Daddie0",
"avatar_url": "https://avatars.githubusercontent.com/u/33762262?v=4",
"profile": "https://daddie.dev",
"contributions": [
"translation"
]
},
{
"login": "Simoneu01",
"name": "Simone",
"avatar_url": "https://avatars.githubusercontent.com/u/43807696?v=4",
"profile": "http://ungaro.me",
"contributions": [
"translation"
]
},
{
"login": "adan89lion",
"name": "Seohyun Joo",
"avatar_url": "https://avatars.githubusercontent.com/u/6585644?v=4",
"profile": "https://github.com/adan89lion",
"contributions": [
"translation"
]
},
{
"login": "ty4ko",
"name": "Sergey",
"avatar_url": "https://avatars.githubusercontent.com/u/21213535?v=4",
"profile": "https://github.com/ty4ko",
"contributions": [
"translation"
]
},
{
"login": "skafte1990",
"name": "Shaaft",
"avatar_url": "https://avatars.githubusercontent.com/u/31465453?v=4",
"profile": "https://github.com/skafte1990",
"contributions": [
"translation"
]
},
{
"login": "sr093906",
"name": "sr093906",
"avatar_url": "https://avatars.githubusercontent.com/u/8369201?v=4",
"profile": "https://github.com/sr093906",
"contributions": [
"translation"
]
},
{
"login": "Nackophilz",
"name": "Nackophilz",
"avatar_url": "https://avatars.githubusercontent.com/u/61667226?v=4",
"profile": "https://github.com/Nackophilz",
"contributions": [
"translation"
]
},
{
"login": "schambers",
"name": "Sean Chambers",
"avatar_url": "https://avatars.githubusercontent.com/u/31563?v=4",
"profile": "https://github.com/schambers",
"contributions": [
"code"
]
},
{
"login": "deniscerri",
"name": "deniscerri",
"avatar_url": "https://avatars.githubusercontent.com/u/64997243?v=4",
"profile": "https://github.com/deniscerri",
"contributions": [
"translation"
]
},
{
"login": "tomgacz",
"name": "tomgacz",
"avatar_url": "https://avatars.githubusercontent.com/u/14138209?v=4",
"profile": "https://github.com/tomgacz",
"contributions": [
"translation"
]
},
{
"login": "Andersborrits",
"name": "Andersborrits",
"avatar_url": "https://avatars.githubusercontent.com/u/29452218?v=4",
"profile": "https://github.com/Andersborrits",
"contributions": [
"translation"
]
},
{
"login": "Maxentr",
"name": "Maxent",
"avatar_url": "https://avatars.githubusercontent.com/u/67283154?v=4",
"profile": "http://maxentrouault.fr",
"contributions": [
"translation"
]
}
],
"badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>",
"contributorsPerLine": 7,
"projectName": "overseerr",
"projectOwner": "sct",
"projectName": "jellyseerr",
"projectOwner": "Fallenbagel",
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true
"skipCi": true,
"commitConvention": "angular",
"commitType": "docs",
"contributors": [
{
"login": "Fallenbagel",
"name": "Fallenbagel",
"avatar_url": "https://avatars.githubusercontent.com/u/98979876?v=4",
"profile": "https://github.com/Fallenbagel",
"contributions": [
"code",
"maintenance"
]
},
{
"login": "seanzhang98",
"name": "Sean",
"avatar_url": "https://avatars.githubusercontent.com/u/34902361?v=4",
"profile": "https://github.com/seanzhang98",
"contributions": [
"translation",
"code"
]
},
{
"login": "notfakie",
"name": "notfakie",
"avatar_url": "https://avatars.githubusercontent.com/u/103784113?v=4",
"profile": "https://github.com/notfakie",
"contributions": [
"code"
]
},
{
"login": "Jumail",
"name": "Mohamed Jumail",
"avatar_url": "https://avatars.githubusercontent.com/u/7672055?v=4",
"profile": "https://github.com/Jumail",
"contributions": [
"review"
]
},
{
"login": "jsl9208",
"name": "Shilong Jiang",
"avatar_url": "https://avatars.githubusercontent.com/u/4048787?v=4",
"profile": "https://www.heywhale.com",
"contributions": [
"code"
]
},
{
"login": "boring-dragon",
"name": "Boring Dragon",
"avatar_url": "https://avatars.githubusercontent.com/u/28459081?v=4",
"profile": "https://jinas.me",
"contributions": [
"code"
]
},
{
"login": "sambartik",
"name": "Samuel Bartík",
"avatar_url": "https://avatars.githubusercontent.com/u/63553146?v=4",
"profile": "https://github.com/sambartik",
"contributions": [
"code"
]
},
{
"login": "CyferShepard",
"name": "Thegan Govender",
"avatar_url": "https://avatars.githubusercontent.com/u/24864904?v=4",
"profile": "https://github.com/CyferShepard",
"contributions": [
"code"
]
},
{
"login": "jab416171",
"name": "jab416171",
"avatar_url": "https://avatars.githubusercontent.com/u/345752?v=4",
"profile": "https://github.com/jab416171",
"contributions": [
"doc"
]
},
{
"login": "NicolaiVdS",
"name": "Nicolai Van der Storm",
"avatar_url": "https://avatars.githubusercontent.com/u/5257222?v=4",
"profile": "https://nvds.be",
"contributions": [
"code"
]
},
{
"login": "Smexhy",
"name": "Smexhy",
"avatar_url": "https://avatars.githubusercontent.com/u/4880625?v=4",
"profile": "https://github.com/Smexhy",
"contributions": [
"translation"
]
},
{
"login": "dd060606",
"name": "dd060606",
"avatar_url": "https://avatars.githubusercontent.com/u/58089504?v=4",
"profile": "https://dd06-dev.fr",
"contributions": [
"code"
]
},
{
"login": "darmiel",
"name": "Daniel",
"avatar_url": "https://avatars.githubusercontent.com/u/71837281?v=4",
"profile": "https://qwer.tz",
"contributions": [
"code"
]
},
{
"login": "undone37",
"name": "undone37",
"avatar_url": "https://avatars.githubusercontent.com/u/10513808?v=4",
"profile": "https://github.com/undone37",
"contributions": [
"translation"
]
},
{
"login": "CheChu10",
"name": "Chechu García",
"avatar_url": "https://avatars.githubusercontent.com/u/32913133?v=4",
"profile": "https://github.com/CheChu10",
"contributions": [
"translation"
]
},
{
"login": "DimitriDR",
"name": "Dimitri",
"avatar_url": "https://avatars.githubusercontent.com/u/56969769?v=4",
"profile": "https://github.com/DimitriDR",
"contributions": [
"translation"
]
},
{
"login": "andrey4korop",
"name": "andrey4korop",
"avatar_url": "https://avatars.githubusercontent.com/u/24610708?v=4",
"profile": "https://github.com/andrey4korop",
"contributions": [
"code",
"translation"
]
},
{
"login": "GeoffreyCoulaud",
"name": "Geoffrey Coulaud",
"avatar_url": "https://avatars.githubusercontent.com/u/20744730?v=4",
"profile": "https://geoffrey-coulaud.fr",
"contributions": [
"translation"
]
},
{
"login": "Pikachu920",
"name": "Pikachu920",
"avatar_url": "https://avatars.githubusercontent.com/u/28607612?v=4",
"profile": "https://github.com/Pikachu920",
"contributions": [
"code"
]
},
{
"login": "yalagin",
"name": "Maxim Yalagin",
"avatar_url": "https://avatars.githubusercontent.com/u/12879142?v=4",
"profile": "https://github.com/yalagin",
"contributions": [
"code"
]
},
{
"login": "jeaboswell",
"name": "Jesse Boswell",
"avatar_url": "https://avatars.githubusercontent.com/u/11653068?v=4",
"profile": "https://github.com/jeaboswell",
"contributions": [
"code"
]
},
{
"login": "d-fendrich",
"name": "d-fendrich",
"avatar_url": "https://avatars.githubusercontent.com/u/27904138?v=4",
"profile": "https://github.com/d-fendrich",
"contributions": [
"translation"
]
},
{
"login": "davidfdezalcoba",
"name": "David Fernández Alcoba",
"avatar_url": "https://avatars.githubusercontent.com/u/15996018?v=4",
"profile": "https://github.com/davidfdezalcoba",
"contributions": [
"code"
]
},
{
"login": "Gauvino",
"name": "Gauvino",
"avatar_url": "https://avatars.githubusercontent.com/u/68083474?v=4",
"profile": "https://github.com/Gauvino",
"contributions": [
"translation"
]
},
{
"login": "EthanArmbrust",
"name": "EthanArmbrust",
"avatar_url": "https://avatars.githubusercontent.com/u/22754714?v=4",
"profile": "https://github.com/EthanArmbrust",
"contributions": [
"code"
]
},
{
"login": "SirMartin",
"name": "Eduardo",
"avatar_url": "https://avatars.githubusercontent.com/u/854646?v=4",
"profile": "http://www.piribisoft.com",
"contributions": [
"doc"
]
},
{
"login": "RickLuiken",
"name": "RickLuiken",
"avatar_url": "https://avatars.githubusercontent.com/u/34110371?v=4",
"profile": "https://github.com/RickLuiken",
"contributions": [
"code"
]
},
{
"login": "Br33ce",
"name": "Br33ce",
"avatar_url": "https://avatars.githubusercontent.com/u/124933490?v=4",
"profile": "https://github.com/Br33ce",
"contributions": [
"translation"
]
},
{
"login": "athphane",
"name": "Athfan Khaleel",
"avatar_url": "https://avatars.githubusercontent.com/u/13810742?v=4",
"profile": "https://athfan.com",
"contributions": [
"doc"
]
},
{
"login": "mdll23",
"name": "Michael Dallinger",
"avatar_url": "https://avatars.githubusercontent.com/u/142844478?v=4",
"profile": "https://github.com/mdll23",
"contributions": [
"translation"
]
},
{
"login": "xeruf",
"name": "Janek",
"avatar_url": "https://avatars.githubusercontent.com/u/13354331?v=4",
"profile": "https://github.com/xeruf",
"contributions": [
"doc"
]
},
{
"login": "aleksasiriski",
"name": "Aleksa Siriški",
"avatar_url": "https://avatars.githubusercontent.com/u/31509435?v=4",
"profile": "https://aleksasiriski.dev",
"contributions": [
"infra"
]
},
{
"login": "Danish-H",
"name": "Danish Humair",
"avatar_url": "https://avatars.githubusercontent.com/u/121830048?v=4",
"profile": "http://danishhumair.com",
"contributions": [
"code"
]
},
{
"login": "trackmastersteve",
"name": "Stephen Harris",
"avatar_url": "https://avatars.githubusercontent.com/u/16858514?v=4",
"profile": "https://arm0.red",
"contributions": [
"doc"
]
}
]
}

View File

@@ -26,3 +26,4 @@ public/os_logo_filled.png
public/preview.jpg
snap
stylelint.config.js
cypress

View File

@@ -7,6 +7,7 @@ module.exports = {
'plugin:jsx-a11y/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:react/jsx-runtime',
'prettier',
],
parserOptions: {
@@ -26,11 +27,21 @@ module.exports = {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'@typescript-eslint/explicit-function-return-type': 'off',
'prettier/prettier': ['error', { endOfLine: 'auto' }],
'formatjs/no-offset': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['error'],
'@typescript-eslint/array-type': ['error', { default: 'array' }],
'jsx-a11y/no-onchange': 'off',
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
},
],
'no-relative-import-paths/no-relative-import-paths': [
'error',
{ allowSameFolder: true },
],
},
overrides: [
{
@@ -40,7 +51,7 @@ module.exports = {
},
},
],
plugins: ['jsx-a11y', 'prettier', 'react-hooks', 'formatjs'],
plugins: ['jsx-a11y', 'react-hooks', 'formatjs', 'no-relative-import-paths'],
settings: {
react: {
pragma: 'React',

21
.gitattributes vendored
View File

@@ -24,3 +24,24 @@
*.woff binary
*.pyc binary
*.pdf binary
#
## Theses files/directories should be excluded from git archives
#
.husky export-ignore
.vscode export-ignore
docs export-ignore
.git* export-ignore
*ignore export-ignore
*.md export-ignore
.all-contributorsrc export-ignore
.editorconfig export-ignore
Dockerfile.local export-ignore
docker-compose.yml export-ignore
stylelint.config.js export-ignore
public/os_logo_filled.png export-ignore
public/preview.jpg export-ignore

7
.github/CODEOWNERS vendored
View File

@@ -1,7 +1,2 @@
# Global code ownership
- @Fallenbagel
# i18n locale files
src/i18n/locale/ @Fallenbagel
* @Fallenbagel

3
.github/FUNDING.yml vendored
View File

@@ -1,2 +1 @@
github: [sct]
patreon: overseerr
github: [Fallenbagel]

View File

@@ -19,7 +19,7 @@ body:
id: version
attributes:
label: Version
description: What version of Overseerr are you running? (You can find this in Settings → About → Version.)
description: What version of Jellyseerr are you running? (You can find this in Settings → About → Version.)
validations:
required: true
- type: textarea
@@ -87,5 +87,5 @@ body:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Overseerr's Code of Conduct
- label: I agree to follow Jellyseerr's Code of Conduct
required: true

View File

@@ -2,7 +2,7 @@ blank_issues_enabled: false
contact_links:
- name: 💬 Support via Discord
url: https://discord.gg/ckbvBtDJgC
about: Chat with other users and the Overseerr dev team
about: Chat with other users and the Jellyseerr dev team
- name: 💬 Support via GitHub Discussions
url: https://github.com/fallenbagel/jellyseerr/discussions
about: Ask questions and discuss with other community members

View File

@@ -33,5 +33,5 @@ body:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Overseerr's Code of Conduct
- label: I agree to follow Jellyseerr's Code of Conduct
required: true

5
.github/holopin.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
organization: overseerr
defaultSticker: clcyagj1j329008l468ya8pu2
stickers:
- id: clcyagj1j329008l468ya8pu2
alias: overseerr-contributor

View File

@@ -3,7 +3,7 @@ name: Jellyseerr CI
on:
pull_request:
branches:
- "*"
- '*'
push:
branches:
- develop
@@ -12,45 +12,51 @@ jobs:
test:
name: Lint & Test Build
if: github.event_name == 'pull_request'
runs-on: ubuntu-20.04
container: node:16.14-alpine
runs-on: ubuntu-22.04
container: node:18.18-alpine
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
env:
HUSKY_SKIP_INSTALL: 1
HUSKY: 0
run: yarn
- name: Lint
run: yarn lint
- name: Formatting
run: yarn format:check
- name: Build
run: yarn build
build_and_push:
name: Build & Publish Docker Images
if: github.ref == 'refs/heads/develop' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set lower case owner name
run: |
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
env:
OWNER: ${{ github.repository_owner }}
- name: Build and push
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
@@ -60,32 +66,24 @@ jobs:
COMMIT_TAG=${{ github.sha }}
tags: |
fallenbagel/jellyseerr:develop
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
- # Temporary fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
ghcr.io/${{ env.OWNER_LC }}/jellyseerr:develop
discord:
name: Send Discord Notification
needs: build_and_push
if: always() && github.event_name != 'pull_request' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v2
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo ::set-output name=status::failure
echo "status=failure" >> $GITHUB_OUTPUT
else
echo ::set-output name=status::$WORKFLOW_CONCLUSION
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1

41
.github/workflows/codeql.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: 'CodeQL'
on:
push:
branches: ['develop']
pull_request:
branches: ['develop']
schedule:
- cron: '50 7 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [javascript]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: '/language:${{ matrix.language }}'

30
.github/workflows/cypress.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Cypress Tests
on:
pull_request:
branches:
- '*'
push:
branches:
- develop
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v4
with:
build: yarn cypress:build
start: yarn start
wait-on: 'http://localhost:5055'
record: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_MIGRATIONS: true
# Fix test titles in cypress dashboard
COMMIT_INFO_MESSAGE: ${{github.event.pull_request.title}}
COMMIT_INFO_SHA: ${{github.event.pull_request.head.sha}}

View File

@@ -3,33 +3,33 @@ name: Jellyseerr Preview
on:
push:
tags:
- "preview-*"
- 'preview-*'
jobs:
build_and_push:
name: Build & Publish Docker Preview Images
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
uses: docker/build-push-action@v3
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
build-args: |
COMMIT_TAG=${{ github.sha }}

View File

@@ -1,39 +0,0 @@
name: 'create docker image on pull request and push to private registery'
on:
pull_request:
branches:
- develop
workflow_dispatch:
jobs:
build-image:
runs-on: self-hosted
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to private registery
uses: docker/login-action@v2.0.0
with:
registry: ${{ secrets.REGISTRY_URL }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: ./
file: ./Dockerfile
builder: ${{ steps.buildx.outputs.name }}
push: true
tags: '${{ secrets.REGISTRY_URL }}/fallenbagel/jellyseerr:${{ github.sha }}'
cache-from: 'type=registry,ref=${{ secrets.REGISTRY_URL }}/fallenbagel/jellyseerr:buildcache'
cache-to: 'type=registry,ref=${{ secrets.REGISTRY_URL }}/fallenbagel/jellyseerr:buildcache,mode=max'

View File

@@ -5,7 +5,7 @@ on: workflow_dispatch
jobs:
semantic-release:
name: Tag and release latest version
runs-on: self-hosted
runs-on: ubuntu-22.04
env:
HUSKY: 0
steps:
@@ -18,16 +18,14 @@ jobs:
with:
node-version: 16
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Install Yarn
run: npm install -g yarn
- name: Install dependencies
run: yarn
- name: Release
@@ -37,22 +35,77 @@ jobs:
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: npx semantic-release
build-snap:
name: Build Snap Package (${{ matrix.architecture }})
needs: semantic-release
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
architecture:
- amd64
- arm64
- armhf
steps:
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Switch to main branch
run: git checkout main
- name: Pull latest changes
run: git pull
- name: Prepare
id: prepare
run: |
git fetch --prune --tags
if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
echo "RELEASE=stable" >> $GITHUB_OUTPUT
else
echo "RELEASE=edge" >> $GITHUB_OUTPUT
fi
- name: Set Up QEMU
uses: docker/setup-qemu-action@v1
with:
image: tonistiigi/binfmt@sha256:df15403e06a03c2f461c1f7938b171fda34a5849eb63a70e2a2109ed5a778bde
- name: Build Snap Package
uses: diddlesnaps/snapcraft-multiarch-action@v1
id: build
with:
architecture: ${{ matrix.architecture }}
- name: Upload Snap Package
uses: actions/upload-artifact@v2
with:
name: jellyseerr-snap-package-${{ matrix.architecture }}
path: ${{ steps.build.outputs.snap }}
- name: Review Snap Package
uses: diddlesnaps/snapcraft-review-tools-action@v1
with:
snap: ${{ steps.build.outputs.snap }}
- name: Publish Snap Package
uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: ${{ steps.prepare.outputs.RELEASE }}
discord:
name: Send Discord Notification
needs: semantic-release
if: always()
runs-on: self-hosted
runs-on: ubuntu-22.04
steps:
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v2
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo ::set-output name=status::failure
echo "status=failure" >> $GITHUB_OUTPUT
else
echo ::set-output name=status::$WORKFLOW_CONCLUSION
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1

91
.github/workflows/snap.yaml vendored Normal file
View File

@@ -0,0 +1,91 @@
name: Publish Snap
on:
push:
branches:
- develop
jobs:
jobs:
name: Job Check
runs-on: ubuntu-22.04
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.10.0
with:
access_token: ${{ secrets.GITHUB_TOKEN }}
build-snap:
name: Build Snap Package (${{ matrix.architecture }})
needs: jobs
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
architecture:
- amd64
- arm64
- armhf
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Prepare
id: prepare
run: |
git fetch --prune --unshallow --tags
if [[ $GITHUB_REF == refs/tags/* || $GITHUB_REF == refs/heads/master ]]; then
echo "RELEASE=stable" >> $GITHUB_OUTPUT
else
echo "RELEASE=edge" >> $GITHUB_OUTPUT
fi
- name: Set Up QEMU
uses: docker/setup-qemu-action@v2
- name: Configure Git
run: git config --add safe.directory /data/parts/jellyseerr/src
- name: Build Snap Package
uses: diddlesnaps/snapcraft-multiarch-action@v1
id: build
with:
architecture: ${{ matrix.architecture }}
- name: Upload Snap Package
uses: actions/upload-artifact@v3
with:
name: jellyseerr-snap-package-${{ matrix.architecture }}
path: ${{ steps.build.outputs.snap }}
- name: Review Snap Package
uses: diddlesnaps/snapcraft-review-tools-action@v1
with:
snap: ${{ steps.build.outputs.snap }}
- name: Publish Snap Package
uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: ${{ steps.prepare.outputs.RELEASE }}
discord:
name: Send Discord Notification
needs: build-snap
if: always() && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-22.04
steps:
- name: Get Build Job Status
uses: technote-space/workflow-conclusion-action@v3
- name: Combine Job Status
id: status
run: |
failures=(neutral, skipped, timed_out, action_required)
if [[ ${array[@]} =~ $WORKFLOW_CONCLUSION ]]; then
echo "status=failure" >> $GITHUB_OUTPUT
else
echo "status=$WORKFLOW_CONCLUSION" >> $GITHUB_OUTPUT
fi
- name: Post Status to Discord
uses: sarisia/actions-status-discord@v1
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
status: ${{ steps.status.outputs.status }}
title: ${{ github.workflow }}
nofail: true

14
.gitignore vendored
View File

@@ -54,5 +54,19 @@ config/db/db.sqlite3-journal
# VS Code
.vscode/launch.json
# Cypress
cypress.env.json
cypress/videos
cypress/screenshots
# ESLint
.eslintcache
# TS Build Info
tsconfig.tsbuildinfo
# Webstorm
.idea
# Config Cache Directory
config/cache

View File

@@ -2,6 +2,7 @@
.next/
dist/
config/
CHANGELOG.md
# assets
src/assets/

5
.prettierrc.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
plugins: [require('./merged-prettier-plugin.js')],
singleQuote: true,
trailingComma: 'es5',
};

View File

@@ -11,9 +11,6 @@
// https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
"esbenp.prettier-vscode",
// https://marketplace.visualstudio.com/items?itemName=eg2.vscode-npm-script
"eg2.vscode-npm-script",
// https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest
"Orta.vscode-jest",

View File

@@ -15,8 +15,9 @@
"database": "./config/db/db.sqlite3"
}
],
"editor.codeActionsOnSave": {
"source.organizeImports": true
},
"editor.formatOnSave": true
"editor.formatOnSave": true,
"typescript.preferences.importModuleSpecifier": "non-relative",
"files.associations": {
"globals.css": "tailwindcss"
}
}

View File

@@ -1,207 +1,21 @@
# [1.1.1](https://github.com/fallenbagel/jellyseerr/compare/v1.1.0...v1.1.1) (2022-06-20)
# [1.3.0](https://github.com/fallenbagel/jellyseerr/compare/v1.2.1...v1.3.0) (2023-01-02)
### Bug Fixes
* conditional media server name for 4k url to add emby to tvdetails ([ddd773c](https://github.com/fallenbagel/jellyseerr/commit/ddd773c03ff61654490644dec21f406d03374b3d))
* don't show 0 playcount in slideover ([dec4062](https://github.com/fallenbagel/jellyseerr/commit/dec4062cdcecbe297f72364ede6a000b863117f4))
* fix mediaServerType not set for Plex which leads to Plex users seeing Jellyfin settings ([94ade93](https://github.com/fallenbagel/jellyseerr/commit/94ade93e16f02b372dafd2765bea475117431975))
* fixes jellyfin forgot password and adds emby support to the forgot password link ([0259975](https://github.com/fallenbagel/jellyseerr/commit/02599754026e6a66662f753bb6b6117dfabb5f9a)), closes [#99](https://github.com/fallenbagel/jellyseerr/issues/99)
* hide plex guid cache settings from ui when running in jellyfin/emby mode ([7450138](https://github.com/fallenbagel/jellyseerr/commit/7450138ac12640797952c1a2d5e1e111d17a11e1))
* **import all:** fis for import all ([29478fc](https://github.com/fallenbagel/jellyseerr/commit/29478fc19534589db37499f1cdcc21ea4d389a74))
* **jellyfin:** ignore additional items with virtual location type ([c811548](https://github.com/fallenbagel/jellyseerr/commit/c81154800fd7dc48fe890f4dd57ff33cbab973bb))
* **jellyfinimportmodal:** fix for importing all jellyfin users ([a483ca9](https://github.com/fallenbagel/jellyseerr/commit/a483ca9837e12e2385d0e2407e52d6c64ae435e2))
* **jellyfin:** sync errors ([d1dbd6e](https://github.com/fallenbagel/jellyseerr/commit/d1dbd6e3b9b1134e06150fc5eb21f729f64c0955))
* manual browser refresh would redirect to home on search page ([9ded45f](https://github.com/fallenbagel/jellyseerr/commit/9ded45fef80b4a7e0be237fbe0301629f862fff9))
* manual browser refresh would redirect to home on search page ([#2692](https://github.com/fallenbagel/jellyseerr/issues/2692)) ([b287839](https://github.com/fallenbagel/jellyseerr/commit/b2878390b486e338151f26a2354711147012f88e)), closes [#2683](https://github.com/fallenbagel/jellyseerr/issues/2683)
* only show mediaserver settings for current active mediaserver ([739f5f9](https://github.com/fallenbagel/jellyseerr/commit/739f5f9c9ade8a1680bcb374f6c9e919a9e1426c))
* **recommendations:** fixed recommendations page causing infinite network requests to tmdb api ([4f972be](https://github.com/fallenbagel/jellyseerr/commit/4f972be8584e48f544268aef9d1d05769ba2e38e))
* **recommendations:** only load more titles if there can be more than 40 ([#2749](https://github.com/fallenbagel/jellyseerr/issues/2749)) ([14519ef](https://github.com/fallenbagel/jellyseerr/commit/14519ef5559038b0d9d037a2bdc5d98e63c9db6f)), closes [#2710](https://github.com/fallenbagel/jellyseerr/issues/2710)
* remove internal Overseerr sponsor link, this is remaining on the main github page instead ([4b7bdd3](https://github.com/fallenbagel/jellyseerr/commit/4b7bdd3d7d608fe0bf52f494766fd7c40bede859))
* **scan:** ignore virtual seasons ([6574e18](https://github.com/fallenbagel/jellyseerr/commit/6574e18516201bc11b5f0c422bf6b432c722e067)), closes [#119](https://github.com/fallenbagel/jellyseerr/issues/119)
* **search:** use correct param to filter movies by year ([b07f703](https://github.com/fallenbagel/jellyseerr/commit/b07f7032ad89ccb359f3a6a4f4508de6b59ec393))
* **search:** use correct param to filter movies by year ([#2727](https://github.com/fallenbagel/jellyseerr/issues/2727)) ([1054b4e](https://github.com/fallenbagel/jellyseerr/commit/1054b4e2d7262d841fa83cde624f1138ad7bd23a))
* **setup&login:** fix a description error in the manual scan in setup and add emby to login page ([8810c20](https://github.com/fallenbagel/jellyseerr/commit/8810c20fc18a55c2f6768ddc40830a8494946072))
* **ui:** don't show 0 playcount in slideover ([#2714](https://github.com/fallenbagel/jellyseerr/issues/2714)) ([29be659](https://github.com/fallenbagel/jellyseerr/commit/29be6595125017700eccb34d33a0e852f23c97ba))
* **ui:** fix Avatar being broken when setup using internal ip ([01e81a7](https://github.com/fallenbagel/jellyseerr/commit/01e81a73a3ae3c4692d0b9b68dc27fe1a54b1a1d)), closes [#110](https://github.com/fallenbagel/jellyseerr/issues/110)
* **ui:** fix translation errors for all locales in the import plex user button ([0fb5803](https://github.com/fallenbagel/jellyseerr/commit/0fb5803eb9a7589141a63e13df9a8aa8ea4cebf2))
* **ui:** fix ui elements not reflecting the env variable ([722dda5](https://github.com/fallenbagel/jellyseerr/commit/722dda585631be365a2fb400b62dbc201f2b80de))
* **ui:** fixed translation issue where it showed as import {mediaServerName} user ([819190c](https://github.com/fallenbagel/jellyseerr/commit/819190ce98720d8d66a07c98a4f12e3c8cdcac94))
* **ui:** rectangular avatars getting stretched ([#2782](https://github.com/fallenbagel/jellyseerr/issues/2782)) ([db05172](https://github.com/fallenbagel/jellyseerr/commit/db05172d8b924a591ece4fae72d076eb59ee5f82))
* **ui:** replaced {mediaServerName} in the plex variable in NL locale ([d417fca](https://github.com/fallenbagel/jellyseerr/commit/d417fcafa1e38c6d56ed8360ae451e8b8ff82a8d))
- added deep links to issues and status badges ([#3065](https://github.com/fallenbagel/jellyseerr/issues/3065)) ([bfe56c3](https://github.com/fallenbagel/jellyseerr/commit/bfe56c347073001795b1c3e917eb7a5afcc4462c))
- **api:** handle auth for accounts where the plex id may have been set to null ([#3125](https://github.com/fallenbagel/jellyseerr/issues/3125)) ([15e2469](https://github.com/fallenbagel/jellyseerr/commit/15e246929bdbc2b7b5bdab7a84bd7882b79d5cb1))
- **api:** ignore Music,Books,Photos,MusicVideo libraries ([d9ca3c6](https://github.com/fallenbagel/jellyseerr/commit/d9ca3c6e52c118698ca71021217f6ca409e71974))
- count combined episodes ([64339e5](https://github.com/fallenbagel/jellyseerr/commit/64339e5f0374f8490e685e5c086e088bb7fd737e))
- improved PTR scrolling performance ([#3095](https://github.com/fallenbagel/jellyseerr/issues/3095)) ([07ec3ef](https://github.com/fallenbagel/jellyseerr/commit/07ec3efbcaf669de7ccde4421c1112bfd23675d6))
- **locale:** fix the duplicated wording in the Clear Media Warning message ([7e20c7c](https://github.com/fallenbagel/jellyseerr/commit/7e20c7cb78a44c32ab8a5f21203e285f23f402ab))
- **ui:** adds mediaServerName to statusBadge and manageSlideOver ([d0cdce9](https://github.com/fallenbagel/jellyseerr/commit/d0cdce9e90fba642d2bf934a4266e1421424bc73)), closes [#254](https://github.com/fallenbagel/jellyseerr/issues/254)
- update API docs to allow 'all' seasons value ([#3073](https://github.com/fallenbagel/jellyseerr/issues/3073)) ([1dfa943](https://github.com/fallenbagel/jellyseerr/commit/1dfa9431a95e7e2a1843746c2473d8a06f03e184))
### Features
* add Paramount+ to network slider ([d22bc09](https://github.com/fallenbagel/jellyseerr/commit/d22bc09652e5d4e703fca6838d06e4908432fe06))
* **api:** add issue counts endpoint ([af23a25](https://github.com/fallenbagel/jellyseerr/commit/af23a257d5795b5c3930cd3884a84a2e2eeeb1dc))
* **api:** add issue counts endpoint ([#2713](https://github.com/fallenbagel/jellyseerr/issues/2713)) ([e4039d0](https://github.com/fallenbagel/jellyseerr/commit/e4039d09c0380d80f03c7a00b51a150f88c02cca))
* conditional media server name ([2bfdf02](https://github.com/fallenbagel/jellyseerr/commit/2bfdf02c7942762bd9f5201459b1a9ad6003b9a6))
* conditional media server name to add emby to tvdetails ([e75b71b](https://github.com/fallenbagel/jellyseerr/commit/e75b71b8168b4a661971b809c88f9910c4206545))
* conditional media server name to add emby to tvdetails ([ff3e3ce](https://github.com/fallenbagel/jellyseerr/commit/ff3e3ce841f0676713242d0c8e3a977ef65530d8))
* **discover:** add Paramount+ to network slider ([#2608](https://github.com/fallenbagel/jellyseerr/issues/2608)) ([1d00229](https://github.com/fallenbagel/jellyseerr/commit/1d00229a485bb2b376e9f63b52c70c7719f5f023))
* email ([a8bc0c0](https://github.com/fallenbagel/jellyseerr/commit/a8bc0c068b305710a224fa56a3725cc7e0758eb7)), closes [#122](https://github.com/fallenbagel/jellyseerr/issues/122)
* **email validation:** email requirement and validation + better importer ([d835336](https://github.com/fallenbagel/jellyseerr/commit/d835336d330abfef5b15bc9febcb748a8154c7df))
* **manage slideover:** show more request override details ([#2772](https://github.com/fallenbagel/jellyseerr/issues/2772)) ([90095bb](https://github.com/fallenbagel/jellyseerr/commit/90095bb18548dfd663a78df1908c40dbf2f99faf))
* **uesrprofile:** email requirement and validation ([543859e](https://github.com/fallenbagel/jellyseerr/commit/543859e6f3b3a8cd4c61499a74bda610d3217626))
* **ui:** add emby as a mediaServerType to the import user button ([6a6bfe0](https://github.com/fallenbagel/jellyseerr/commit/6a6bfe0c6875a1d8ccb1a6fdc409f595202ef38e))
* **ui:** add emby user badge to the user list and fix local user badge ([410b536](https://github.com/fallenbagel/jellyseerr/commit/410b536c9474806ab9f7f5f097cedfafde1fbf67))
* **ui:** add emby user badge to the userProfile ([b9546e6](https://github.com/fallenbagel/jellyseerr/commit/b9546e6daa8583c60fac7961447a13715bbc7f6b))
* **ui:** conditional media server name to add emby to issuedetails play on button ([377a4fd](https://github.com/fallenbagel/jellyseerr/commit/377a4fd85b7194afb48a8ba9bfa4ce4ccf996be8))
* **ui:** conditional media server name to add emby to moviedetails ([14d2937](https://github.com/fallenbagel/jellyseerr/commit/14d293799bb37f45449c201ab03638af257623be))
* **user email setting:** added field to save user email ([30c48f1](https://github.com/fallenbagel/jellyseerr/commit/30c48f16ca0a74e7551b533bd75bc43304f946b1)), closes [#122](https://github.com/fallenbagel/jellyseerr/issues/122)
* **user settings:** added email field to user profiel settings ([b22f20b](https://github.com/fallenbagel/jellyseerr/commit/b22f20b6fa5f68398850ccbf9b6e1cc233b3c8f4)), closes [#122](https://github.com/fallenbagel/jellyseerr/issues/122)
# [1.1.0](https://github.com/fallenbagel/jellyseerr/compare/v1.0.2...v1.1.0) (2022-05-21)
### Bug Fixes
* add Discord ID setting to general user settings page ([#2406](https://github.com/fallenbagel/jellyseerr/issues/2406)) ([eff665e](https://github.com/fallenbagel/jellyseerr/commit/eff665ef4b688aac881408790304b77bd9a31ddb))
* add missing route guards to issues pages ([#2235](https://github.com/fallenbagel/jellyseerr/issues/2235)) ([c79dc9f](https://github.com/fallenbagel/jellyseerr/commit/c79dc9f70f512dbec0e3460ee78dbc9feccfbbb1))
* address unhandled promise rejections & bump node to v16.13 ([#2398](https://github.com/fallenbagel/jellyseerr/issues/2398)) ([8cba486](https://github.com/fallenbagel/jellyseerr/commit/8cba486249fed88232e93a688c8bfe0f6179c589))
* allow basic HTTP auth in hostname validation ([#2307](https://github.com/fallenbagel/jellyseerr/issues/2307)) ([d48a7ba](https://github.com/fallenbagel/jellyseerr/commit/d48a7ba518f9c79d70e499037cb730eb3efe2c08))
* **api:** return queried user's requests instead of own requests ([#2174](https://github.com/fallenbagel/jellyseerr/issues/2174)) ([0edb1f4](https://github.com/fallenbagel/jellyseerr/commit/0edb1f452b6ff4a49ae2bde15f7273769788cf4f))
* **api:** use query builder for user requests endpoint ([#2119](https://github.com/fallenbagel/jellyseerr/issues/2119)) ([a20f395](https://github.com/fallenbagel/jellyseerr/commit/a20f395c94c97dd7ddbc25590f15def2c9bf13c9))
* apply request overrides iff override & selected servers match ([#2164](https://github.com/fallenbagel/jellyseerr/issues/2164)) ([50ce198](https://github.com/fallenbagel/jellyseerr/commit/50ce198471b1a3777a183d68904bbfb39ebd4523))
* **auth:** resolve local/password authentication issues ([#2677](https://github.com/fallenbagel/jellyseerr/issues/2677)) ([b75fc7b](https://github.com/fallenbagel/jellyseerr/commit/b75fc7b2384ce760432620faaa92277dcd42b8e1))
* **css:** rename form-input to form-input-area ([#2613](https://github.com/fallenbagel/jellyseerr/issues/2613)) ([086f0b6](https://github.com/fallenbagel/jellyseerr/commit/086f0b6ce23f607d20c2cec3c73b2e4d1ce9b426))
* disable user-import from mediaserver for non-plex mediaservers until implemented ([4db8e54](https://github.com/fallenbagel/jellyseerr/commit/4db8e5464d6ce3450e2687a0cbee126961d847d2))
* **docker:** explicitly install python3 ([#2273](https://github.com/fallenbagel/jellyseerr/issues/2273)) [skip ci] ([f1cd087](https://github.com/fallenbagel/jellyseerr/commit/f1cd0878a5c74bddc864f5f8ce9e2f041bdde5ec))
* don't allow login for unimported Jellyfin users if not set in settings ([72ca694](https://github.com/fallenbagel/jellyseerr/commit/72ca694f212ab616ca7b7fe02e428ff61f79c67c))
* **email:** do not attempt to display logo if app URL not configured ([#2125](https://github.com/fallenbagel/jellyseerr/issues/2125)) ([b3b421a](https://github.com/fallenbagel/jellyseerr/commit/b3b421a67408a4a48d23c15341fcdf7aaf19b25a))
* **email:** enclose PGP encryption logic in try/catch ([#2519](https://github.com/fallenbagel/jellyseerr/issues/2519)) ([a76b608](https://github.com/fallenbagel/jellyseerr/commit/a76b608ab796944c0c660e3296a7aca6615d69f3))
* **email:** use decrypted private key ([#2232](https://github.com/fallenbagel/jellyseerr/issues/2232)) ([8d29685](https://github.com/fallenbagel/jellyseerr/commit/8d2968572a569ed77a4d7c14ae1dc69935fa847e))
* fix usertype from local user to mediaServerType ([25bee8b](https://github.com/fallenbagel/jellyseerr/commit/25bee8b9f70d7948191ba9cf07d16427da81d425))
* **frontend:** disable autocomplete on search field ([#2592](https://github.com/fallenbagel/jellyseerr/issues/2592)) ([82d1617](https://github.com/fallenbagel/jellyseerr/commit/82d16177bf763fe8097b4aae326793e3e21e847d))
* **frontend:** more issues-related fixes ([#2234](https://github.com/fallenbagel/jellyseerr/issues/2234)) ([3ec4a9c](https://github.com/fallenbagel/jellyseerr/commit/3ec4a9c76e1f31bee5c8801b389721bf8e5884e0))
* **frontend:** notification type validation ([#2207](https://github.com/fallenbagel/jellyseerr/issues/2207)) ([2f204b9](https://github.com/fallenbagel/jellyseerr/commit/2f204b995269a53ae36f2a8733f27ae6ab70da5a))
* **frontend:** setup page backdrops ([#2251](https://github.com/fallenbagel/jellyseerr/issues/2251)) ([78a8091](https://github.com/fallenbagel/jellyseerr/commit/78a8091bcd29a7cf50cc7c493c28710389817adf))
* **frontend:** theme-color meta tag ([#2420](https://github.com/fallenbagel/jellyseerr/issues/2420)) ([ff28c9b](https://github.com/fallenbagel/jellyseerr/commit/ff28c9bfebf4a930e2542ee3b3c35f8af4e1b97e))
* **frontend:** use consistent formatting & strings ([#2231](https://github.com/fallenbagel/jellyseerr/issues/2231)) ([2164471](https://github.com/fallenbagel/jellyseerr/commit/216447121b686b6d01a31b95ec0c8eb005f6b103))
* **frontend:** various fixes ([#2524](https://github.com/fallenbagel/jellyseerr/issues/2524)) ([c3dbd0d](https://github.com/fallenbagel/jellyseerr/commit/c3dbd0d6913946e0e1b5308edfbb5ca744740223))
* handle Plex library settings migration failure gracefully ([#2254](https://github.com/fallenbagel/jellyseerr/issues/2254)) ([ed53810](https://github.com/fallenbagel/jellyseerr/commit/ed53810fb33f70722361c67d176ff4edf531ba45))
* **holiday:** remove special holiday slider ([22f2037](https://github.com/fallenbagel/jellyseerr/commit/22f2037ea6c5a0ba2ffa4d69f2b7cf42bdcf8575))
* **issues:** only allow edit of own comments & do not allow non-admin delete of issues with comments ([#2248](https://github.com/fallenbagel/jellyseerr/issues/2248)) ([bba09d6](https://github.com/fallenbagel/jellyseerr/commit/bba09d69c1bc55c2f35db5a7986e7c935cc9619c))
* jellyfin user signin after manual user import ([36c3c9d](https://github.com/fallenbagel/jellyseerr/commit/36c3c9d7c60176a5c4090b86313743b3ce433406))
* **lang:** add missing string ([#2370](https://github.com/fallenbagel/jellyseerr/issues/2370)) ([d36c1d2](https://github.com/fallenbagel/jellyseerr/commit/d36c1d29295020efb76bac21a443b6f9049802f3))
* **lang:** rename 'Media' notification types for clarity ([#2400](https://github.com/fallenbagel/jellyseerr/issues/2400)) ([399b037](https://github.com/fallenbagel/jellyseerr/commit/399b0379186ed34dcc436bd95330fd1a05fef4b3))
* **lang:** string edits ([#2229](https://github.com/fallenbagel/jellyseerr/issues/2229)) ([ab20c21](https://github.com/fallenbagel/jellyseerr/commit/ab20c21184639e1c7725f7cae96249c6fa157351))
* **lang:** translations update from Hosted Weblate ([#2625](https://github.com/fallenbagel/jellyseerr/issues/2625)) ([19cdedd](https://github.com/fallenbagel/jellyseerr/commit/19cdedd2a6656b1a852e1cc653bbdb140e978b51))
* **lang:** translations update from Hosted Weblate ([#2639](https://github.com/fallenbagel/jellyseerr/issues/2639)) ([418a533](https://github.com/fallenbagel/jellyseerr/commit/418a533588bbbdbbbb4caee1ef91d57c1ca35717))
* **lang:** translations update from Weblate ([#2212](https://github.com/fallenbagel/jellyseerr/issues/2212)) ([85aec4f](https://github.com/fallenbagel/jellyseerr/commit/85aec4f8925746ebae9bcc99d8480b78ccfd851e))
* **logs:** handle log message nested extra properties ([#2459](https://github.com/fallenbagel/jellyseerr/issues/2459)) ([d777940](https://github.com/fallenbagel/jellyseerr/commit/d7779408d162949b2eafcacefc8eabe53fae229f))
* **logs:** handle unexpected log messages ([#2303](https://github.com/fallenbagel/jellyseerr/issues/2303)) ([f284e4a](https://github.com/fallenbagel/jellyseerr/commit/f284e4ab978e502d2cc08e76226a8ebac91bb48f))
* **logs:** lazily parse log message label ([#2359](https://github.com/fallenbagel/jellyseerr/issues/2359)) ([5af06bd](https://github.com/fallenbagel/jellyseerr/commit/5af06bd87226fbc6176b0c5e362824793165a34e))
* **notif:** correct issue notif action URLs ([#2333](https://github.com/fallenbagel/jellyseerr/issues/2333)) ([dc7f959](https://github.com/fallenbagel/jellyseerr/commit/dc7f959cb422a8d89bcebc78377f1513412e542c))
* **notif:** duplicate notification check logic ([#2424](https://github.com/fallenbagel/jellyseerr/issues/2424)) ([10651ba](https://github.com/fallenbagel/jellyseerr/commit/10651baa675993f7109989bbac67f54661c8693f))
* **notif:** only send MEDIA_AVAILABLE notifications for non-declined requests ([#2343](https://github.com/fallenbagel/jellyseerr/issues/2343)) ([fcb0dcf](https://github.com/fallenbagel/jellyseerr/commit/fcb0dcf5be64bf9ca814bfe119586908922099c5))
* **notif:** show event in pop up notification for slack ([#2413](https://github.com/fallenbagel/jellyseerr/issues/2413)) ([d4438c8](https://github.com/fallenbagel/jellyseerr/commit/d4438c82e3753c9b29b6269ad406d263b3fcef4c)), closes [#2408](https://github.com/fallenbagel/jellyseerr/issues/2408)
* only run scheduled mediaserver jobs that apply to the current mediaserver ([791106a](https://github.com/fallenbagel/jellyseerr/commit/791106a7f5b8356b67119300bad245f587f6dc5f))
* play on Jellyfin for TV shows ([d0c5481](https://github.com/fallenbagel/jellyseerr/commit/d0c5481d22ddceee0b5c3d7d82029f44c46dbbd0))
* plex Login ([9d54776](https://github.com/fallenbagel/jellyseerr/commit/9d54776a2c4c23a61d5e619ca952b9e5d947a79b))
* **plex:** correctly generate uuid for safari ([#2614](https://github.com/fallenbagel/jellyseerr/issues/2614)) ([d06f2cd](https://github.com/fallenbagel/jellyseerr/commit/d06f2cdb08bfa6f05cf7cec2c408a258fa926b09))
* **plex:** find TV series in addition to movies from IMDb IDs ([#1830](https://github.com/fallenbagel/jellyseerr/issues/1830)) ([30644f6](https://github.com/fallenbagel/jellyseerr/commit/30644f65ea2e8437676422ae0b083c642a836887))
* **plex:** include 'Overseerr' in X-Plex-Device-Name header ([#2635](https://github.com/fallenbagel/jellyseerr/issues/2635)) ([d4f9650](https://github.com/fallenbagel/jellyseerr/commit/d4f9650cd07704a97f8b591b7de7351c1e85b825))
* **plex:** use unique client identifier ([#2602](https://github.com/fallenbagel/jellyseerr/issues/2602)) ([648b346](https://github.com/fallenbagel/jellyseerr/commit/648b346cbe5a941c7e1ec4ddfb276fb0e27ed502))
* **plex:** user import ([#2442](https://github.com/fallenbagel/jellyseerr/issues/2442)) ([86dff12](https://github.com/fallenbagel/jellyseerr/commit/86dff12cdeef6dca92527dd31757a3a4c7f921bf))
* **radarr:** correctly check for existing movies ([#2490](https://github.com/fallenbagel/jellyseerr/issues/2490)) ([5d4b06b](https://github.com/fallenbagel/jellyseerr/commit/5d4b06bbcc6cf6d328f6b4a86c4c0f9b0f3aff3e))
* **radarr:** remove PreDB minimum availability option ([#2386](https://github.com/fallenbagel/jellyseerr/issues/2386)) ([3e5eb4e](https://github.com/fallenbagel/jellyseerr/commit/3e5eb4e148a9f88b871abc4ee1784b870f691534))
* relax jellyfin url validation to allow local domains ([3a010f8](https://github.com/fallenbagel/jellyseerr/commit/3a010f821189414efd334b4cad2a300501f40a18))
* replaced unknown job with jellyfin in jobsandcache and added translations for it ([f09b86a](https://github.com/fallenbagel/jellyseerr/commit/f09b86aa87d84af1ddee07390a04dd8543cff8a6))
* **requests:** check for existing media of same type when requesting ([#2445](https://github.com/fallenbagel/jellyseerr/issues/2445)) ([eb9ca2e](https://github.com/fallenbagel/jellyseerr/commit/eb9ca2e86f3be3f4ff8ee2e7c4aecdf337d8976d))
* **requests:** do not fail request edits if acting user lacks Manage Users permission ([#2338](https://github.com/fallenbagel/jellyseerr/issues/2338)) ([91bfff7](https://github.com/fallenbagel/jellyseerr/commit/91bfff71b7c05c9b9aad2c95282533eefbb6b2e7))
* **scripts:** update migration scripts ([#2208](https://github.com/fallenbagel/jellyseerr/issues/2208)) [skip ci] ([d0ac74e](https://github.com/fallenbagel/jellyseerr/commit/d0ac74ea4bbfcf3d25d30cbd422d9df1c1259a18))
* secure session cookie ([#2308](https://github.com/fallenbagel/jellyseerr/issues/2308)) ([7f330af](https://github.com/fallenbagel/jellyseerr/commit/7f330aff2e1d3546e8dd1a3e4b037b9beb1cc7f0))
* **servarr:** handle baseurl error when testing connection ([#2294](https://github.com/fallenbagel/jellyseerr/issues/2294)) ([93b5ea2](https://github.com/fallenbagel/jellyseerr/commit/93b5ea20ca590996f6dc90713a76800180d0621c))
* **servarr:** handle servaarr server being unavailable when scanning downloads ([#2358](https://github.com/fallenbagel/jellyseerr/issues/2358)) ([488874f](https://github.com/fallenbagel/jellyseerr/commit/488874fc17e4e4719e90d383b83b1e1a5217213b))
* **sonarr:** monitor existing series upon request approval ([#2553](https://github.com/fallenbagel/jellyseerr/issues/2553)) ([aa062d9](https://github.com/fallenbagel/jellyseerr/commit/aa062d921c425d4b64bfdb28a5f102b0c92f7d87))
* **sonarr:** only scan seasons that exist in TMDb ([#2523](https://github.com/fallenbagel/jellyseerr/issues/2523)) ([6168185](https://github.com/fallenbagel/jellyseerr/commit/61681857b123802aaeff02a8f61b1ba046c5d333))
* sort collection parts by release date ([#2368](https://github.com/fallenbagel/jellyseerr/issues/2368)) ([1b3797c](https://github.com/fallenbagel/jellyseerr/commit/1b3797cf6e6ef6b3d8c81e644382f6e3f68cfaaa))
* **tautulli:** fetch additional user history as necessary to return 20 unique media ([#2446](https://github.com/fallenbagel/jellyseerr/issues/2446)) ([7d19de6](https://github.com/fallenbagel/jellyseerr/commit/7d19de6a4af6297be18140ca59402b40f7bbb30b))
* **ui:** Fix webhook URL validation regex ([#864](https://github.com/fallenbagel/jellyseerr/issues/864)) ([726f62b](https://github.com/fallenbagel/jellyseerr/commit/726f62b9b69b5078e718f129e26abdf358f5cb06))
* **ui:** refinements for 'About' page ([#2173](https://github.com/fallenbagel/jellyseerr/issues/2173)) ([084a842](https://github.com/fallenbagel/jellyseerr/commit/084a842a4f9b6caaed22edbe77bc9e414bc1f387))
* **ui:** request badge styling in request list ([#2302](https://github.com/fallenbagel/jellyseerr/issues/2302)) ([f2375c9](https://github.com/fallenbagel/jellyseerr/commit/f2375c902b79dcb1f349500862775ae57ea7d406))
### Features
* **about:** show config directory ([#2600](https://github.com/fallenbagel/jellyseerr/issues/2600)) ([0c7373c](https://github.com/fallenbagel/jellyseerr/commit/0c7373c7e89a4ff717efaa7d6a5854f7ccd6a8d3))
* add emby detail url support ([88c2c5e](https://github.com/fallenbagel/jellyseerr/commit/88c2c5ebcddd1eb8aea4a4e72c68a91197dec065))
* add production countries to movie/TV detail pages ([#2170](https://github.com/fallenbagel/jellyseerr/issues/2170)) ([30b20df](https://github.com/fallenbagel/jellyseerr/commit/30b20df37a9604ba1c066f89e54a5482a09575ea))
* add quotas, advanced options, and toggles to collection request modal ([#1742](https://github.com/fallenbagel/jellyseerr/issues/1742)) ([af40212](https://github.com/fallenbagel/jellyseerr/commit/af40212a738f8d6d9a5bf26dc20c0c87780d6020))
* allow Jellyfin to set a playback URL different to the Jellyfin host specified during setup ([9fbc407](https://github.com/fallenbagel/jellyseerr/commit/9fbc4074e491bbeba7880fd54c99d4e3c95c7d01))
* **api:** add additional request counts ([#2426](https://github.com/fallenbagel/jellyseerr/issues/2426)) ([2535edc](https://github.com/fallenbagel/jellyseerr/commit/2535edcc7fd6ec66fd45ad754c03929f1fe94871))
* **discord:** add 'Enable Mentions' setting ([#1779](https://github.com/fallenbagel/jellyseerr/issues/1779)) ([5f7538a](https://github.com/fallenbagel/jellyseerr/commit/5f7538ae2bf9c6e2feea385cc299bd08df071218))
* display release dates for theatrical, digital, and physical release types ([#1492](https://github.com/fallenbagel/jellyseerr/issues/1492)) ([a4dca23](https://github.com/fallenbagel/jellyseerr/commit/a4dca2356b7605026f7bc45b691496e765c3328c))
* dynamically fetch login screen backdrop images ([#2206](https://github.com/fallenbagel/jellyseerr/issues/2206)) ([3486d0b](https://github.com/fallenbagel/jellyseerr/commit/3486d0bf5520cbdff60bd8fd023caed76c452973))
* **frontend:** add Discovery+ to network slider ([#2345](https://github.com/fallenbagel/jellyseerr/issues/2345)) ([2ded8f5](https://github.com/fallenbagel/jellyseerr/commit/2ded8f5484168bd7b8f45124d9ebdd296a5708d5))
* **frontend:** add Hulu to network slider ([#2204](https://github.com/fallenbagel/jellyseerr/issues/2204)) ([1e402f7](https://github.com/fallenbagel/jellyseerr/commit/1e402f710b53c11855aab0abdb4b12c51c30b022))
* **frontend:** open media management slideover on status badge click ([#2407](https://github.com/fallenbagel/jellyseerr/issues/2407)) ([1f5785d](https://github.com/fallenbagel/jellyseerr/commit/1f5785d6c53b2ca2da67a8ccee72165c052c61a1))
* implement import users from Jellyfin button ([9e2f3f0](https://github.com/fallenbagel/jellyseerr/commit/9e2f3f06393e71ba5d1c0ba3c9512b64a3ce3ad7))
* initialize Jellyfin/Emby users with local login ([103350f](https://github.com/fallenbagel/jellyseerr/commit/103350fe146fbf212b12a3348bcfb40399e1a0fc))
* issues ([#2180](https://github.com/fallenbagel/jellyseerr/issues/2180)) ([e402c42](https://github.com/fallenbagel/jellyseerr/commit/e402c42aaa7d795cd724856a2e23615bb1a3695d))
* **jobs:** allow modifying job schedules ([#1440](https://github.com/fallenbagel/jellyseerr/issues/1440)) ([82614ca](https://github.com/fallenbagel/jellyseerr/commit/82614ca4410782a12d65b4c0a6526ff064be1241))
* **lang:** add Albanian display language ([#2605](https://github.com/fallenbagel/jellyseerr/issues/2605)) ([3d32462](https://github.com/fallenbagel/jellyseerr/commit/3d32462f50b4ced0d9205b79003c35d6d1c948a3))
* **lang:** add Czech and Danish display languages ([#2176](https://github.com/fallenbagel/jellyseerr/issues/2176)) ([8d8db6c](https://github.com/fallenbagel/jellyseerr/commit/8d8db6cf5d98d4e498a31db339d02f8a98057c8d))
* **lang:** add Polish display language ([#2261](https://github.com/fallenbagel/jellyseerr/issues/2261)) ([c760cea](https://github.com/fallenbagel/jellyseerr/commit/c760ceaa5f36c77fa3ce320fae1b4597d2d8b976))
* **lang:** translated using Weblate (Chinese (Traditional)) ([#2272](https://github.com/fallenbagel/jellyseerr/issues/2272)) ([d401e33](https://github.com/fallenbagel/jellyseerr/commit/d401e33249cbbca6e707479e5f0207e298ef3248))
* **lang:** translations update from Hosted Weblate ([#2277](https://github.com/fallenbagel/jellyseerr/issues/2277)) ([92732fc](https://github.com/fallenbagel/jellyseerr/commit/92732fcb42c56242d16daab00e2d38740b92dea0))
* **lang:** translations update from Hosted Weblate ([#2315](https://github.com/fallenbagel/jellyseerr/issues/2315)) ([6245be1](https://github.com/fallenbagel/jellyseerr/commit/6245be1e10dda67c869b59522c1290e7c100145f))
* **lang:** translations update from Hosted Weblate ([#2320](https://github.com/fallenbagel/jellyseerr/issues/2320)) ([68112fa](https://github.com/fallenbagel/jellyseerr/commit/68112faefbd64d5c71d3eff21620767f88ccfc34))
* **lang:** translations update from Hosted Weblate ([#2325](https://github.com/fallenbagel/jellyseerr/issues/2325)) ([febf067](https://github.com/fallenbagel/jellyseerr/commit/febf0677b880d2fed2822ce510db7cbb0826a920))
* **lang:** translations update from Hosted Weblate ([#2336](https://github.com/fallenbagel/jellyseerr/issues/2336)) ([3f7ef7a](https://github.com/fallenbagel/jellyseerr/commit/3f7ef7af97a807ef38041f4f2642b565aa33d066))
* **lang:** translations update from Hosted Weblate ([#2341](https://github.com/fallenbagel/jellyseerr/issues/2341)) ([33fe0bd](https://github.com/fallenbagel/jellyseerr/commit/33fe0bdd1e00da40e85b4e4b4780134b31a105d2))
* **lang:** translations update from Hosted Weblate ([#2346](https://github.com/fallenbagel/jellyseerr/issues/2346)) ([50dc934](https://github.com/fallenbagel/jellyseerr/commit/50dc9341dd98cb2d8ef3ef6471882a5a9b060afa))
* **lang:** translations update from Hosted Weblate ([#2364](https://github.com/fallenbagel/jellyseerr/issues/2364)) ([d437cc2](https://github.com/fallenbagel/jellyseerr/commit/d437cc25392e9c0881888371ffabc82892a1b15c))
* **lang:** translations update from Hosted Weblate ([#2366](https://github.com/fallenbagel/jellyseerr/issues/2366)) ([cc2b2bc](https://github.com/fallenbagel/jellyseerr/commit/cc2b2bc7a8ecd89e1feb38a907596b16df9bf0fc))
* **lang:** translations update from Hosted Weblate ([#2374](https://github.com/fallenbagel/jellyseerr/issues/2374)) ([b9bedac](https://github.com/fallenbagel/jellyseerr/commit/b9bedac7d7ba85223ecf1d9b93b96e2a490d571a))
* **lang:** translations update from Hosted Weblate ([#2379](https://github.com/fallenbagel/jellyseerr/issues/2379)) ([bd93168](https://github.com/fallenbagel/jellyseerr/commit/bd93168ba1ed650baf4024569bb6a76811a99820))
* **lang:** translations update from Hosted Weblate ([#2389](https://github.com/fallenbagel/jellyseerr/issues/2389)) ([d2241a4](https://github.com/fallenbagel/jellyseerr/commit/d2241a41877d126a802fc53c925d258af31f34fd))
* **lang:** translations update from Hosted Weblate ([#2404](https://github.com/fallenbagel/jellyseerr/issues/2404)) ([1b29b15](https://github.com/fallenbagel/jellyseerr/commit/1b29b15d7c9a7ec918cb59116d60e1ae2e797dc4))
* **lang:** translations update from Hosted Weblate ([#2405](https://github.com/fallenbagel/jellyseerr/issues/2405)) ([879df20](https://github.com/fallenbagel/jellyseerr/commit/879df20022c8c5d9b32858ac5499d3e4369fc064))
* **lang:** translations update from Hosted Weblate ([#2414](https://github.com/fallenbagel/jellyseerr/issues/2414)) ([88536b1](https://github.com/fallenbagel/jellyseerr/commit/88536b1f9d6e8c1a11e1adf91b85bab4f34b751c))
* **lang:** translations update from Hosted Weblate ([#2425](https://github.com/fallenbagel/jellyseerr/issues/2425)) ([e9d4b63](https://github.com/fallenbagel/jellyseerr/commit/e9d4b6327b50a005ee6c2c3292b6f107e90fc50c))
* **lang:** translations update from Hosted Weblate ([#2428](https://github.com/fallenbagel/jellyseerr/issues/2428)) ([f8b1bcc](https://github.com/fallenbagel/jellyseerr/commit/f8b1bccda44371bb6f3f8f4ceeab900b1df3de31))
* **lang:** translations update from Hosted Weblate ([#2436](https://github.com/fallenbagel/jellyseerr/issues/2436)) ([99c0407](https://github.com/fallenbagel/jellyseerr/commit/99c04072e9f7be8191f25cbcfd5103017b8796eb))
* **lang:** translations update from Hosted Weblate ([#2452](https://github.com/fallenbagel/jellyseerr/issues/2452)) ([b5bd6ee](https://github.com/fallenbagel/jellyseerr/commit/b5bd6ee78f3d4aa14f0c440d1f2a8323dccfa399))
* **lang:** translations update from Hosted Weblate ([#2457](https://github.com/fallenbagel/jellyseerr/issues/2457)) ([92b2d32](https://github.com/fallenbagel/jellyseerr/commit/92b2d32d2e1e1d319410a9e357e1304065a77598))
* **lang:** translations update from Hosted Weblate ([#2489](https://github.com/fallenbagel/jellyseerr/issues/2489)) ([ec08fa6](https://github.com/fallenbagel/jellyseerr/commit/ec08fa67934715ff4a4d618d5b9ff97853913b78))
* **lang:** translations update from Hosted Weblate ([#2508](https://github.com/fallenbagel/jellyseerr/issues/2508)) ([9f4ae34](https://github.com/fallenbagel/jellyseerr/commit/9f4ae34da76707a40e2c89a50c722ffa1c0327c0))
* **lang:** translations update from Hosted Weblate ([#2531](https://github.com/fallenbagel/jellyseerr/issues/2531)) ([54b32eb](https://github.com/fallenbagel/jellyseerr/commit/54b32ebfd6b2eb6aeeea98c25939166eda8cc17f))
* **lang:** translations update from Hosted Weblate ([#2541](https://github.com/fallenbagel/jellyseerr/issues/2541)) ([4549ed3](https://github.com/fallenbagel/jellyseerr/commit/4549ed389e4f25c0946dc01526387e5ac000c3cf))
* **lang:** translations update from Hosted Weblate ([#2611](https://github.com/fallenbagel/jellyseerr/issues/2611)) ([81c75c8](https://github.com/fallenbagel/jellyseerr/commit/81c75c800edf6d36a1082a291ef7e308f338d005))
* **lang:** translations update from Hosted Weblate ([#2629](https://github.com/fallenbagel/jellyseerr/issues/2629)) ([1d0cbd2](https://github.com/fallenbagel/jellyseerr/commit/1d0cbd2e761072be0b4b3de461397ad9f9f681f3))
* **lang:** translations update from Hosted Weblate ([#2645](https://github.com/fallenbagel/jellyseerr/issues/2645)) ([341e3b8](https://github.com/fallenbagel/jellyseerr/commit/341e3b8f0657e09f53ad0b813b051290947343c0))
* **lang:** translations update from Weblate ([#2101](https://github.com/fallenbagel/jellyseerr/issues/2101)) ([c73cf7b](https://github.com/fallenbagel/jellyseerr/commit/c73cf7b19cbc19e97a777c0facb9264fb0113093))
* **lang:** translations update from Weblate ([#2179](https://github.com/fallenbagel/jellyseerr/issues/2179)) ([e3312ce](https://github.com/fallenbagel/jellyseerr/commit/e3312cef33821c8cb76a4a63bd565c78d67b3e0b))
* **lang:** translations update from Weblate ([#2185](https://github.com/fallenbagel/jellyseerr/issues/2185)) ([dce10f7](https://github.com/fallenbagel/jellyseerr/commit/dce10f743f52cb04036e2cdaee280e26a81b253b))
* **lang:** translations update from Weblate ([#2202](https://github.com/fallenbagel/jellyseerr/issues/2202)) ([492d8e3](https://github.com/fallenbagel/jellyseerr/commit/492d8e3daa5fb99aa9df2a18978085d5ddd581e7))
* **lang:** translations update from Weblate ([#2210](https://github.com/fallenbagel/jellyseerr/issues/2210)) ([0a6ef6c](https://github.com/fallenbagel/jellyseerr/commit/0a6ef6cc81376f7a02f1483109be7ae4ab851c48))
* **lang:** translations update from Weblate ([#2226](https://github.com/fallenbagel/jellyseerr/issues/2226)) ([62b3dc5](https://github.com/fallenbagel/jellyseerr/commit/62b3dc5471c28f4d0e4399cb3bc8bfab94cff5ea))
* **lang:** translations update from Weblate ([#2241](https://github.com/fallenbagel/jellyseerr/issues/2241)) ([2b0b8e0](https://github.com/fallenbagel/jellyseerr/commit/2b0b8e05d9c95ff9218cea858a920a2815871186))
* **lang:** translations update from Weblate ([#2244](https://github.com/fallenbagel/jellyseerr/issues/2244)) ([0828b00](https://github.com/fallenbagel/jellyseerr/commit/0828b008badc8b512316799a6787bb7c403658d5))
* **lang:** translations update from Weblate ([#2247](https://github.com/fallenbagel/jellyseerr/issues/2247)) ([8c49309](https://github.com/fallenbagel/jellyseerr/commit/8c49309c35c31f7bcd0b84b0a307febc16842f68))
* **lang:** translations update from Weblate ([#2252](https://github.com/fallenbagel/jellyseerr/issues/2252)) ([99d5000](https://github.com/fallenbagel/jellyseerr/commit/99d50004e58f6b4594df0a171f6bc668635ec50c))
* **lang:** translations update from Weblate ([#2265](https://github.com/fallenbagel/jellyseerr/issues/2265)) ([b1b367a](https://github.com/fallenbagel/jellyseerr/commit/b1b367aac625ed3eb865832c94c2352e5a5c40f5))
* **logs:** use separate json file to parse logs for log viewer ([#2399](https://github.com/fallenbagel/jellyseerr/issues/2399)) ([ce31bef](https://github.com/fallenbagel/jellyseerr/commit/ce31bef8a125c5492f2a1cfef0dcf3d8a4e9ee11))
* **notif:** 4K media notifications ([#2324](https://github.com/fallenbagel/jellyseerr/issues/2324)) ([88a8c1a](https://github.com/fallenbagel/jellyseerr/commit/88a8c1aa596e1113d6da52e5e8cbe443abc6384f))
* **notif:** add Gotify agent ([#2196](https://github.com/fallenbagel/jellyseerr/issues/2196)) ([e0b6abe](https://github.com/fallenbagel/jellyseerr/commit/e0b6abe4796f5a324c0ff78cff317fcaead671f1)), closes [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2077](https://github.com/fallenbagel/jellyseerr/issues/2077) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2077](https://github.com/fallenbagel/jellyseerr/issues/2077) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183) [#2183](https://github.com/fallenbagel/jellyseerr/issues/2183)
* **notif:** add Pushbullet and Pushover agents to user notification settings ([#1740](https://github.com/fallenbagel/jellyseerr/issues/1740)) ([aeb7a48](https://github.com/fallenbagel/jellyseerr/commit/aeb7a48d72cec3fa2b857030aad3eaa0a457a896))
* **notif:** add Pushbullet channel tag ([#2198](https://github.com/fallenbagel/jellyseerr/issues/2198)) ([f9200b7](https://github.com/fallenbagel/jellyseerr/commit/f9200b7977208f9b8267ce3a74bd8a86d6f28f7b))
* **notif:** issue notifications ([#2242](https://github.com/fallenbagel/jellyseerr/issues/2242)) ([c9ffac3](https://github.com/fallenbagel/jellyseerr/commit/c9ffac33f7c04d926f8c45295703689d42fe87af))
* **plex:** selective user import ([#2188](https://github.com/fallenbagel/jellyseerr/issues/2188)) ([9cb97db](https://github.com/fallenbagel/jellyseerr/commit/9cb97db13ced5df2dc595cd9033470b1a0750093))
* remove email requirement for jellyfin/emby non-admin users ([3e1e11d](https://github.com/fallenbagel/jellyseerr/commit/3e1e11d9d93e5d055c92989361a3ced3b77b1d39))
* **search:** close search bar when hitting return ([#2260](https://github.com/fallenbagel/jellyseerr/issues/2260)) ([b423dc1](https://github.com/fallenbagel/jellyseerr/commit/b423dc167d12f0ba49f902876bceb2e876e35f58))
* **search:** filter search results by year ([#2460](https://github.com/fallenbagel/jellyseerr/issues/2460)) ([72c825d](https://github.com/fallenbagel/jellyseerr/commit/72c825d2a5109688bcc1991a30249284bf281500))
* **search:** search by id ([#2082](https://github.com/fallenbagel/jellyseerr/issues/2082)) ([b31cdbf](https://github.com/fallenbagel/jellyseerr/commit/b31cdbf074d5dbecbbf6da135a9b686aea9e3c0e))
* **servarr:** auto fill base url when testing service if missing ([#1995](https://github.com/fallenbagel/jellyseerr/issues/1995)) ([739f667](https://github.com/fallenbagel/jellyseerr/commit/739f667b54d8dec258b74d0cd8fd8b3b88dcf8d5))
* Tautulli integration ([#2230](https://github.com/fallenbagel/jellyseerr/issues/2230)) ([0842c23](https://github.com/fallenbagel/jellyseerr/commit/0842c233d0fc56d44824cad18749492cd52cbed5))
* **tautulli:** validate upon saving settings ([#2511](https://github.com/fallenbagel/jellyseerr/issues/2511)) ([1dc900d](https://github.com/fallenbagel/jellyseerr/commit/1dc900d5ce9689d179c9d2f554abc74ca50bd9cb))
* **ui:** add trakt external link ([#2367](https://github.com/fallenbagel/jellyseerr/issues/2367)) ([4e56bae](https://github.com/fallenbagel/jellyseerr/commit/4e56bae98508c1a60aeb3a08560ba1c00acce7e7))
* **ui:** allow admins to edit & approve request from advanced request modal ([#2067](https://github.com/fallenbagel/jellyseerr/issues/2067)) ([340f1a2](https://github.com/fallenbagel/jellyseerr/commit/340f1a211952bd2e8f40f0ea4622b52dbe934e85))
* **ui:** link processing/requested status badges to service URL ([#1761](https://github.com/fallenbagel/jellyseerr/issues/1761)) ([032c14a](https://github.com/fallenbagel/jellyseerr/commit/032c14a22680f62f8106943297b081b68645ce61))
* verify Plex server access during auth for existing users with Plex IDs ([#2458](https://github.com/fallenbagel/jellyseerr/issues/2458)) ([85bb30e](https://github.com/fallenbagel/jellyseerr/commit/85bb30e252c27047ae367491f0e5bb92a7d52605))
- **api:** adds support for Mixed Libraries ([ba82ece](https://github.com/fallenbagel/jellyseerr/commit/ba82ecec5c994e79d7c9b658372041522b58a120)), closes [#95](https://github.com/fallenbagel/jellyseerr/issues/95)
- custom image proxy ([#3056](https://github.com/fallenbagel/jellyseerr/issues/3056)) ([500cd1f](https://github.com/fallenbagel/jellyseerr/commit/500cd1f872942923d2b9c3b835e6329e335d4a3f))
- **lang:** add Croatian display language ([#3041](https://github.com/fallenbagel/jellyseerr/issues/3041)) ([64aab6d](https://github.com/fallenbagel/jellyseerr/commit/64aab6dd8240e191026512733b34cc046b6e508a))
## [1.29.1](https://github.com/sct/overseerr/compare/v1.29.0...v1.29.1) (2022-04-06)

View File

@@ -1,4 +1,4 @@
# Contributing to Overseerr
# Contributing to Jellyseerr
All help is welcome and greatly appreciated! If you would like to contribute to the project, the following instructions should get you started...
@@ -17,7 +17,7 @@ All help is welcome and greatly appreciated! If you would like to contribute to
1. [Fork](https://help.github.com/articles/fork-a-repo/) the repository to your own GitHub account and [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device:
```bash
git clone https://github.com/YOUR_USERNAME/overseerr.git
git clone https://github.com/YOUR_USERNAME/jellyseerr.git
cd overseerr/
```
@@ -86,7 +86,7 @@ When adding new UI text, please try to adhere to the following guidelines:
1. Be concise and clear, and use as few words as possible to make your point.
2. Use the Oxford comma where appropriate.
3. Use the appropriate Unicode characters for ellipses, arrows, and other special characters/symbols.
4. Capitalize proper nouns, such as Plex, Radarr, Sonarr, Telegram, Slack, Pushover, etc. Be sure to also use the official capitalization for any abbreviations; e.g., TMDb and IMDb have a lowercase 'b', whereas TheTVDB has a capital 'B'.
4. Capitalize proper nouns, such as Plex, Radarr, Sonarr, Telegram, Slack, Pushover, etc. Be sure to also use the official capitalization for any abbreviations; e.g., IMDb has a lowercase 'b', whereas TMDB and TheTVDB have a capital 'B'.
5. Title case headings, button text, and form labels. Note that verbs such as "is" should be capitalized, whereas prepositions like "from" should be lowercase (unless as the first or last word of the string, in which case they are also capitalized).
6. Capitalize the first word in validation error messages, dropdowns, and form "tips." These strings should not end in punctuation.
7. Ensure that toast notification strings are complete sentences ending in punctuation.
@@ -97,9 +97,9 @@ When adding new UI text, please try to adhere to the following guidelines:
## Translation
We use [Weblate](https://hosted.weblate.org/engage/overseerr/) for our translations, and your help with localizing Overseerr would be greatly appreciated! If your language is not listed below, please [open a feature request](https://github.com/fallenbagel/jellyseerr/issues/new/choose).
We use [Weblate](https://jellyseerr.borgcube.de/projects/jellyseerr/jellyseerr-frontend/) for our translations, and your help with localizing Overseerr would be greatly appreciated! If your language is not listed below, please [open a feature request](https://github.com/fallenbagel/jellyseerr/issues/new/choose).
<a href="https://hosted.weblate.org/engage/overseerr/"><img src="https://hosted.weblate.org/widgets/overseerr/-/overseerr-frontend/multi-auto.svg" alt="Translation status" /></a>
<a href="https://jellyseerr.borgcube.de/engage/jellysseerr/"><img src="https://jellyseerr.borgcube.de/widget/jellyseerr/multi-auto.svg" alt="Translation status" /></a>
## Attribution

View File

@@ -1,4 +1,4 @@
FROM node:16.14-alpine AS BUILD_IMAGE
FROM node:18.18-alpine AS BUILD_IMAGE
WORKDIR /app
@@ -7,14 +7,15 @@ ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
RUN \
case "${TARGETPLATFORM}" in \
'linux/arm64' | 'linux/arm/v7') \
apk add --no-cache python3 make g++ && \
ln -s /usr/bin/python3 /usr/bin/python \
;; \
'linux/arm64' | 'linux/arm/v7') \
apk update && \
apk add --no-cache python3 make g++ gcc libc6-compat bash && \
yarn global add node-gyp \
;; \
esac
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --network-timeout 1000000
RUN CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile --network-timeout 1000000
COPY . ./
@@ -33,7 +34,10 @@ RUN touch config/DOCKER
RUN echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json
FROM node:16.14-alpine
FROM node:18.18-alpine
# Metadata for Github Package Registry
LABEL org.opencontainers.image.source="https://github.com/Fallenbagel/jellyseerr"
WORKDIR /app

View File

@@ -1,4 +1,4 @@
FROM node:16.14-alpine
FROM node:18.18-alpine
COPY . /app
WORKDIR /app

334
README.md
View File

@@ -2,47 +2,152 @@
<img src="./public/logo_full.svg" alt="Jellyseerr" style="margin: 20px 0;">
</p>
<p align="center">
<a href="https://discord.gg/ckbvBtDJgC"><img src="https://img.shields.io/badge/Discord-Chat-lightgrey" alt="Discord"></a>
<a href="https://hub.docker.com/r/fallenbagel/jellyseerr"><img src="https://img.shields.io/docker/pulls/fallenbagel/jellyseerr" alt="Docker pulls"></a>
<a href="https://github.com/fallenbagel/jellyseerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/fallenbagel/jellyseerr"></a>
<img src="https://github.com/Fallenbagel/jellyseerr/actions/workflows/release.yml/badge.svg" alt="Jellyseerr Release" />
<img src="https://github.com/Fallenbagel/jellyseerr/actions/workflows/ci.yml/badge.svg" alt="Jellyseerr CI">
</p>
<p align="center">
<a href="https://discord.gg/ckbvBtDJgC"><img src="https://img.shields.io/discord/952656177924300932" alt="Discord"></a>
<a href="https://hub.docker.com/r/fallenbagel/jellyseerr"><img src="https://img.shields.io/docker/pulls/fallenbagel/jellyseerr" alt="Docker pulls"></a>
<a href="http://jellyseerr.borgcube.de/engage/jellyseerr/"><img src="http://jellyseerr.borgcube.de/widget/jellyseerr/jellyseerr-frontend/svg-badge.svg" alt="Translation status" /></a>
<a href="https://github.com/fallenbagel/jellyseerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/fallenbagel/jellyseerr"></a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-34-orange.svg"/></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
**Jellyseerr** is a free and open source software application for managing requests for your media library. It is a a fork of Overseerr built to bring support for Jellyfin & Emby media servers!
**Jellyseerr** is a free and open source software application for managing requests for your media library.
It is a fork of [Overseerr](https://github.com/sct/overseerr) built to bring support for [Jellyfin](https://github.com/jellyfin/jellyfin) & [Emby](https://github.com/MediaBrowser/Emby) media servers!
_The original Overseerr team have been busy and Jellyfin/Emby support aren't on their roadmap, so we started this project as we wanted to bring the Overseerr experience to the Jellyfin/Emby Community!_
## Current Features
- Jellyfin Support
- Emby Support
Along with all the existing Overseerr features:
- Full Plex integration. Authenticate and manage user access with Plex!
- Full Jellyfin/Emby/Plex integration including authentication with user import & management
- Supports Movies, Shows and Mixed Libraries
- Ability to change email addresses for smtp purposes
- Easy integration with your existing services. Currently, Jellyseerr supports Sonarr and Radarr. More to come!
- Plex library scan, to keep track of the titles which are already available.
- Jellyfin/Emby/Plex library scan, to keep track of the titles which are already available.
- Customizable request system, which allows users to request individual seasons or movies in a friendly, easy-to-use interface.
- Incredibly simple request management UI. Don't dig through the app to simply approve recent requests!
- Granular permission system.
- Support for various notification agents.
- Mobile-friendly design, for when you need to approve requests on the go!
(Upcoming Features include: Multiple Server Instances, and much more!)
With more features on the way! Check out our [issue tracker](https://github.com/fallenbagel/jellyseerr/issues) to see the features which have already been requested.
## Getting Started
Check out our dockerhub for instructions on how to install and run Jellyseerr:
#### Pre-requisite (Important)
_*On Jellyfin/Emby, ensure the `Settings > Home > Automatically group content from the following folders into views such as 'Movies', 'Music' and 'TV'` is turned off*_
### Launching Jellyseerr using Docker (Recommended)
Check out our docker hub for instructions on how to install and run Jellyseerr:
https://hub.docker.com/r/fallenbagel/jellyseerr
### Launching Jellyseerr manually:
### Building from source (ADVANCED):
```bash
yarn install
#### Windows
Pre-requisites:
- Nodejs [v18](https://nodejs.org/download/release/v18.18.2)
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install)
- Download/git clone the source code from the github (Either develop branch or main for stable)
```cmd
npm i -g win-node-env
set CYPRESS_INSTALL_BINARY=0
yarn install --frozen-lockfile --network-timeout 1000000
yarn run build
yarn start
```
(You can use task scheduler to run a bat script with `@echo off` and `yarn start` to run jellyseerr in the background)
_To set env variables such as `JELLYFIN_TYPE=emby` create a file called `.env` in the root directory of jellyseerr_
#### Linux
**Pre-requisites:**
- Nodejs [v18](https://nodejs.org/en/download/package-manager)
- [Yarn](https://classic.yarnpkg.com/lang/en/docs/install) (on Debian based distros, the package manager provided `yarn` is different and is a package called cmdlet. You can remove that using `apt-remove cmdlet` then install yarn using `npm install -g yarn`)
- Git
**Steps:**
1. Assuming you want the root folder for the jellyseerr source code to be cloned to `/opt`
```bash
cd /opt
```
2. Then execute the following commands to clone and checkout to the stable version
```bash
git clone https://github.com/Fallenbagel/jellyseerr.git && cd jellyseerr
git checkout main
```
3. Then install the dependencies and build the dist
```bash
CYPRESS_INSTALL_BINARY=0 yarn install --frozen-lockfile --network-timeout 1000000
yarn run build
```
4. Now you can start jellyseerr using `yarn start` and opening http://localhost:5055 in your browser.
5. If you want to run jellyseerr as a _Systemd-service:_
- assuming jellyseerr was cloned to `/opt/`
- first create the environment file at `/etc/jellyseerr/jellyseerr.conf`
Environment file:
```
# Jellyseerr's default port is 5055, if you want to use both, change this.
# specify on which port to listen
PORT=5055
# specify on which interface to listen, by default jellyseerr listens on all interfaces
#HOST=127.0.0.1
# Uncomment if your media server is emby instead of jellyfin.
# JELLYFIN_TYPE=emby
```
- Then run the command `which node` to find your node path (assuming it's at `/usr/bin/node`)
- Then create the service file using `sudo systemctl edit jellyseerr.service` or creating and editing a file at `/etc/systemd/system/jellyseerr.service`
Service file contents:
```
[Unit]
Description=Jellyseerr Service
Wants=network-online.target
After=network-online.target
[Service]
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
Environment=NODE_ENV=production
Type=exec
Restart=on-failure
WorkingDirectory=/opt/jellyseerr
ExecStart=/usr/bin/node dist/index.js
[Install]
WantedBy=multi-user.target
```
### Packages:
Archlinux: [AUR](https://aur.archlinux.org/packages/jellyseerr)
Nixpkg: [Nixpkg](https://search.nixos.org/packages?channel=unstable&show=jellyseerr)
Snap: [Snap](https://snapcraft.io/jellyseerr)
## Preview
@@ -69,3 +174,202 @@ Our [Code of Conduct](https://github.com/fallenbagel/jellyseerr/blob/develop/COD
## Contributing
You can help improve Jellyseerr too! Check out our [Contribution Guide](https://github.com/fallenbagel/jellyseerr/blob/develop/CONTRIBUTING.md) to get started.
## Contributors ✨
Thanks goes to these wonderful people from Overseerr ([emoji key](https://allcontributors.org/docs/en/emoji-key)) and all those that contributed directly to Jellyseerr:
### Jellyseerr Contributors ✨
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fallenbagel"><img src="https://avatars.githubusercontent.com/u/98979876?v=4?s=100" width="100px;" alt="Fallenbagel"/><br /><sub><b>Fallenbagel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Fallenbagel" title="Code">💻</a> <a href="#maintenance-Fallenbagel" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/seanzhang98"><img src="https://avatars.githubusercontent.com/u/34902361?v=4?s=100" width="100px;" alt="Sean"/><br /><sub><b>Sean</b></sub></a><br /><a href="#translation-seanzhang98" title="Translation">🌍</a> <a href="https://github.com/Fallenbagel/jellyseerr/commits?author=seanzhang98" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notfakie"><img src="https://avatars.githubusercontent.com/u/103784113?v=4?s=100" width="100px;" alt="notfakie"/><br /><sub><b>notfakie</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=notfakie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jumail"><img src="https://avatars.githubusercontent.com/u/7672055?v=4?s=100" width="100px;" alt="Mohamed Jumail"/><br /><sub><b>Mohamed Jumail</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/pulls?q=is%3Apr+reviewed-by%3AJumail" title="Reviewed Pull Requests">👀</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.heywhale.com"><img src="https://avatars.githubusercontent.com/u/4048787?v=4?s=100" width="100px;" alt="Shilong Jiang"/><br /><sub><b>Shilong Jiang</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jsl9208" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://jinas.me"><img src="https://avatars.githubusercontent.com/u/28459081?v=4?s=100" width="100px;" alt="Boring Dragon"/><br /><sub><b>Boring Dragon</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=boring-dragon" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sambartik"><img src="https://avatars.githubusercontent.com/u/63553146?v=4?s=100" width="100px;" alt="Samuel Bartík"/><br /><sub><b>Samuel Bartík</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=sambartik" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CyferShepard"><img src="https://avatars.githubusercontent.com/u/24864904?v=4?s=100" width="100px;" alt="Thegan Govender"/><br /><sub><b>Thegan Govender</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=CyferShepard" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jab416171"><img src="https://avatars.githubusercontent.com/u/345752?v=4?s=100" width="100px;" alt="jab416171"/><br /><sub><b>jab416171</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jab416171" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nvds.be"><img src="https://avatars.githubusercontent.com/u/5257222?v=4?s=100" width="100px;" alt="Nicolai Van der Storm"/><br /><sub><b>Nicolai Van der Storm</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=NicolaiVdS" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Smexhy"><img src="https://avatars.githubusercontent.com/u/4880625?v=4?s=100" width="100px;" alt="Smexhy"/><br /><sub><b>Smexhy</b></sub></a><br /><a href="#translation-Smexhy" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://dd06-dev.fr"><img src="https://avatars.githubusercontent.com/u/58089504?v=4?s=100" width="100px;" alt="dd060606"/><br /><sub><b>dd060606</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=dd060606" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://qwer.tz"><img src="https://avatars.githubusercontent.com/u/71837281?v=4?s=100" width="100px;" alt="Daniel"/><br /><sub><b>Daniel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=darmiel" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/undone37"><img src="https://avatars.githubusercontent.com/u/10513808?v=4?s=100" width="100px;" alt="undone37"/><br /><sub><b>undone37</b></sub></a><br /><a href="#translation-undone37" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/CheChu10"><img src="https://avatars.githubusercontent.com/u/32913133?v=4?s=100" width="100px;" alt="Chechu García"/><br /><sub><b>Chechu García</b></sub></a><br /><a href="#translation-CheChu10" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DimitriDR"><img src="https://avatars.githubusercontent.com/u/56969769?v=4?s=100" width="100px;" alt="Dimitri"/><br /><sub><b>Dimitri</b></sub></a><br /><a href="#translation-DimitriDR" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrey4korop"><img src="https://avatars.githubusercontent.com/u/24610708?v=4?s=100" width="100px;" alt="andrey4korop"/><br /><sub><b>andrey4korop</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=andrey4korop" title="Code">💻</a> <a href="#translation-andrey4korop" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://geoffrey-coulaud.fr"><img src="https://avatars.githubusercontent.com/u/20744730?v=4?s=100" width="100px;" alt="Geoffrey Coulaud"/><br /><sub><b>Geoffrey Coulaud</b></sub></a><br /><a href="#translation-GeoffreyCoulaud" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Pikachu920"><img src="https://avatars.githubusercontent.com/u/28607612?v=4?s=100" width="100px;" alt="Pikachu920"/><br /><sub><b>Pikachu920</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Pikachu920" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/yalagin"><img src="https://avatars.githubusercontent.com/u/12879142?v=4?s=100" width="100px;" alt="Maxim Yalagin"/><br /><sub><b>Maxim Yalagin</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=yalagin" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jeaboswell"><img src="https://avatars.githubusercontent.com/u/11653068?v=4?s=100" width="100px;" alt="Jesse Boswell"/><br /><sub><b>Jesse Boswell</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=jeaboswell" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/d-fendrich"><img src="https://avatars.githubusercontent.com/u/27904138?v=4?s=100" width="100px;" alt="d-fendrich"/><br /><sub><b>d-fendrich</b></sub></a><br /><a href="#translation-d-fendrich" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/davidfdezalcoba"><img src="https://avatars.githubusercontent.com/u/15996018?v=4?s=100" width="100px;" alt="David Fernández Alcoba"/><br /><sub><b>David Fernández Alcoba</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=davidfdezalcoba" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Gauvino"><img src="https://avatars.githubusercontent.com/u/68083474?v=4?s=100" width="100px;" alt="Gauvino"/><br /><sub><b>Gauvino</b></sub></a><br /><a href="#translation-Gauvino" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/EthanArmbrust"><img src="https://avatars.githubusercontent.com/u/22754714?v=4?s=100" width="100px;" alt="EthanArmbrust"/><br /><sub><b>EthanArmbrust</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=EthanArmbrust" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.piribisoft.com"><img src="https://avatars.githubusercontent.com/u/854646?v=4?s=100" width="100px;" alt="Eduardo"/><br /><sub><b>Eduardo</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=SirMartin" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RickLuiken"><img src="https://avatars.githubusercontent.com/u/34110371?v=4?s=100" width="100px;" alt="RickLuiken"/><br /><sub><b>RickLuiken</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=RickLuiken" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Br33ce"><img src="https://avatars.githubusercontent.com/u/124933490?v=4?s=100" width="100px;" alt="Br33ce"/><br /><sub><b>Br33ce</b></sub></a><br /><a href="#translation-Br33ce" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://athfan.com"><img src="https://avatars.githubusercontent.com/u/13810742?v=4?s=100" width="100px;" alt="Athfan Khaleel"/><br /><sub><b>Athfan Khaleel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=athphane" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mdll23"><img src="https://avatars.githubusercontent.com/u/142844478?v=4?s=100" width="100px;" alt="Michael Dallinger"/><br /><sub><b>Michael Dallinger</b></sub></a><br /><a href="#translation-mdll23" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/xeruf"><img src="https://avatars.githubusercontent.com/u/13354331?v=4?s=100" width="100px;" alt="Janek"/><br /><sub><b>Janek</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=xeruf" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://aleksasiriski.dev"><img src="https://avatars.githubusercontent.com/u/31509435?v=4?s=100" width="100px;" alt="Aleksa Siriški"/><br /><sub><b>Aleksa Siriški</b></sub></a><br /><a href="#infra-aleksasiriski" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://danishhumair.com"><img src="https://avatars.githubusercontent.com/u/121830048?v=4?s=100" width="100px;" alt="Danish Humair"/><br /><sub><b>Danish Humair</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Danish-H" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://arm0.red"><img src="https://avatars.githubusercontent.com/u/16858514?v=4?s=100" width="100px;" alt="Stephen Harris"/><br /><sub><b>Stephen Harris</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=trackmastersteve" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
### Overseerr Contributors ✨
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://sct.dev"><img src="https://avatars1.githubusercontent.com/u/234213?v=4?s=100" width="100px;" alt="sct"/><br /><sub><b>sct</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=sct" title="Code">💻</a> <a href="#design-sct" title="Design">🎨</a> <a href="#ideas-sct" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/azoitos"><img src="https://avatars2.githubusercontent.com/u/26529049?v=4?s=100" width="100px;" alt="Alex Zoitos"/><br /><sub><b>Alex Zoitos</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=azoitos" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/OwsleyJr"><img src="https://avatars3.githubusercontent.com/u/8635678?v=4?s=100" width="100px;" alt="Brandon Cohen"/><br /><sub><b>Brandon Cohen</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=OwsleyJr" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Ahreluth"><img src="https://avatars2.githubusercontent.com/u/75682440?v=4?s=100" width="100px;" alt="Ahreluth"/><br /><sub><b>Ahreluth</b></sub></a><br /><a href="#translation-Ahreluth" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KovalevArtem"><img src="https://avatars0.githubusercontent.com/u/36500228?v=4?s=100" width="100px;" alt="KovalevArtem"/><br /><sub><b>KovalevArtem</b></sub></a><br /><a href="#translation-KovalevArtem" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/GiyomuWeb"><img src="https://avatars0.githubusercontent.com/u/62489209?v=4?s=100" width="100px;" alt="GiyomuWeb"/><br /><sub><b>GiyomuWeb</b></sub></a><br /><a href="#translation-GiyomuWeb" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/angrycuban13"><img src="https://avatars3.githubusercontent.com/u/39564898?v=4?s=100" width="100px;" alt="Angry Cuban"/><br /><sub><b>Angry Cuban</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=angrycuban13" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jvennik"><img src="https://avatars3.githubusercontent.com/u/6672637?v=4?s=100" width="100px;" alt="jvennik"/><br /><sub><b>jvennik</b></sub></a><br /><a href="#translation-jvennik" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/darknessgp"><img src="https://avatars0.githubusercontent.com/u/1521243?v=4?s=100" width="100px;" alt="darknessgp"/><br /><sub><b>darknessgp</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=darknessgp" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/saltydk"><img src="https://avatars1.githubusercontent.com/u/6587950?v=4?s=100" width="100px;" alt="salty"/><br /><sub><b>salty</b></sub></a><br /><a href="#infra-saltydk" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shutruk"><img src="https://avatars2.githubusercontent.com/u/9198633?v=4?s=100" width="100px;" alt="Shutruk"/><br /><sub><b>Shutruk</b></sub></a><br /><a href="#translation-Shutruk" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/krystiancharubin"><img src="https://avatars2.githubusercontent.com/u/17775600?v=4?s=100" width="100px;" alt="Krystian Charubin"/><br /><sub><b>Krystian Charubin</b></sub></a><br /><a href="#design-krystiancharubin" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kieron"><img src="https://avatars2.githubusercontent.com/u/8655212?v=4?s=100" width="100px;" alt="Kieron Boswell"/><br /><sub><b>Kieron Boswell</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=kieron" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/samwiseg0"><img src="https://avatars1.githubusercontent.com/u/2241731?v=4?s=100" width="100px;" alt="samwiseg0"/><br /><sub><b>samwiseg0</b></sub></a><br /><a href="#question-samwiseg0" title="Answering Questions">💬</a> <a href="#infra-samwiseg0" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ecelebi29"><img src="https://avatars2.githubusercontent.com/u/8337120?v=4?s=100" width="100px;" alt="ecelebi29"/><br /><sub><b>ecelebi29</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mmozeiko"><img src="https://avatars3.githubusercontent.com/u/1665010?v=4?s=100" width="100px;" alt="Mārtiņš Možeiko"/><br /><sub><b>Mārtiņš Možeiko</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=mmozeiko" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mazzetta86"><img src="https://avatars2.githubusercontent.com/u/45591560?v=4?s=100" width="100px;" alt="mazzetta86"/><br /><sub><b>mazzetta86</b></sub></a><br /><a href="#translation-mazzetta86" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Panzer1119"><img src="https://avatars1.githubusercontent.com/u/23016343?v=4?s=100" width="100px;" alt="Paul Hagedorn"/><br /><sub><b>Paul Hagedorn</b></sub></a><br /><a href="#translation-Panzer1119" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shagon94"><img src="https://avatars3.githubusercontent.com/u/9140783?v=4?s=100" width="100px;" alt="Shagon94"/><br /><sub><b>Shagon94</b></sub></a><br /><a href="#translation-Shagon94" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sebstrgg"><img src="https://avatars3.githubusercontent.com/u/27026694?v=4?s=100" width="100px;" alt="sebstrgg"/><br /><sub><b>sebstrgg</b></sub></a><br /><a href="#translation-sebstrgg" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/danshilm"><img src="https://avatars2.githubusercontent.com/u/20923978?v=4?s=100" width="100px;" alt="Danshil Mungur"/><br /><sub><b>Danshil Mungur</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=danshilm" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=danshilm" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/doob187"><img src="https://avatars1.githubusercontent.com/u/60312740?v=4?s=100" width="100px;" alt="doob187"/><br /><sub><b>doob187</b></sub></a><br /><a href="#infra-doob187" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/johnpyp"><img src="https://avatars2.githubusercontent.com/u/20625636?v=4?s=100" width="100px;" alt="johnpyp"/><br /><sub><b>johnpyp</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=johnpyp" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ankarhem"><img src="https://avatars1.githubusercontent.com/u/14110063?v=4?s=100" width="100px;" alt="Jakob Ankarhem"/><br /><sub><b>Jakob Ankarhem</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ankarhem" title="Documentation">📖</a> <a href="https://github.com/sct/overseerr/commits?author=ankarhem" title="Code">💻</a> <a href="#translation-ankarhem" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jayesh100"><img src="https://avatars1.githubusercontent.com/u/8022175?v=4?s=100" width="100px;" alt="Jayesh"/><br /><sub><b>Jayesh</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jayesh100" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/flying-sausages"><img src="https://avatars1.githubusercontent.com/u/23618693?v=4?s=100" width="100px;" alt="flying-sausages"/><br /><sub><b>flying-sausages</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=flying-sausages" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/hirenshah"><img src="https://avatars2.githubusercontent.com/u/418112?v=4?s=100" width="100px;" alt="hirenshah"/><br /><sub><b>hirenshah</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=hirenshah" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheCatLady"><img src="https://avatars0.githubusercontent.com/u/52870424?v=4?s=100" width="100px;" alt="TheCatLady"/><br /><sub><b>TheCatLady</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=TheCatLady" title="Code">💻</a> <a href="#translation-TheCatLady" title="Translation">🌍</a> <a href="https://github.com/sct/overseerr/commits?author=TheCatLady" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/chriscpritchard"><img src="https://avatars1.githubusercontent.com/u/1839074?v=4?s=100" width="100px;" alt="Chris Pritchard"/><br /><sub><b>Chris Pritchard</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=chriscpritchard" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=chriscpritchard" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Tamberlox"><img src="https://avatars3.githubusercontent.com/u/56069014?v=4?s=100" width="100px;" alt="Tamberlox"/><br /><sub><b>Tamberlox</b></sub></a><br /><a href="#translation-Tamberlox" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://hmnd.io"><img src="https://avatars.githubusercontent.com/u/12853597?v=4?s=100" width="100px;" alt="David"/><br /><sub><b>David</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=hmnd" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.douglas-parker.com"><img src="https://avatars.githubusercontent.com/u/18235822?v=4?s=100" width="100px;" alt="Douglas Parker"/><br /><sub><b>Douglas Parker</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=douglasparker" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dancarter"><img src="https://avatars.githubusercontent.com/u/4387516?v=4?s=100" width="100px;" alt="Daniel Carter"/><br /><sub><b>Daniel Carter</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=dancarter" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nuro.dev"><img src="https://avatars.githubusercontent.com/u/4991309?v=4?s=100" width="100px;" alt="nuro"/><br /><sub><b>nuro</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=NuroDev" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/onedr0p"><img src="https://avatars.githubusercontent.com/u/213795?v=4?s=100" width="100px;" alt="ᗪєνιη ᗷυнʟ"/><br /><sub><b>ᗪєνιη ᗷυнʟ</b></sub></a><br /><a href="#infra-onedr0p" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JonnyWong16"><img src="https://avatars.githubusercontent.com/u/9099342?v=4?s=100" width="100px;" alt="JonnyWong16"/><br /><sub><b>JonnyWong16</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=JonnyWong16" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Roxedus"><img src="https://avatars.githubusercontent.com/u/7110194?v=4?s=100" width="100px;" alt="Roxedus"/><br /><sub><b>Roxedus</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Roxedus" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/WoisWoi"><img src="https://avatars.githubusercontent.com/u/75491231?v=4?s=100" width="100px;" alt="WoisWoi"/><br /><sub><b>WoisWoi</b></sub></a><br /><a href="#translation-WoisWoi" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/HubDuck"><img src="https://avatars.githubusercontent.com/u/77843475?v=4?s=100" width="100px;" alt="HubDuck"/><br /><sub><b>HubDuck</b></sub></a><br /><a href="#translation-HubDuck" title="Translation">🌍</a> <a href="https://github.com/sct/overseerr/commits?author=HubDuck" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/costaht"><img src="https://avatars.githubusercontent.com/u/50637431?v=4?s=100" width="100px;" alt="costaht"/><br /><sub><b>costaht</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=costaht" title="Documentation">📖</a> <a href="#translation-costaht" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Shjosan"><img src="https://avatars.githubusercontent.com/u/20847626?v=4?s=100" width="100px;" alt="Shjosan"/><br /><sub><b>Shjosan</b></sub></a><br /><a href="#translation-Shjosan" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kobaubarr"><img src="https://avatars.githubusercontent.com/u/28481522?v=4?s=100" width="100px;" alt="kobaubarr"/><br /><sub><b>kobaubarr</b></sub></a><br /><a href="#translation-kobaubarr" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/notorius28"><img src="https://avatars.githubusercontent.com/u/1621513?v=4?s=100" width="100px;" alt="Ricardo González"/><br /><sub><b>Ricardo González</b></sub></a><br /><a href="#translation-notorius28" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://torkili.uz"><img src="https://avatars.githubusercontent.com/u/460764?v=4?s=100" width="100px;" alt="Torkil"/><br /><sub><b>Torkil</b></sub></a><br /><a href="#translation-Torkiliuz" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.jagandeepbrar.io"><img src="https://avatars.githubusercontent.com/u/3048295?v=4?s=100" width="100px;" alt="Jagandeep Brar"/><br /><sub><b>Jagandeep Brar</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=JagandeepBrar" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://dtalens.com"><img src="https://avatars.githubusercontent.com/u/6631832?v=4?s=100" width="100px;" alt="dtalens"/><br /><sub><b>dtalens</b></sub></a><br /><a href="#translation-dtalens" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/acortelyou"><img src="https://avatars.githubusercontent.com/u/1689668?v=4?s=100" width="100px;" alt="Alex Cortelyou"/><br /><sub><b>Alex Cortelyou</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=acortelyou" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://nz.linkedin.com/in/jonocairns"><img src="https://avatars.githubusercontent.com/u/182836?v=4?s=100" width="100px;" alt="Jono Cairns"/><br /><sub><b>Jono Cairns</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jonocairns" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://scias.net/"><img src="https://avatars.githubusercontent.com/u/439655?v=4?s=100" width="100px;" alt="DJScias"/><br /><sub><b>DJScias</b></sub></a><br /><a href="#translation-DJScias" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Dabu-dot"><img src="https://avatars.githubusercontent.com/u/52525576?v=4?s=100" width="100px;" alt="Dabu-dot"/><br /><sub><b>Dabu-dot</b></sub></a><br /><a href="#translation-Dabu-dot" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Jabster28"><img src="https://avatars.githubusercontent.com/u/29015942?v=4?s=100" width="100px;" alt="Jabster28"/><br /><sub><b>Jabster28</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Jabster28" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/littlerooster"><img src="https://avatars.githubusercontent.com/u/83890654?v=4?s=100" width="100px;" alt="littlerooster"/><br /><sub><b>littlerooster</b></sub></a><br /><a href="#translation-littlerooster" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/dphildebrandt"><img src="https://avatars.githubusercontent.com/u/154459?v=4?s=100" width="100px;" alt="Dustin Hildebrandt"/><br /><sub><b>Dustin Hildebrandt</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=dphildebrandt" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Generator"><img src="https://avatars.githubusercontent.com/u/44146?v=4?s=100" width="100px;" alt="Bruno Guerreiro"/><br /><sub><b>Bruno Guerreiro</b></sub></a><br /><a href="#translation-Generator" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/iceHtwoO"><img src="https://avatars.githubusercontent.com/u/27020492?v=4?s=100" width="100px;" alt="Alexander Neuhäuser"/><br /><sub><b>Alexander Neuhäuser</b></sub></a><br /><a href="#translation-iceHtwoO" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://www.unext.co.jp"><img src="https://avatars.githubusercontent.com/u/37431541?v=4?s=100" width="100px;" alt="Livio"/><br /><sub><b>Livio</b></sub></a><br /><a href="#design-liviokanone" title="Design">🎨</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tangentThought"><img src="https://avatars.githubusercontent.com/u/25516090?v=4?s=100" width="100px;" alt="tangentThought"/><br /><sub><b>tangentThought</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=tangentThought" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicospz"><img src="https://avatars.githubusercontent.com/u/31373060?v=4?s=100" width="100px;" alt="Nicolás Espinoza"/><br /><sub><b>Nicolás Espinoza</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=nicospz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sootylunatic"><img src="https://avatars.githubusercontent.com/u/36486087?v=4?s=100" width="100px;" alt="sootylunatic"/><br /><sub><b>sootylunatic</b></sub></a><br /><a href="#translation-sootylunatic" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JoKerIsCraZy"><img src="https://avatars.githubusercontent.com/u/47474211?v=4?s=100" width="100px;" alt="JoKerIsCraZy"/><br /><sub><b>JoKerIsCraZy</b></sub></a><br /><a href="#translation-JoKerIsCraZy" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://daddie.dev"><img src="https://avatars.githubusercontent.com/u/33762262?v=4?s=100" width="100px;" alt="Daddie0"/><br /><sub><b>Daddie0</b></sub></a><br /><a href="#translation-GoByeBye" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://ungaro.me"><img src="https://avatars.githubusercontent.com/u/43807696?v=4?s=100" width="100px;" alt="Simone"/><br /><sub><b>Simone</b></sub></a><br /><a href="#translation-Simoneu01" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/adan89lion"><img src="https://avatars.githubusercontent.com/u/6585644?v=4?s=100" width="100px;" alt="Seohyun Joo"/><br /><sub><b>Seohyun Joo</b></sub></a><br /><a href="#translation-adan89lion" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ty4ko"><img src="https://avatars.githubusercontent.com/u/21213535?v=4?s=100" width="100px;" alt="Sergey"/><br /><sub><b>Sergey</b></sub></a><br /><a href="#translation-ty4ko" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/skafte1990"><img src="https://avatars.githubusercontent.com/u/31465453?v=4?s=100" width="100px;" alt="Shaaft"/><br /><sub><b>Shaaft</b></sub></a><br /><a href="#translation-skafte1990" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sr093906"><img src="https://avatars.githubusercontent.com/u/8369201?v=4?s=100" width="100px;" alt="sr093906"/><br /><sub><b>sr093906</b></sub></a><br /><a href="#translation-sr093906" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nackophilz"><img src="https://avatars.githubusercontent.com/u/61667226?v=4?s=100" width="100px;" alt="Nackophilz"/><br /><sub><b>Nackophilz</b></sub></a><br /><a href="#translation-Nackophilz" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/schambers"><img src="https://avatars.githubusercontent.com/u/31563?v=4?s=100" width="100px;" alt="Sean Chambers"/><br /><sub><b>Sean Chambers</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=schambers" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/deniscerri"><img src="https://avatars.githubusercontent.com/u/64997243?v=4?s=100" width="100px;" alt="deniscerri"/><br /><sub><b>deniscerri</b></sub></a><br /><a href="#translation-deniscerri" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/tomgacz"><img src="https://avatars.githubusercontent.com/u/14138209?v=4?s=100" width="100px;" alt="tomgacz"/><br /><sub><b>tomgacz</b></sub></a><br /><a href="#translation-tomgacz" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Andersborrits"><img src="https://avatars.githubusercontent.com/u/29452218?v=4?s=100" width="100px;" alt="Andersborrits"/><br /><sub><b>Andersborrits</b></sub></a><br /><a href="#translation-Andersborrits" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://maxentrouault.fr"><img src="https://avatars.githubusercontent.com/u/67283154?v=4?s=100" width="100px;" alt="Maxent"/><br /><sub><b>Maxent</b></sub></a><br /><a href="#translation-Maxentr" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sambartik"><img src="https://avatars.githubusercontent.com/u/63553146?v=4?s=100" width="100px;" alt="Samuel Bartík"/><br /><sub><b>Samuel Bartík</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=sambartik" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/frank-cywong"><img src="https://avatars.githubusercontent.com/u/90653148?v=4?s=100" width="100px;" alt="Chun Yeung Wong"/><br /><sub><b>Chun Yeung Wong</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=frank-cywong" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/TheMeanCanEHdian"><img src="https://avatars.githubusercontent.com/u/16025103?v=4?s=100" width="100px;" alt="TheMeanCanEHdian"/><br /><sub><b>TheMeanCanEHdian</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=TheMeanCanEHdian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Gylesie"><img src="https://avatars.githubusercontent.com/u/86306812?v=4?s=100" width="100px;" alt="Gylesie"/><br /><sub><b>Gylesie</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Gylesie" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fhd-pro"><img src="https://avatars.githubusercontent.com/u/82862079?v=4?s=100" width="100px;" alt="Fhd-pro"/><br /><sub><b>Fhd-pro</b></sub></a><br /><a href="#translation-Fhd-pro" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/PovilasID"><img src="https://avatars.githubusercontent.com/u/396243?v=4?s=100" width="100px;" alt="PovilasID"/><br /><sub><b>PovilasID</b></sub></a><br /><a href="#translation-PovilasID" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/byakurau"><img src="https://avatars.githubusercontent.com/u/1811683?v=4?s=100" width="100px;" alt="byakurau"/><br /><sub><b>byakurau</b></sub></a><br /><a href="#translation-byakurau" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/miknii"><img src="https://avatars.githubusercontent.com/u/109232569?v=4?s=100" width="100px;" alt="miknii"/><br /><sub><b>miknii</b></sub></a><br /><a href="#translation-miknii" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Eclipseop"><img src="https://avatars.githubusercontent.com/u/5846213?v=4?s=100" width="100px;" alt="Mackenzie"/><br /><sub><b>Mackenzie</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Eclipseop" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/s0up4200"><img src="https://avatars.githubusercontent.com/u/18177310?v=4?s=100" width="100px;" alt="soup"/><br /><sub><b>soup</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=s0up4200" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ceptonit"><img src="https://avatars.githubusercontent.com/u/12678743?v=4?s=100" width="100px;" alt="ceptonit"/><br /><sub><b>ceptonit</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ceptonit" title="Documentation">📖</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aedelbro"><img src="https://avatars.githubusercontent.com/u/36162221?v=4?s=100" width="100px;" alt="aedelbro"/><br /><sub><b>aedelbro</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=aedelbro" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="http://twitter.com/lunks/"><img src="https://avatars.githubusercontent.com/u/91118?v=4?s=100" width="100px;" alt="Pedro Nascimento"/><br /><sub><b>Pedro Nascimento</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=lunks" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://voke.dev"><img src="https://avatars.githubusercontent.com/u/1899334?v=4?s=100" width="100px;" alt="Owen Voke"/><br /><sub><b>Owen Voke</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=owenvoke" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Nimelrian"><img src="https://avatars.githubusercontent.com/u/8960836?v=4?s=100" width="100px;" alt="Sebastian K"/><br /><sub><b>Sebastian K</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Nimelrian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jariz"><img src="https://avatars.githubusercontent.com/u/1415847?v=4?s=100" width="100px;" alt="jariz"/><br /><sub><b>jariz</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=jariz" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://arouillard.fr"><img src="https://avatars.githubusercontent.com/u/13947260?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Alexays" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Zebebles"><img src="https://avatars.githubusercontent.com/u/11425451?v=4?s=100" width="100px;" alt="Zeb Muller"/><br /><sub><b>Zeb Muller</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=Zebebles" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://smoores.dev"><img src="https://avatars.githubusercontent.com/u/5354254?v=4?s=100" width="100px;" alt="Shane Friedman"/><br /><sub><b>Shane Friedman</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=SMores" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://izaacj.me"><img src="https://avatars.githubusercontent.com/u/711323?v=4?s=100" width="100px;" alt="Izaac Brånn"/><br /><sub><b>Izaac Brånn</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=IzaacJ" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SalmanTariq"><img src="https://avatars.githubusercontent.com/u/13284494?v=4?s=100" width="100px;" alt="Salman Tariq"/><br /><sub><b>Salman Tariq</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=SalmanTariq" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/andrew-kennedy"><img src="https://avatars.githubusercontent.com/u/2387159?v=4?s=100" width="100px;" alt="Andrew Kennedy"/><br /><sub><b>Andrew Kennedy</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=andrew-kennedy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Fallenbagel"><img src="https://avatars.githubusercontent.com/u/98979876?v=4?s=100" width="100px;" alt="Fallenbagel"/><br /><sub><b>Fallenbagel</b></sub></a><br /><a href="https://github.com/Fallenbagel/jellyseerr/commits?author=Fallenbagel" title="Jellyseerr">🪼⌨️</a> <a href="https://github.com/sct/overseerr/commits?author=Fallenbagel" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://aidoge.xyz"><img src="https://avatars.githubusercontent.com/u/9427639?v=4?s=100" width="100px;" alt="Anton K. (ai Doge)"/><br /><sub><b>Anton K. (ai Doge)</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=scorp200" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://marcofaggian.com"><img src="https://avatars.githubusercontent.com/u/19221001?v=4?s=100" width="100px;" alt="Marco Faggian"/><br /><sub><b>Marco Faggian</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=marcofaggian" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://nemchik.com/"><img src="https://avatars.githubusercontent.com/u/725456?v=4?s=100" width="100px;" alt="Eric Nemchik"/><br /><sub><b>Eric Nemchik</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=nemchik" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RemiRigal"><img src="https://avatars.githubusercontent.com/u/19256051?v=4?s=100" width="100px;" alt="RemiRigal"/><br /><sub><b>RemiRigal</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=RemiRigal" title="Code">💻</a></td>
</tr>
</tbody>
</table>

19
cypress.config.ts Normal file
View File

@@ -0,0 +1,19 @@
import { defineConfig } from 'cypress';
export default defineConfig({
projectId: 'xkm1b4',
e2e: {
baseUrl: 'http://localhost:5055',
experimentalSessionAndOrigin: true,
},
env: {
ADMIN_EMAIL: 'admin@seerr.dev',
ADMIN_PASSWORD: 'test1234',
USER_EMAIL: 'friend@seerr.dev',
USER_PASSWORD: 'test1234',
},
retries: {
runMode: 2,
openMode: 0,
},
});

View File

@@ -0,0 +1,149 @@
{
"clientId": "6919275e-142a-48d8-be6b-93594cbd4626",
"vapidPrivate": "tmnslaO8ZWN6bNbSEv_rolPeBTlNxOwCCAHrM9oZz3M",
"vapidPublic": "BK_EpP8NDm9waor2zn6_S28o3ZYv4kCkJOfYpO3pt3W6jnPmxrgTLANUBNbbyaNatPnSQ12De9CeqSYQrqWzHTs",
"main": {
"apiKey": "testkey",
"applicationTitle": "Overseerr",
"applicationUrl": "",
"csrfProtection": false,
"cacheImages": false,
"defaultPermissions": 32,
"defaultQuotas": {
"movie": {},
"tv": {}
},
"hideAvailable": false,
"localLogin": true,
"newPlexLogin": true,
"region": "",
"originalLanguage": "",
"trustProxy": false,
"partialRequestsEnabled": true,
"locale": "en"
},
"plex": {
"name": "Seerr",
"ip": "192.168.1.1",
"port": 32400,
"useSsl": false,
"libraries": [
{
"id": "1",
"name": "Movies",
"enabled": true,
"type": "movie"
}
],
"machineId": "test"
},
"tautulli": {},
"radarr": [],
"sonarr": [],
"public": {
"initialized": true
},
"notifications": {
"agents": {
"email": {
"enabled": false,
"options": {
"emailFrom": "",
"smtpHost": "",
"smtpPort": 587,
"secure": false,
"ignoreTls": false,
"requireTls": false,
"allowSelfSigned": false,
"senderName": "Overseerr"
}
},
"discord": {
"enabled": false,
"types": 0,
"options": {
"webhookUrl": "",
"enableMentions": true
}
},
"lunasea": {
"enabled": false,
"types": 0,
"options": {
"webhookUrl": ""
}
},
"slack": {
"enabled": false,
"types": 0,
"options": {
"webhookUrl": ""
}
},
"telegram": {
"enabled": false,
"types": 0,
"options": {
"botAPI": "",
"chatId": "",
"sendSilently": false
}
},
"pushbullet": {
"enabled": false,
"types": 0,
"options": {
"accessToken": ""
}
},
"pushover": {
"enabled": false,
"types": 0,
"options": {
"accessToken": "",
"userToken": ""
}
},
"webhook": {
"enabled": false,
"types": 0,
"options": {
"webhookUrl": "",
"jsonPayload": "IntcbiAgICBcIm5vdGlmaWNhdGlvbl90eXBlXCI6IFwie3tub3RpZmljYXRpb25fdHlwZX19XCIsXG4gICAgXCJldmVudFwiOiBcInt7ZXZlbnR9fVwiLFxuICAgIFwic3ViamVjdFwiOiBcInt7c3ViamVjdH19XCIsXG4gICAgXCJtZXNzYWdlXCI6IFwie3ttZXNzYWdlfX1cIixcbiAgICBcImltYWdlXCI6IFwie3tpbWFnZX19XCIsXG4gICAgXCJ7e21lZGlhfX1cIjoge1xuICAgICAgICBcIm1lZGlhX3R5cGVcIjogXCJ7e21lZGlhX3R5cGV9fVwiLFxuICAgICAgICBcInRtZGJJZFwiOiBcInt7bWVkaWFfdG1kYmlkfX1cIixcbiAgICAgICAgXCJ0dmRiSWRcIjogXCJ7e21lZGlhX3R2ZGJpZH19XCIsXG4gICAgICAgIFwic3RhdHVzXCI6IFwie3ttZWRpYV9zdGF0dXN9fVwiLFxuICAgICAgICBcInN0YXR1czRrXCI6IFwie3ttZWRpYV9zdGF0dXM0a319XCJcbiAgICB9LFxuICAgIFwie3tyZXF1ZXN0fX1cIjoge1xuICAgICAgICBcInJlcXVlc3RfaWRcIjogXCJ7e3JlcXVlc3RfaWR9fVwiLFxuICAgICAgICBcInJlcXVlc3RlZEJ5X2VtYWlsXCI6IFwie3tyZXF1ZXN0ZWRCeV9lbWFpbH19XCIsXG4gICAgICAgIFwicmVxdWVzdGVkQnlfdXNlcm5hbWVcIjogXCJ7e3JlcXVlc3RlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXF1ZXN0ZWRCeV9hdmF0YXJcIjogXCJ7e3JlcXVlc3RlZEJ5X2F2YXRhcn19XCJcbiAgICB9LFxuICAgIFwie3tpc3N1ZX19XCI6IHtcbiAgICAgICAgXCJpc3N1ZV9pZFwiOiBcInt7aXNzdWVfaWR9fVwiLFxuICAgICAgICBcImlzc3VlX3R5cGVcIjogXCJ7e2lzc3VlX3R5cGV9fVwiLFxuICAgICAgICBcImlzc3VlX3N0YXR1c1wiOiBcInt7aXNzdWVfc3RhdHVzfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2VtYWlsXCI6IFwie3tyZXBvcnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X3VzZXJuYW1lXCI6IFwie3tyZXBvcnRlZEJ5X3VzZXJuYW1lfX1cIixcbiAgICAgICAgXCJyZXBvcnRlZEJ5X2F2YXRhclwiOiBcInt7cmVwb3J0ZWRCeV9hdmF0YXJ9fVwiXG4gICAgfSxcbiAgICBcInt7Y29tbWVudH19XCI6IHtcbiAgICAgICAgXCJjb21tZW50X21lc3NhZ2VcIjogXCJ7e2NvbW1lbnRfbWVzc2FnZX19XCIsXG4gICAgICAgIFwiY29tbWVudGVkQnlfZW1haWxcIjogXCJ7e2NvbW1lbnRlZEJ5X2VtYWlsfX1cIixcbiAgICAgICAgXCJjb21tZW50ZWRCeV91c2VybmFtZVwiOiBcInt7Y29tbWVudGVkQnlfdXNlcm5hbWV9fVwiLFxuICAgICAgICBcImNvbW1lbnRlZEJ5X2F2YXRhclwiOiBcInt7Y29tbWVudGVkQnlfYXZhdGFyfX1cIlxuICAgIH0sXG4gICAgXCJ7e2V4dHJhfX1cIjogW11cbn0i"
}
},
"webpush": {
"enabled": false,
"options": {}
},
"gotify": {
"enabled": false,
"types": 0,
"options": {
"url": "",
"token": ""
}
}
}
},
"jobs": {
"plex-recently-added-scan": {
"schedule": "0 */5 * * * *"
},
"plex-full-scan": {
"schedule": "0 0 3 * * *"
},
"radarr-scan": {
"schedule": "0 0 4 * * *"
},
"sonarr-scan": {
"schedule": "0 30 4 * * *"
},
"download-sync": {
"schedule": "0 * * * * *"
},
"download-sync-reset": {
"schedule": "0 0 1 * * *"
}
}
}

214
cypress/e2e/discover.cy.ts Normal file
View File

@@ -0,0 +1,214 @@
const clickFirstTitleCardInSlider = (sliderTitle: string): void => {
cy.contains('.slider-header', sliderTitle)
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.trigger('mouseover')
.find('[data-testid=title-card-title]')
.invoke('text')
.then((text) => {
cy.contains('.slider-header', sliderTitle)
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.click();
cy.get('[data-testid=media-title]').should('contain', text);
});
};
describe('Discover', () => {
beforeEach(() => {
cy.loginAsAdmin();
});
it('loads a trending item', () => {
cy.intercept('/api/v1/discover/trending*').as('getTrending');
cy.visit('/');
cy.wait('@getTrending');
clickFirstTitleCardInSlider('Trending');
});
it('loads popular movies', () => {
cy.intercept('/api/v1/discover/movies*').as('getPopularMovies');
cy.visit('/');
cy.wait('@getPopularMovies');
clickFirstTitleCardInSlider('Popular Movies');
});
it('loads upcoming movies', () => {
cy.intercept('/api/v1/discover/movies?page=1&primaryReleaseDateGte*').as(
'getUpcomingMovies'
);
cy.visit('/');
cy.wait('@getUpcomingMovies');
clickFirstTitleCardInSlider('Upcoming Movies');
});
it('loads popular series', () => {
cy.intercept('/api/v1/discover/tv*').as('getPopularTv');
cy.visit('/');
cy.wait('@getPopularTv');
clickFirstTitleCardInSlider('Popular Series');
});
it('loads upcoming series', () => {
cy.intercept('/api/v1/discover/tv?page=1&firstAirDateGte=*').as(
'getUpcomingSeries'
);
cy.visit('/');
cy.wait('@getUpcomingSeries');
clickFirstTitleCardInSlider('Upcoming Series');
});
it('displays error for media with invalid TMDB ID', () => {
cy.intercept('GET', '/api/v1/media?*', {
pageInfo: { pages: 1, pageSize: 20, results: 1, page: 1 },
results: [
{
downloadStatus: [],
downloadStatus4k: [],
id: 1922,
mediaType: 'movie',
tmdbId: 998814,
tvdbId: null,
imdbId: null,
status: 5,
status4k: 1,
createdAt: '2022-08-18T18:11:13.000Z',
updatedAt: '2022-08-18T19:56:41.000Z',
lastSeasonChange: '2022-08-18T19:56:41.000Z',
mediaAddedAt: '2022-08-18T19:56:41.000Z',
serviceId: null,
serviceId4k: null,
externalServiceId: null,
externalServiceId4k: null,
externalServiceSlug: null,
externalServiceSlug4k: null,
ratingKey: null,
ratingKey4k: null,
seasons: [],
},
],
}).as('getMedia');
cy.visit('/');
cy.wait('@getMedia');
cy.contains('.slider-header', 'Recently Added')
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.find('[data-testid=title-card-title]')
.contains('Movie Not Found');
});
it('displays error for request with invalid TMDB ID', () => {
cy.intercept('GET', '/api/v1/request?*', {
pageInfo: { pages: 1, pageSize: 10, results: 1, page: 1 },
results: [
{
id: 582,
status: 1,
createdAt: '2022-08-18T18:11:13.000Z',
updatedAt: '2022-08-18T18:11:13.000Z',
type: 'movie',
is4k: false,
serverId: null,
profileId: null,
rootFolder: null,
languageProfileId: null,
tags: null,
media: {
downloadStatus: [],
downloadStatus4k: [],
id: 1922,
mediaType: 'movie',
tmdbId: 998814,
tvdbId: null,
imdbId: null,
status: 2,
status4k: 1,
createdAt: '2022-08-18T18:11:13.000Z',
updatedAt: '2022-08-18T18:11:13.000Z',
lastSeasonChange: '2022-08-18T18:11:13.000Z',
mediaAddedAt: null,
serviceId: null,
serviceId4k: null,
externalServiceId: null,
externalServiceId4k: null,
externalServiceSlug: null,
externalServiceSlug4k: null,
ratingKey: null,
ratingKey4k: null,
},
seasons: [],
modifiedBy: null,
requestedBy: {
permissions: 4194336,
id: 18,
email: 'friend@seerr.dev',
plexUsername: null,
username: '',
recoveryLinkExpirationDate: null,
userType: 2,
avatar:
'https://gravatar.com/avatar/c77fdc27cab83732b8623d2ea873d330?default=mm&size=200',
movieQuotaLimit: null,
movieQuotaDays: null,
tvQuotaLimit: null,
tvQuotaDays: null,
createdAt: '2022-08-17T04:55:28.000Z',
updatedAt: '2022-08-17T04:55:28.000Z',
requestCount: 1,
displayName: 'friend@seerr.dev',
},
seasonCount: 0,
},
],
}).as('getRequests');
cy.visit('/');
cy.wait('@getRequests');
cy.contains('.slider-header', 'Recent Requests')
.next('[data-testid=media-slider]')
.find('[data-testid=request-card]')
.first()
.find('[data-testid=request-card-title]')
.contains('Movie Not Found');
});
it('loads plex watchlist', () => {
cy.intercept('/api/v1/discover/watchlist', {
fixture: 'watchlist.json',
}).as('getWatchlist');
// Wait for one of the watchlist movies to resolve
cy.intercept('/api/v1/movie/361743').as('getTmdbMovie');
cy.visit('/');
cy.wait('@getWatchlist');
const sliderHeader = cy.contains('.slider-header', 'Watchlist');
sliderHeader.scrollIntoView();
cy.wait('@getTmdbMovie');
// Wait a little longer to make sure the movie component reloaded
cy.wait(500);
sliderHeader
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.trigger('mouseover')
.find('[data-testid=title-card-title]')
.invoke('text')
.then((text) => {
cy.contains('.slider-header', 'Watchlist')
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.click();
cy.get('[data-testid=media-title]').should('contain', text);
});
});
});

13
cypress/e2e/login.cy.ts Normal file
View File

@@ -0,0 +1,13 @@
describe('Login Page', () => {
it('succesfully logs in as an admin', () => {
cy.loginAsAdmin();
cy.visit('/');
cy.contains('Trending');
});
it('succesfully logs in as a local user', () => {
cy.loginAsUser();
cy.visit('/');
cy.contains('Trending');
});
});

View File

@@ -0,0 +1,12 @@
describe('Movie Details', () => {
it('loads a movie page', () => {
cy.loginAsAdmin();
// Try to load minions: rise of gru
cy.visit('/movie/438148');
cy.get('[data-testid=media-title]').should(
'contain',
'Minions: The Rise of Gru (2022)'
);
});
});

View File

@@ -0,0 +1,25 @@
describe('Pull To Refresh', () => {
beforeEach(() => {
cy.login(Cypress.env('ADMIN_EMAIL'), Cypress.env('ADMIN_PASSWORD'));
cy.viewport(390, 844);
cy.visitMobile('/');
});
it('reloads the current page', () => {
cy.wait(500);
cy.intercept({
method: 'GET',
url: '/api/v1/*',
}).as('apiCall');
cy.get('.searchbar').swipe('bottom', [190, 500]);
cy.wait('@apiCall').then((interception) => {
assert.isNotNull(
interception.response.body,
'API was called and received data'
);
});
});
});

View File

@@ -0,0 +1,163 @@
describe('Discover Customization', () => {
beforeEach(() => {
cy.loginAsAdmin();
cy.intercept('/api/v1/settings/discover').as('getDiscoverSliders');
});
it('show the discover customization settings', () => {
cy.visit('/');
cy.get('[data-testid=discover-start-editing]').click();
cy.get('[data-testid=create-slider-header')
.should('contain', 'Create New Slider')
.scrollIntoView();
// There should be some built in options
cy.get('[data-testid=discover-slider-edit-mode]').should(
'contain',
'Recently Added'
);
cy.get('[data-testid=discover-slider-edit-mode]').should(
'contain',
'Recent Requests'
);
});
it('can drag to re-order elements and save to persist the changes', () => {
let dataTransfer = new DataTransfer();
cy.visit('/');
cy.get('[data-testid=discover-start-editing]').click();
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.trigger('dragstart', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.trigger('drop', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.trigger('dragend', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.should('contain', 'Recently Added');
cy.get('[data-testid=discover-customize-submit').click();
cy.wait('@getDiscoverSliders');
cy.reload();
cy.get('[data-testid=discover-start-editing]').click();
dataTransfer = new DataTransfer();
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.should('contain', 'Recently Added');
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.trigger('dragstart', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.trigger('drop', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.trigger('dragend', { dataTransfer });
cy.get('[data-testid=discover-slider-edit-mode]')
.eq(1)
.should('contain', 'Recent Requests');
cy.get('[data-testid=discover-customize-submit').click();
cy.wait('@getDiscoverSliders');
});
it('can create a new discover option and remove it', () => {
cy.visit('/');
cy.intercept('/api/v1/settings/discover/*').as('discoverSlider');
cy.intercept('/api/v1/search/keyword*').as('searchKeyword');
cy.get('[data-testid=discover-start-editing]').click();
const sliderTitle = 'Custom Keyword Slider';
cy.get('#sliderType').select('TMDB Movie Keyword');
cy.get('#title').type(sliderTitle);
// First confirm that an invalid keyword doesn't allow us to submit anything
cy.get('#data').type('invalidkeyword{enter}', { delay: 100 });
cy.wait('@searchKeyword');
cy.get('[data-testid=create-discover-option-form]')
.find('button')
.should('be.disabled');
cy.get('#data').clear();
cy.get('#data').type('christmas{enter}', { delay: 100 });
// Confirming we have some results
cy.contains('.slider-header', sliderTitle)
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]');
cy.get('[data-testid=create-discover-option-form]').submit();
cy.wait('@discoverSlider');
cy.wait('@getDiscoverSliders');
cy.wait(1000);
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.should('contain', sliderTitle);
// Make sure its still there even if we reload
cy.reload();
cy.get('[data-testid=discover-start-editing]').click();
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.should('contain', sliderTitle);
// Verify it's not rendering on our discover page (its still disabled!)
cy.visit('/');
cy.get('.slider-header').should('not.contain', sliderTitle);
cy.get('[data-testid=discover-start-editing]').click();
// Enable it, and check again
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.find('[role="checkbox"]')
.click();
cy.get('[data-testid=discover-customize-submit').click();
cy.wait('@getDiscoverSliders');
cy.visit('/');
cy.contains('.slider-header', sliderTitle)
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]');
cy.get('[data-testid=discover-start-editing]').click();
// let's delete it and confirm its deleted.
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.find('[data-testid=discover-slider-remove-button]')
.click();
cy.wait('@discoverSlider');
cy.wait('@getDiscoverSliders');
cy.wait(1000);
cy.get('[data-testid=discover-slider-edit-mode]')
.first()
.should('not.contain', sliderTitle);
});
});

View File

@@ -0,0 +1,32 @@
describe('General Settings', () => {
beforeEach(() => {
cy.loginAsAdmin();
});
it('opens the settings page from the home page', () => {
cy.visit('/');
cy.get('[data-testid=sidebar-toggle]').click();
cy.get('[data-testid=sidebar-menu-settings-mobile]').click();
cy.get('.heading').should('contain', 'General Settings');
});
it('modifies setting that requires restart', () => {
cy.visit('/settings');
cy.get('#trustProxy').click();
cy.get('[data-testid=settings-main-form]').submit();
cy.get('[data-testid=modal-title]').should(
'contain',
'Server Restart Required'
);
cy.get('[data-testid=modal-ok-button]').click();
cy.get('[data-testid=modal-title]').should('not.exist');
cy.get('[type=checkbox]#trustProxy').click();
cy.get('[data-testid=settings-main-form]').submit();
cy.get('[data-testid=modal-title]').should('not.exist');
});
});

View File

@@ -0,0 +1,28 @@
describe('TV Details', () => {
it('loads a tv details page', () => {
cy.loginAsAdmin();
// Try to load stranger things
cy.visit('/tv/66732');
cy.get('[data-testid=media-title]').should(
'contain',
'Stranger Things (2016)'
);
});
it('shows seasons and expands episodes', () => {
cy.loginAsAdmin();
// Try to load stranger things
cy.visit('/tv/66732');
// intercept request for season info
cy.intercept('/api/v1/tv/66732/season/4').as('season4');
cy.contains('Season 4').should('be.visible').scrollIntoView().click();
cy.wait('@season4');
cy.contains('Chapter Nine').should('be.visible');
});
});

View File

@@ -0,0 +1,74 @@
const visitUserEditPage = (email: string): void => {
cy.visit('/users');
cy.contains('[data-testid=user-list-row]', email).contains('Edit').click();
};
describe('Auto Request Settings', () => {
beforeEach(() => {
cy.loginAsAdmin();
});
it('should not see watchlist sync settings on an account without permissions', () => {
visitUserEditPage(Cypress.env('USER_EMAIL'));
cy.contains('Auto-Request Movies').should('not.exist');
cy.contains('Auto-Request Series').should('not.exist');
});
it('should see watchlist sync settings on an admin account', () => {
visitUserEditPage(Cypress.env('ADMIN_EMAIL'));
cy.contains('Auto-Request Movies').should('exist');
cy.contains('Auto-Request Series').should('exist');
});
it('should see auto-request settings after being given permission', () => {
visitUserEditPage(Cypress.env('USER_EMAIL'));
cy.get('[data-testid=settings-nav-desktop').contains('Permissions').click();
cy.get('#autorequest').should('not.be.checked').click();
cy.intercept('/api/v1/user/*/settings/permissions').as('userPermissions');
cy.contains('Save Changes').click();
cy.wait('@userPermissions');
cy.reload();
cy.get('#autorequest').should('be.checked');
cy.get('#autorequestmovies').should('be.checked');
cy.get('#autorequesttv').should('be.checked');
cy.get('[data-testid=settings-nav-desktop').contains('General').click();
cy.contains('Auto-Request Movies').should('exist');
cy.contains('Auto-Request Series').should('exist');
cy.get('#watchlistSyncMovies').should('not.be.checked').click();
cy.get('#watchlistSyncTv').should('not.be.checked').click();
cy.intercept('/api/v1/user/*/settings/main').as('userMain');
cy.contains('Save Changes').click();
cy.wait('@userMain');
cy.reload();
cy.get('#watchlistSyncMovies').should('be.checked').click();
cy.get('#watchlistSyncTv').should('be.checked').click();
cy.contains('Save Changes').click();
cy.wait('@userMain');
cy.get('[data-testid=settings-nav-desktop').contains('Permissions').click();
cy.get('#autorequest').should('be.checked').click();
cy.contains('Save Changes').click();
});
});

View File

@@ -0,0 +1,50 @@
describe('User Profile', () => {
beforeEach(() => {
cy.loginAsAdmin();
});
it('opens user profile page from the home page', () => {
cy.visit('/');
cy.get('[data-testid=user-menu]').click();
cy.get('[data-testid=user-menu-profile]').click();
cy.get('h1').should('contain', Cypress.env('ADMIN_EMAIL'));
});
it('loads plex watchlist', () => {
cy.intercept('/api/v1/user/[0-9]*/watchlist', {
fixture: 'watchlist.json',
}).as('getWatchlist');
// Wait for one of the watchlist movies to resolve
cy.intercept('/api/v1/movie/361743').as('getTmdbMovie');
cy.visit('/profile');
cy.wait('@getWatchlist');
const sliderHeader = cy.contains('.slider-header', 'Plex Watchlist');
sliderHeader.scrollIntoView();
cy.wait('@getTmdbMovie');
// Wait a little longer to make sure the movie component reloaded
cy.wait(500);
sliderHeader
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.trigger('mouseover')
.find('[data-testid=title-card-title]')
.invoke('text')
.then((text) => {
cy.contains('.slider-header', 'Plex Watchlist')
.next('[data-testid=media-slider]')
.find('[data-testid=title-card]')
.first()
.click();
cy.get('[data-testid=media-title]').should('contain', text);
});
});
});

View File

@@ -0,0 +1,70 @@
const testUser = {
displayName: 'Test User',
emailAddress: 'test@seeerr.dev',
password: 'test1234',
};
describe('User List', () => {
beforeEach(() => {
cy.loginAsAdmin();
});
it('opens the user list from the home page', () => {
cy.visit('/');
cy.get('[data-testid=sidebar-toggle]').click();
cy.get('[data-testid=sidebar-menu-users-mobile]').click();
cy.get('[data-testid=page-header]').should('contain', 'User List');
});
it('can find the admin user and friend user in the user list', () => {
cy.visit('/users');
cy.get('[data-testid=user-list-row]').contains(Cypress.env('ADMIN_EMAIL'));
cy.get('[data-testid=user-list-row]').contains(Cypress.env('USER_EMAIL'));
});
it('can create a local user', () => {
cy.visit('/users');
cy.contains('Create Local User').click();
cy.get('[data-testid=modal-title]').should('contain', 'Create Local User');
cy.get('#displayName').type(testUser.displayName);
cy.get('#email').type(testUser.emailAddress);
cy.get('#password').type(testUser.password);
cy.intercept('/api/v1/user?take=10&skip=0&sort=displayname').as('user');
cy.get('[data-testid=modal-ok-button]').click();
cy.wait('@user');
// Wait a little longer for the user list to fully re-render
cy.wait(1000);
cy.get('[data-testid=user-list-row]').contains(testUser.emailAddress);
});
it('can delete the created local test user', () => {
cy.visit('/users');
cy.contains('[data-testid=user-list-row]', testUser.emailAddress)
.contains('Delete')
.click();
cy.get('[data-testid=modal-title]').should('contain', `Delete User`);
cy.intercept('/api/v1/user?take=10&skip=0&sort=displayname').as('user');
cy.get('[data-testid=modal-ok-button]').should('contain', 'Delete').click();
cy.wait('@user');
cy.wait(1000);
cy.get('[data-testid=user-list-row]')
.contains(testUser.emailAddress)
.should('not.exist');
});
});

View File

@@ -0,0 +1,25 @@
{
"page": 1,
"totalPages": 1,
"totalResults": 3,
"results": [
{
"ratingKey": "5d776be17a53e9001e732ab9",
"title": "Top Gun: Maverick",
"mediaType": "movie",
"tmdbId": 361743
},
{
"ratingKey": "5e16338fbc1372003ea68ab3",
"title": "Nope",
"mediaType": "movie",
"tmdbId": 762504
},
{
"ratingKey": "5f409b8452f200004161e126",
"title": "Hocus Pocus 2",
"mediaType": "movie",
"tmdbId": 642885
}
]
}

View File

@@ -0,0 +1,35 @@
/// <reference types="cypress" />
import 'cy-mobile-commands';
Cypress.Commands.add('login', (email, password) => {
cy.session(
[email, password],
() => {
cy.visit('/login');
cy.contains('Use your Overseerr account').click();
cy.get('[data-testid=email]').type(email);
cy.get('[data-testid=password]').type(password);
cy.intercept('/api/v1/auth/local').as('localLogin');
cy.get('[data-testid=local-signin-button]').click();
cy.wait('@localLogin');
cy.url().should('contain', '/');
},
{
validate() {
cy.request('/api/v1/auth/me').its('status').should('eq', 200);
},
}
);
});
Cypress.Commands.add('loginAsAdmin', () => {
cy.login(Cypress.env('ADMIN_EMAIL'), Cypress.env('ADMIN_PASSWORD'));
});
Cypress.Commands.add('loginAsUser', () => {
cy.login(Cypress.env('USER_EMAIL'), Cypress.env('USER_PASSWORD'));
});

7
cypress/support/e2e.ts Normal file
View File

@@ -0,0 +1,7 @@
import './commands';
before(() => {
if (Cypress.env('SEED_DATABASE')) {
cy.exec('yarn cypress:prepare');
}
});

14
cypress/support/index.ts Normal file
View File

@@ -0,0 +1,14 @@
/* eslint-disable @typescript-eslint/no-namespace */
/// <reference types="cypress" />
declare global {
namespace Cypress {
interface Chainable {
login(email?: string, password?: string): Chainable<Element>;
loginAsAdmin(): Chainable<Element>;
loginAsUser(): Chainable<Element>;
}
}
}
export {};

10
cypress/tsconfig.json Normal file
View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"],
"resolveJsonModule": true,
"esModuleInterop": true
},
"include": ["**/*.ts"]
}

View File

@@ -1,6 +1,6 @@
version: '3'
services:
overseerr:
jellyseerr:
build:
context: .
dockerfile: Dockerfile.local

View File

@@ -11,4 +11,4 @@ To use Fail2ban with Overseerr, create a new file named `overseerr.local` in you
failregex = .*\[warn\]\[API\]\: Failed sign-in attempt.*"ip":"<HOST>"
```
You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documetation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail.
You can then add a jail using this filter in `jail.local`. Please see the [Fail2ban documentation](https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails) for details on how to configure the jail.

View File

@@ -138,6 +138,7 @@ location ^~ /overseerr {
sub_filter 'href="/"' 'href="/$app"';
sub_filter 'href="/login"' 'href="/$app/login"';
sub_filter 'href:"/"' 'href:"/$app"';
sub_filter '\/_next' '\/$app\/_next';
sub_filter '/_next' '/$app/_next';
sub_filter '/api/v1' '/$app/api/v1';
sub_filter '/login/plex/loading' '/$app/login/plex/loading';

View File

@@ -9,7 +9,7 @@
- [LunaSea](https://docs.lunasea.app/modules/overseerr), a self-hosted controller for mobile and macOS
- [Requestrr](https://github.com/darkalfx/requestrr/wiki/Configuring-Overseerr), a Discord chatbot
- [Doplarr](https://github.com/kiranshila/Doplarr), a Discord request bot
- [Overseerr Assistant](https://github.com/RemiRigal/Overseerr-Assistant), a browser extension for requesting directly from TMDb and IMDb
- [Overseerr Assistant](https://github.com/RemiRigal/Overseerr-Assistant), a browser extension for requesting directly from TMDB and IMDb
- [ha-overseerr](https://github.com/vaparr/ha-overseerr), a custom Home Assistant component
- [OverCLIrr](https://github.com/WillFantom/OverCLIrr), a command-line tool
- [Overseerr Exporter](https://github.com/WillFantom/overseerr-exporter), a Prometheus exporter

View File

@@ -28,6 +28,7 @@ docker run -d \
--name overseerr \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tokyo \
-e PORT=5055 `#optional` \
-p 5055:5055 \
-v /path/to/appdata/config:/app/config \
--restart unless-stopped \
@@ -81,6 +82,7 @@ services:
environment:
- LOG_LEVEL=debug
- TZ=Asia/Tokyo
- PORT=5055 #optional
ports:
- 5055:5055
volumes:
@@ -88,7 +90,7 @@ services:
restart: unless-stopped
```
Then, start all services defined in the your Compose file:
Then, start all services defined in the Compose file:
```bash
docker-compose up -d
@@ -146,8 +148,6 @@ Then, create and start the Overseerr container:
docker run -d --name overseerr -e LOG_LEVEL=debug -e TZ=Asia/Tokyo -p 5055:5055 -v "overseerr-data:/app/config" --restart unless-stopped fallenbagel/jellyseerr:latest
```
If using a named volume like above, you can safely ignore the warning about the `/app/config` folder being incorrectly mounted on the setup page.
To access the files inside the volume created above, navigate to `\\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes\overseerr-data\_data` using File Explorer.
{% hint style="info" %}
@@ -155,7 +155,7 @@ Docker on Windows works differently than it does on Linux; it runs Docker inside
**If you must run Docker on Windows, you should put the `/app/config` directory mount inside the VM and not on the Windows host.** (This also applies to other containers with SQLite databases.)
Named volumes, like in the example commands above, are automatically mounted inside the VM.
Named volumes, like in the example commands above, are automatically mounted inside the VM. Therefore the warning on the setup about the `/app/config` folder being incorrectly mounted page should be ignored.
{% endhint %}
## Linux

View File

@@ -45,7 +45,7 @@ Overseerr currently supports the following agents:
- New Plex TV
- Legacy Plex TV
- TheTVDB
- TMDb
- TMDB
- [HAMA](https://github.com/ZeroQI/Hama.bundle)
Please verify that your library is using one of the agents previously listed.
@@ -67,7 +67,7 @@ You can also perform the following to verify the media item has a GUID Overseerr
1. Go to the media item in Plex and **"Get info"** and click on **"View XML"**.
2. Verify that the media item's GUID follows one of the below formats:
1. TMDb agent `guid="com.plexapp.agents.themoviedb://1705"`
1. TMDB agent `guid="com.plexapp.agents.themoviedb://1705"`
2. New Plex Movie agent `<Guid id="tmdb://464052"/>`
3. TheTVDB agent `guid="com.plexapp.agents.thetvdb://78874/1/1"`
4. Legacy Plex Movie agent `guid="com.plexapp.agents.imdb://tt0765446"`

View File

@@ -81,7 +81,7 @@ These following special variables are only included in media-related notificatio
| Variable | Value |
| -------------------- | -------------------------------------------------------------------------------------------------------------- |
| `{{media_type}}` | The media type (`movie` or `tv`) |
| `{{media_tmdbid}}` | The media's TMDb ID |
| `{{media_tmdbid}}` | The media's TMDB ID |
| `{{media_tvdbid}}` | The media's TheTVDB ID |
| `{{media_status}}` | The media's availability status (`UNKNOWN`, `PENDING`, `PROCESSING`, `PARTIALLY_AVAILABLE`, or `AVAILABLE`) |
| `{{media_status4k}}` | The media's 4K availability status (`UNKNOWN`, `PENDING`, `PROCESSING`, `PARTIALLY_AVAILABLE`, or `AVAILABLE`) |

View File

@@ -40,6 +40,14 @@ If you enable this setting and find yourself unable to access Overseerr, you can
This setting is **disabled** by default.
### Enable Image Caching
When enabled, Overseerr will proxy and cache images from pre-configured sources (such as TMDB). This can use a significant amount of disk space.
Images are saved in the `config/cache/images` and stale images are cleared out every 24 hours.
You should enable this if you are having issues with loading images directly from TMDB in your browser.
### Display Language
Set the default display language for Overseerr. Users can override this setting in their user settings.

21
merged-prettier-plugin.js Normal file
View File

@@ -0,0 +1,21 @@
/* eslint-disable */
const tailwind = require('prettier-plugin-tailwindcss');
const organizeImports = require('prettier-plugin-organize-imports');
const combinedFormatter = {
...tailwind,
parsers: {
...tailwind.parsers,
...Object.keys(organizeImports.parsers).reduce((acc, key) => {
acc[key] = {
...tailwind.parsers[key],
preprocess(code, options) {
return organizeImports.parsers[key].preprocess(code, options);
},
};
return acc;
}, {}),
},
};
module.exports = combinedFormatter;

View File

@@ -1,3 +1,6 @@
/**
* @type {import('next').NextConfig}
*/
module.exports = {
env: {
commitTag: process.env.COMMIT_TAG || 'local',
@@ -18,4 +21,8 @@ module.exports = {
return config;
},
experimental: {
scrollRestoration: true,
largePageDataBytes: 256000,
},
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,28 @@
{
"name": "jellyseerr",
"version": "1.1.1",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "nodemon -e ts --watch server --watch overseerr-api.yml -e .json,.ts,.yml -x ts-node --files --project server/tsconfig.json server/index.ts",
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates",
"dev": "nodemon -e ts --watch server --watch overseerr-api.yml -e .json,.ts,.yml -x ts-node -r tsconfig-paths/register --files --project server/tsconfig.json server/index.ts",
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates && tsc-alias -p server/tsconfig.json",
"build:next": "next build",
"build": "yarn build:next && yarn build:server",
"lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\"",
"lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\" --cache",
"lintfix": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\" --fix",
"start": "NODE_ENV=production node dist/index.js",
"i18n:extract": "extract-messages -l=en -o src/i18n/locale -d en --flat true --overwriteDefault true \"./src/**/!(*.test).{ts,tsx}\"",
"migration:generate": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate",
"migration:create": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create",
"migration:run": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run",
"format": "prettier --write .",
"prepare": "husky install"
"migration:generate": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate -d server/datasource.ts",
"migration:create": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create -d server/datasource.ts",
"migration:run": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run -d server/datasource.ts",
"format": "prettier --loglevel warn --write --cache .",
"format:check": "prettier --check --cache .",
"typecheck": "yarn typecheck:server && yarn typecheck:client",
"typecheck:server": "tsc --project server/tsconfig.json --noEmit",
"typecheck:client": "tsc --noEmit",
"prepare": "husky install",
"cypress:open": "cypress open",
"cypress:prepare": "ts-node -r tsconfig-paths/register --files --project server/tsconfig.json server/scripts/prepareTestDb.ts",
"cypress:build": "yarn build && yarn cypress:prepare"
},
"repository": {
"type": "git",
@@ -22,129 +30,148 @@
},
"license": "MIT",
"dependencies": {
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.6",
"@supercharge/request-ip": "^1.2.0",
"@svgr/webpack": "^6.2.1",
"@tanem/react-nprogress": "^4.0.10",
"ace-builds": "^1.4.14",
"axios": "^0.26.1",
"bcrypt": "^5.0.1",
"bowser": "^2.11.0",
"connect-typeorm": "^1.1.4",
"cookie-parser": "^1.4.6",
"copy-to-clipboard": "^3.3.1",
"country-flag-icons": "^1.4.21",
"csurf": "^1.11.0",
"email-templates": "^8.0.10",
"email-validator": "^2.0.4",
"express": "^4.17.3",
"express-openapi-validator": "^4.13.6",
"express-rate-limit": "^6.3.0",
"express-session": "^1.17.2",
"formik": "^2.2.9",
"gravatar-url": "^3.1.0",
"intl": "^1.2.5",
"lodash": "^4.17.21",
"next": "12.1.0",
"node-cache": "^5.1.2",
"node-gyp": "^9.0.0",
"node-schedule": "^2.1.0",
"nodemailer": "^6.7.2",
"openpgp": "^5.2.0",
"plex-api": "^5.3.2",
"pug": "^3.0.2",
"react": "17.0.2",
"react-ace": "^9.5.0",
"react-animate-height": "^2.0.23",
"react-dom": "17.0.2",
"react-intersection-observer": "^8.33.1",
"react-intl": "5.24.7",
"react-markdown": "^8.0.0",
"react-select": "^5.2.2",
"react-spring": "^9.4.4",
"react-toast-notifications": "^2.5.1",
"react-transition-group": "^4.4.2",
"react-truncate-markup": "^5.1.0",
"react-use-clipboard": "1.0.7",
"reflect-metadata": "^0.1.13",
"secure-random-password": "^0.2.3",
"semver": "^7.3.5",
"sqlite3": "^5.0.2",
"swagger-ui-express": "^4.3.0",
"swr": "^1.2.2",
"typeorm": "0.2.45",
"web-push": "^3.4.5",
"winston": "^3.6.0",
"winston-daily-rotate-file": "^4.6.1",
"xml2js": "^0.4.23",
"yamljs": "^0.3.0",
"yup": "^0.32.11"
"@formatjs/intl-displaynames": "6.2.6",
"@formatjs/intl-locale": "3.1.1",
"@formatjs/intl-pluralrules": "5.1.10",
"@formatjs/intl-utils": "3.8.4",
"@headlessui/react": "1.7.12",
"@heroicons/react": "2.0.16",
"@supercharge/request-ip": "1.2.0",
"@svgr/webpack": "6.5.1",
"@tanem/react-nprogress": "5.0.30",
"ace-builds": "1.15.2",
"axios": "1.3.4",
"axios-rate-limit": "1.3.0",
"bcrypt": "5.1.0",
"bowser": "2.11.0",
"connect-typeorm": "1.1.4",
"cookie-parser": "1.4.6",
"copy-to-clipboard": "3.3.3",
"country-flag-icons": "1.5.5",
"cronstrue": "2.23.0",
"csurf": "1.11.0",
"date-fns": "2.29.3",
"dayjs": "1.11.7",
"email-templates": "9.0.0",
"email-validator": "2.0.4",
"express": "4.18.2",
"express-openapi-validator": "4.13.8",
"express-rate-limit": "6.7.0",
"express-session": "1.17.3",
"formik": "2.2.9",
"gravatar-url": "3.1.0",
"intl": "1.2.5",
"lodash": "4.17.21",
"next": "12.3.4",
"node-cache": "5.1.2",
"node-gyp": "9.3.1",
"node-schedule": "2.1.1",
"nodemailer": "6.9.1",
"openpgp": "5.7.0",
"plex-api": "5.3.2",
"pug": "3.0.2",
"react": "18.2.0",
"react-ace": "10.1.0",
"react-animate-height": "2.1.2",
"react-aria": "3.23.0",
"react-dom": "18.2.0",
"react-intersection-observer": "9.4.3",
"react-intl": "6.2.10",
"react-markdown": "8.0.5",
"react-popper-tooltip": "4.4.2",
"react-select": "5.7.0",
"react-spring": "9.7.1",
"react-tailwindcss-datepicker-sct": "1.3.4",
"react-toast-notifications": "2.5.1",
"react-truncate-markup": "5.1.2",
"react-use-clipboard": "1.0.9",
"reflect-metadata": "0.1.13",
"secure-random-password": "0.2.3",
"semver": "7.3.8",
"sqlite3": "5.1.4",
"swagger-ui-express": "4.6.2",
"swr": "2.0.4",
"typeorm": "0.3.12",
"web-push": "3.5.0",
"winston": "3.8.2",
"winston-daily-rotate-file": "4.7.1",
"xml2js": "0.4.23",
"yamljs": "0.3.0",
"yup": "0.32.11",
"zod": "3.20.6"
},
"devDependencies": {
"@babel/cli": "^7.17.6",
"@commitlint/cli": "^16.2.1",
"@commitlint/config-conventional": "^16.2.1",
"@next/eslint-plugin-next": "^12.1.6",
"@semantic-release/changelog": "^6.0.1",
"@semantic-release/commit-analyzer": "^9.0.2",
"@semantic-release/exec": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@tailwindcss/aspect-ratio": "^0.4.0",
"@tailwindcss/forms": "^0.5.0",
"@tailwindcss/typography": "^0.5.2",
"@types/bcrypt": "^5.0.0",
"@types/cookie-parser": "^1.4.2",
"@types/country-flag-icons": "^1.2.0",
"@types/csurf": "^1.11.2",
"@types/email-templates": "^8.0.4",
"@types/express": "^4.17.13",
"@types/express-session": "^1.17.4",
"@types/lodash": "^4.14.179",
"@types/node": "^17.0.21",
"@types/node-schedule": "^1.3.2",
"@types/nodemailer": "^6.4.4",
"@types/react": "^17.0.40",
"@types/react-dom": "^17.0.13",
"@types/react-transition-group": "^4.4.4",
"@types/secure-random-password": "^0.2.1",
"@types/semver": "^7.3.9",
"@types/swagger-ui-express": "^4.1.3",
"@types/web-push": "^3.3.2",
"@types/xml2js": "^0.4.9",
"@types/yamljs": "^0.2.31",
"@types/yup": "^0.29.13",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"autoprefixer": "^10.4.2",
"babel-plugin-react-intl": "^8.2.25",
"babel-plugin-react-intl-auto": "^3.3.0",
"commitizen": "^4.2.4",
"copyfiles": "^2.4.1",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.11.0",
"eslint-config-next": "^12.1.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-formatjs": "^3.0.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.3",
"eslint-plugin-react-hooks": "^4.3.0",
"extract-react-intl-messages": "^4.1.1",
"husky": "^7.0.4",
"lint-staged": "^12.3.5",
"nodemon": "^2.0.15",
"postcss": "^8.4.8",
"prettier": "^2.5.1",
"prettier-plugin-tailwindcss": "^0.1.8",
"semantic-release": "^19.0.2",
"semantic-release-docker-buildx": "^1.0.1",
"tailwindcss": "^3.0.23",
"ts-node": "^10.7.0",
"typescript": "^4.6.2"
"@babel/cli": "7.21.0",
"@commitlint/cli": "17.4.4",
"@commitlint/config-conventional": "17.4.4",
"@semantic-release/changelog": "6.0.2",
"@semantic-release/commit-analyzer": "9.0.2",
"@semantic-release/exec": "6.0.3",
"@semantic-release/git": "10.0.1",
"@tailwindcss/aspect-ratio": "0.4.2",
"@tailwindcss/forms": "0.5.3",
"@tailwindcss/typography": "0.5.9",
"@types/bcrypt": "5.0.0",
"@types/cookie-parser": "1.4.3",
"@types/country-flag-icons": "1.2.0",
"@types/csurf": "1.11.2",
"@types/email-templates": "8.0.4",
"@types/express": "4.17.17",
"@types/express-session": "1.17.6",
"@types/lodash": "4.14.191",
"@types/node": "17.0.36",
"@types/node-schedule": "2.1.0",
"@types/nodemailer": "6.4.7",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"@types/react-transition-group": "4.4.5",
"@types/secure-random-password": "0.2.1",
"@types/semver": "7.3.13",
"@types/swagger-ui-express": "4.1.3",
"@types/web-push": "3.3.2",
"@types/xml2js": "0.4.11",
"@types/yamljs": "0.2.31",
"@types/yup": "0.29.14",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"autoprefixer": "10.4.13",
"babel-plugin-react-intl": "8.2.25",
"babel-plugin-react-intl-auto": "3.3.0",
"commitizen": "4.3.0",
"copyfiles": "2.4.1",
"cy-mobile-commands": "0.3.0",
"cypress": "12.7.0",
"cz-conventional-changelog": "3.3.0",
"eslint": "8.35.0",
"eslint-config-next": "12.3.4",
"eslint-config-prettier": "8.6.0",
"eslint-plugin-formatjs": "4.9.0",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-no-relative-import-paths": "1.5.2",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-hooks": "4.6.0",
"extract-react-intl-messages": "4.1.1",
"husky": "8.0.3",
"lint-staged": "13.1.2",
"nodemon": "2.0.20",
"postcss": "8.4.21",
"prettier": "2.8.4",
"prettier-plugin-organize-imports": "3.2.2",
"prettier-plugin-tailwindcss": "0.2.3",
"semantic-release": "19.0.5",
"semantic-release-docker-buildx": "1.0.1",
"tailwindcss": "3.2.7",
"ts-node": "10.9.1",
"tsc-alias": "1.8.2",
"tsconfig-paths": "4.1.2",
"typescript": "4.9.5"
},
"resolutions": {
"sqlite3/node-gyp": "^8.4.1"
"sqlite3/node-gyp": "8.4.1",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"@types/express-session": "1.17.6"
},
"config": {
"commitizen": {
@@ -165,10 +192,6 @@
"@commitlint/config-conventional"
]
},
"prettier": {
"singleQuote": true,
"trailingComma": "es5"
},
"release": {
"plugins": [
"@semantic-release/commit-analyzer",
@@ -206,7 +229,7 @@
{
"path": "semantic-release-docker-buildx",
"buildArgs": {
"COMMIT_TAG": "$GITHUB_SHA"
"COMMIT_TAG": "$GIT_SHA"
},
"imageNames": [
"fallenbagel/jellyseerr"

View File

@@ -17,7 +17,7 @@
}
h1 {
color: #6366F1;
color: #6366f1;
}
p {
@@ -37,7 +37,7 @@
<!-- Inline the page's JavaScript file. -->
<script>
// Manual reload feature.
document.querySelector("button").addEventListener("click", () => {
document.querySelector('button').addEventListener('click', () => {
window.location.reload();
});

View File

@@ -1,3 +0,0 @@
[ZoneTransfer]
LastWriterPackageFamilyName=Microsoft.ScreenSketch_8wekyb3d8bbwe
ZoneId=3

View File

@@ -4,30 +4,30 @@
// This variable is intentionally declared and unused.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const OFFLINE_VERSION = 3;
const CACHE_NAME = "offline";
const CACHE_NAME = 'offline';
// Customize this with a different URL if needed.
const OFFLINE_URL = "/offline.html";
const OFFLINE_URL = '/offline.html';
self.addEventListener("install", (event) => {
self.addEventListener('install', (event) => {
event.waitUntil(
(async () => {
const cache = await caches.open(CACHE_NAME);
// Setting {cache: 'reload'} in the new request will ensure that the
// response isn't fulfilled from the HTTP cache; i.e., it will be from
// the network.
await cache.add(new Request(OFFLINE_URL, { cache: "reload" }));
await cache.add(new Request(OFFLINE_URL, { cache: 'reload' }));
})()
);
// Force the waiting service worker to become the active service worker.
self.skipWaiting();
});
self.addEventListener("activate", (event) => {
self.addEventListener('activate', (event) => {
event.waitUntil(
(async () => {
// Enable navigation preload if it's supported.
// See https://developers.google.com/web/updates/2017/02/navigation-preload
if ("navigationPreload" in self.registration) {
if ('navigationPreload' in self.registration) {
await self.registration.navigationPreload.enable();
}
})()
@@ -37,10 +37,10 @@ self.addEventListener("activate", (event) => {
clients.claim();
});
self.addEventListener("fetch", (event) => {
self.addEventListener('fetch', (event) => {
// We only want to call event.respondWith() if this is a navigation request
// for an HTML page.
if (event.request.mode === "navigate") {
if (event.request.mode === 'navigate') {
event.respondWith(
(async () => {
try {
@@ -59,7 +59,7 @@ self.addEventListener("fetch", (event) => {
// If fetch() returns a valid HTTP response with a response code in
// the 4xx or 5xx range, the catch() will NOT be called.
// eslint-disable-next-line no-console
console.log("Fetch failed; returning offline page instead.", error);
console.log('Fetch failed; returning offline page instead.', error);
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(OFFLINE_URL);
@@ -85,15 +85,13 @@ self.addEventListener('push', (event) => {
requestId: payload.requestId,
},
actions: [],
}
};
if (payload.actionUrl){
options.actions.push(
{
action: 'view',
title: payload.actionUrlTitle ?? 'View',
}
);
if (payload.actionUrl) {
options.actions.push({
action: 'view',
title: payload.actionUrlTitle ?? 'View',
});
}
if (payload.notificationType === 'MEDIA_PENDING') {
@@ -109,27 +107,29 @@ self.addEventListener('push', (event) => {
);
}
event.waitUntil(
self.registration.showNotification(payload.subject, options)
);
event.waitUntil(self.registration.showNotification(payload.subject, options));
});
self.addEventListener('notificationclick', (event) => {
const notificationData = event.notification.data;
self.addEventListener(
'notificationclick',
(event) => {
const notificationData = event.notification.data;
event.notification.close();
event.notification.close();
if (event.action === 'approve') {
fetch(`/api/v1/request/${notificationData.requestId}/approve`, {
method: 'POST',
});
} else if (event.action === 'decline') {
fetch(`/api/v1/request/${notificationData.requestId}/decline`, {
method: 'POST',
});
}
if (notificationData.actionUrl) {
clients.openWindow(notificationData.actionUrl);
}
}, false);
if (event.action === 'approve') {
fetch(`/api/v1/request/${notificationData.requestId}/approve`, {
method: 'POST',
});
} else if (event.action === 'decline') {
fetch(`/api/v1/request/${notificationData.requestId}/decline`, {
method: 'POST',
});
}
if (notificationData.actionUrl) {
clients.openWindow(notificationData.actionUrl);
}
},
false
);

21
renovate.json Normal file
View File

@@ -0,0 +1,21 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:js-app",
"group:allNonMajor",
"docker:disableMajor",
"helpers:disableTypesNodeMajor"
],
"packageRules": [
{
"matchManagers": ["github-actions"],
"groupName": "GitHub Actions",
"groupSlug": "github-actions"
},
{
"matchPackageNames": ["node"],
"groupName": "Node.js",
"groupSlug": "node"
}
]
}

View File

@@ -1,8 +1,8 @@
import logger from '@server/logger';
import axios from 'axios';
import xml2js from 'xml2js';
import fs, { promises as fsp } from 'fs';
import path from 'path';
import logger from '../logger';
import xml2js from 'xml2js';
const UPDATE_INTERVAL_MSEC = 24 * 3600 * 1000; // how often to download new mapping in milliseconds
// originally at https://raw.githubusercontent.com/ScudLee/anime-lists/master/anime-list.xml
@@ -14,7 +14,7 @@ const LOCAL_PATH = process.env.CONFIG_DIRECTORY
const mappingRegexp = new RegExp(/;[0-9]+-([0-9]+)/g);
// Anime-List xml files are community maintained mappings that Hama agent uses to map AniDB IDs to TVDB/TMDb IDs
// Anime-List xml files are community maintained mappings that Hama agent uses to map AniDB IDs to TVDB/TMDB IDs
// https://github.com/Anime-Lists/anime-lists/
interface AnimeMapping {

View File

@@ -1,5 +1,7 @@
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import NodeCache from 'node-cache';
import type { AxiosInstance, AxiosRequestConfig } from 'axios';
import axios from 'axios';
import rateLimit from 'axios-rate-limit';
import type NodeCache from 'node-cache';
// 5 minute default TTL (in seconds)
const DEFAULT_TTL = 300;
@@ -10,6 +12,10 @@ const DEFAULT_ROLLING_BUFFER = 10000;
interface ExternalAPIOptions {
nodeCache?: NodeCache;
headers?: Record<string, unknown>;
rateLimit?: {
maxRPS: number;
maxRequests: number;
};
}
class ExternalAPI {
@@ -31,6 +37,14 @@ class ExternalAPI {
...options.headers,
},
});
if (options.rateLimit) {
this.axios = rateLimit(this.axios, {
maxRequests: options.rateLimit.maxRequests,
maxRPS: options.rateLimit.maxRPS,
});
}
this.baseUrl = baseUrl;
this.cache = options.nodeCache;
}
@@ -55,6 +69,30 @@ class ExternalAPI {
return response.data;
}
protected async post<T>(
endpoint: string,
data: Record<string, unknown>,
config?: AxiosRequestConfig,
ttl?: number
): Promise<T> {
const cacheKey = this.serializeCacheKey(endpoint, {
config: config?.params,
data,
});
const cachedItem = this.cache?.get<T>(cacheKey);
if (cachedItem) {
return cachedItem;
}
const response = await this.axios.post<T>(endpoint, data, config);
if (this.cache) {
this.cache.set(cacheKey, response.data, ttl ?? DEFAULT_TTL);
}
return response.data;
}
protected async getRolling<T>(
endpoint: string,
config?: AxiosRequestConfig,

View File

@@ -1,5 +1,5 @@
import cacheManager from '../lib/cache';
import logger from '../logger';
import cacheManager from '@server/lib/cache';
import logger from '@server/logger';
import ExternalAPI from './externalapi';
interface GitHubRelease {

View File

@@ -1,12 +1,17 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import axios, { AxiosInstance } from 'axios';
import logger from '../logger';
import availabilitySync from '@server/lib/availabilitySync';
import logger from '@server/logger';
import type { AxiosInstance } from 'axios';
import axios from 'axios';
export interface JellyfinUserResponse {
Name: string;
ServerId: string;
ServerName: string;
Id: string;
Policy: {
IsAdministrator: boolean;
};
PrimaryImageTag?: string;
}
@@ -16,7 +21,7 @@ export interface JellyfinLoginResponse {
}
export interface JellyfinUserListResponse {
users: Array<JellyfinUserResponse>;
users: JellyfinUserResponse[];
}
export interface JellyfinLibrary {
@@ -37,6 +42,7 @@ export interface JellyfinLibraryItem {
SeasonId?: string;
SeasonName?: string;
IndexNumber?: number;
IndexNumberEnd?: number;
ParentIndexNumber?: number;
MediaType: string;
}
@@ -169,6 +175,9 @@ class JellyfinAPI {
public async getLibraries(): Promise<JellyfinLibrary[]> {
try {
// TODO: Try to fix automatic grouping without fucking up LDAP users
// const libraries = await this.axios.get<any>('/Library/VirtualFolders');
const account = await this.axios.get<any>(
`/Users/${this.userId ?? 'Me'}/Views`
);
@@ -177,8 +186,10 @@ class JellyfinAPI {
(Item: any) => {
return (
Item.Type === 'CollectionFolder' &&
(Item.CollectionType === 'tvshows' ||
Item.CollectionType === 'movies')
Item.CollectionType !== 'music' &&
Item.CollectionType !== 'books' &&
Item.CollectionType !== 'musicvideos' &&
Item.CollectionType !== 'homevideos'
);
}
).map((Item: any) => {
@@ -203,7 +214,7 @@ class JellyfinAPI {
public async getLibraryContents(id: string): Promise<JellyfinLibraryItem[]> {
try {
const contents = await this.axios.get<any>(
`/Users/${this.userId}/Items?SortBy=SortName&SortOrder=Ascending&IncludeItemTypes=Series,Movie&Recursive=true&StartIndex=0&ParentId=${id}`
`/Users/${this.userId}/Items?SortBy=SortName&SortOrder=Ascending&IncludeItemTypes=Series,Movie,Others&Recursive=true&StartIndex=0&ParentId=${id}`
);
return contents.data.Items.filter(
@@ -234,7 +245,9 @@ class JellyfinAPI {
}
}
public async getItemData(id: string): Promise<JellyfinLibraryItemExtended> {
public async getItemData(
id: string
): Promise<JellyfinLibraryItemExtended | undefined> {
try {
const contents = await this.axios.get<any>(
`/Users/${this.userId}/Items/${id}`
@@ -242,6 +255,11 @@ class JellyfinAPI {
return contents.data;
} catch (e) {
if (availabilitySync.running) {
if (e.response && e.response.status === 500) {
return undefined;
}
}
logger.error(
`Something went wrong while getting library content from the Jellyfin server: ${e.message}`,
{ label: 'Jellyfin API' }
@@ -254,9 +272,7 @@ class JellyfinAPI {
try {
const contents = await this.axios.get<any>(`/Shows/${seriesID}/Seasons`);
return contents.data.Items.filter(
(item: JellyfinLibraryItem) => item.LocationType !== 'Virtual'
);
return contents.data.Items;
} catch (e) {
logger.error(
`Something went wrong while getting the list of seasons from the Jellyfin server: ${e.message}`,

View File

@@ -1,6 +1,7 @@
import type { Library, PlexSettings } from '@server/lib/settings';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import NodePlexAPI from 'plex-api';
import { getSettings, Library, PlexSettings } from '../lib/settings';
import logger from '../logger';
export interface PlexLibraryItem {
ratingKey: string;
@@ -130,7 +131,6 @@ class PlexAPI {
});
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
public async getStatus() {
return await this.plexClient.query('/');
}
@@ -226,12 +226,17 @@ class PlexAPI {
id: string,
options: { addedAt: number } = {
addedAt: Date.now() - 1000 * 60 * 60,
}
},
mediaType: 'movie' | 'show'
): Promise<PlexLibraryItem[]> {
const response = await this.plexClient.query<PlexLibraryResponse>({
uri: `/library/sections/${id}/all?sort=addedAt%3Adesc&addedAt>>=${Math.floor(
options.addedAt / 1000
)}`,
uri: `/library/sections/${id}/all?type=${
mediaType === 'show' ? '4' : '1'
}&sort=addedAt%3Adesc&addedAt>>=${Math.floor(options.addedAt / 1000)}`,
extraHeaders: {
'X-Plex-Container-Start': `0`,
'X-Plex-Container-Size': `500`,
},
});
return response.MediaContainer.Metadata;

View File

@@ -1,8 +1,9 @@
import axios, { AxiosInstance } from 'axios';
import type { PlexDevice } from '@server/interfaces/api/plexInterfaces';
import cacheManager from '@server/lib/cache';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import xml2js from 'xml2js';
import { PlexDevice } from '../interfaces/api/plexInterfaces';
import { getSettings } from '../lib/settings';
import logger from '../logger';
import ExternalAPI from './externalapi';
interface PlexAccountResponse {
user: PlexUser;
@@ -81,21 +82,6 @@ interface ServerResponse {
};
}
interface FriendResponse {
MediaContainer: {
User: {
$: {
id: string;
title: string;
username: string;
email: string;
thumb: string;
};
Server?: ServerResponse[];
}[];
};
}
interface UsersResponse {
MediaContainer: {
User: {
@@ -111,20 +97,54 @@ interface UsersResponse {
};
}
class PlexTvAPI {
interface WatchlistResponse {
MediaContainer: {
totalSize: number;
Metadata?: {
ratingKey: string;
}[];
};
}
interface MetadataResponse {
MediaContainer: {
Metadata: {
ratingKey: string;
type: 'movie' | 'show';
title: string;
Guid: {
id: `imdb://tt${number}` | `tmdb://${number}` | `tvdb://${number}`;
}[];
}[];
};
}
export interface PlexWatchlistItem {
ratingKey: string;
tmdbId: number;
tvdbId?: number;
type: 'movie' | 'show';
title: string;
}
class PlexTvAPI extends ExternalAPI {
private authToken: string;
private axios: AxiosInstance;
constructor(authToken: string) {
super(
'https://plex.tv',
{},
{
headers: {
'X-Plex-Token': authToken,
'Content-Type': 'application/json',
Accept: 'application/json',
},
nodeCache: cacheManager.getCache('plextv').data,
}
);
this.authToken = authToken;
this.axios = axios.create({
baseURL: 'https://plex.tv',
headers: {
'X-Plex-Token': this.authToken,
'Content-Type': 'application/json',
Accept: 'application/json',
},
});
}
public async getDevices(): Promise<PlexDevice[]> {
@@ -199,19 +219,6 @@ class PlexTvAPI {
}
}
public async getFriends(): Promise<FriendResponse> {
const response = await this.axios.get('/pms/friends/all', {
transformResponse: [],
responseType: 'text',
});
const parsedXml = (await xml2js.parseStringPromise(
response.data
)) as FriendResponse;
return parsedXml;
}
public async checkUserAccess(userId: number): Promise<boolean> {
const settings = getSettings();
@@ -220,9 +227,9 @@ class PlexTvAPI {
throw new Error('Plex is not configured!');
}
const friends = await this.getFriends();
const usersResponse = await this.getUsers();
const users = friends.MediaContainer.User;
const users = usersResponse.MediaContainer.User;
const user = users.find((u) => parseInt(u.$.id) === userId);
@@ -252,6 +259,83 @@ class PlexTvAPI {
)) as UsersResponse;
return parsedXml;
}
public async getWatchlist({
offset = 0,
size = 20,
}: { offset?: number; size?: number } = {}): Promise<{
offset: number;
size: number;
totalSize: number;
items: PlexWatchlistItem[];
}> {
try {
const response = await this.axios.get<WatchlistResponse>(
'/library/sections/watchlist/all',
{
params: {
'X-Plex-Container-Start': offset,
'X-Plex-Container-Size': size,
},
baseURL: 'https://metadata.provider.plex.tv',
}
);
const watchlistDetails = await Promise.all(
(response.data.MediaContainer.Metadata ?? []).map(
async (watchlistItem) => {
const detailedResponse = await this.getRolling<MetadataResponse>(
`/library/metadata/${watchlistItem.ratingKey}`,
{
baseURL: 'https://metadata.provider.plex.tv',
}
);
const metadata = detailedResponse.MediaContainer.Metadata[0];
const tmdbString = metadata.Guid.find((guid) =>
guid.id.startsWith('tmdb')
);
const tvdbString = metadata.Guid.find((guid) =>
guid.id.startsWith('tvdb')
);
return {
ratingKey: metadata.ratingKey,
// This should always be set? But I guess it also cannot be?
// We will filter out the 0's afterwards
tmdbId: tmdbString ? Number(tmdbString.id.split('//')[1]) : 0,
tvdbId: tvdbString
? Number(tvdbString.id.split('//')[1])
: undefined,
title: metadata.title,
type: metadata.type,
};
}
)
);
const filteredList = watchlistDetails.filter((detail) => detail.tmdbId);
return {
offset,
size,
totalSize: response.data.MediaContainer.totalSize,
items: filteredList,
};
} catch (e) {
logger.error('Failed to retrieve watchlist items', {
label: 'Plex.TV Metadata API',
errorMessage: e.message,
});
return {
offset,
size,
totalSize: 0,
items: [],
};
}
}
}
export default PlexTvAPI;

56
server/api/pushover.ts Normal file
View File

@@ -0,0 +1,56 @@
import ExternalAPI from './externalapi';
interface PushoverSoundsResponse {
sounds: {
[name: string]: string;
};
status: number;
request: string;
}
export interface PushoverSound {
name: string;
description: string;
}
export const mapSounds = (sounds: {
[name: string]: string;
}): PushoverSound[] =>
Object.entries(sounds).map(
([name, description]) =>
({
name,
description,
} as PushoverSound)
);
class PushoverAPI extends ExternalAPI {
constructor() {
super(
'https://api.pushover.net/1',
{},
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
}
);
}
public async getSounds(appToken: string): Promise<PushoverSound[]> {
try {
const data = await this.get<PushoverSoundsResponse>('/sounds.json', {
params: {
token: appToken,
},
});
return mapSounds(data.sounds);
} catch (e) {
throw new Error(`[Pushover] Failed to retrieve sounds: ${e.message}`);
}
}
}
export default PushoverAPI;

View File

@@ -0,0 +1,195 @@
import ExternalAPI from '@server/api/externalapi';
import cacheManager from '@server/lib/cache';
type IMDBRadarrProxyResponse = IMDBMovie[];
interface IMDBMovie {
ImdbId: string;
Overview: string;
Title: string;
OriginalTitle: string;
TitleSlug: string;
Ratings: Rating[];
MovieRatings: MovieRatings;
Runtime: number;
Images: Image[];
Genres: string[];
Popularity: number;
Premier: string;
InCinema: string;
PhysicalRelease: any;
DigitalRelease: string;
Year: number;
AlternativeTitles: AlternativeTitle[];
Translations: Translation[];
Recommendations: Recommendation[];
Credits: Credits;
Studio: string;
YoutubeTrailerId: string;
Certifications: Certification[];
Status: any;
Collection: Collection;
OriginalLanguage: string;
Homepage: string;
TmdbId: number;
}
interface Rating {
Count: number;
Value: number;
Origin: string;
Type: string;
}
interface MovieRatings {
Tmdb: Tmdb;
Imdb: Imdb;
Metacritic: Metacritic;
RottenTomatoes: RottenTomatoes;
}
interface Tmdb {
Count: number;
Value: number;
Type: string;
}
interface Imdb {
Count: number;
Value: number;
Type: string;
}
interface Metacritic {
Count: number;
Value: number;
Type: string;
}
interface RottenTomatoes {
Count: number;
Value: number;
Type: string;
}
interface Image {
CoverType: string;
Url: string;
}
interface AlternativeTitle {
Title: string;
Type: string;
Language: string;
}
interface Translation {
Title: string;
Overview: string;
Language: string;
}
interface Recommendation {
TmdbId: number;
Title: string;
}
interface Credits {
Cast: Cast[];
Crew: Crew[];
}
interface Cast {
Name: string;
Order: number;
Character: string;
TmdbId: number;
CreditId: string;
Images: Image2[];
}
interface Image2 {
CoverType: string;
Url: string;
}
interface Crew {
Name: string;
Job: string;
Department: string;
TmdbId: number;
CreditId: string;
Images: Image3[];
}
interface Image3 {
CoverType: string;
Url: string;
}
interface Certification {
Country: string;
Certification: string;
}
interface Collection {
Name: string;
Images: any;
Overview: any;
Translations: any;
Parts: any;
TmdbId: number;
}
export interface IMDBRating {
title: string;
url: string;
criticsScore: number;
}
/**
* This is a best-effort API. The IMDB API is technically
* private and getting access costs money/requires approval.
*
* Radarr hosts a public proxy that's in use by all Radarr instances.
*/
class IMDBRadarrProxy extends ExternalAPI {
constructor() {
super('https://api.radarr.video/v1', {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
nodeCache: cacheManager.getCache('imdb').data,
});
}
/**
* Ask the Radarr IMDB Proxy for the movie
*
* @param IMDBid Id of IMDB movie
*/
public async getMovieRatings(IMDBid: string): Promise<IMDBRating | null> {
try {
const data = await this.get<IMDBRadarrProxyResponse>(
`/movie/imdb/${IMDBid}`
);
if (!data?.length || data[0].ImdbId !== IMDBid) {
return null;
}
return {
title: data[0].Title,
url: `https://www.imdb.com/title/${data[0].ImdbId}`,
criticsScore: data[0].MovieRatings.Imdb.Value,
};
} catch (e) {
throw new Error(
`[IMDB RADARR PROXY API] Failed to retrieve movie ratings: ${e.message}`
);
}
}
}
export default IMDBRadarrProxy;

View File

@@ -0,0 +1,209 @@
import ExternalAPI from '@server/api/externalapi';
import cacheManager from '@server/lib/cache';
import { getSettings } from '@server/lib/settings';
interface RTAlgoliaSearchResponse {
results: {
hits: RTAlgoliaHit[];
index: 'content_rt' | 'people_rt';
}[];
}
interface RTAlgoliaHit {
emsId: string;
emsVersionId: string;
tmsId: string;
type: string;
title: string;
titles: string[];
description: string;
releaseYear: number;
rating: string;
genres: string[];
updateDate: string;
isEmsSearchable: boolean;
rtId: number;
vanity: string;
aka: string[];
posterImageUrl: string;
rottenTomatoes: {
audienceScore: number;
criticsIconUrl: string;
wantToSeeCount: number;
audienceIconUrl: string;
scoreSentiment: string;
certifiedFresh: boolean;
criticsScore: number;
};
}
export interface RTRating {
title: string;
year: number;
criticsRating: 'Certified Fresh' | 'Fresh' | 'Rotten';
criticsScore: number;
audienceRating?: 'Upright' | 'Spilled';
audienceScore?: number;
url: string;
}
/**
* This is a best-effort API. The Rotten Tomatoes API is technically
* private and getting access costs money/requires approval.
*
* They do, however, have a "public" api that they use to request the
* data on their own site. We use this to get ratings for movies/tv shows.
*
* Unfortunately, we need to do it by searching for the movie name, so it's
* not always accurate.
*/
class RottenTomatoes extends ExternalAPI {
constructor() {
const settings = getSettings();
super(
'https://79frdp12pn-dsn.algolia.net/1/indexes/*',
{
'x-algolia-agent':
'Algolia%20for%20JavaScript%20(4.14.3)%3B%20Browser%20(lite)',
'x-algolia-api-key': '175588f6e5f8319b27702e4cc4013561',
'x-algolia-application-id': '79FRDP12PN',
},
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
'x-algolia-usertoken': settings.clientId,
},
nodeCache: cacheManager.getCache('rt').data,
}
);
}
/**
* Search the RT algolia api for the movie title
*
* We compare the release date to make sure its the correct
* match. But it's not guaranteed to have results.
*
* @param name Movie name
* @param year Release Year
*/
public async getMovieRatings(
name: string,
year: number
): Promise<RTRating | null> {
try {
const data = await this.post<RTAlgoliaSearchResponse>('/queries', {
requests: [
{
indexName: 'content_rt',
query: name,
params: 'filters=isEmsSearchable%20%3D%201&hitsPerPage=20',
},
],
});
const contentResults = data.results.find((r) => r.index === 'content_rt');
if (!contentResults) {
return null;
}
// First, attempt to match exact name and year
let movie = contentResults.hits.find(
(movie) => movie.releaseYear === year && movie.title === name
);
// If we don't find a movie, try to match partial name and year
if (!movie) {
movie = contentResults.hits.find(
(movie) => movie.releaseYear === year && movie.title.includes(name)
);
}
// If we still dont find a movie, try to match just on year
if (!movie) {
movie = contentResults.hits.find((movie) => movie.releaseYear === year);
}
// One last try, try exact name match only
if (!movie) {
movie = contentResults.hits.find((movie) => movie.title === name);
}
if (!movie) {
return null;
}
return {
title: movie.title,
url: `https://www.rottentomatoes.com/m/${movie.vanity}`,
criticsRating: movie.rottenTomatoes.certifiedFresh
? 'Certified Fresh'
: movie.rottenTomatoes.criticsScore >= 60
? 'Fresh'
: 'Rotten',
criticsScore: movie.rottenTomatoes.criticsScore,
audienceRating:
movie.rottenTomatoes.audienceScore >= 60 ? 'Upright' : 'Spilled',
audienceScore: movie.rottenTomatoes.audienceScore,
year: Number(movie.releaseYear),
};
} catch (e) {
throw new Error(
`[RT API] Failed to retrieve movie ratings: ${e.message}`
);
}
}
public async getTVRatings(
name: string,
year?: number
): Promise<RTRating | null> {
try {
const data = await this.post<RTAlgoliaSearchResponse>('/queries', {
requests: [
{
indexName: 'content_rt',
query: name,
params: 'filters=isEmsSearchable%20%3D%201&hitsPerPage=20',
},
],
});
const contentResults = data.results.find((r) => r.index === 'content_rt');
if (!contentResults) {
return null;
}
let tvshow: RTAlgoliaHit | undefined = contentResults.hits[0];
if (year) {
tvshow = contentResults.hits.find(
(series) => series.releaseYear === year
);
}
if (!tvshow) {
return null;
}
return {
title: tvshow.title,
url: `https://www.rottentomatoes.com/tv/${tvshow.vanity}`,
criticsRating:
tvshow.rottenTomatoes.criticsScore >= 60 ? 'Fresh' : 'Rotten',
criticsScore: tvshow.rottenTomatoes.criticsScore,
audienceRating:
tvshow.rottenTomatoes.audienceScore >= 60 ? 'Upright' : 'Spilled',
audienceScore: tvshow.rottenTomatoes.audienceScore,
year: Number(tvshow.releaseYear),
};
} catch (e) {
throw new Error(`[RT API] Failed to retrieve tv ratings: ${e.message}`);
}
}
}
export default RottenTomatoes;

7
server/api/ratings.ts Normal file
View File

@@ -0,0 +1,7 @@
import { type IMDBRating } from '@server/api/rating/imdbRadarrProxy';
import { type RTRating } from '@server/api/rating/rottentomatoes';
export interface RatingResponse {
rt?: RTRating;
imdb?: IMDBRating;
}

View File

@@ -1,161 +0,0 @@
import cacheManager from '../lib/cache';
import ExternalAPI from './externalapi';
interface RTSearchResult {
meterClass: 'certified_fresh' | 'fresh' | 'rotten';
meterScore: number;
url: string;
}
interface RTTvSearchResult extends RTSearchResult {
title: string;
startYear: number;
endYear: number;
}
interface RTMovieSearchResult extends RTSearchResult {
name: string;
url: string;
year: number;
}
interface RTMultiSearchResponse {
tvCount: number;
tvSeries: RTTvSearchResult[];
movieCount: number;
movies: RTMovieSearchResult[];
}
export interface RTRating {
title: string;
year: number;
criticsRating: 'Certified Fresh' | 'Fresh' | 'Rotten';
criticsScore: number;
audienceRating?: 'Upright' | 'Spilled';
audienceScore?: number;
url: string;
}
/**
* This is a best-effort API. The Rotten Tomatoes API is technically
* private and getting access costs money/requires approval.
*
* They do, however, have a "public" api that they use to request the
* data on their own site. We use this to get ratings for movies/tv shows.
*
* Unfortunately, we need to do it by searching for the movie name, so it's
* not always accurate.
*/
class RottenTomatoes extends ExternalAPI {
constructor() {
super(
'https://www.rottentomatoes.com/api/private',
{},
{
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
nodeCache: cacheManager.getCache('rt').data,
}
);
}
/**
* Search the 1.0 api for the movie title
*
* We compare the release date to make sure its the correct
* match. But it's not guaranteed to have results.
*
* We use the 1.0 API here because the 2.0 search api does
* not return audience ratings.
*
* @param name Movie name
* @param year Release Year
*/
public async getMovieRatings(
name: string,
year: number
): Promise<RTRating | null> {
try {
const data = await this.get<RTMultiSearchResponse>('/v2.0/search/', {
params: { q: name, limit: 10 },
});
// First, attempt to match exact name and year
let movie = data.movies.find(
(movie) => movie.year === year && movie.name === name
);
// If we don't find a movie, try to match partial name and year
if (!movie) {
movie = data.movies.find(
(movie) => movie.year === year && movie.name.includes(name)
);
}
// If we still dont find a movie, try to match just on year
if (!movie) {
movie = data.movies.find((movie) => movie.year === year);
}
// One last try, try exact name match only
if (!movie) {
movie = data.movies.find((movie) => movie.name === name);
}
if (!movie) {
return null;
}
return {
title: movie.name,
url: `https://www.rottentomatoes.com${movie.url}`,
criticsRating:
movie.meterClass === 'certified_fresh'
? 'Certified Fresh'
: movie.meterClass === 'fresh'
? 'Fresh'
: 'Rotten',
criticsScore: movie.meterScore,
year: movie.year,
};
} catch (e) {
throw new Error(
`[RT API] Failed to retrieve movie ratings: ${e.message}`
);
}
}
public async getTVRatings(
name: string,
year?: number
): Promise<RTRating | null> {
try {
const data = await this.get<RTMultiSearchResponse>('/v2.0/search/', {
params: { q: name, limit: 10 },
});
let tvshow: RTTvSearchResult | undefined = data.tvSeries[0];
if (year) {
tvshow = data.tvSeries.find((series) => series.startYear === year);
}
if (!tvshow) {
return null;
}
return {
title: tvshow.title,
url: `https://www.rottentomatoes.com${tvshow.url}`,
criticsRating: tvshow.meterClass === 'fresh' ? 'Fresh' : 'Rotten',
criticsScore: tvshow.meterScore,
year: tvshow.startYear,
};
} catch (e) {
throw new Error(`[RT API] Failed to retrieve tv ratings: ${e.message}`);
}
}
}
export default RottenTomatoes;

View File

@@ -1,6 +1,7 @@
import cacheManager, { AvailableCacheIds } from '../../lib/cache';
import { DVRSettings } from '../../lib/settings';
import ExternalAPI from '../externalapi';
import ExternalAPI from '@server/api/externalapi';
import type { AvailableCacheIds } from '@server/lib/cache';
import cacheManager from '@server/lib/cache';
import type { DVRSettings } from '@server/lib/settings';
export interface SystemStatus {
version: string;
@@ -157,7 +158,12 @@ class ServarrBase<QueueItemAppendT> extends ExternalAPI {
public getQueue = async (): Promise<(QueueItem & QueueItemAppendT)[]> => {
try {
const response = await this.axios.get<QueueResponse<QueueItemAppendT>>(
`/queue`
`/queue`,
{
params: {
includeEpisode: true,
},
}
);
return response.data.records;

View File

@@ -1,4 +1,4 @@
import logger from '../../logger';
import logger from '@server/logger';
import ServarrBase from './base';
export interface RadarrMovieOptions {
@@ -69,7 +69,7 @@ class RadarrAPI extends ServarrBase<{ movieId: number }> {
return response.data[0];
} catch (e) {
logger.error('Error retrieving movie by TMDb ID', {
logger.error('Error retrieving movie by TMDB ID', {
label: 'Radarr API',
errorMessage: e.message,
tmdbId: id,
@@ -213,6 +213,20 @@ class RadarrAPI extends ServarrBase<{ movieId: number }> {
);
}
}
public removeMovie = async (movieId: number): Promise<void> => {
try {
const { id, title } = await this.getMovieByTmdbId(movieId);
await this.axios.delete(`/movie/${id}`, {
params: {
deleteFiles: true,
addImportExclusion: false,
},
});
logger.info(`[Radarr] Removed movie ${title}`);
} catch (e) {
throw new Error(`[Radarr] Failed to remove movie: ${e.message}`);
}
};
}
export default RadarrAPI;

View File

@@ -1,7 +1,7 @@
import logger from '../../logger';
import logger from '@server/logger';
import ServarrBase from './base';
interface SonarrSeason {
export interface SonarrSeason {
seasonNumber: number;
monitored: boolean;
statistics?: {
@@ -13,6 +13,21 @@ interface SonarrSeason {
percentOfEpisodes: number;
};
}
interface EpisodeResult {
seriesId: number;
episodeFileId: number;
seasonNumber: number;
episodeNumber: number;
title: string;
airDate: string;
airDateUtc: string;
overview: string;
hasFile: boolean;
monitored: boolean;
absoluteEpisodeNumber: number;
unverifiedSceneNumbering: boolean;
id: number;
}
export interface SonarrSeries {
title: string;
@@ -61,6 +76,15 @@ export interface SonarrSeries {
ignoreEpisodesWithoutFiles?: boolean;
searchForMissingEpisodes?: boolean;
};
statistics: {
seasonCount: number;
episodeFileCount: number;
episodeCount: number;
totalEpisodeCount: number;
sizeOnDisk: number;
releaseGroups: string[];
percentOfEpisodes: number;
};
}
export interface AddSeriesOptions {
@@ -82,7 +106,11 @@ export interface LanguageProfile {
name: string;
}
class SonarrAPI extends ServarrBase<{ seriesId: number; episodeId: number }> {
class SonarrAPI extends ServarrBase<{
seriesId: number;
episodeId: number;
episode: EpisodeResult;
}> {
constructor({ url, apiKey }: { url: string; apiKey: string }) {
super({ url, apiKey, apiName: 'Sonarr', cacheName: 'sonarr' });
}
@@ -97,6 +125,16 @@ class SonarrAPI extends ServarrBase<{ seriesId: number; episodeId: number }> {
}
}
public async getSeriesById(id: number): Promise<SonarrSeries> {
try {
const response = await this.axios.get<SonarrSeries>(`/series/${id}`);
return response.data;
} catch (e) {
throw new Error(`[Sonarr] Failed to retrieve series by ID: ${e.message}`);
}
}
public async getSeriesByTitle(title: string): Promise<SonarrSeries[]> {
try {
const response = await this.axios.get<SonarrSeries[]>('/series/lookup', {
@@ -302,6 +340,20 @@ class SonarrAPI extends ServarrBase<{ seriesId: number; episodeId: number }> {
return newSeasons;
}
public removeSerie = async (serieId: number): Promise<void> => {
try {
const { id, title } = await this.getSeriesByTvdbId(serieId);
await this.axios.delete(`/series/${id}`, {
params: {
deleteFiles: true,
addImportExclusion: false,
},
});
logger.info(`[Radarr] Removed serie ${title}`);
} catch (e) {
throw new Error(`[Radarr] Failed to remove serie: ${e.message}`);
}
};
}
export default SonarrAPI;

View File

@@ -1,8 +1,9 @@
import axios, { AxiosInstance } from 'axios';
import type { User } from '@server/entity/User';
import type { TautulliSettings } from '@server/lib/settings';
import logger from '@server/logger';
import type { AxiosInstance } from 'axios';
import axios from 'axios';
import { uniqWith } from 'lodash';
import { User } from '../entity/User';
import { TautulliSettings } from '../lib/settings';
import logger from '../logger';
export interface TautulliHistoryRecord {
date: number;

View File

@@ -1,11 +1,14 @@
import ExternalAPI from '@server/api/externalapi';
import cacheManager from '@server/lib/cache';
import { sortBy } from 'lodash';
import cacheManager from '../../lib/cache';
import ExternalAPI from '../externalapi';
import {
import type {
TmdbCollection,
TmdbCompanySearchResponse,
TmdbExternalIdResponse,
TmdbGenre,
TmdbGenresResult,
TmdbKeyword,
TmdbKeywordSearchResponse,
TmdbLanguage,
TmdbMovieDetails,
TmdbNetwork,
@@ -19,6 +22,8 @@ import {
TmdbSeasonWithEpisodes,
TmdbTvDetails,
TmdbUpcomingMoviesResponse,
TmdbWatchProviderDetails,
TmdbWatchProviderRegion,
} from './interfaces';
interface SearchOptions {
@@ -32,30 +37,43 @@ interface SingleSearchOptions extends SearchOptions {
year?: number;
}
export type SortOptions =
| 'popularity.asc'
| 'popularity.desc'
| 'release_date.asc'
| 'release_date.desc'
| 'revenue.asc'
| 'revenue.desc'
| 'primary_release_date.asc'
| 'primary_release_date.desc'
| 'original_title.asc'
| 'original_title.desc'
| 'vote_average.asc'
| 'vote_average.desc'
| 'vote_count.asc'
| 'vote_count.desc'
| 'first_air_date.asc'
| 'first_air_date.desc';
interface DiscoverMovieOptions {
page?: number;
includeAdult?: boolean;
language?: string;
primaryReleaseDateGte?: string;
primaryReleaseDateLte?: string;
withRuntimeGte?: string;
withRuntimeLte?: string;
voteAverageGte?: string;
voteAverageLte?: string;
voteCountGte?: string;
voteCountLte?: string;
originalLanguage?: string;
genre?: number;
studio?: number;
sortBy?:
| 'popularity.asc'
| 'popularity.desc'
| 'release_date.asc'
| 'release_date.desc'
| 'revenue.asc'
| 'revenue.desc'
| 'primary_release_date.asc'
| 'primary_release_date.desc'
| 'original_title.asc'
| 'original_title.desc'
| 'vote_average.asc'
| 'vote_average.desc'
| 'vote_count.asc'
| 'vote_count.desc';
genre?: string;
studio?: string;
keywords?: string;
sortBy?: SortOptions;
watchRegion?: string;
watchProviders?: string;
}
interface DiscoverTvOptions {
@@ -63,19 +81,20 @@ interface DiscoverTvOptions {
language?: string;
firstAirDateGte?: string;
firstAirDateLte?: string;
withRuntimeGte?: string;
withRuntimeLte?: string;
voteAverageGte?: string;
voteAverageLte?: string;
voteCountGte?: string;
voteCountLte?: string;
includeEmptyReleaseDate?: boolean;
originalLanguage?: string;
genre?: number;
genre?: string;
network?: number;
sortBy?:
| 'popularity.asc'
| 'popularity.desc'
| 'vote_average.asc'
| 'vote_average.desc'
| 'vote_count.asc'
| 'vote_count.desc'
| 'first_air_date.asc'
| 'first_air_date.desc';
keywords?: string;
sortBy?: SortOptions;
watchRegion?: string;
watchProviders?: string;
}
class TheMovieDb extends ExternalAPI {
@@ -92,6 +111,10 @@ class TheMovieDb extends ExternalAPI {
},
{
nodeCache: cacheManager.getCache('tmdb').data,
rateLimit: {
maxRequests: 20,
maxRPS: 50,
},
}
);
this.region = region;
@@ -192,7 +215,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch person details: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch person details: ${e.message}`);
}
};
@@ -214,7 +237,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(
`[TMDb] Failed to fetch person combined credits: ${e.message}`
`[TMDB] Failed to fetch person combined credits: ${e.message}`
);
}
};
@@ -233,7 +256,7 @@ class TheMovieDb extends ExternalAPI {
params: {
language,
append_to_response:
'credits,external_ids,videos,release_dates,watch/providers',
'credits,external_ids,videos,keywords,release_dates,watch/providers',
},
},
43200
@@ -241,7 +264,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch movie details: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch movie details: ${e.message}`);
}
};
@@ -267,7 +290,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch TV show details: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch TV show details: ${e.message}`);
}
};
@@ -293,7 +316,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch TV show details: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch TV show details: ${e.message}`);
}
};
@@ -319,7 +342,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
}
}
@@ -345,7 +368,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
}
}
@@ -371,7 +394,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch movies by keyword: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch movies by keyword: ${e.message}`);
}
}
@@ -398,7 +421,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(
`[TMDb] Failed to fetch TV recommendations: ${e.message}`
`[TMDB] Failed to fetch TV recommendations: ${e.message}`
);
}
}
@@ -422,7 +445,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch TV similar: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch TV similar: ${e.message}`);
}
}
@@ -436,8 +459,27 @@ class TheMovieDb extends ExternalAPI {
originalLanguage,
genre,
studio,
keywords,
withRuntimeGte,
withRuntimeLte,
voteAverageGte,
voteAverageLte,
voteCountGte,
voteCountLte,
watchProviders,
watchRegion,
}: DiscoverMovieOptions = {}): Promise<TmdbSearchMovieResponse> => {
try {
const defaultFutureDate = new Date(
Date.now() + 1000 * 60 * 60 * 24 * (365 * 1.5)
)
.toISOString()
.split('T')[0];
const defaultPastDate = new Date('1900-01-01')
.toISOString()
.split('T')[0];
const data = await this.get<TmdbSearchMovieResponse>('/discover/movie', {
params: {
sort_by: sortBy,
@@ -445,17 +487,39 @@ class TheMovieDb extends ExternalAPI {
include_adult: includeAdult,
language,
region: this.region,
with_original_language: originalLanguage ?? this.originalLanguage,
'primary_release_date.gte': primaryReleaseDateGte,
'primary_release_date.lte': primaryReleaseDateLte,
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? undefined
: this.originalLanguage,
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'primary_release_date.gte':
!primaryReleaseDateGte && primaryReleaseDateLte
? defaultPastDate
: primaryReleaseDateGte,
'primary_release_date.lte':
!primaryReleaseDateLte && primaryReleaseDateGte
? defaultFutureDate
: primaryReleaseDateLte,
with_genres: genre,
with_companies: studio,
with_keywords: keywords,
'with_runtime.gte': withRuntimeGte,
'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
watch_region: watchRegion,
with_watch_providers: watchProviders,
},
});
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
}
};
@@ -469,26 +533,67 @@ class TheMovieDb extends ExternalAPI {
originalLanguage,
genre,
network,
keywords,
withRuntimeGte,
withRuntimeLte,
voteAverageGte,
voteAverageLte,
voteCountGte,
voteCountLte,
watchProviders,
watchRegion,
}: DiscoverTvOptions = {}): Promise<TmdbSearchTvResponse> => {
try {
const defaultFutureDate = new Date(
Date.now() + 1000 * 60 * 60 * 24 * (365 * 1.5)
)
.toISOString()
.split('T')[0];
const defaultPastDate = new Date('1900-01-01')
.toISOString()
.split('T')[0];
const data = await this.get<TmdbSearchTvResponse>('/discover/tv', {
params: {
sort_by: sortBy,
page,
language,
region: this.region,
'first_air_date.gte': firstAirDateGte,
'first_air_date.lte': firstAirDateLte,
with_original_language: originalLanguage ?? this.originalLanguage,
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'first_air_date.gte':
!firstAirDateGte && firstAirDateLte
? defaultPastDate
: firstAirDateGte,
'first_air_date.lte':
!firstAirDateLte && firstAirDateGte
? defaultFutureDate
: firstAirDateLte,
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? undefined
: this.originalLanguage,
include_null_first_air_dates: includeEmptyReleaseDate,
with_genres: genre,
with_networks: network,
with_keywords: keywords,
'with_runtime.gte': withRuntimeGte,
'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
with_watch_providers: watchProviders,
watch_region: watchRegion,
},
});
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch discover TV: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch discover TV: ${e.message}`);
}
};
@@ -514,7 +619,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch upcoming movies: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch upcoming movies: ${e.message}`);
}
};
@@ -541,7 +646,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
}
};
@@ -564,7 +669,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
}
};
@@ -587,7 +692,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
}
};
@@ -619,7 +724,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to find by external ID: ${e.message}`);
throw new Error(`[TMDB] Failed to find by external ID: ${e.message}`);
}
}
@@ -657,7 +762,7 @@ class TheMovieDb extends ExternalAPI {
throw new Error(`No movie or show returned from API for ID ${imdbId}`);
} catch (e) {
throw new Error(
`[TMDb] Failed to find media using external IMDb ID: ${e.message}`
`[TMDB] Failed to find media using external IMDb ID: ${e.message}`
);
}
}
@@ -687,7 +792,7 @@ class TheMovieDb extends ExternalAPI {
throw new Error(`No show returned from API for ID ${tvdbId}`);
} catch (e) {
throw new Error(
`[TMDb] Failed to get TV show using the external TVDB ID: ${e.message}`
`[TMDB] Failed to get TV show using the external TVDB ID: ${e.message}`
);
}
}
@@ -711,7 +816,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch collection: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch collection: ${e.message}`);
}
}
@@ -727,7 +832,7 @@ class TheMovieDb extends ExternalAPI {
return regions;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch countries: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch countries: ${e.message}`);
}
}
@@ -743,7 +848,7 @@ class TheMovieDb extends ExternalAPI {
return languages;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch langauges: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch langauges: ${e.message}`);
}
}
@@ -755,7 +860,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch movie studio: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch movie studio: ${e.message}`);
}
}
@@ -765,7 +870,7 @@ class TheMovieDb extends ExternalAPI {
return data;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch TV network: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch TV network: ${e.message}`);
}
}
@@ -816,7 +921,7 @@ class TheMovieDb extends ExternalAPI {
return movieGenres;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch movie genres: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch movie genres: ${e.message}`);
}
}
@@ -867,7 +972,153 @@ class TheMovieDb extends ExternalAPI {
return tvGenres;
} catch (e) {
throw new Error(`[TMDb] Failed to fetch TV genres: ${e.message}`);
throw new Error(`[TMDB] Failed to fetch TV genres: ${e.message}`);
}
}
public async getKeywordDetails({
keywordId,
}: {
keywordId: number;
}): Promise<TmdbKeyword> {
try {
const data = await this.get<TmdbKeyword>(
`/keyword/${keywordId}`,
undefined,
604800 // 7 days
);
return data;
} catch (e) {
throw new Error(`[TMDB] Failed to fetch keyword: ${e.message}`);
}
}
public async searchKeyword({
query,
page = 1,
}: {
query: string;
page?: number;
}): Promise<TmdbKeywordSearchResponse> {
try {
const data = await this.get<TmdbKeywordSearchResponse>(
'/search/keyword',
{
params: {
query,
page,
},
},
86400 // 24 hours
);
return data;
} catch (e) {
throw new Error(`[TMDB] Failed to search keyword: ${e.message}`);
}
}
public async searchCompany({
query,
page = 1,
}: {
query: string;
page?: number;
}): Promise<TmdbCompanySearchResponse> {
try {
const data = await this.get<TmdbCompanySearchResponse>(
'/search/company',
{
params: {
query,
page,
},
},
86400 // 24 hours
);
return data;
} catch (e) {
throw new Error(`[TMDB] Failed to search companies: ${e.message}`);
}
}
public async getAvailableWatchProviderRegions({
language,
}: {
language?: string;
}) {
try {
const data = await this.get<{ results: TmdbWatchProviderRegion[] }>(
'/watch/providers/regions',
{
params: {
language: language ?? this.originalLanguage,
},
},
86400 // 24 hours
);
return data.results;
} catch (e) {
throw new Error(
`[TMDB] Failed to fetch available watch regions: ${e.message}`
);
}
}
public async getMovieWatchProviders({
language,
watchRegion,
}: {
language?: string;
watchRegion: string;
}) {
try {
const data = await this.get<{ results: TmdbWatchProviderDetails[] }>(
'/watch/providers/movie',
{
params: {
language: language ?? this.originalLanguage,
watch_region: watchRegion,
},
},
86400 // 24 hours
);
return data.results;
} catch (e) {
throw new Error(
`[TMDB] Failed to fetch movie watch providers: ${e.message}`
);
}
}
public async getTvWatchProviders({
language,
watchRegion,
}: {
language?: string;
watchRegion: string;
}) {
try {
const data = await this.get<{ results: TmdbWatchProviderDetails[] }>(
'/watch/providers/tv',
{
params: {
language: language ?? this.originalLanguage,
watch_region: watchRegion,
},
},
86400 // 24 hours
);
return data.results;
} catch (e) {
throw new Error(
`[TMDB] Failed to fetch TV watch providers: ${e.message}`
);
}
}
}

View File

@@ -28,6 +28,18 @@ export interface TmdbTvResult extends TmdbMediaResult {
first_air_date: string;
}
export interface TmdbCollectionResult {
id: number;
media_type: 'collection';
title: string;
original_title: string;
adult: boolean;
poster_path?: string;
backdrop_path?: string;
overview: string;
original_language: string;
}
export interface TmdbPersonResult {
id: number;
name: string;
@@ -45,7 +57,12 @@ interface TmdbPaginatedResponse {
}
export interface TmdbSearchMultiResponse extends TmdbPaginatedResponse {
results: (TmdbMovieResult | TmdbTvResult | TmdbPersonResult)[];
results: (
| TmdbMovieResult
| TmdbTvResult
| TmdbPersonResult
| TmdbCollectionResult
)[];
}
export interface TmdbSearchMovieResponse extends TmdbPaginatedResponse {
@@ -171,6 +188,9 @@ export interface TmdbMovieDetails {
id: number;
results?: { [iso_3166_1: string]: TmdbWatchProviders };
};
keywords: {
keywords: TmdbKeyword[];
};
}
export interface TmdbVideo {
@@ -191,7 +211,7 @@ export interface TmdbVideo {
export interface TmdbTvEpisodeResult {
id: number;
air_date: string;
air_date: string | null;
episode_number: number;
name: string;
overview: string;
@@ -372,7 +392,8 @@ export interface TmdbPersonCombinedCredits {
crew: TmdbPersonCreditCrew[];
}
export interface TmdbSeasonWithEpisodes extends TmdbTvSeasonResult {
export interface TmdbSeasonWithEpisodes
extends Omit<TmdbTvSeasonResult, 'episode_count'> {
episodes: TmdbTvEpisodeResult[];
external_ids: TmdbExternalIds;
}
@@ -427,3 +448,24 @@ export interface TmdbWatchProviderDetails {
provider_id: number;
provider_name: string;
}
export interface TmdbKeywordSearchResponse extends TmdbPaginatedResponse {
results: TmdbKeyword[];
}
// We have production companies, but the company search results return less data
export interface TmdbCompany {
id: number;
logo_path?: string;
name: string;
}
export interface TmdbCompanySearchResponse extends TmdbPaginatedResponse {
results: TmdbCompany[];
}
export interface TmdbWatchProviderRegion {
iso_3166_1: string;
english_name: string;
native_name: string;
}

View File

@@ -0,0 +1,100 @@
import type DiscoverSlider from '@server/entity/DiscoverSlider';
export enum DiscoverSliderType {
RECENTLY_ADDED = 1,
RECENT_REQUESTS,
PLEX_WATCHLIST,
TRENDING,
POPULAR_MOVIES,
MOVIE_GENRES,
UPCOMING_MOVIES,
STUDIOS,
POPULAR_TV,
TV_GENRES,
UPCOMING_TV,
NETWORKS,
TMDB_MOVIE_KEYWORD,
TMDB_MOVIE_GENRE,
TMDB_TV_KEYWORD,
TMDB_TV_GENRE,
TMDB_SEARCH,
TMDB_STUDIO,
TMDB_NETWORK,
TMDB_MOVIE_STREAMING_SERVICES,
TMDB_TV_STREAMING_SERVICES,
}
export const defaultSliders: Partial<DiscoverSlider>[] = [
{
type: DiscoverSliderType.RECENTLY_ADDED,
enabled: true,
isBuiltIn: true,
order: 0,
},
{
type: DiscoverSliderType.RECENT_REQUESTS,
enabled: true,
isBuiltIn: true,
order: 1,
},
{
type: DiscoverSliderType.PLEX_WATCHLIST,
enabled: true,
isBuiltIn: true,
order: 2,
},
{
type: DiscoverSliderType.TRENDING,
enabled: true,
isBuiltIn: true,
order: 3,
},
{
type: DiscoverSliderType.POPULAR_MOVIES,
enabled: true,
isBuiltIn: true,
order: 4,
},
{
type: DiscoverSliderType.MOVIE_GENRES,
enabled: true,
isBuiltIn: true,
order: 5,
},
{
type: DiscoverSliderType.UPCOMING_MOVIES,
enabled: true,
isBuiltIn: true,
order: 6,
},
{
type: DiscoverSliderType.STUDIOS,
enabled: true,
isBuiltIn: true,
order: 7,
},
{
type: DiscoverSliderType.POPULAR_TV,
enabled: true,
isBuiltIn: true,
order: 8,
},
{
type: DiscoverSliderType.TV_GENRES,
enabled: true,
isBuiltIn: true,
order: 9,
},
{
type: DiscoverSliderType.UPCOMING_TV,
enabled: true,
isBuiltIn: true,
order: 10,
},
{
type: DiscoverSliderType.NETWORKS,
enabled: true,
isBuiltIn: true,
order: 11,
},
];

View File

@@ -2,6 +2,7 @@ export enum MediaRequestStatus {
PENDING = 1,
APPROVED,
DECLINED,
FAILED,
}
export enum MediaType {

View File

@@ -1,4 +1,8 @@
const devConfig = {
import 'reflect-metadata';
import type { DataSourceOptions, EntityTarget, Repository } from 'typeorm';
import { DataSource } from 'typeorm';
const devConfig: DataSourceOptions = {
type: 'sqlite',
database: process.env.CONFIG_DIRECTORY
? `${process.env.CONFIG_DIRECTORY}/db/db.sqlite3`
@@ -10,31 +14,30 @@ const devConfig = {
entities: ['server/entity/**/*.ts'],
migrations: ['server/migration/**/*.ts'],
subscribers: ['server/subscriber/**/*.ts'],
cli: {
entitiesDir: 'server/entity',
migrationsDir: 'server/migration',
},
};
const prodConfig = {
const prodConfig: DataSourceOptions = {
type: 'sqlite',
database: process.env.CONFIG_DIRECTORY
? `${process.env.CONFIG_DIRECTORY}/db/db.sqlite3`
: 'config/db/db.sqlite3',
synchronize: false,
migrationsRun: false,
logging: false,
enableWAL: true,
entities: ['dist/entity/**/*.js'],
migrations: ['dist/migration/**/*.js'],
migrationsRun: false,
subscribers: ['dist/subscriber/**/*.js'],
cli: {
entitiesDir: 'dist/entity',
migrationsDir: 'dist/migration',
},
};
const finalConfig =
process.env.NODE_ENV !== 'production' ? devConfig : prodConfig;
const dataSource = new DataSource(
process.env.NODE_ENV !== 'production' ? devConfig : prodConfig
);
module.exports = finalConfig;
export const getRepository = <Entity extends object>(
target: EntityTarget<Entity>
): Repository<Entity> => {
return dataSource.getRepository(target);
};
export default dataSource;

View File

@@ -0,0 +1,69 @@
import type { DiscoverSliderType } from '@server/constants/discover';
import { defaultSliders } from '@server/constants/discover';
import { getRepository } from '@server/datasource';
import logger from '@server/logger';
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
class DiscoverSlider {
public static async bootstrapSliders(): Promise<void> {
const sliderRepository = getRepository(DiscoverSlider);
for (const slider of defaultSliders) {
const existingSlider = await sliderRepository.findOne({
where: {
type: slider.type,
},
});
if (!existingSlider) {
logger.info('Creating built-in discovery slider', {
label: 'Discover Slider',
slider,
});
await sliderRepository.save(new DiscoverSlider(slider));
}
}
}
@PrimaryGeneratedColumn()
public id: number;
@Column({ type: 'int' })
public type: DiscoverSliderType;
@Column({ type: 'int' })
public order: number;
@Column({ default: false })
public isBuiltIn: boolean;
@Column({ default: true })
public enabled: boolean;
@Column({ nullable: true })
// Title is not required for built in sliders because we will
// use translations for them.
public title?: string;
@Column({ nullable: true })
public data?: string;
@CreateDateColumn()
public createdAt: Date;
@UpdateDateColumn()
public updatedAt: Date;
constructor(init?: Partial<DiscoverSlider>) {
Object.assign(this, init);
}
}
export default DiscoverSlider;

View File

@@ -1,3 +1,5 @@
import type { IssueType } from '@server/constants/issue';
import { IssueStatus } from '@server/constants/issue';
import {
Column,
CreateDateColumn,
@@ -7,7 +9,6 @@ import {
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { IssueStatus, IssueType } from '../constants/issue';
import IssueComment from './IssueComment';
import Media from './Media';
import { User } from './User';

View File

@@ -1,22 +1,24 @@
import RadarrAPI from '@server/api/servarr/radarr';
import SonarrAPI from '@server/api/servarr/sonarr';
import { MediaStatus, MediaType } from '@server/constants/media';
import { MediaServerType } from '@server/constants/server';
import { getRepository } from '@server/datasource';
import type { User } from '@server/entity/User';
import { Watchlist } from '@server/entity/Watchlist';
import type { DownloadingItem } from '@server/lib/downloadtracker';
import downloadTracker from '@server/lib/downloadtracker';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import {
AfterLoad,
Column,
CreateDateColumn,
Entity,
getRepository,
In,
Index,
OneToMany,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import RadarrAPI from '../api/servarr/radarr';
import SonarrAPI from '../api/servarr/sonarr';
import { MediaStatus, MediaType } from '../constants/media';
import { MediaServerType } from '../constants/server';
import downloadTracker, { DownloadingItem } from '../lib/downloadtracker';
import { getSettings } from '../lib/settings';
import logger from '../logger';
import Issue from './Issue';
import { MediaRequest } from './MediaRequest';
import Season from './Season';
@@ -24,6 +26,7 @@ import Season from './Season';
@Entity()
class Media {
public static async getRelatedMedia(
user: User | undefined,
tmdbIds: number | number[]
): Promise<Media[]> {
const mediaRepository = getRepository(Media);
@@ -36,9 +39,16 @@ class Media {
finalIds = tmdbIds;
}
const media = await mediaRepository.find({
tmdbId: In(finalIds),
});
const media = await mediaRepository
.createQueryBuilder('media')
.leftJoinAndSelect(
'media.watchlists',
'watchlist',
'media.id= watchlist.media and watchlist.requestedBy = :userId',
{ userId: user?.id }
) //,
.where(' media.tmdbId in (:...finalIds)', { finalIds })
.getMany();
return media;
} catch (e) {
@@ -56,10 +66,10 @@ class Media {
try {
const media = await mediaRepository.findOne({
where: { tmdbId: id, mediaType },
relations: ['requests', 'issues'],
relations: { requests: true, issues: true },
});
return media;
return media ?? undefined;
} catch (e) {
logger.error(e.message);
return undefined;
@@ -93,6 +103,9 @@ class Media {
@OneToMany(() => MediaRequest, (request) => request.media, { cascade: true })
public requests: MediaRequest[];
@OneToMany(() => Watchlist, (watchlist) => watchlist.media)
public watchlists: null | Watchlist[];
@OneToMany(() => Season, (season) => season.media, {
cascade: true,
eager: true,
@@ -114,35 +127,35 @@ class Media {
@Column({ type: 'datetime', nullable: true })
public mediaAddedAt: Date;
@Column({ nullable: true })
public serviceId?: number;
@Column({ nullable: true, type: 'int' })
public serviceId?: number | null;
@Column({ nullable: true })
public serviceId4k?: number;
@Column({ nullable: true, type: 'int' })
public serviceId4k?: number | null;
@Column({ nullable: true })
public externalServiceId?: number;
@Column({ nullable: true, type: 'int' })
public externalServiceId?: number | null;
@Column({ nullable: true })
public externalServiceId4k?: number;
@Column({ nullable: true, type: 'int' })
public externalServiceId4k?: number | null;
@Column({ nullable: true })
public externalServiceSlug?: string;
@Column({ nullable: true, type: 'varchar' })
public externalServiceSlug?: string | null;
@Column({ nullable: true })
public externalServiceSlug4k?: string;
@Column({ nullable: true, type: 'varchar' })
public externalServiceSlug4k?: string | null;
@Column({ nullable: true })
public ratingKey?: string;
@Column({ nullable: true, type: 'varchar' })
public ratingKey?: string | null;
@Column({ nullable: true })
public ratingKey4k?: string;
@Column({ nullable: true, type: 'varchar' })
public ratingKey4k?: string | null;
@Column({ nullable: true })
public jellyfinMediaId?: string;
@Column({ nullable: true, type: 'varchar' })
public jellyfinMediaId?: string | null;
@Column({ nullable: true })
public jellyfinMediaId4k?: string;
@Column({ nullable: true, type: 'varchar' })
public jellyfinMediaId4k?: string | null;
public serviceUrl?: string;
public serviceUrl4k?: string;
@@ -152,6 +165,9 @@ class Media {
public mediaUrl?: string;
public mediaUrl4k?: string;
public iOSPlexUrl?: string;
public iOSPlexUrl4k?: string;
public tautulliUrl?: string;
public tautulliUrl4k?: string;
@@ -172,35 +188,44 @@ class Media {
this.ratingKey
}`;
this.iOSPlexUrl = `plex://preplay/?metadataKey=%2Flibrary%2Fmetadata%2F${this.ratingKey}&server=${machineId}`;
if (tautulliUrl) {
this.tautulliUrl = `${tautulliUrl}/info?rating_key=${this.ratingKey}`;
}
}
if (this.ratingKey4k) {
this.mediaUrl4k = `${
webAppUrl ? webAppUrl : 'https://app.plex.tv/desktop'
}#!/server/${machineId}/details?key=%2Flibrary%2Fmetadata%2F${
this.ratingKey4k
}`;
if (this.ratingKey4k) {
this.mediaUrl4k = `${
webAppUrl ? webAppUrl : 'https://app.plex.tv/desktop'
}#!/server/${machineId}/details?key=%2Flibrary%2Fmetadata%2F${
this.ratingKey4k
}`;
if (tautulliUrl) {
this.tautulliUrl4k = `${tautulliUrl}/info?rating_key=${this.ratingKey4k}`;
this.iOSPlexUrl4k = `plex://preplay/?metadataKey=%2Flibrary%2Fmetadata%2F${this.ratingKey4k}&server=${machineId}`;
if (tautulliUrl) {
this.tautulliUrl4k = `${tautulliUrl}/info?rating_key=${this.ratingKey4k}`;
}
}
}
} else {
const pageName =
process.env.JELLYFIN_TYPE === 'emby' ? 'item' : 'details';
const { serverId, hostname, externalHostname } = getSettings().jellyfin;
const jellyfinHost =
let jellyfinHost =
externalHostname && externalHostname.length > 0
? externalHostname
: hostname;
jellyfinHost = jellyfinHost.endsWith('/')
? jellyfinHost.slice(0, -1)
: jellyfinHost;
if (this.jellyfinMediaId) {
this.mediaUrl = `${jellyfinHost}/web/index.html#!/${pageName}?id=${this.jellyfinMediaId}&context=home&serverId=${serverId}`;
}
if (this.jellyfinMediaId4k) {
this.mediaUrl4k = `${jellyfinHost}/web/index.html#!/${pageName}?id=${this.jellyfinMediaId4k}&context=home&serverId=${serverId}`;
this.mediaUrl4k = `${jellyfinHost}/web/index.html#!/${pageName}?id=${this.jellyfinMediaId}&context=home&serverId=${serverId}`;
}
}
}
@@ -275,7 +300,9 @@ class Media {
if (this.mediaType === MediaType.MOVIE) {
if (
this.externalServiceId !== undefined &&
this.serviceId !== undefined
this.externalServiceId !== null &&
this.serviceId !== undefined &&
this.serviceId !== null
) {
this.downloadStatus = downloadTracker.getMovieProgress(
this.serviceId,
@@ -285,7 +312,9 @@ class Media {
if (
this.externalServiceId4k !== undefined &&
this.serviceId4k !== undefined
this.externalServiceId4k !== null &&
this.serviceId4k !== undefined &&
this.serviceId4k !== null
) {
this.downloadStatus4k = downloadTracker.getMovieProgress(
this.serviceId4k,
@@ -297,7 +326,9 @@ class Media {
if (this.mediaType === MediaType.TV) {
if (
this.externalServiceId !== undefined &&
this.serviceId !== undefined
this.externalServiceId !== null &&
this.serviceId !== undefined &&
this.serviceId !== null
) {
this.downloadStatus = downloadTracker.getSeriesProgress(
this.serviceId,
@@ -307,7 +338,9 @@ class Media {
if (
this.externalServiceId4k !== undefined &&
this.serviceId4k !== undefined
this.externalServiceId4k !== null &&
this.serviceId4k !== undefined &&
this.serviceId4k !== null
) {
this.downloadStatus4k = downloadTracker.getSeriesProgress(
this.serviceId4k,

View File

@@ -1,3 +1,23 @@
import type { RadarrMovieOptions } from '@server/api/servarr/radarr';
import RadarrAPI from '@server/api/servarr/radarr';
import type {
AddSeriesOptions,
SonarrSeries,
} from '@server/api/servarr/sonarr';
import SonarrAPI from '@server/api/servarr/sonarr';
import TheMovieDb from '@server/api/themoviedb';
import { ANIME_KEYWORD_ID } from '@server/api/themoviedb/constants';
import {
MediaRequestStatus,
MediaStatus,
MediaType,
} from '@server/constants/media';
import { getRepository } from '@server/datasource';
import type { MediaRequestBody } from '@server/interfaces/api/requestInterfaces';
import notificationManager, { Notification } from '@server/lib/notifications';
import { Permission } from '@server/lib/permissions';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import { isEqual, truncate } from 'lodash';
import {
AfterInsert,
@@ -6,30 +26,347 @@ import {
Column,
CreateDateColumn,
Entity,
getRepository,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
RelationCount,
UpdateDateColumn,
} from 'typeorm';
import RadarrAPI, { RadarrMovieOptions } from '../api/servarr/radarr';
import SonarrAPI, {
AddSeriesOptions,
SonarrSeries,
} from '../api/servarr/sonarr';
import TheMovieDb from '../api/themoviedb';
import { ANIME_KEYWORD_ID } from '../api/themoviedb/constants';
import { MediaRequestStatus, MediaStatus, MediaType } from '../constants/media';
import notificationManager, { Notification } from '../lib/notifications';
import { getSettings } from '../lib/settings';
import logger from '../logger';
import Media from './Media';
import SeasonRequest from './SeasonRequest';
import { User } from './User';
export class RequestPermissionError extends Error {}
export class QuotaRestrictedError extends Error {}
export class DuplicateMediaRequestError extends Error {}
export class NoSeasonsAvailableError extends Error {}
type MediaRequestOptions = {
isAutoRequest?: boolean;
};
@Entity()
export class MediaRequest {
public static async request(
requestBody: MediaRequestBody,
user: User,
options: MediaRequestOptions = {}
): Promise<MediaRequest> {
const tmdb = new TheMovieDb();
const mediaRepository = getRepository(Media);
const requestRepository = getRepository(MediaRequest);
const userRepository = getRepository(User);
let requestUser = user;
if (
requestBody.userId &&
!requestUser.hasPermission([
Permission.MANAGE_USERS,
Permission.MANAGE_REQUESTS,
])
) {
throw new RequestPermissionError(
'You do not have permission to modify the request user.'
);
} else if (requestBody.userId) {
requestUser = await userRepository.findOneOrFail({
where: { id: requestBody.userId },
});
}
if (!requestUser) {
throw new Error('User missing from request context.');
}
if (
requestBody.mediaType === MediaType.MOVIE &&
!requestUser.hasPermission(
requestBody.is4k
? [Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE]
: [Permission.REQUEST, Permission.REQUEST_MOVIE],
{
type: 'or',
}
)
) {
throw new RequestPermissionError(
`You do not have permission to make ${
requestBody.is4k ? '4K ' : ''
}movie requests.`
);
} else if (
requestBody.mediaType === MediaType.TV &&
!requestUser.hasPermission(
requestBody.is4k
? [Permission.REQUEST_4K, Permission.REQUEST_4K_TV]
: [Permission.REQUEST, Permission.REQUEST_TV],
{
type: 'or',
}
)
) {
throw new RequestPermissionError(
`You do not have permission to make ${
requestBody.is4k ? '4K ' : ''
}series requests.`
);
}
const quotas = await requestUser.getQuota();
if (requestBody.mediaType === MediaType.MOVIE && quotas.movie.restricted) {
throw new QuotaRestrictedError('Movie Quota exceeded.');
} else if (requestBody.mediaType === MediaType.TV && quotas.tv.restricted) {
throw new QuotaRestrictedError('Series Quota exceeded.');
}
const tmdbMedia =
requestBody.mediaType === MediaType.MOVIE
? await tmdb.getMovie({ movieId: requestBody.mediaId })
: await tmdb.getTvShow({ tvId: requestBody.mediaId });
let media = await mediaRepository.findOne({
where: {
tmdbId: requestBody.mediaId,
mediaType: requestBody.mediaType,
},
relations: ['requests'],
});
if (!media) {
media = new Media({
tmdbId: tmdbMedia.id,
tvdbId: requestBody.tvdbId ?? tmdbMedia.external_ids.tvdb_id,
status: !requestBody.is4k ? MediaStatus.PENDING : MediaStatus.UNKNOWN,
status4k: requestBody.is4k ? MediaStatus.PENDING : MediaStatus.UNKNOWN,
mediaType: requestBody.mediaType,
});
} else {
if (media.status === MediaStatus.UNKNOWN && !requestBody.is4k) {
media.status = MediaStatus.PENDING;
}
if (media.status4k === MediaStatus.UNKNOWN && requestBody.is4k) {
media.status4k = MediaStatus.PENDING;
}
}
const existing = await requestRepository
.createQueryBuilder('request')
.leftJoin('request.media', 'media')
.leftJoinAndSelect('request.requestedBy', 'user')
.where('request.is4k = :is4k', { is4k: requestBody.is4k })
.andWhere('media.tmdbId = :tmdbId', { tmdbId: tmdbMedia.id })
.andWhere('media.mediaType = :mediaType', {
mediaType: requestBody.mediaType,
})
.getMany();
if (existing && existing.length > 0) {
// If there is an existing movie request that isn't declined, don't allow a new one.
if (
requestBody.mediaType === MediaType.MOVIE &&
existing[0].status !== MediaRequestStatus.DECLINED
) {
logger.warn('Duplicate request for media blocked', {
tmdbId: tmdbMedia.id,
mediaType: requestBody.mediaType,
is4k: requestBody.is4k,
label: 'Media Request',
});
throw new DuplicateMediaRequestError(
'Request for this media already exists.'
);
}
// If an existing auto-request for this media exists from the same user,
// don't allow a new one.
if (
existing.find(
(r) => r.requestedBy.id === requestUser.id && r.isAutoRequest
)
) {
throw new DuplicateMediaRequestError(
'Auto-request for this media and user already exists.'
);
}
}
if (requestBody.mediaType === MediaType.MOVIE) {
await mediaRepository.save(media);
const request = new MediaRequest({
type: MediaType.MOVIE,
media,
requestedBy: requestUser,
// If the user is an admin or has the "auto approve" permission, automatically approve the request
status: user.hasPermission(
[
requestBody.is4k
? Permission.AUTO_APPROVE_4K
: Permission.AUTO_APPROVE,
requestBody.is4k
? Permission.AUTO_APPROVE_4K_MOVIE
: Permission.AUTO_APPROVE_MOVIE,
Permission.MANAGE_REQUESTS,
],
{ type: 'or' }
)
? MediaRequestStatus.APPROVED
: MediaRequestStatus.PENDING,
modifiedBy: user.hasPermission(
[
requestBody.is4k
? Permission.AUTO_APPROVE_4K
: Permission.AUTO_APPROVE,
requestBody.is4k
? Permission.AUTO_APPROVE_4K_MOVIE
: Permission.AUTO_APPROVE_MOVIE,
Permission.MANAGE_REQUESTS,
],
{ type: 'or' }
)
? user
: undefined,
is4k: requestBody.is4k,
serverId: requestBody.serverId,
profileId: requestBody.profileId,
rootFolder: requestBody.rootFolder,
tags: requestBody.tags,
isAutoRequest: options.isAutoRequest ?? false,
});
await requestRepository.save(request);
return request;
} else {
const tmdbMediaShow = tmdbMedia as Awaited<
ReturnType<typeof tmdb.getTvShow>
>;
const requestedSeasons =
requestBody.seasons === 'all'
? tmdbMediaShow.seasons
.map((season) => season.season_number)
.filter((sn) => sn > 0)
: (requestBody.seasons as number[]);
let existingSeasons: number[] = [];
// We need to check existing requests on this title to make sure we don't double up on seasons that were
// already requested. In the case they were, we just throw out any duplicates but still approve the request.
// (Unless there are no seasons, in which case we abort)
if (media.requests) {
existingSeasons = media.requests
.filter(
(request) =>
request.is4k === requestBody.is4k &&
request.status !== MediaRequestStatus.DECLINED
)
.reduce((seasons, request) => {
const combinedSeasons = request.seasons.map(
(season) => season.seasonNumber
);
return [...seasons, ...combinedSeasons];
}, [] as number[]);
}
// We should also check seasons that are available/partially available but don't have existing requests
if (media.seasons) {
existingSeasons = [
...existingSeasons,
...media.seasons
.filter(
(season) =>
season[requestBody.is4k ? 'status4k' : 'status'] !==
MediaStatus.UNKNOWN
)
.map((season) => season.seasonNumber),
];
}
const finalSeasons = requestedSeasons.filter(
(rs) => !existingSeasons.includes(rs)
);
if (finalSeasons.length === 0) {
throw new NoSeasonsAvailableError('No seasons available to request');
} else if (
quotas.tv.limit &&
finalSeasons.length > (quotas.tv.remaining ?? 0)
) {
throw new QuotaRestrictedError('Series Quota exceeded.');
}
await mediaRepository.save(media);
const request = new MediaRequest({
type: MediaType.TV,
media,
requestedBy: requestUser,
// If the user is an admin or has the "auto approve" permission, automatically approve the request
status: user.hasPermission(
[
requestBody.is4k
? Permission.AUTO_APPROVE_4K
: Permission.AUTO_APPROVE,
requestBody.is4k
? Permission.AUTO_APPROVE_4K_TV
: Permission.AUTO_APPROVE_TV,
Permission.MANAGE_REQUESTS,
],
{ type: 'or' }
)
? MediaRequestStatus.APPROVED
: MediaRequestStatus.PENDING,
modifiedBy: user.hasPermission(
[
requestBody.is4k
? Permission.AUTO_APPROVE_4K
: Permission.AUTO_APPROVE,
requestBody.is4k
? Permission.AUTO_APPROVE_4K_TV
: Permission.AUTO_APPROVE_TV,
Permission.MANAGE_REQUESTS,
],
{ type: 'or' }
)
? user
: undefined,
is4k: requestBody.is4k,
serverId: requestBody.serverId,
profileId: requestBody.profileId,
rootFolder: requestBody.rootFolder,
languageProfileId: requestBody.languageProfileId,
tags: requestBody.tags,
seasons: finalSeasons.map(
(sn) =>
new SeasonRequest({
seasonNumber: sn,
status: user.hasPermission(
[
requestBody.is4k
? Permission.AUTO_APPROVE_4K
: Permission.AUTO_APPROVE,
requestBody.is4k
? Permission.AUTO_APPROVE_4K_TV
: Permission.AUTO_APPROVE_TV,
Permission.MANAGE_REQUESTS,
],
{ type: 'or' }
)
? MediaRequestStatus.APPROVED
: MediaRequestStatus.PENDING,
})
),
isAutoRequest: options.isAutoRequest ?? false,
});
await requestRepository.save(request);
return request;
}
}
@PrimaryGeneratedColumn()
public id: number;
@@ -120,6 +457,9 @@ export class MediaRequest {
})
public tags?: number[];
@Column({ default: false })
public isAutoRequest: boolean;
constructor(init?: Partial<MediaRequest>) {
Object.assign(this, init);
}
@@ -147,6 +487,10 @@ export class MediaRequest {
}
this.sendNotification(media, Notification.MEDIA_PENDING);
if (this.isAutoRequest) {
this.sendNotification(media, Notification.MEDIA_AUTO_REQUESTED);
}
}
}
@@ -191,6 +535,14 @@ export class MediaRequest {
: Notification.MEDIA_APPROVED
: Notification.MEDIA_DECLINED
);
if (
this.status === MediaRequestStatus.APPROVED &&
autoApproved &&
this.isAutoRequest
) {
this.sendNotification(media, Notification.MEDIA_AUTO_REQUESTED);
}
}
}
@@ -207,7 +559,7 @@ export class MediaRequest {
const mediaRepository = getRepository(Media);
const media = await mediaRepository.findOne({
where: { id: this.media.id },
relations: ['requests'],
relations: { requests: true },
});
if (!media) {
logger.error('Media data not found', {
@@ -272,7 +624,7 @@ export class MediaRequest {
const mediaRepository = getRepository(Media);
const fullMedia = await mediaRepository.findOneOrFail({
where: { id: this.media.id },
relations: ['requests'],
relations: { requests: true },
});
if (
@@ -352,7 +704,7 @@ export class MediaRequest {
let rootFolder = radarrSettings.activeDirectory;
let qualityProfile = radarrSettings.activeProfileId;
let tags = radarrSettings.tags;
let tags = radarrSettings.tags ? [...radarrSettings.tags] : [];
if (
this.rootFolder &&
@@ -412,10 +764,51 @@ export class MediaRequest {
return;
}
if (radarrSettings.tagRequests) {
let userTag = (await radarr.getTags()).find((v) =>
v.label.startsWith(this.requestedBy.id + ' - ')
);
if (!userTag) {
logger.info(`Requester has no active tag. Creating new`, {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
userId: this.requestedBy.id,
newTag:
this.requestedBy.id + ' - ' + this.requestedBy.displayName,
});
userTag = await radarr.createTag({
label: this.requestedBy.id + ' - ' + this.requestedBy.displayName,
});
}
if (userTag.id) {
if (!tags?.find((v) => v === userTag?.id)) {
tags?.push(userTag.id);
}
} else {
logger.warn(`Requester has no tag and failed to add one`, {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
userId: this.requestedBy.id,
radarrServer: radarrSettings.hostname + ':' + radarrSettings.port,
});
}
}
if (
media[this.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
) {
throw new Error('Media already available');
logger.warn('Media already exists, marking request as APPROVED', {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
});
const requestRepository = getRepository(MediaRequest);
this.status = MediaRequestStatus.APPROVED;
await requestRepository.save(this);
return;
}
const radarrMovieOptions: RadarrMovieOptions = {
@@ -452,10 +845,13 @@ export class MediaRequest {
await mediaRepository.save(media);
})
.catch(async () => {
media[this.is4k ? 'status4k' : 'status'] = MediaStatus.UNKNOWN;
await mediaRepository.save(media);
const requestRepository = getRepository(MediaRequest);
this.status = MediaRequestStatus.FAILED;
requestRepository.save(this);
logger.warn(
'Something went wrong sending movie request to Radarr, marking status as UNKNOWN',
'Something went wrong sending movie request to Radarr, marking status as FAILED',
{
label: 'Media Request',
requestId: this.id,
@@ -543,7 +939,7 @@ export class MediaRequest {
const media = await mediaRepository.findOne({
where: { id: this.media.id },
relations: ['requests'],
relations: { requests: true },
});
if (!media) {
@@ -553,7 +949,16 @@ export class MediaRequest {
if (
media[this.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
) {
throw new Error('Media already available');
logger.warn('Media already exists, marking request as APPROVED', {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
});
const requestRepository = getRepository(MediaRequest);
this.status = MediaRequestStatus.APPROVED;
await requestRepository.save(this);
return;
}
const tmdb = new TheMovieDb();
@@ -579,7 +984,7 @@ export class MediaRequest {
(keyword) => keyword.id === ANIME_KEYWORD_ID
)
) {
seriesType = 'anime';
seriesType = sonarrSettings.animeSeriesType ?? 'anime';
}
let rootFolder =
@@ -597,7 +1002,11 @@ export class MediaRequest {
let tags =
seriesType === 'anime'
? sonarrSettings.animeTags
: sonarrSettings.tags;
? [...sonarrSettings.animeTags]
: []
: sonarrSettings.tags
? [...sonarrSettings.tags]
: [];
if (
this.rootFolder &&
@@ -649,6 +1058,38 @@ export class MediaRequest {
});
}
if (sonarrSettings.tagRequests) {
let userTag = (await sonarr.getTags()).find((v) =>
v.label.startsWith(this.requestedBy.id + ' - ')
);
if (!userTag) {
logger.info(`Requester has no active tag. Creating new`, {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
userId: this.requestedBy.id,
newTag:
this.requestedBy.id + ' - ' + this.requestedBy.displayName,
});
userTag = await sonarr.createTag({
label: this.requestedBy.id + ' - ' + this.requestedBy.displayName,
});
}
if (userTag.id) {
if (!tags?.find((v) => v === userTag?.id)) {
tags?.push(userTag.id);
}
} else {
logger.warn(`Requester has no tag and failed to add one`, {
label: 'Media Request',
requestId: this.id,
mediaId: this.media.id,
userId: this.requestedBy.id,
sonarrServer: sonarrSettings.hostname + ':' + sonarrSettings.port,
});
}
}
const sonarrSeriesOptions: AddSeriesOptions = {
profileId: qualityProfile,
languageProfileId: languageProfile,
@@ -670,7 +1111,7 @@ export class MediaRequest {
// We grab media again here to make sure we have the latest version of it
const media = await mediaRepository.findOne({
where: { id: this.media.id },
relations: ['requests'],
relations: { requests: true },
});
if (!media) {
@@ -685,10 +1126,13 @@ export class MediaRequest {
await mediaRepository.save(media);
})
.catch(async () => {
media[this.is4k ? 'status4k' : 'status'] = MediaStatus.UNKNOWN;
await mediaRepository.save(media);
const requestRepository = getRepository(MediaRequest);
this.status = MediaRequestStatus.FAILED;
requestRepository.save(this);
logger.warn(
'Something went wrong sending series request to Sonarr, marking status as UNKNOWN',
'Something went wrong sending series request to Sonarr, marking status as FAILED',
{
label: 'Media Request',
requestId: this.id,
@@ -723,6 +1167,7 @@ export class MediaRequest {
const mediaType = this.type === MediaType.MOVIE ? 'Movie' : 'Series';
let event: string | undefined;
let notifyAdmin = true;
let notifySystem = true;
switch (type) {
case Notification.MEDIA_APPROVED:
@@ -736,6 +1181,13 @@ export class MediaRequest {
case Notification.MEDIA_PENDING:
event = `New ${this.is4k ? '4K ' : ''}${mediaType} Request`;
break;
case Notification.MEDIA_AUTO_REQUESTED:
event = `${
this.is4k ? '4K ' : ''
}${mediaType} Request Automatically Submitted`;
notifyAdmin = false;
notifySystem = false;
break;
case Notification.MEDIA_AUTO_APPROVED:
event = `${
this.is4k ? '4K ' : ''
@@ -752,6 +1204,7 @@ export class MediaRequest {
media,
request: this,
notifyAdmin,
notifySystem,
notifyUser: notifyAdmin ? undefined : this.requestedBy,
event,
subject: `${movie.title}${
@@ -770,6 +1223,7 @@ export class MediaRequest {
media,
request: this,
notifyAdmin,
notifySystem,
notifyUser: notifyAdmin ? undefined : this.requestedBy,
event,
subject: `${tv.name}${
@@ -801,3 +1255,5 @@ export class MediaRequest {
}
}
}
export default MediaRequest;

View File

@@ -1,12 +1,12 @@
import { MediaStatus } from '@server/constants/media';
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
CreateDateColumn,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { MediaStatus } from '../constants/media';
import Media from './Media';
@Entity()

View File

@@ -1,12 +1,14 @@
import { MediaRequestStatus } from '@server/constants/media';
import { getRepository } from '@server/datasource';
import {
Entity,
PrimaryGeneratedColumn,
AfterRemove,
Column,
CreateDateColumn,
UpdateDateColumn,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { MediaRequestStatus } from '../constants/media';
import { MediaRequest } from './MediaRequest';
@Entity()
@@ -34,6 +36,18 @@ class SeasonRequest {
constructor(init?: Partial<SeasonRequest>) {
Object.assign(this, init);
}
@AfterRemove()
public async handleRemoveParent(): Promise<void> {
const mediaRequestRepository = getRepository(MediaRequest);
const requestToBeDeleted = await mediaRequestRepository.findOneOrFail({
where: { id: this.request.id },
});
if (requestToBeDeleted.seasons.length === 0) {
await mediaRequestRepository.delete({ id: this.request.id });
}
}
}
export default SeasonRequest;

View File

@@ -1,5 +1,5 @@
import { ISession } from 'connect-typeorm';
import { Index, Column, PrimaryColumn, Entity } from 'typeorm';
import type { ISession } from 'connect-typeorm';
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
@Entity()
export class Session implements ISession {

View File

@@ -1,3 +1,14 @@
import { MediaRequestStatus, MediaType } from '@server/constants/media';
import { UserType } from '@server/constants/user';
import { getRepository } from '@server/datasource';
import { Watchlist } from '@server/entity/Watchlist';
import type { QuotaResponse } from '@server/interfaces/api/userInterfaces';
import PreparedEmail from '@server/lib/email';
import type { PermissionCheckOptions } from '@server/lib/permissions';
import { hasPermission, Permission } from '@server/lib/permissions';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import { AfterDate } from '@server/utils/dateHelpers';
import bcrypt from 'bcrypt';
import { randomUUID } from 'crypto';
import path from 'path';
@@ -7,8 +18,6 @@ import {
Column,
CreateDateColumn,
Entity,
getRepository,
MoreThan,
Not,
OneToMany,
OneToOne,
@@ -16,17 +25,6 @@ import {
RelationCount,
UpdateDateColumn,
} from 'typeorm';
import { MediaRequestStatus, MediaType } from '../constants/media';
import { UserType } from '../constants/user';
import { QuotaResponse } from '../interfaces/api/userInterfaces';
import PreparedEmail from '../lib/email';
import {
hasPermission,
Permission,
PermissionCheckOptions,
} from '../lib/permissions';
import { getSettings } from '../lib/settings';
import logger from '../logger';
import Issue from './Issue';
import { MediaRequest } from './MediaRequest';
import SeasonRequest from './SeasonRequest';
@@ -42,7 +40,7 @@ export class User {
return users.map((u) => u.filter(showFiltered));
}
static readonly filteredFields: string[] = ['email'];
static readonly filteredFields: string[] = ['email', 'plexId'];
public displayName: string;
@@ -79,7 +77,7 @@ export class User {
@Column({ type: 'integer', default: UserType.PLEX })
public userType: UserType;
@Column({ nullable: true })
@Column({ nullable: true, select: true })
public plexId?: number;
@Column({ nullable: true })
@@ -106,6 +104,9 @@ export class User {
@OneToMany(() => MediaRequest, (request) => request.requestedBy)
public requests: MediaRequest[];
@OneToMany(() => Watchlist, (watchlist) => watchlist.requestedBy)
public watchlists: Watchlist[];
@Column({ nullable: true })
public movieQuotaLimit?: number;
@@ -270,13 +271,14 @@ export class User {
if (movieQuotaDays) {
movieDate.setDate(movieDate.getDate() - movieQuotaDays);
}
const movieQuotaStartDate = movieDate.toJSON();
const movieQuotaUsed = movieQuotaLimit
? await requestRepository.count({
where: {
requestedBy: this,
createdAt: MoreThan(movieQuotaStartDate),
requestedBy: {
id: this.id,
},
createdAt: AfterDate(movieDate),
type: MediaType.MOVIE,
status: Not(MediaRequestStatus.DECLINED),
},

View File

@@ -1,3 +1,6 @@
import type { NotificationAgentTypes } from '@server/interfaces/api/userSettingsInterfaces';
import { hasNotificationType, Notification } from '@server/lib/notifications';
import { NotificationAgentKey } from '@server/lib/settings';
import {
Column,
Entity,
@@ -5,9 +8,6 @@ import {
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { NotificationAgentTypes } from '../interfaces/api/userSettingsInterfaces';
import { hasNotificationType, Notification } from '../lib/notifications';
import { NotificationAgentKey } from '../lib/settings';
import { User } from './User';
export const ALL_NOTIFICATIONS = Object.values(Notification)
@@ -51,12 +51,21 @@ export class UserSettings {
@Column({ nullable: true })
public pushoverUserKey?: string;
@Column({ nullable: true })
public pushoverSound?: string;
@Column({ nullable: true })
public telegramChatId?: string;
@Column({ nullable: true })
public telegramSendSilently?: boolean;
@Column({ nullable: true })
public watchlistSyncMovies?: boolean;
@Column({ nullable: true })
public watchlistSyncTv?: boolean;
@Column({
type: 'text',
nullable: true,

157
server/entity/Watchlist.ts Normal file
View File

@@ -0,0 +1,157 @@
import TheMovieDb from '@server/api/themoviedb';
import { MediaType } from '@server/constants/media';
import { getRepository } from '@server/datasource';
import Media from '@server/entity/Media';
import { User } from '@server/entity/User';
import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces';
import logger from '@server/logger';
import {
Column,
CreateDateColumn,
Entity,
Index,
ManyToOne,
PrimaryGeneratedColumn,
Unique,
UpdateDateColumn,
} from 'typeorm';
import type { ZodNumber, ZodOptional, ZodString } from 'zod';
export class DuplicateWatchlistRequestError extends Error {}
export class NotFoundError extends Error {
constructor(message = 'Not found') {
super(message);
this.name = 'NotFoundError';
}
}
@Entity()
@Unique('UNIQUE_USER_DB', ['tmdbId', 'requestedBy'])
export class Watchlist implements WatchlistItem {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar' })
public ratingKey = '';
@Column({ type: 'varchar' })
public mediaType: MediaType;
@Column({ type: 'varchar' })
title = '';
@Column()
@Index()
public tmdbId: number;
@ManyToOne(() => User, (user) => user.watchlists, {
eager: true,
onDelete: 'CASCADE',
})
public requestedBy: User;
@ManyToOne(() => Media, (media) => media.watchlists, {
eager: true,
onDelete: 'CASCADE',
})
public media: Media;
@CreateDateColumn()
public createdAt: Date;
@UpdateDateColumn()
public updatedAt: Date;
constructor(init?: Partial<Watchlist>) {
Object.assign(this, init);
}
public static async createWatchlist({
watchlistRequest,
user,
}: {
watchlistRequest: {
mediaType: MediaType;
ratingKey?: ZodOptional<ZodString>['_output'];
title?: ZodOptional<ZodString>['_output'];
tmdbId: ZodNumber['_output'];
};
user: User;
}): Promise<Watchlist> {
const watchlistRepository = getRepository(this);
const mediaRepository = getRepository(Media);
const tmdb = new TheMovieDb();
const tmdbMedia =
watchlistRequest.mediaType === MediaType.MOVIE
? await tmdb.getMovie({ movieId: watchlistRequest.tmdbId })
: await tmdb.getTvShow({ tvId: watchlistRequest.tmdbId });
const existing = await watchlistRepository
.createQueryBuilder('watchlist')
.leftJoinAndSelect('watchlist.requestedBy', 'user')
.where('user.id = :userId', { userId: user.id })
.andWhere('watchlist.tmdbId = :tmdbId', {
tmdbId: watchlistRequest.tmdbId,
})
.andWhere('watchlist.mediaType = :mediaType', {
mediaType: watchlistRequest.mediaType,
})
.getMany();
if (existing && existing.length > 0) {
logger.warn('Duplicate request for watchlist blocked', {
tmdbId: watchlistRequest.tmdbId,
mediaType: watchlistRequest.mediaType,
label: 'Watchlist',
});
throw new DuplicateWatchlistRequestError();
}
let media = await mediaRepository.findOne({
where: {
tmdbId: watchlistRequest.tmdbId,
mediaType: watchlistRequest.mediaType,
},
});
if (!media) {
media = new Media({
tmdbId: tmdbMedia.id,
tvdbId: tmdbMedia.external_ids.tvdb_id,
mediaType: watchlistRequest.mediaType,
});
}
const watchlist = new this({
...watchlistRequest,
requestedBy: user,
media,
});
await mediaRepository.save(media);
await watchlistRepository.save(watchlist);
return watchlist;
}
public static async deleteWatchlist(
tmdbId: Watchlist['tmdbId'],
user: User
): Promise<Watchlist | null> {
const watchlistRepository = getRepository(this);
const watchlist = await watchlistRepository.findOneBy({
tmdbId,
requestedBy: { id: user.id },
});
if (!watchlist) {
throw new NotFoundError('not Found');
}
if (watchlist) {
await watchlistRepository.delete(watchlist.id);
}
return watchlist;
}
}

View File

@@ -1,34 +1,40 @@
import PlexAPI from '@server/api/plexapi';
import dataSource, { getRepository } from '@server/datasource';
import DiscoverSlider from '@server/entity/DiscoverSlider';
import { Session } from '@server/entity/Session';
import { User } from '@server/entity/User';
import { startJobs } from '@server/job/schedule';
import notificationManager from '@server/lib/notifications';
import DiscordAgent from '@server/lib/notifications/agents/discord';
import EmailAgent from '@server/lib/notifications/agents/email';
import GotifyAgent from '@server/lib/notifications/agents/gotify';
import LunaSeaAgent from '@server/lib/notifications/agents/lunasea';
import PushbulletAgent from '@server/lib/notifications/agents/pushbullet';
import PushoverAgent from '@server/lib/notifications/agents/pushover';
import SlackAgent from '@server/lib/notifications/agents/slack';
import TelegramAgent from '@server/lib/notifications/agents/telegram';
import WebhookAgent from '@server/lib/notifications/agents/webhook';
import WebPushAgent from '@server/lib/notifications/agents/webpush';
import { getSettings } from '@server/lib/settings';
import logger from '@server/logger';
import clearCookies from '@server/middleware/clearcookies';
import routes from '@server/routes';
import imageproxy from '@server/routes/imageproxy';
import { getAppVersion } from '@server/utils/appVersion';
import restartFlag from '@server/utils/restartFlag';
import { getClientIp } from '@supercharge/request-ip';
import { TypeormStore } from 'connect-typeorm/out';
import cookieParser from 'cookie-parser';
import csurf from 'csurf';
import express, { NextFunction, Request, Response } from 'express';
import type { NextFunction, Request, Response } from 'express';
import express from 'express';
import * as OpenApiValidator from 'express-openapi-validator';
import session, { Store } from 'express-session';
import type { Store } from 'express-session';
import session from 'express-session';
import next from 'next';
import path from 'path';
import swaggerUi from 'swagger-ui-express';
import { createConnection, getRepository } from 'typeorm';
import YAML from 'yamljs';
import PlexAPI from './api/plexapi';
import { Session } from './entity/Session';
import { User } from './entity/User';
import { startJobs } from './job/schedule';
import notificationManager from './lib/notifications';
import DiscordAgent from './lib/notifications/agents/discord';
import EmailAgent from './lib/notifications/agents/email';
import GotifyAgent from './lib/notifications/agents/gotify';
import LunaSeaAgent from './lib/notifications/agents/lunasea';
import PushbulletAgent from './lib/notifications/agents/pushbullet';
import PushoverAgent from './lib/notifications/agents/pushover';
import SlackAgent from './lib/notifications/agents/slack';
import TelegramAgent from './lib/notifications/agents/telegram';
import WebhookAgent from './lib/notifications/agents/webhook';
import WebPushAgent from './lib/notifications/agents/webpush';
import { getSettings } from './lib/settings';
import logger from './logger';
import routes from './routes';
import { getAppVersion } from './utils/appVersion';
const API_SPEC_PATH = path.join(__dirname, '../overseerr-api.yml');
@@ -40,7 +46,7 @@ const handle = app.getRequestHandler();
app
.prepare()
.then(async () => {
const dbConnection = await createConnection();
const dbConnection = await dataSource.initialize();
// Run migrations in production
if (process.env.NODE_ENV === 'production') {
@@ -51,6 +57,7 @@ app
// Load Settings
const settings = getSettings().load();
restartFlag.initializeSettings(settings.main);
// Migrate library types
if (
@@ -59,8 +66,8 @@ app
) {
const userRepository = getRepository(User);
const admin = await userRepository.findOne({
select: ['id', 'plexToken'],
order: { id: 'ASC' },
select: { id: true, plexToken: true },
where: { id: 1 },
});
if (admin) {
@@ -87,8 +94,21 @@ app
new WebPushAgent(),
]);
// Start Jobs
startJobs();
const userRepository = getRepository(User);
const totalUsers = await userRepository.count();
if (totalUsers > 0) {
startJobs();
} else {
logger.info(
`Skipping starting the scheduled jobs as we have no Plex/Jellyfin/Emby servers setup yet`,
{
label: 'Server',
}
);
}
// Bootstrap Discovery Sliders
await DiscoverSlider.bootstrapSliders();
const server = express();
if (settings.main.trustProxy) {
@@ -142,7 +162,7 @@ app
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 30,
httpOnly: true,
sameSite: true,
sameSite: settings.main.csrfProtection ? 'strict' : 'lax',
secure: 'auto',
},
store: new TypeormStore({
@@ -172,6 +192,10 @@ app
next();
});
server.use('/api/v1', routes);
// Do not set cookies so CDNs can cache them
server.use('/imageproxy', clearCookies, imageproxy);
server.get('*', (req, res) => handle(req, res));
server.use(
(

View File

@@ -3,3 +3,17 @@ export interface GenreSliderItem {
name: string;
backdrops: string[];
}
export interface WatchlistItem {
ratingKey: string;
tmdbId: number;
mediaType: 'movie' | 'tv';
title: string;
}
export interface WatchlistResponse {
page: number;
totalPages: number;
totalResults: number;
results: WatchlistItem[];
}

View File

@@ -1,5 +1,5 @@
import Issue from '../../entity/Issue';
import { PaginatedResponse } from './common';
import type Issue from '@server/entity/Issue';
import type { PaginatedResponse } from './common';
export interface IssueResultsResponse extends PaginatedResponse {
results: Issue[];

View File

@@ -1,6 +1,6 @@
import type Media from '../../entity/Media';
import { User } from '../../entity/User';
import { PaginatedResponse } from './common';
import type Media from '@server/entity/Media';
import type { User } from '@server/entity/User';
import type { PaginatedResponse } from './common';
export interface MediaResultsResponse extends PaginatedResponse {
results: Media[];

View File

@@ -1,4 +1,4 @@
import { PersonCreditCast, PersonCreditCrew } from '../../models/Person';
import type { PersonCreditCast, PersonCreditCrew } from '@server/models/Person';
export interface PersonCombinedCreditsResponse {
id: number;

View File

@@ -1,4 +1,4 @@
import { PlexSettings } from '../../lib/settings';
import type { PlexSettings } from '@server/lib/settings';
export interface PlexStatus {
settings: PlexSettings;

View File

@@ -1,6 +1,21 @@
import type { MediaType } from '@server/constants/media';
import type { MediaRequest } from '@server/entity/MediaRequest';
import type { PaginatedResponse } from './common';
import type { MediaRequest } from '../../entity/MediaRequest';
export interface RequestResultsResponse extends PaginatedResponse {
results: MediaRequest[];
}
export type MediaRequestBody = {
mediaType: MediaType;
mediaId: number;
tvdbId?: number;
seasons?: number[] | 'all';
is4k?: boolean;
serverId?: number;
profileId?: number;
rootFolder?: string;
languageProfileId?: number;
userId?: number;
tags?: number[];
};

View File

@@ -1,5 +1,5 @@
import { QualityProfile, RootFolder, Tag } from '../../api/servarr/base';
import { LanguageProfile } from '../../api/servarr/sonarr';
import type { QualityProfile, RootFolder, Tag } from '@server/api/servarr/base';
import type { LanguageProfile } from '@server/api/servarr/sonarr';
export interface ServiceCommonServer {
id: number;

View File

@@ -22,7 +22,9 @@ export interface SettingsAboutResponse {
export interface PublicSettingsResponse {
jellyfinHost?: string;
jellyfinExternalHost?: string;
jellyfinServerName?: string;
jellyfinForgotPasswordUrl?: string;
initialized: boolean;
applicationTitle: string;
applicationUrl: string;
@@ -54,9 +56,15 @@ export interface CacheItem {
};
}
export interface CacheResponse {
apiCaches: CacheItem[];
imageCache: Record<'tmdb', { size: number; imageCount: number }>;
}
export interface StatusResponse {
version: string;
commitTag: string;
updateAvailable: boolean;
commitsBehind: number;
restartRequired: boolean;
}

View File

@@ -1,7 +1,7 @@
import Media from '../../entity/Media';
import { MediaRequest } from '../../entity/MediaRequest';
import type { User } from '../../entity/User';
import { PaginatedResponse } from './common';
import type Media from '@server/entity/Media';
import type { MediaRequest } from '@server/entity/MediaRequest';
import type { User } from '@server/entity/User';
import type { PaginatedResponse } from './common';
export interface UserResultsResponse extends PaginatedResponse {
results: User[];
@@ -23,6 +23,7 @@ export interface QuotaResponse {
movie: QuotaStatus;
tv: QuotaStatus;
}
export interface UserWatchDataResponse {
recentlyWatched: Media[];
playCount: number;

Some files were not shown because too many files have changed in this diff Show More