From 694904d15a97f31628923b8d4270533283e2ef0b Mon Sep 17 00:00:00 2001 From: Danshil Kokil Mungur Date: Sat, 12 Jun 2021 02:25:45 +0400 Subject: [PATCH 01/45] docs: fix small typo (#1782) [skip ci] --- docs/support/need-help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/support/need-help.md b/docs/support/need-help.md index ff2a9eb4b..8e2cc8567 100644 --- a/docs/support/need-help.md +++ b/docs/support/need-help.md @@ -35,6 +35,6 @@ Try to answer the following questions: ## How can I share my logs? -1. Locate the current log file at `/logs/overseerr.log`. +1. Locate the current log file at `/logs/overseerr.log`. 2. Open the log file and **copy its contents** into a [**secret gist** on GitHub](https://gist.github.com/). If you upload your logs elsewhere, we may ask you to share them again via GitHub Gist. 3. **Share the link/URL to your secret gist** in the [`#support` channel in our Discord server](https://discord.gg/overseerr). From 6a75a05c2348455d5374132a2574d988879d543a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 12 Jun 2021 00:30:52 +0200 Subject: [PATCH 02/45] feat(lang): translations update from Weblate (#1772) * feat(lang): translated using Weblate (Dutch) Currently translated at 100.0% (879 of 879 strings) Co-authored-by: Kobe Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/nl/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Portuguese (Portugal)) Currently translated at 99.4% (874 of 879 strings) feat(lang): translated using Weblate (Portuguese (Portugal)) Currently translated at 99.6% (876 of 879 strings) feat(lang): translated using Weblate (Portuguese (Portugal)) Currently translated at 99.6% (876 of 879 strings) Co-authored-by: Bruno Guerreiro Co-authored-by: Hosted Weblate Co-authored-by: Marcos Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_PT/ Translation: Overseerr/Overseerr Frontend * feat(lang): translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (879 of 879 strings) Co-authored-by: Tijuco Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/pt_BR/ Translation: Overseerr/Overseerr Frontend Co-authored-by: Kobe Co-authored-by: Bruno Guerreiro Co-authored-by: Marcos Co-authored-by: Tijuco --- src/i18n/locale/nl.json | 2 +- src/i18n/locale/pt_BR.json | 2 +- src/i18n/locale/pt_PT.json | 230 ++++++++++++++++++------------------- 3 files changed, 117 insertions(+), 117 deletions(-) diff --git a/src/i18n/locale/nl.json b/src/i18n/locale/nl.json index 47bfd1982..ec5980604 100644 --- a/src/i18n/locale/nl.json +++ b/src/i18n/locale/nl.json @@ -322,7 +322,7 @@ "components.UserList.creating": "Bezig met aanmaken…", "components.UserList.validationpasswordminchars": "Wachtwoord is te kort; moet minimaal 8 tekens bevatten", "components.UserList.usercreatedsuccess": "Gebruiker met succes aangemaakt!", - "components.UserList.passwordinfodescription": "E-mailmeldingen moeten ingeschakeld worden om wachtwoorden automatisch te genereren.", + "components.UserList.passwordinfodescription": "Configureer een applicatie-URL en schakel e-mailmeldingen in om automatische wachtwoordgeneratie mogelijk te maken.", "components.UserList.password": "Wachtwoord", "components.UserList.localuser": "Lokale gebruiker", "components.UserList.email": "E-mailadres", diff --git a/src/i18n/locale/pt_BR.json b/src/i18n/locale/pt_BR.json index 269f5394b..88bd7eb58 100644 --- a/src/i18n/locale/pt_BR.json +++ b/src/i18n/locale/pt_BR.json @@ -318,7 +318,7 @@ "components.UserList.validationpasswordminchars": "Senha muito curta; necessário ter no mínimo 8 caracteres", "components.UserList.usercreatedsuccess": "Usuário criado com sucesso!", "components.UserList.usercreatedfailed": "Algo deu errado ao criar usuário.", - "components.UserList.passwordinfodescription": "Habilite notificações via e-mail para permitir a geração automática de senha.", + "components.UserList.passwordinfodescription": "Configure a URL da aplicação e habilite notificações via e-mail para permitir a geração automática de senha.", "components.UserList.password": "Senha", "components.UserList.localuser": "Usuário Local", "components.UserList.email": "Endereço de E-mail", diff --git a/src/i18n/locale/pt_PT.json b/src/i18n/locale/pt_PT.json index 661195185..5e557dfcf 100644 --- a/src/i18n/locale/pt_PT.json +++ b/src/i18n/locale/pt_PT.json @@ -57,14 +57,14 @@ "components.Settings.Notifications.webhookUrl": "URL de Webhook", "components.Settings.Notifications.NotificationsWebhook.webhookUrl": "URL de Webhook", "components.Settings.Notifications.NotificationsSlack.webhookUrl": "URL de Webhook", - "components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Definições de notificação Slack gravdas com sucesso!", - "components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Falhou ao gravas as definições de notificação do Slack.", + "components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Definições de notificação Slack gravadas com sucesso!", + "components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Falha ao gravas as definições de notificação do Slack.", "components.Settings.Notifications.NotificationsSlack.agentenabled": "Ativar Agente", "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Tem de fornecer um utilizador válido ou uma chave de grupo", "components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Deve fornecer um token de aplicação válido", "components.Settings.Notifications.NotificationsPushover.userToken": "Chave de Utilizador ou Grupo", "components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Definições de notificação Pushover gravadas com sucesso!", - "components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Falhou ao gravar as definições de notificação Pushover .", + "components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Falha ao gravar as definições de notificação Pushover.", "components.Settings.Notifications.NotificationsPushover.agentenabled": "Ativar Agente", "components.Settings.Notifications.NotificationsPushover.accessToken": "Token de Aplicação API", "components.Search.searchresults": "Resultados da Pesquisa", @@ -84,10 +84,10 @@ "components.RequestModal.pending4krequest": "Pedido 4K pendente para {title}", "components.RequestModal.numberofepisodes": "# de Episódios", "components.RequestModal.extras": "Extras", - "components.RequestModal.errorediting": "Algo correu mal durante a edição do pedido.", + "components.RequestModal.errorediting": "Ocorreu um erro durante a edição do pedido.", "components.RequestModal.cancel": "Cancelar Pedido", "components.RequestModal.autoapproval": "Aprovação Automática", - "components.RequestModal.AdvancedRequester.rootfolder": "Pasta Raíz", + "components.RequestModal.AdvancedRequester.rootfolder": "Pasta Raiz", "components.RequestModal.AdvancedRequester.qualityprofile": "Perfil de Qualidade", "components.RequestModal.AdvancedRequester.destinationserver": "Servidor de Destino", "components.RequestModal.AdvancedRequester.default": "{name} (Predefinição)", @@ -98,7 +98,7 @@ "components.RequestList.showallrequests": "Mostrar Todos os Pedidos", "components.RequestList.requests": "Pedidos", "components.RequestList.RequestItem.seasons": "{seasonCount, plural, one {Temporada} other {Temporadas}}", - "components.RequestList.RequestItem.failedretry": "Algo correu mal ao voltar a tentar o pedido.", + "components.RequestList.RequestItem.failedretry": "Ocorreu um erro ao voltar a tentar o pedido.", "components.RequestCard.seasons": "{seasonCount, plural, one {Temporada} other {Temporadas}}", "components.RequestButton.viewrequest4k": "Ver Pedido 4K", "components.RequestButton.viewrequest": "Ver Pedido", @@ -114,8 +114,8 @@ "components.RequestButton.approve4krequests": "Aprovar {requestCount, plural, one {Solicitação 4K} other {{requestCount} Solicitações 4K}}", "components.RequestBlock.server": "Servidor de Destino", "components.RequestBlock.seasons": "{seasonCount, plural, one {Temporada} other {Temporadas}}", - "components.RequestBlock.rootfolder": "Pasta Raíz", - "components.RequestBlock.requestoverrides": "Alterações dos Pedidos", + "components.RequestBlock.rootfolder": "Pasta Raiz", + "components.RequestBlock.requestoverrides": "Alterações de Pedidos", "components.RequestBlock.profilechanged": "Perfil de Qualidade", "components.PersonDetails.crewmember": "Equipa Técnica", "components.PersonDetails.ascharacter": "como {character}", @@ -136,11 +136,11 @@ "components.MovieDetails.similar": "Títulos Similares", "components.MovieDetails.runtime": "{minutes} minutos", "components.MovieDetails.revenue": "Receita", - "components.MovieDetails.releasedate": "Data de Lançamento", + "components.MovieDetails.releasedate": "Data de Estreia", "components.MovieDetails.recommendations": "Recomendações", "components.MovieDetails.overviewunavailable": "Sinopse indisponível.", "components.MovieDetails.overview": "Sinopse", - "components.MovieDetails.originallanguage": "Língua original", + "components.MovieDetails.originallanguage": "Idioma Original", "components.MovieDetails.manageModalTitle": "Gerir Filme", "components.MovieDetails.manageModalRequests": "Pedidos", "components.MovieDetails.manageModalNoRequests": "Sem pedidos.", @@ -153,8 +153,8 @@ "components.MediaSlider.ShowMoreCard.seemore": "Ver Mais", "components.Login.validationpasswordrequired": "Deve fornecer uma palavra-passe", "components.Login.validationemailrequired": "Deve fornecer um e-mail válido", - "components.Login.signinwithoverseerr": "Utilizar sua conta {applicationTitle}", - "components.Login.loginerror": "Algo correu mal ao tentar iniciar a sessão.", + "components.Login.signinwithoverseerr": "Utilizar a sua conta {applicationTitle}", + "components.Login.loginerror": "Ocorreu um erro ao tentar iniciar a sessão.", "components.Login.password": "Palavra-passe", "components.Login.email": "Endereço E-mail", "components.Layout.UserDropdown.signout": "Sair", @@ -181,14 +181,14 @@ "pages.returnHome": "Voltar Para Página Inicial", "pages.oops": "Oops", "i18n.tvshows": "Séries", - "i18n.retry": "Retentar", + "i18n.retry": "Tentar Novamente", "i18n.requested": "Pedido", - "i18n.processing": "Processando", + "i18n.processing": "A Processar", "i18n.partiallyavailable": "Parcialmente Disponível", "i18n.movies": "Filmes", - "i18n.failed": "Falhou", + "i18n.failed": "Falha", "i18n.experimental": "Experimental", - "i18n.deleting": "Apagando…", + "i18n.deleting": "A eliminar…", "i18n.declined": "Rejeitado", "i18n.close": "Fechar", "i18n.cancel": "Cancelar", @@ -196,40 +196,40 @@ "i18n.approve": "Aprovar", "components.UserList.validationpasswordminchars": "Palavra-passe muito curta; necessário ter no mínimo 8 caracteres", "components.UserList.userlist": "Lista de Utilizadores", - "components.UserList.userdeleteerror": "Algo errou apagando o utilizador.", - "components.UserList.userdeleted": "Utilizador apago com sucesso!", + "components.UserList.userdeleteerror": "Ocorreu um erro ao eliminar o utilizador.", + "components.UserList.userdeleted": "Utilizador eliminado com sucesso!", "components.UserList.usercreatedsuccess": "Utilizador criado com sucesso!", - "components.UserList.usercreatedfailed": "Algo errou criando o utilizador.", + "components.UserList.usercreatedfailed": "Ocorreu um erro ao criar o utilizador.", "components.UserList.user": "Utilizador", "components.UserList.totalrequests": "Total de Pedidos", "components.UserList.role": "Função", "components.UserList.plexuser": "Utilizador Plex", - "components.UserList.passwordinfodescription": "Ativar as notificações por e-mail para permitir a geração automática de palavra-passe.", + "components.UserList.passwordinfodescription": "Configurar um URL de aplicação e ativar as notificações por e-mail para permitir a geração automática de palavra-passe.", "components.UserList.localuser": "Utilizador Local", "components.UserList.lastupdated": "Última Atualização", - "components.UserList.importfromplexerror": "Algo errou importando utilizadores do Plex.", + "components.UserList.importfromplexerror": "Ocorreu um erro ao importar utilizadores do Plex.", "components.UserList.importfromplex": "Importar Utilizadores do Plex", - "components.UserList.importedfromplex": "{userCount, plural, =0 {Nenhum novo utilizador} one {# novo utilizador} other {# novos utilizadores}} importado(s) do Plex com sucesso!", + "components.UserList.importedfromplex": "{userCount, plural, one {# novo utilizador} other {# novos utilizadores}} importados do Plex com sucesso!", "components.UserList.email": "Endereço de E-mail", "components.UserList.deleteuser": "Apagar Utilizador", - "components.UserList.deleteconfirm": "Tem certeza que deseja apagar esse utilizador? Todos os seus dados de pedidos serão removidos permanentemente.", - "components.UserList.creating": "Criando…", + "components.UserList.deleteconfirm": "Tem certeza que deseja apagar este utilizador? Todos os seus dados de pedidos serão removidos permanentemente.", + "components.UserList.creating": "A criar…", "components.UserList.createlocaluser": "Criar Utilizador Local", "components.Setup.welcome": "Bem-Vindo ao Overseerr", "components.Setup.tip": "Dica", - "components.Setup.signinMessage": "Comece conectando-se com sua conta Plex", - "components.Setup.loginwithplex": "Conecte-se com Plex", - "components.Setup.finishing": "Finalizando…", + "components.Setup.signinMessage": "Comece iniciando sessão com a sua conta Plex", + "components.Setup.loginwithplex": "Iniciar Sessão com Plex", + "components.Setup.finishing": "A finalizar…", "components.Setup.finish": "Finalizar Configurações", "components.Setup.continue": "Continuar", "components.Setup.configureservices": "Configurar Serviços", "components.Setup.configureplex": "Configurar Plex", - "components.Settings.toastSettingsSuccess": "Configurações salvas com sucesso!", - "components.Settings.toastSettingsFailure": "Algo errou salvando as configurações.", + "components.Settings.toastSettingsSuccess": "Definições gravadas com sucesso!", + "components.Settings.toastSettingsFailure": "Ocorreu um erro ao gravar as definições.", "components.Settings.toastApiKeySuccess": "Nova chave API gerada com sucesso!", - "components.Settings.toastApiKeyFailure": "Algo errou gerando uma nova chave API.", - "components.Settings.startscan": "Iniciar Scaneamento", - "components.Settings.sonarrsettings": "Configurações do Sonarr", + "components.Settings.toastApiKeyFailure": "Ocorreu um erro ao gerar uma nova chave API.", + "components.Settings.startscan": "Iniciar Sincronização", + "components.Settings.sonarrsettings": "Definições do Sonarr", "components.Settings.radarrsettings": "Definições Radarr", "components.Settings.port": "Porta", "components.Settings.plexsettingsDescription": "Configure as definições para o seu servidor Plex. Overseerr sincroniza as suas bibliotecas Plex para determinar a disponibilidade de conteúdo.", @@ -255,7 +255,7 @@ "components.Settings.generalsettings": "Definições Gerais", "i18n.edit": "Modificar", "components.Settings.deleteserverconfirm": "Tem certeza que deseja eliminar este servidor?", - "i18n.delete": "Apagar", + "i18n.delete": "Eliminar", "components.Settings.default4k": "Predefinição 4K", "components.Settings.default": "Predefinição", "components.Settings.currentlibrary": "Biblioteca Atual: {name}", @@ -272,8 +272,8 @@ "components.Settings.RadarrModal.validationHostnameRequired": "Deve fornecer um nome de hospedeiro ou endereço IP", "components.Settings.SonarrModal.validationHostnameRequired": "Deve fornecer um nome de hospedeiro ou endereço IP", "components.Settings.SonarrModal.validationPortRequired": "Deve fornecer um número de porta válido", - "components.Settings.validationPortRequired": "Você deve fornecer um número de porta válido", - "components.Settings.validationHostnameRequired": "Você deve fornecer um nome de host ou endereço IP válido", + "components.Settings.validationPortRequired": "Deve fornecer um número de porta válido", + "components.Settings.validationHostnameRequired": "Deve fornecer um nome de hospedeiro ou endereço IP válido", "components.Settings.SonarrModal.validationApiKeyRequired": "Deve fornecer uma chave API", "components.Settings.SonarrModal.testFirstRootFolders": "Testar ligação para carregar as pastas raiz", "components.Settings.SonarrModal.testFirstQualityProfiles": "Testar ligação para carregar perfis de qualidade", @@ -328,7 +328,7 @@ "components.TvDetails.watchtrailer": "Ver Trailer", "components.TvDetails.viewfullcrew": "Ver Equipa Técnica Completa", "i18n.unavailable": "Indisponível", - "components.TvDetails.similar": "Séries Similares", + "components.TvDetails.similar": "Séries Semelhantes", "components.TvDetails.showtype": "Tipo de Série", "components.TvDetails.recommendations": "Recomendações", "i18n.pending": "Pendente", @@ -339,13 +339,13 @@ "components.TvDetails.manageModalTitle": "Gerir Série", "components.TvDetails.manageModalRequests": "Pedidos", "components.TvDetails.manageModalNoRequests": "Sem pedidos.", - "components.TvDetails.manageModalClearMediaWarning": "* Isso removerá irreversivelmente todos os dados dessa séries, incluindo todas os pedidos. Se esse item existir em sua biblioteca Plex, as informações de multimédia serão recriadas durante a próxima sincronização.", + "components.TvDetails.manageModalClearMediaWarning": "* Isso removerá irreversivelmente todos os dados dessa série, incluindo todas os pedidos. Se esse item existir na sua biblioteca Plex, as informações de multimédia serão recriadas durante a próxima sincronização.", "components.TvDetails.manageModalClearMedia": "Limpar Dados de Multimédia", - "components.TvDetails.firstAirDate": "Primeira Exibição", + "components.TvDetails.firstAirDate": "Data da Estreia", "i18n.decline": "Rejeitar", "components.TvDetails.cast": "Elenco", "i18n.available": "Disponível", - "components.TvDetails.anime": "Animes", + "components.TvDetails.anime": "Anime", "components.TvDetails.TvCrew.fullseriescrew": "Equipa Técnica Completa da Série", "components.TvDetails.TvCast.fullseriescast": "Elenco Completo da Série", "components.StatusChacker.reloadOverseerr": "Recarregar", @@ -353,24 +353,24 @@ "components.StatusChacker.newversionDescription": "Overseerr foi atualizado! Clique no botão abaixo para recarregar a página.", "components.StatusBadge.status4k": "4K {status}", "components.Login.signinwithplex": "Iniciar sessão com a sua conta Plex", - "components.RequestModal.requesterror": "Algo correu mal ao submeter o pedido.", + "components.RequestModal.requesterror": "Ocorreu um erro ao submeter o pedido.", "components.RequestModal.SearchByNameModal.notvdbiddescription": "Não foi possível associar seu pedido automaticamente. Por favor selecione a correspondência correta a partir da lista abaixo.", "components.RequestModal.SearchByNameModal.nosummary": "Sinopse não encontrada para este título.", "components.Login.signinheader": "Iniciar sessão para continuar", - "components.Login.signingin": "A iniciar sessão…", + "components.Login.signingin": "A Iniciar Sessão…", "components.Login.signin": "Iniciar Sessão", "components.Settings.notificationAgentSettingsDescription": "Configurar e ativar agentes de notificação.", "components.PlexLoginButton.signinwithplex": "Iniciar Sessão", - "components.PlexLoginButton.signingin": "A iniciar sessão…", - "components.UserList.userssaved": "Permissões de utilizador salvas com sucesso!", + "components.PlexLoginButton.signingin": "A Iniciar Sessão…", + "components.UserList.userssaved": "Permissões de utilizador gravadas com sucesso!", "components.UserList.bulkedit": "Edição em Massa", - "components.Settings.toastPlexRefreshSuccess": "Lista de servidores Plex recuperada com sucesso!", + "components.Settings.toastPlexRefreshSuccess": "Lista de servidores Plex obtida com sucesso!", "components.Settings.toastPlexRefreshFailure": "Falha ao recuperar a lista de servidores Plex.", - "components.Settings.toastPlexRefresh": "Obtendo lista de servidores do Plex…", - "components.Settings.toastPlexConnectingSuccess": "Conexão Plex estabelecida com sucesso!", - "components.Settings.toastPlexConnectingFailure": "Falha ao conectar ao Plex.", - "components.Settings.toastPlexConnecting": "Tentando conectar ao Plex…", - "components.Settings.settingUpPlexDescription": "Para configurar o Plex, você pode inserir os detalhes manualmente ou selecionar um dos servidores disponíveis obtidos de plex.tv. Clique no botão à direita do dropdown para obter a lista de servidores disponíveis.", + "components.Settings.toastPlexRefresh": "A obter lista de servidores do Plex…", + "components.Settings.toastPlexConnectingSuccess": "Ligação ao Plex estabelecida com sucesso!", + "components.Settings.toastPlexConnectingFailure": "Falha ao ligar ao Plex.", + "components.Settings.toastPlexConnecting": "A tentar ligar ao Plex…", + "components.Settings.settingUpPlexDescription": "Para configurar o Plex, pode inserir os detalhes manualmente ou selecionar um dos servidores disponíveis obtidos de plex.tv. Clique no botão à direita da lista de servidores disponíveis.", "components.Settings.serverpresetRefreshing": "A obter servidores…", "components.Settings.serverpresetManualMessage": "Configuração Manual", "components.Settings.serverpresetLoad": "Clique no botão para carregar os servidores disponíveis", @@ -417,12 +417,12 @@ "components.MovieDetails.playonplex": "Ver no Plex", "components.MovieDetails.openradarr4k": "Abrir filme no Radarr 4K", "components.MovieDetails.openradarr": "Abrir filme no Radarr", - "components.TvDetails.downloadstatus": "Estado do download", + "components.TvDetails.downloadstatus": "Estado da transferência", "components.MovieDetails.downloadstatus": "Estado da transferência", "components.TvDetails.markavailable": "Marcar como Disponível", "components.TvDetails.mark4kavailable": "Marcar como Disponível em 4K", "components.TvDetails.allseasonsmarkedavailable": "* Todas temporadas serão marcadas como disponíveis.", - "components.Settings.trustProxyTip": "Permitir que o Overseerr registre corretamente os endereços IP do cliente por trás de um proxy (o Overseerr deve ser recarregado para que as alterações tenham efeito)", + "components.Settings.trustProxyTip": "Permitir que o Overseerr registe corretamente os endereços IP do cliente por trás de um proxy (o Overseerr deve ser recarregado para que as alterações tenham efeito)", "components.Settings.trustProxy": "Ativar Suporte de Proxy", "components.MovieDetails.markavailable": "Marcar como Disponível", "components.MovieDetails.mark4kavailable": "Marcar como Disponível em 4K", @@ -454,19 +454,19 @@ "components.Search.search": "Pesquisar", "components.Settings.applicationTitle": "Título da Aplicação", "components.Setup.setup": "Configurar", - "components.Settings.validationApplicationTitle": "Você deve fornecer um título de aplicação", + "components.Settings.validationApplicationTitle": "Deve fornecer um título de aplicação", "components.Settings.RadarrModal.validationApplicationUrlTrailingSlash": "A URL não deve terminar com uma barra final", "components.Settings.SonarrModal.validationApplicationUrlTrailingSlash": "A URL não deve terminar com uma barra final", "components.Settings.validationApplicationUrlTrailingSlash": "A URL não deve terminar com uma barra final", "components.Settings.SonarrModal.validationApplicationUrl": "Deve fornecer um URL valido", - "components.Settings.validationApplicationUrl": "Você deve fornecer uma URL valida", + "components.Settings.validationApplicationUrl": "Deve fornecer um URL valido", "components.Settings.RadarrModal.validationApplicationUrl": "Deve fornecer um URL valido", "components.RequestModal.AdvancedRequester.requestas": "Pedir Como", "components.PermissionEdit.viewrequestsDescription": "Conceder permissão para ver pedidos de outros utilizadores.", "components.PermissionEdit.viewrequests": "Ver Pedidos", "components.Discover.discover": "Descobrir", "components.AppDataWarning.dockerVolumeMissingDescription": "O ponto de montagem {appDataPath} não foi configurado corretamente . Todos dados serão perdidos quando o contentor parar ou reiniciar.", - "components.TvDetails.nextAirDate": "Próxima Data de Transmissão", + "components.TvDetails.nextAirDate": "Data do próximo Episódio", "components.Settings.SonarrModal.validationBaseUrlTrailingSlash": "URL Base não deve terminar com uma barra", "components.Settings.SonarrModal.validationBaseUrlLeadingSlash": "URL Base deve iniciar com uma barra", "components.Settings.RadarrModal.validationBaseUrlTrailingSlash": "URL Base não deve terminar com uma barra", @@ -474,7 +474,7 @@ "components.Settings.Notifications.NotificationsSlack.validationWebhookUrl": "Deve fornecer um URL valido", "components.Settings.Notifications.NotificationsWebhook.validationWebhookUrl": "Deve fornecer um URL valido", "components.Settings.Notifications.validationEmail": "Deve fornecer um e-mail válido", - "components.UserList.validationEmail": "Você deve fornecer um e-mail válido", + "components.UserList.validationEmail": "Deve fornecer um e-mail válido", "components.ResetPassword.validationpasswordrequired": "Deve fornecer uma palavra-passe", "components.ResetPassword.validationpasswordminchars": "Palavra-passe muito curta; necessário ter no mínimo 8 caracteres", "components.ResetPassword.validationpasswordmatch": "Palavras-passe devem corresponder", @@ -512,26 +512,26 @@ "components.UserProfile.UserSettings.menuNotifications": "Notificações", "components.UserProfile.UserSettings.menuGeneralSettings": "Geral", "components.UserProfile.UserSettings.menuChangePass": "Palavra-passe", - "components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Permissões salvas com sucesso!", - "components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "Algo errou salvando as configurações.", + "components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Permissões gravadas com sucesso!", + "components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "Ocorreu um erro ao gravar as definições.", "components.UserProfile.UserSettings.UserPermissions.permissions": "Permissões", - "components.UserProfile.UserSettings.UserPasswordChange.validationNewPassword": "Você deve fornecer uma nova palavra-passe", - "components.UserProfile.UserSettings.UserPasswordChange.validationCurrentPassword": "Você deve fornecer sua palavra-passe atual", + "components.UserProfile.UserSettings.UserPasswordChange.validationNewPassword": "Deve fornecer uma nova palavra-passe", + "components.UserProfile.UserSettings.UserPasswordChange.validationCurrentPassword": "Deve fornecer sua palavra-passe atual", "components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPasswordSame": "Palavras-passe devem corresponder", - "components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "Você deve confirmar a nova palavra-passe", - "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "Palavra-passe salva com sucesso!", + "components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "Deve confirmar a nova palavra-passe", + "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "Palavra-passe gravada com sucesso!", "components.UserProfile.UserSettings.UserPasswordChange.password": "Palavra-passe", "components.UserProfile.UserSettings.UserPasswordChange.newpassword": "Nova Palavra-passe", "components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "Palavra-passe Atual", "components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "Confirmar Palavra-passe", - "components.UserProfile.UserSettings.UserNotificationSettings.notificationsettings": "Configurações de Notificação", - "components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsSuccess": "Configurações salvas com sucesso!", - "components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsFailure": "Algo errou salvando as configurações.", + "components.UserProfile.UserSettings.UserNotificationSettings.notificationsettings": "Definicções de Notificação", + "components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsSuccess": "Definições gravadas com sucesso!", + "components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsFailure": "Ocorreu um erro ao gravar as definições.", "components.UserProfile.UserSettings.UserGeneralSettings.plexuser": "Utilizador Plex", "components.UserProfile.UserSettings.UserGeneralSettings.localuser": "Utilizador Local", - "components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "Configurações Gerais", + "components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "Definições Gerais", "components.UserProfile.UserSettings.UserGeneralSettings.displayName": "Nome de Exibição", - "components.UserProfile.ProfileHeader.settings": "Modificar Configuracões", + "components.UserProfile.ProfileHeader.settings": "Modificar Definições", "components.UserProfile.ProfileHeader.profile": "Ver Perfil", "components.UserList.edituser": "Modificar Permissões do Utilizador", "components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "Deve fornecer um token de acesso", @@ -540,19 +540,19 @@ "components.Layout.UserDropdown.settings": "Definições", "components.Layout.UserDropdown.myprofile": "Perfil", "components.UserProfile.UserSettings.UserPasswordChange.validationNewPasswordLength": "Palavra-passe muito curta; necessário ter no mínimo 8 caracteres", - "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "Algo errou ao salvar a palavra-passe.", - "components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "Você deve fornecer um ID de utilizador válido", - "components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "O número de ID para sua conta de utilizador", + "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "Ocorreu um erro ao gravar a palavra-passe.", + "components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "Deve fornecer um ID de utilizador válido", + "components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "O número de ID da sua conta de utilizador", "components.UserProfile.UserSettings.UserNotificationSettings.discordId": "ID de Utilizador", - "components.UserList.userfail": "Ocorreu um erro ao salvar as permissões do utilizador.", + "components.UserList.userfail": "Ocorreu um erro ao gravar as permissões do utilizador.", "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Definições de notificação Pushbullet gravadas com sucesso!", "components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Falha ao gravar as definições de notificação Pushbullet.", "components.CollectionDetails.requestswillbecreated4k": "Os seguintes títulos terão pedidos de 4K criados para eles:", "components.CollectionDetails.requestcollection4k": "Pedir Coleção em 4K", - "components.UserProfile.UserSettings.UserGeneralSettings.regionTip": "Filtrar conteúdo por disponibilidade regional", + "components.UserProfile.UserSettings.UserGeneralSettings.regionTip": "Filtrar conteúdo por disponibilidade da região", "components.UserProfile.UserSettings.UserGeneralSettings.region": "Descubrir Região", "components.UserProfile.UserSettings.UserGeneralSettings.originallanguageTip": "Filtrar conteúdo por idioma original", - "components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Descubrir Idioma", + "components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Descobrir Idioma", "components.Settings.regionTip": "Filtrar conteúdo por disponibilidade regional", "components.Settings.region": "Descubrir Região", "components.Settings.originallanguageTip": "Filtrar conteúdo por idioma original", @@ -562,7 +562,7 @@ "components.Settings.webhook": "Webhook", "components.Settings.email": "E-Mail", "components.RegionSelector.regionServerDefault": "Predefinição ({region})", - "components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "Você não tem permissão para modificar a palavra-passe deste utilizador.", + "components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "Não tem permissão para modificar a palavra-passe deste utilizador.", "components.UserProfile.UserSettings.UserGeneralSettings.user": "Utilizador", "components.UserProfile.UserSettings.UserGeneralSettings.role": "Função", "components.UserProfile.UserSettings.UserGeneralSettings.owner": "Proprietário", @@ -570,9 +570,9 @@ "components.UserProfile.UserSettings.UserGeneralSettings.accounttype": "Tipo de Conta", "components.UserList.owner": "Proprietário", "components.UserList.accounttype": "Tipo de Conta", - "i18n.loading": "Carregando…", - "components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "Você deve fornecer um ID de chat válido", - "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "Iniciar um chat, adicionar @get_id_bot, e enviar o comando /my_id", + "i18n.loading": "A carregar…", + "components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "Deve fornecer um ID de chat válido", + "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "Iniciar uma conversa, adicionar @get_id_bot, e enviar o comando /my_id", "components.UserProfile.UserSettings.UserNotificationSettings.telegramChatId": "ID do Chat", "components.UserProfile.UserSettings.UserNotificationSettings.sendSilentlyDescription": "Envia notificações sem som", "components.UserProfile.UserSettings.UserNotificationSettings.sendSilently": "Enviar Silenciosamente", @@ -585,7 +585,7 @@ "components.Discover.DiscoverStudio.studioMovies": "Filmes por {studio}", "components.Discover.DiscoverNetwork.networkSeries": "Séries por {network}", "components.Discover.DiscoverMovieGenre.genreMovies": "Filmes de {genre}", - "components.Setup.scanbackground": "O escaneamento será executado em segundo plano. Você pode continuar o processo de configuração enquanto isso.", + "components.Setup.scanbackground": "A sincronizaçao será executada em segundo plano. Entretanto pode continuar o processo de configuração.", "components.Settings.scanning": "A sincronizar…", "components.Settings.scan": "Sincronizar Bibliotecas Plex", "components.Settings.SettingsJobsCache.sonarr-scan": "Sincronizar Sonarr", @@ -607,11 +607,11 @@ "components.Settings.SettingsUsers.userSettingsDescription": "Configurar as definições de utilizador global e predefinição.", "components.Settings.SettingsUsers.userSettings": "Definições de Utilizador", "components.Settings.SettingsUsers.toastSettingsSuccess": "Definições de utilizador gravadas com sucesso!", - "components.Settings.SettingsUsers.toastSettingsFailure": "Algo correu mal enquanto guardava as definições.", + "components.Settings.SettingsUsers.toastSettingsFailure": "Ocorreu um erro enquanto guardava as definições.", "components.Settings.SettingsUsers.localLogin": "Ativar Inicio de Sessão Local", "components.Settings.SettingsUsers.defaultPermissions": "Permissões Predefinições", - "components.UserProfile.UserSettings.unauthorizedDescription": "Você não tem permissão para modificar as configurações deste utilizador.", - "components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "Você não pode modificar suas próprias permissões.", + "components.UserProfile.UserSettings.unauthorizedDescription": "Não tem permissão para modificar as definições deste utilizador.", + "components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "Não pode modificar suas próprias permissões.", "components.NotificationTypeSelector.mediaAutoApprovedDescription": "Enviar notificações quando os utilizadores apresentarem novos pedidos de multimédia que são automaticamente aprovados.", "components.NotificationTypeSelector.mediaAutoApproved": "Multimédia Aprovada Automaticamente", "components.UserProfile.norequests": "Sem pedidos.", @@ -630,13 +630,13 @@ "components.Discover.MovieGenreSlider.moviegenres": "Géneros de Filmes", "components.Discover.MovieGenreList.moviegenres": "Géneros de Filmes", "pages.errormessagewithcode": "{statusCode} - {error}", - "pages.somethingwentwrong": "Algo Errou", - "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailureVerifyCurrent": "Algo errou ao salvar a palavra-passe. Sua palavra-passe atual foi inserida corretamente?", + "pages.somethingwentwrong": "Ocorreu um erro", + "components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailureVerifyCurrent": "Ocorreu um erro ao grvar a palavra-passe. A sua palavra-passe atual foi inserida corretamente?", "pages.serviceunavailable": "Serviço Indisponível", "pages.pagenotfound": "Página Não Encontrada", "pages.internalservererror": "Erro Interno do Servidor", "i18n.usersettings": "Utilizadores", - "i18n.settings": "Configurações", + "i18n.settings": "Definições", "components.UserProfile.UserSettings.UserNotificationSettings.notifications": "Notificações", "components.Settings.services": "Serviços", "components.Settings.plex": "Plex", @@ -700,20 +700,20 @@ "i18n.all": "Todas", "i18n.view": "Ver", "i18n.tvshow": "Séries", - "i18n.testing": "Testando…", + "i18n.testing": "A testar…", "i18n.test": "Teste", "i18n.status": "Estado", - "i18n.showingresults": "Mostrando {from} para {to} de {total} resultados", - "i18n.saving": "Salvando…", - "i18n.save": "Salvar Mudanças", + "i18n.showingresults": "A mostrar {from} para {to} de {total} resultados", + "i18n.saving": "A Gravar…", + "i18n.save": "Gravar Alterações", "i18n.resultsperpage": "Mostrar {pageSize} resultados por página", "i18n.requesting": "A Pedir…", "i18n.request4k": "Pedir em 4K", "i18n.previous": "Anterior", "i18n.notrequested": "Não Pedido", - "i18n.noresults": "Nenhum resultado.", + "i18n.noresults": "Sem resultados.", "i18n.movie": "Filme", - "i18n.canceling": "Cancelando…", + "i18n.canceling": "A cancelar…", "i18n.back": "Voltar", "i18n.areyousure": "Tem certeza?", "components.TvDetails.originaltitle": "Título Original", @@ -733,7 +733,7 @@ "components.Settings.SonarrModal.selecttags": "Selecionar tags", "components.Settings.RadarrModal.selecttags": "Selecionar tags", "components.Settings.SonarrModal.notagoptions": "Nenhuma tag.", - "components.Settings.RadarrModal.notagoptions": "Nenhum tag.", + "components.Settings.RadarrModal.notagoptions": "Nenhuma tag.", "components.Settings.RadarrModal.loadingTags": "A carregar tags…", "components.Settings.RadarrModal.edit4kradarr": "Modificar Servidor Radarr 4K", "components.Settings.RadarrModal.default4kserver": "Servidor 4K Predefinido", @@ -741,12 +741,12 @@ "components.RequestModal.AdvancedRequester.tags": "Tags", "components.RequestModal.AdvancedRequester.selecttags": "Selecionar tags", "components.RequestModal.AdvancedRequester.notagoptions": "Nenhuma tag.", - "components.UserProfile.UserSettings.UserNotificationSettings.validationPgpPublicKey": "Você deve fornecer uma chave pública PGP válida", + "components.UserProfile.UserSettings.UserNotificationSettings.validationPgpPublicKey": "Deve fornecer uma chave pública PGP válida", "components.UserProfile.UserSettings.UserNotificationSettings.pgpPublicKey": "Chave Pública PGP", - "components.UserProfile.UserSettings.UserNotificationSettings.pgpPublicKeyTip": "Encriptar mensagens de e-mail usando OpenPGP ", + "components.UserProfile.UserSettings.UserNotificationSettings.pgpPublicKeyTip": "Encriptar mensagens de e-mail usando OpenPGP", "components.Settings.Notifications.validationPgpPrivateKey": "Deve fornecer uma chave privada PGP válida", "components.Settings.Notifications.validationPgpPassword": "Deve fornecer uma palavra-passe PGP", - "components.Settings.Notifications.botUsernameTip": "Permitir que utilizadores iniciem um chat com o seu bot e configurem as suas próprias notificações", + "components.Settings.Notifications.botUsernameTip": "Permitir que utilizadores iniciem uma conversa com o seu bot e configurem as suas próprias notificações", "components.RequestModal.pendingapproval": "O seu pedido está com aprovação pendente.", "components.RequestList.RequestItem.mediaerror": "O título associado a este pedido não está mais disponível.", "components.RequestList.RequestItem.deleterequest": "Apagar Pedido", @@ -757,19 +757,19 @@ "components.Layout.VersionStatus.streamdevelop": "Overseerr Develop", "components.Layout.VersionStatus.outofdate": "Desatualizado", "components.Layout.VersionStatus.commitsbehind": "{commitsBehind} {commitsBehind, plural, one {commit} other {commits}} atrás", - "components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Configurações de notificação Telegram salvas com sucesso!", - "components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingsfailed": "Falhou ao salvar das configurações de notificação Telegram.", - "components.UserProfile.UserSettings.UserNotificationSettings.emailsettingssaved": "Configurações de notificação e-mail salvas com sucesso!", - "components.UserProfile.UserSettings.UserNotificationSettings.emailsettingsfailed": "Falhou ao salvar das configurações de notificação e-mail.", + "components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Definições de notificação Telegram gravadas com sucesso!", + "components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingsfailed": "Falha ao gravas as definições de notificação Telegram.", + "components.UserProfile.UserSettings.UserNotificationSettings.emailsettingssaved": "Definições de notificação e-mail gravadas com sucesso!", + "components.UserProfile.UserSettings.UserNotificationSettings.emailsettingsfailed": "Falha ao gravas as definições de notificação e-mail.", "components.UserProfile.UserSettings.UserNotificationSettings.email": "E-Mail", - "components.UserProfile.UserSettings.UserNotificationSettings.discordsettingssaved": "Configurações de notificação Discord salvas com sucesso!", - "components.UserProfile.UserSettings.UserNotificationSettings.discordsettingsfailed": "Falhou ao salvar das configurações de notificação Discord.", + "components.UserProfile.UserSettings.UserNotificationSettings.discordsettingssaved": "Definições de notificação Discord gravadas com sucesso!", + "components.UserProfile.UserSettings.UserNotificationSettings.discordsettingsfailed": "Falha ao gravar as definições de notificação Discord.", "components.RequestList.RequestItem.cancelRequest": "Cancelar Pedido", "components.Discover.noRequests": "Sem pedidos.", - "components.Settings.serviceSettingsDescription": "Configure seu(s) servidor(es) {serverType} abaixo. Pode conectar vários servidores {serverType}, mas apenas dois deles podem ser marcados como padrões (um não 4K e um 4K). Os administradores podem mudar o servidor usado para processar novos pedidos antes da aprovação.", + "components.Settings.serviceSettingsDescription": "Configure o seu(s) servidor(es) {serverType} abaixo. Pode ligar vários servidores {serverType}, mas apenas dois deles podem ser marcados como predefinidos (um não 4K e um 4K). Os administradores podem mudar o servidor usado para processar novos pedidos antes da aprovação.", "components.Settings.noDefaultServer": "Pelo menos um servidor {serverType} deve ser marcado como predefinido para que os pedidos de {mediaType} sejam processados.", "components.Settings.noDefaultNon4kServer": "Se tiver apenas um único servidor {serverType} para conteúdo não 4K e 4K (ou se apenas transfere conteúdo 4K), o seu servidor {serverType} NÃO deve ser designado como um servidor 4K.", - "components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "Atualmente, sua conta não tem uma palavra-passe definida. Configure uma palavra-passe abaixo para permitir a conexão como um \"utilizador local\" usando seu e-mail.", + "components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "Atualmente, sua conta não tem uma palavra-passe definida. Configure uma palavra-passe abaixo para permitir o inicio de sessão como um \"utilizador local\" usando o seu e-mail.", "components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "Atualmente, a conta deste utilizador não tem uma palavra-passe definida. Configure uma palavra-passe abaixo para permitir que esta conta se conecte como um \"utilizador local\".", "components.Settings.mediaTypeSeries": "séries", "components.Settings.mediaTypeMovie": "filme", @@ -777,9 +777,9 @@ "components.Settings.SettingsAbout.outofdate": "Desatualizado", "components.Layout.betawarning": "Isto é um software em BETA. As funcionalidades podem estar quebradas e/ou instáveis. Relate qualquer problema no GitHub!", "components.UserList.autogeneratepasswordTip": "Enviar uma palavra-passe gerada pelo servidor para o utilizador por e-mail", - "i18n.retrying": "Tentando novamente…", + "i18n.retrying": "A tentar novamente…", "components.Settings.serverSecure": "seguro", - "components.UserList.usercreatedfailedexisting": "A e-mail fornecida já está sendo usada por outro utilizador.", + "components.UserList.usercreatedfailedexisting": "A e-mail fornecido já está a ser usado por outro utilizador.", "components.RequestModal.edit": "Modificar Pedido", "components.RequestList.RequestItem.editrequest": "Modificar Pedido", "components.Settings.SonarrModal.enableSearch": "Ativar Pesquisa Automática", @@ -791,14 +791,14 @@ "components.Settings.Notifications.NotificationsWebPush.webpushsettingsfailed": "Falha ao gravar as definições de notificação web push.", "components.Settings.Notifications.NotificationsWebPush.agentenabled": "Ativar Agente", "components.Settings.Notifications.NotificationsLunaSea.profileNameTip": "Requerido apenas se não estiver a usar o perfil default", - "components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "Definições de notificação do LunaSea gravadas com sucesso!", - "components.Settings.Notifications.NotificationsLunaSea.settingsFailed": "Falhou ao gravar as definições de notificação do LunaSea.", + "components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "Definições de notificação LunaSea gravadas com sucesso!", + "components.Settings.Notifications.NotificationsLunaSea.settingsFailed": "Falha ao gravar as definições de notificação do LunaSea.", "components.Settings.Notifications.NotificationsLunaSea.webhookUrl": "URL de Webhook", "components.Settings.Notifications.NotificationsLunaSea.validationWebhookUrl": "Deve fornecer uma URL valido", "components.Settings.Notifications.NotificationsLunaSea.profileName": "Nome do Perfil", "components.Settings.Notifications.NotificationsLunaSea.agentenabled": "Ativar Agente", - "components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingssaved": "Configurações de notificação web push salvas com sucesso!", - "components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "Falhou ao salvar das configurações de notificação web push.", + "components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingssaved": "Definições de notificação web push gravadas com sucesso!", + "components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "Falha ao gravar as definições de notificação web push.", "components.Settings.noDefault4kServer": "Um servidor 4K {serverType} deve ser marcado como predefinido para permitir que os utilizador enviem pedidos 4K de {mediaType}.", "components.Settings.is4k": "4K", "components.Settings.SettingsUsers.newPlexLoginTip": "Permitir que Utilizadores do Plex iniciem sessão sem primeiro serem importados", @@ -829,17 +829,17 @@ "components.Settings.Notifications.NotificationsSlack.toastSlackTestFailed": "Falha ao enviar notificação de teste Slack.", "components.Settings.Notifications.NotificationsPushover.toastPushoverTestFailed": "Falha ao enviar notificação de teste Pushover.", "components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestFailed": "Falha ao enviar notificação de teste Pushbullet.", - "components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestFailed": "Falhou ao enviar notificação de teste ao LunaSea.", + "components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestFailed": "Falha ao enviar notificação de teste ao LunaSea.", "components.PermissionEdit.requestTvDescription": "Conceder permissão para pedir séries não 4K.", "components.PermissionEdit.requestTv": "Pedir Séries", "components.PermissionEdit.requestMoviesDescription": "Conceder permissão para pedir filmes não 4K.", "components.PermissionEdit.requestMovies": "Pedir Filmes", - "components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "Padrão ({language})", - "components.UserList.localLoginDisabled": "A configuração Ativar Conexão Local está desativada no momento.", + "components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "Predefinido ({language})", + "components.UserList.localLoginDisabled": "A configuração Ativar inicio de sessão Local está desativada de momento.", "components.UserList.displayName": "Nome de Exibição", - "components.Settings.webAppUrlTip": "Opcionalmente, direcionar os utilizadores para a aplicação de web app em seu servidor, em vez da aplicação de web app \"hospedada\"", + "components.Settings.webAppUrlTip": "Opcionalmente direcionar os utilizadores para a aplicação de web app no seu servidor, em vez da aplicação de web app \"hospedada\"", "components.Settings.webAppUrl": "URL Web App", - "components.Settings.validationWebAppUrl": "Você deve fornecer um URL válido da Web App do Plex", + "components.Settings.validationWebAppUrl": "Deve fornecer um URL válido da Web App do Plex", "components.Settings.locale": "Idioma de Exibição", "components.Settings.Notifications.webhookUrlTip": "Criar um webhook de integração no seu servidor", "components.Settings.Notifications.encryptionTip": "Na maioria dos casos, o TLS implícito usa a porta 465 e o STARTTLS usa a porta 587", @@ -848,7 +848,7 @@ "components.Settings.Notifications.encryptionImplicitTls": "Usar TLS Implícito", "components.Settings.Notifications.encryptionDefault": "Usar STARTTLS se disponível", "components.Settings.Notifications.encryption": "Método de Encriptação", - "components.Settings.Notifications.chatIdTip": "Iniciar um chat com o seu bot, adicione @get_id_bot e execute o comando /my_id", + "components.Settings.Notifications.chatIdTip": "Iniciar uma conversa com o seu bot, adicione @get_id_bot e execute o comando /my_id", "components.Settings.Notifications.NotificationsPushover.accessTokenTip": "Registe uma aplicação para usar com Overseerr", "components.Settings.Notifications.botApiTip": "Criar um bot para usar com Overseerr", "components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Para receber notificações via web push, o Overseerr deve ser servido via HTTPS.", @@ -857,7 +857,7 @@ "components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "Criar um token a partir das suas Definições de Conta", "components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "Sua URL de webhook para notificação baseada em utilizador ou dispositivo", "components.RequestList.RequestItem.requesteddate": "Pedido", - "components.RequestCard.failedretry": "Algo correu mal ao voltar a tentar o pedido.", + "components.RequestCard.failedretry": "Ocorreu um erro ao voltar a tentar o pedido.", "components.DownloadBlock.estimatedtime": "Estimativa {time}", "components.Settings.SettingsUsers.localLoginTip": "Permitir que os utilizadores iniciem sessão usando e-mail e palavra-passe, em vez de Plex OAuth", "components.Settings.SettingsUsers.defaultPermissionsTip": "Permissões iniciais atribuídas a novos utilizadores", @@ -873,7 +873,7 @@ "components.Settings.Notifications.NotificationsPushover.validationTypes": "Deve selecionar pelo menos um tipo de notificação", "components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Deve selecionar pelo menos um tipo de notificação", "components.Settings.Notifications.NotificationsLunaSea.validationTypes": "Deve selecionar pelo menos um tipo de notificação", - "components.NotificationTypeSelector.usermediarequestedDescription": "Notificado quando outros utilizadores enviarem novos pedidos de multimédia que requeiram aprovação.", + "components.NotificationTypeSelector.usermediarequestedDescription": "Notificar quando outros utilizadores enviarem novos pedidos de multimédia que requeiram aprovação.", "components.NotificationTypeSelector.usermediafailedDescription": "Notificar quando os pedidos de multimédia não forem adicionados ao Radarr ou Sonarr.", "components.NotificationTypeSelector.usermediadeclinedDescription": "Notificar quando seus pedidos de multimédia forem recusados.", "components.NotificationTypeSelector.usermediaavailableDescription": "Notificar quando os seus pedidos de multimédia ficarem disponíveis.", From de56380c054ac3c7f076d01c801ce1b9051870ae Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Mon, 14 Jun 2021 22:52:23 -0400 Subject: [PATCH 03/45] docs(api): update and correct API documentation (#1733) [skip ci] --- overseerr-api.yml | 64 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/overseerr-api.yml b/overseerr-api.yml index 463d8ad1d..a9211e16e 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -52,9 +52,15 @@ components: email: type: string example: 'hey@itsme.com' + readOnly: true + username: + type: string plexToken: type: string readOnly: true + plexUsername: + type: string + readOnly: true userType: type: integer example: 1 @@ -77,13 +83,6 @@ components: type: number example: 5 readOnly: true - requests: - type: array - readOnly: true - items: - $ref: '#/components/schemas/MediaRequest' - settings: - $ref: '#/components/schemas/UserSettings' required: - id - email @@ -92,11 +91,11 @@ components: UserSettings: type: object properties: - discordId: + locale: type: string region: type: string - language: + originalLanguage: type: string MainSettings: type: object @@ -398,7 +397,6 @@ components: activeLanguageProfileId: type: number example: 1 - nullable: true activeAnimeProfileId: type: number nullable: true @@ -408,6 +406,7 @@ components: activeAnimeProfileName: type: string example: 720p/1080p + nullable: true activeAnimeDirectory: type: string nullable: true @@ -953,7 +952,7 @@ components: status: type: number example: 0 - description: Status of the request. 1 = PENDING APPROVAL, 2 = APPROVED, 3 = DECLINED, 4 = AVAILABLE + description: Status of the request. 1 = PENDING APPROVAL, 2 = APPROVED, 3 = DECLINED readOnly: true media: $ref: '#/components/schemas/MediaInfo' @@ -1587,9 +1586,8 @@ components: UserSettingsNotifications: type: object properties: - notificationAgents: - type: number - example: 0 + notificationTypes: + $ref: '#/components/schemas/NotificationAgentTypes' emailEnabled: type: boolean pgpKey: @@ -1614,6 +1612,25 @@ components: telegramSendSilently: type: boolean nullable: true + NotificationAgentTypes: + type: object + properties: + discord: + type: number + email: + type: number + pushbullet: + type: number + pushover: + type: number + slack: + type: number + telegram: + type: number + webhook: + type: number + webpush: + type: number securitySchemes: cookieAuth: type: apiKey @@ -1842,8 +1859,8 @@ paths: $ref: '#/components/schemas/PlexLibrary' /settings/plex/devices/servers: get: - summary: Gets the user's available plex servers - description: Returns a list of available plex servers and their connectivity state + summary: Gets the user's available Plex servers + description: Returns a list of available Plex servers and their connectivity state tags: - settings responses: @@ -2980,7 +2997,15 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/User' + type: object + properties: + email: + type: string + example: 'hey@itsme.com' + username: + type: string + permissions: + type: number responses: '201': description: The created user @@ -2991,7 +3016,7 @@ paths: put: summary: Update batch of users description: | - Update users with given IDs with provided values in request `body.settings`. You cannot update users' plex tokens through this request. + Update users with given IDs with provided values in request `body.settings`. You cannot update users' Plex tokens through this request. Requires the `MANAGE_USERS` permission. tags: @@ -3018,7 +3043,6 @@ paths: type: array items: $ref: '#/components/schemas/User' - /user/import-from-plex: post: summary: Import all users from Plex @@ -3067,7 +3091,7 @@ paths: get: summary: Get user by ID description: | - Retrieves user details in a JSON object.. Requires the `MANAGE_USERS` permission. + Retrieves user details in a JSON object. Requires the `MANAGE_USERS` permission. tags: - users parameters: From 6789b8701cb644d9a3f1384f30b3dff707201ef7 Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Mon, 14 Jun 2021 23:09:23 -0400 Subject: [PATCH 04/45] fix(plex): do not fail to scan empty libraries (#1771) * fix(plex): do not fail to scan empty libraries * fix(plex): ensure getLibraryContents returns array --- server/api/plexapi.ts | 2 +- server/lib/scanners/plex/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/api/plexapi.ts b/server/api/plexapi.ts index b87dc3421..dea93c535 100644 --- a/server/api/plexapi.ts +++ b/server/api/plexapi.ts @@ -142,7 +142,7 @@ class PlexAPI { `/library/sections/${id}/all` ); - return response.MediaContainer.Metadata; + return response.MediaContainer.Metadata ?? []; } public async getMetadata( diff --git a/server/lib/scanners/plex/index.ts b/server/lib/scanners/plex/index.ts index 5a4bfc081..27fcaa646 100644 --- a/server/lib/scanners/plex/index.ts +++ b/server/lib/scanners/plex/index.ts @@ -7,9 +7,9 @@ import { User } from '../../../entity/User'; import { getSettings, Library } from '../../settings'; import BaseScanner, { MediaIds, + ProcessableSeason, RunnableScanner, StatusBase, - ProcessableSeason, } from '../baseScanner'; const imdbRegex = new RegExp(/imdb:\/\/(tt[0-9]+)/); From 71641d35c45e7c0c6aaada0968d93cd2cb1ca30d Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Mon, 14 Jun 2021 23:16:33 -0400 Subject: [PATCH 05/45] build(deps): bump openpgp from 5.0.0-2 to 5.0.0-3 (#1734) --- package.json | 2 +- server/lib/email/openpgpEncrypt.ts | 8 ++++---- yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 117ac5e7b..0cb3840c2 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "node-cache": "^5.1.2", "node-schedule": "^2.0.0", "nodemailer": "^6.6.1", - "openpgp": "^5.0.0-2", + "openpgp": "^5.0.0-3", "plex-api": "^5.3.1", "pug": "^3.0.2", "react": "17.0.2", diff --git a/server/lib/email/openpgpEncrypt.ts b/server/lib/email/openpgpEncrypt.ts index 607173f79..020e2e493 100644 --- a/server/lib/email/openpgpEncrypt.ts +++ b/server/lib/email/openpgpEncrypt.ts @@ -41,7 +41,7 @@ class PGPEncryptor extends Transform { const validPublicKeys = await Promise.all( this._encryptionKeys.map((armoredKey) => openpgp.readKey({ armoredKey })) ); - let privateKey: openpgp.Key | undefined; + let privateKey: openpgp.PrivateKey | undefined; // Just return the message if there is no one to encrypt for if (!validPublicKeys.length) { @@ -51,7 +51,7 @@ class PGPEncryptor extends Transform { // Only sign the message if private key and password exist if (this._signingKey && this._password) { - privateKey = await openpgp.readKey({ + privateKey = await openpgp.readPrivateKey({ armoredKey: this._signingKey, }); @@ -135,8 +135,8 @@ class PGPEncryptor extends Transform { emailPartDelimiter + messageParts.join(emailPartDelimiter), }), - publicKeys: validPublicKeys, - privateKeys: privateKey, + encryptionKeys: validPublicKeys, + signingKeys: privateKey, }); const body = diff --git a/yarn.lock b/yarn.lock index f689b99cb..ce9c51a10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10293,10 +10293,10 @@ opener@^1.5.1: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -openpgp@^5.0.0-2: - version "5.0.0-2" - resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-5.0.0-2.tgz#da54385eb9298c259bc6aa76ab556532298897d4" - integrity sha512-es+5A50Y+4JbtV+eugLPW9v/UkUIOufeOUyTcjbG8SMILNaLY9nEwUSJKDjQOadY+16w7Uqt0FDQ3Z1Vq7/F9g== +openpgp@^5.0.0-3: + version "5.0.0-3" + resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-5.0.0-3.tgz#08bbd878edc7c8e3c8443d8ace2c3b2236e3150c" + integrity sha512-5Yzd7hjoCtR0m27yrM6+Li1RcuUPIyVJXKMfR82HJotfst5NEEQHxCyUJvDWc8SqKS53zFyTl0SlPaZ08C2PxA== dependencies: asn1.js "^5.0.0" From 15f7941269075b7e12de8bbc0f98418af70df380 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 15 Jun 2021 20:44:55 +0200 Subject: [PATCH 06/45] feat(lang): translated using Weblate (German) (#1791) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 91.8% (807 of 879 strings) Co-authored-by: Alexander Neuhäuser Translate-URL: https://hosted.weblate.org/projects/overseerr/overseerr-frontend/de/ Translation: Overseerr/Overseerr Frontend Co-authored-by: Alexander Neuhäuser --- src/i18n/locale/de.json | 87 ++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/src/i18n/locale/de.json b/src/i18n/locale/de.json index 478b55e7d..86cb01e74 100644 --- a/src/i18n/locale/de.json +++ b/src/i18n/locale/de.json @@ -266,27 +266,27 @@ "components.Settings.Notifications.telegramsettingsfailed": "Telegram-Benachrichtigungseinstellungen konnten nicht gespeichert werden.", "components.Settings.Notifications.senderName": "Absendername", "components.Settings.Notifications.chatId": "Chat-ID", - "components.Settings.Notifications.botAPI": "Bot-Authentifizierungstoken", + "components.Settings.Notifications.botAPI": "Bot-Autorisierungstoken", "components.StatusChacker.reloadOverseerr": "Overseerr neu laden", "components.StatusChacker.newversionavailable": "Anwendungsaktualisierung", "components.StatusChacker.newversionDescription": "Overseerr wurde aktualisiert! Bitte klicke auf die Schaltfläche unten, um die Seite neu zu laden.", "components.Settings.SettingsAbout.documentation": "Dokumentation", - "components.NotificationTypeSelector.mediarequestedDescription": "Sendet eine Benachrichtigung, wenn neue Medien angefordert wurden und auf Genehmigung warten.", + "components.NotificationTypeSelector.mediarequestedDescription": "Sendet Benachrichtigungen, wenn neue Medien angefordert wurden und auf Genehmigung warten.", "components.NotificationTypeSelector.mediarequested": "Medien angefordert", - "components.NotificationTypeSelector.mediafailedDescription": "Sendet eine Benachrichtigung, wenn angeforderte Medien nicht zu Radarr oder Sonarr hinzugefügt werden können.", + "components.NotificationTypeSelector.mediafailedDescription": "Sendet Benachrichtigungen, wenn angeforderte Medien nicht zu Radarr oder Sonarr hinzugefügt werden können.", "components.NotificationTypeSelector.mediafailed": "Medien fehlgeschlagen", - "components.NotificationTypeSelector.mediaapprovedDescription": "Sendet eine Benachrichtigung, wenn das angeforderte Medium manuell genehmigt wird.", - "components.NotificationTypeSelector.mediaavailableDescription": "Sendet eine Benachrichtigung, wenn angeforderte Medien verfügbar werden.", + "components.NotificationTypeSelector.mediaapprovedDescription": "Sendet Benachrichtigungen, wenn angeforderte Medien manuell genehmigt wurden.", + "components.NotificationTypeSelector.mediaavailableDescription": "Sendet Benachrichtigungen, wenn angeforderte Medien verfügbar werden.", "components.NotificationTypeSelector.mediaavailable": "Medien verfügbar", "components.NotificationTypeSelector.mediaapproved": "Medien genehmigt", "i18n.request": "Anfragen", - "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Du musst einen gültigen Benutzerschlüssel angeben", + "components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Sie müssen einen gültigen Benutzer-/Gruppenschlüssel angeben", "components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Du musst ein gültiges Anwendungstoken angeben", "components.Settings.Notifications.NotificationsPushover.userToken": "Benutzer- oder Gruppenschlüssel", "components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover-Benachrichtigungseinstellungen erfolgreich gespeichert!", "components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Pushover-Benachrichtigungseinstellungen konnten nicht gespeichert werden.", "components.Settings.Notifications.NotificationsPushover.agentenabled": "Agent aktivieren", - "components.Settings.Notifications.NotificationsPushover.accessToken": "Anwendungs-/API-Token", + "components.Settings.Notifications.NotificationsPushover.accessToken": "Anwendungs API-Token", "components.RequestList.sortModified": "Zuletzt geändert", "components.RequestList.sortAdded": "Anfragedatum", "components.RequestList.showallrequests": "Zeige alle Anfragen", @@ -348,7 +348,7 @@ "components.RequestBlock.rootfolder": "Stammordner", "components.RequestBlock.profilechanged": "Qualitätsprofil", "components.NotificationTypeSelector.mediadeclined": "Medien abgelehnt", - "components.NotificationTypeSelector.mediadeclinedDescription": "Sendet eine Benachrichtigung, wenn eine Medienanfrage abgelehnt wird.", + "components.NotificationTypeSelector.mediadeclinedDescription": "Sendet Benachrichtigungen, wenn Medienanfrage abgelehnt wurde.", "components.RequestModal.autoapproval": "Automatische Genehmigung", "i18n.experimental": "Experimental", "components.Settings.hideAvailable": "Verfügbare Medien ausblenden", @@ -368,8 +368,8 @@ "components.PermissionEdit.managerequests": "Anfragen verwalten", "components.PermissionEdit.request": "Anfrage", "components.PermissionEdit.autoapproveMovies": "Automatische Genehmigung von Filmen", - "components.PermissionEdit.admin": "Administrator", - "components.PermissionEdit.managerequestsDescription": "Gewähre Berechtigung zum Verwalten von Overseerr-Anfragen (einschließlich Genehmigen und Ablehnen von Anfragen). Alle Anfragen eines Benutzers mit dieser Berechtigung werden automatisch genehmigt.", + "components.PermissionEdit.admin": "Admin", + "components.PermissionEdit.managerequestsDescription": "Gewähre Berechtigung zum Verwalten von Overseerr-Anfragen. Alle Anfragen eines Benutzers mit dieser Berechtigung werden automatisch genehmigt.", "components.UserList.userssaved": "Benutzerberechtigungen erfolgreich gespeichert!", "components.UserList.bulkedit": "Ausgewählte bearbeiten", "components.Settings.toastPlexRefreshSuccess": "Plex-Serverliste erfolgreich abgerufen!", @@ -391,19 +391,19 @@ "components.Settings.SonarrModal.toastSonarrTestFailure": "Verbindung zu Sonarr fehlgeschlagen.", "components.PermissionEdit.usersDescription": "Gewähre Berechtigung zum Verwalten von Overseerr-Benutzern. Benutzer mit dieser Berechtigung können Benutzer mit Adminrechten nicht bearbeiten oder Adminrechte erteilen.", "components.PermissionEdit.users": "Benutzer verwalten", - "components.PermissionEdit.settingsDescription": "Gewähre Berechtigung zum Ändern aller Overseerr-Einstellungen. Ein Benutzer muss über diese Berechtigung verfügen, um sie anderen Benutzern erteilen zu können.", + "components.PermissionEdit.settingsDescription": "Gewähre Berechtigung zum Ändern Overseerr-Einstellungen. Ein Benutzer muss über diese Berechtigung verfügen, um sie anderen Benutzern erteilen zu können.", "components.PermissionEdit.settings": "Einstellungen verwalten", - "components.PermissionEdit.requestDescription": "Gewähre Berechtigung zum Anfragen von Filmen und Serien.", + "components.PermissionEdit.requestDescription": "Gewähre Berechtigung zum Anfragen von nicht 4K Medien.", "components.PermissionEdit.request4kTvDescription": "Gewähre Berechtigung Serien in 4K anzufragen.", "components.PermissionEdit.request4kTv": "4K Serien anfragen", "components.PermissionEdit.request4kMoviesDescription": "Gewähre Berechtigung Filme in 4K anzufragen.", "components.PermissionEdit.request4kMovies": "4K Filme anfragen", "components.PermissionEdit.request4k": "4K anfragen", - "components.PermissionEdit.request4kDescription": "Gewähre Berechtigung Filme und Serien in 4K anzufragen.", - "components.PermissionEdit.autoapproveSeriesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von nicht-4K Serienanfragen für diesen Benutzer.", - "components.PermissionEdit.autoapproveMoviesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von nicht-4K Filmanfragen für diesen Benutzer.", - "components.PermissionEdit.autoapproveDescription": "Gewähre Berechtigung zur automatischen Genehmigung von allen nicht-4K Anfragen für diesen Benutzer.", - "components.PermissionEdit.advancedrequestDescription": "Gewähre Berechtigung zum Verwenden erweiterter Anfrageoptionen (z.B. Ändern von Servern, Profilen oder Pfaden).", + "components.PermissionEdit.request4kDescription": "Gewähre Berechtigung Medien in 4K anzufragen.", + "components.PermissionEdit.autoapproveSeriesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von nicht-4K Serienanfragen.", + "components.PermissionEdit.autoapproveMoviesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von nicht-4K Filmanfragen.", + "components.PermissionEdit.autoapproveDescription": "Gewähre Berechtigung zur automatischen Genehmigung von allen nicht-4K Anfragen.", + "components.PermissionEdit.advancedrequestDescription": "Gewähre Berechtigung zum Verwenden erweiterter Anfrageoptionen.", "components.PermissionEdit.adminDescription": "Voller Administratorzugriff. Umgeht alle anderen Rechteabfragen.", "components.MovieDetails.openradarr4k": "Film in 4K Radarr öffnen", "components.MovieDetails.openradarr": "Film in Radarr öffnen", @@ -418,7 +418,7 @@ "components.TvDetails.playonplex": "Auf Plex abspielen", "components.MovieDetails.playonplex": "Auf Plex abspielen", "components.TvDetails.play4konplex": "4K auf Plex abspielen", - "components.MovieDetails.play4konplex": "4K auf Plex abspielen", + "components.MovieDetails.play4konplex": "In 4K auf Plex abspielen", "components.TvDetails.markavailable": "Als verfügbar markieren", "components.TvDetails.mark4kavailable": "4K als verfügbar markieren", "components.TvDetails.allseasonsmarkedavailable": "* Alle Staffeln werden als verfügbar markiert.", @@ -502,11 +502,11 @@ "components.UserList.sortCreated": "Erstellungsdatum", "components.PermissionEdit.autoapprove4k": "Automatische Genehmigung von 4K", "components.UserList.sortUpdated": "Zuletzt aktualisiert", - "components.PermissionEdit.autoapprove4kSeriesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von 4K Serienanfragen für diesen Benutzer.", + "components.PermissionEdit.autoapprove4kSeriesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von 4K Serienanfragen.", "components.PermissionEdit.autoapprove4kSeries": "Automatische Genehmigung von 4K Serien", - "components.PermissionEdit.autoapprove4kMoviesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von 4K Filmanfragen für diesen Benutzer.", + "components.PermissionEdit.autoapprove4kMoviesDescription": "Gewähre Berechtigung zur automatischen Genehmigung von 4K Filmanfragen.", "components.PermissionEdit.autoapprove4kMovies": "Automatische Genehmigung von 4K Filmen", - "components.PermissionEdit.autoapprove4kDescription": "Gewähre Berechtigung zur automatischen Genehmigung von allen 4K Anfragen für diesen Benutzer.", + "components.PermissionEdit.autoapprove4kDescription": "Gewähre Berechtigung zur automatischen Genehmigung von allen 4K Anfragen.", "components.UserProfile.recentrequests": "Kürzliche Anfragen", "components.UserProfile.UserSettings.menuPermissions": "Berechtigungen", "components.UserProfile.UserSettings.menuNotifications": "Benachrichtigungen", @@ -781,5 +781,48 @@ "components.Layout.VersionStatus.commitsbehind": "{commitsBehind} {commitsBehind, plural, one {Commit} other {Commits}} behind", "components.LanguageSelector.originalLanguageDefault": "Alle Sprachen", "components.LanguageSelector.languageServerDefault": "Standard ({language})", - "components.Discover.noRequests": "Keine Anfragen." + "components.Discover.noRequests": "Keine Anfragen.", + "components.Settings.Notifications.NotificationsWebhook.validationTypes": "Sie müssen mindestens einen Benachrichtigungstypen auswählen", + "components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSuccess": "Webhook test Benachrichtigung gesendet!", + "components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSending": "Webhook test Benachrichtigung wird gesendet…", + "components.Settings.Notifications.NotificationsWebhook.toastWebhookTestFailed": "Webhook Benachrichtigungseinstellungen konnten nicht gespeichert werden.", + "components.Settings.Notifications.NotificationsWebPush.webpushsettingssaved": "Web push Benachrichtigungseinstellungen erfolgreich gespeichert!", + "components.Settings.Notifications.NotificationsWebPush.webpushsettingsfailed": "Web push Benachrichtigungseinstellungen konnten nicht gespeichert werden.", + "components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSuccess": "Web push test Benachrichtigung gesendet!", + "components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSending": "Web push test Benachrichtigung wird gesendet…", + "components.Settings.Notifications.NotificationsWebPush.toastWebPushTestFailed": "Web push test Benachrichtigung fehlgeschlagen.", + "components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Um web push Benachrichtigungen zu erhalten, muss Overseerr über HTTPS gehen.", + "components.Settings.Notifications.NotificationsWebPush.agentenabled": "Agent aktivieren", + "components.Settings.Notifications.NotificationsSlack.validationTypes": "Sie müssen mindestens einen Benachrichtigungstypen auswählen", + "components.Settings.Notifications.NotificationsSlack.toastSlackTestSuccess": "Slack test Benachrichtigung gesendet!", + "components.Settings.Notifications.NotificationsSlack.toastSlackTestSending": "Slack test Benachrichtigung wird gesendet…", + "components.Settings.Notifications.NotificationsSlack.toastSlackTestFailed": "Slack test Benachrichtigung fehlgeschlagen.", + "components.Settings.Notifications.NotificationsPushover.validationTypes": "Sie müssen mindestens einen Benachrichtigungstypen auswählen", + "components.Settings.Notifications.NotificationsPushover.toastPushoverTestSuccess": "Pushover test Benachrichtigung gesendet!", + "components.Settings.Notifications.NotificationsPushover.toastPushoverTestSending": "Pushover test Benachrichtigung wird gesendet…", + "components.Settings.Notifications.NotificationsPushover.toastPushoverTestFailed": "Pushover test Benachrichtigung fehlgeschlagen.", + "components.Settings.Notifications.NotificationsPushover.accessTokenTip": "Registriere eine Anwendung für die Benutzung mit Overseerr", + "components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Sie müssen mindestens einen Benachrichtigungstypen auswählen", + "components.RequestCard.failedretry": "Ein Fehler ist aufgetreten beim erneutem versuch die Anfrage zu senden.", + "components.PermissionEdit.requestTvDescription": "Berechtigungen erteilen um nicht 4K Serien anzufragen.", + "components.NotificationTypeSelector.usermediafailedDescription": "Werde benachrichtigt, wenn die angeforderten Medien bei der Hinzufügung zu Radarr oder Sonarr fehlschlagen.", + "components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "Erstellen Sie einen Tonken in Ihren Account Einstellungen", + "components.Settings.Notifications.NotificationsLunaSea.webhookUrl": "Webhook URL", + "components.Settings.Notifications.NotificationsLunaSea.validationWebhookUrl": "Geben sie eine valide URL an", + "components.Settings.Notifications.NotificationsLunaSea.validationTypes": "Sie müssen mindestens einen Benachrichtigungstypen auswählen", + "components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSuccess": "LunaSea test Benachrichtigung gesendet!", + "components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSending": "LunaSea Test Benachrichtigung wird gesendet…", + "components.Settings.Notifications.NotificationsLunaSea.profileName": "Profil Name", + "components.RequestList.RequestItem.requesteddate": "Angefordert", + "components.QuotaSelector.tvRequests": "{quotaLimit} {seasons} pro {quotaDays} {days}", + "components.QuotaSelector.movieRequests": "{quotaLimit} {movies} pro {quotaDays} {days}", + "components.PermissionEdit.requestTv": "Serie anfordern", + "components.PermissionEdit.requestMoviesDescription": "Berechtigungen erteilen um nicht 4K filme anzufordern.", + "components.PermissionEdit.requestMovies": "Filme Anfragen", + "components.NotificationTypeSelector.usermediarequestedDescription": "Werde benachrichtigt, wenn andere Nutzer ein Medium anfordern, welches eine genehmigt erfordert.", + "components.NotificationTypeSelector.usermediadeclinedDescription": "Werde benachrichtigt, wenn Ihre Medienanfrage abgelehnt wurde.", + "components.NotificationTypeSelector.usermediaavailableDescription": "Werde benachrichtigt, wenn Ihre Medienanfrage verfügbar wird.", + "components.NotificationTypeSelector.usermediaapprovedDescription": "Werde benachrichtigt, wenn Ihre Medienanfrage angenommen wurde.", + "components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Werde benachrichtigt, wenn andere Nutzer Medien anfordern, welche automatisch angenommen werden.", + "components.DownloadBlock.estimatedtime": "Geschätzte {time}" } From c8b5a200d32f0d90abcc63d8d1df55bc85c5e8be Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 16 Jun 2021 17:27:28 +0900 Subject: [PATCH 07/45] docs: add iceHtwoO as a contributor for translation (#1793) [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> --- .all-contributorsrc | 9 +++++++++ README.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index bc7fea695..c07210ef7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -503,6 +503,15 @@ "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" + ] } ], "badgeTemplate": "\"All-orange.svg\"/>", diff --git a/README.md b/README.md index 3dbf40fba..c6475890f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Language grade: JavaScript GitHub -All Contributors +All Contributors

@@ -143,6 +143,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
littlerooster

🌍
Dustin Hildebrandt

💻
Bruno Guerreiro

🌍 +
Alexander Neuhäuser

🌍 From 0db0d4c280fe5132f815701ffdc6c91643a8fe6d Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Thu, 17 Jun 2021 00:12:09 -0400 Subject: [PATCH 08/45] build(deps): bump node to 14.17 and drop uuid in favor of native randomUUID (#1792) --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/snap.yaml | 2 +- Dockerfile | 4 ++-- Dockerfile.local | 2 +- package.json | 2 -- server/entity/User.ts | 4 ++-- server/lib/email/openpgpEncrypt.ts | 4 ++-- server/lib/scanners/baseScanner.ts | 4 ++-- server/lib/settings.ts | 8 ++++---- snap/snapcraft.yaml | 2 +- yarn.lock | 5 ----- 12 files changed, 17 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06cccb78a..9945e234d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: test: name: Lint & Test Build runs-on: ubuntu-20.04 - container: node:14.16-alpine + container: node:14.17-alpine steps: - name: Checkout uses: actions/checkout@v2.3.4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 13464f61e..0f1f661d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ jobs: test: name: Lint & Test Build runs-on: ubuntu-20.04 - container: node:14.16-alpine + container: node:14.17-alpine steps: - name: Checkout uses: actions/checkout@v2.3.4 diff --git a/.github/workflows/snap.yaml b/.github/workflows/snap.yaml index c74e6b132..3e82fe9ae 100644 --- a/.github/workflows/snap.yaml +++ b/.github/workflows/snap.yaml @@ -20,7 +20,7 @@ jobs: name: Lint & Test Build needs: jobs runs-on: ubuntu-20.04 - container: node:14.16-alpine + container: node:14.17-alpine steps: - name: Checkout uses: actions/checkout@v2.3.4 diff --git a/Dockerfile b/Dockerfile index eda37b312..cb80274ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14.16-alpine AS BUILD_IMAGE +FROM node:14.17-alpine AS BUILD_IMAGE WORKDIR /app @@ -31,7 +31,7 @@ RUN touch config/DOCKER RUN echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json -FROM node:14.16-alpine +FROM node:14.17-alpine WORKDIR /app diff --git a/Dockerfile.local b/Dockerfile.local index 64fd61a6e..b0b922e1f 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -1,4 +1,4 @@ -FROM node:14.16-alpine +FROM node:14.17-alpine COPY . /app WORKDIR /app diff --git a/package.json b/package.json index 0cb3840c2..3fac98aa1 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "swagger-ui-express": "^4.1.6", "swr": "^0.5.6", "typeorm": "0.2.32", - "uuid": "^8.3.2", "web-push": "^3.4.4", "winston": "^3.3.3", "winston-daily-rotate-file": "^4.5.5", @@ -104,7 +103,6 @@ "@types/react-transition-group": "^4.4.1", "@types/secure-random-password": "^0.2.0", "@types/swagger-ui-express": "^4.1.2", - "@types/uuid": "^8.3.0", "@types/web-push": "^3.3.0", "@types/xml2js": "^0.4.8", "@types/yamljs": "^0.2.31", diff --git a/server/entity/User.ts b/server/entity/User.ts index 59d347cbb..ed6fc4a6b 100644 --- a/server/entity/User.ts +++ b/server/entity/User.ts @@ -1,4 +1,5 @@ import bcrypt from 'bcrypt'; +import { randomUUID } from 'crypto'; import path from 'path'; import { default as generatePassword } from 'secure-random-password'; import { @@ -15,7 +16,6 @@ import { RelationCount, UpdateDateColumn, } from 'typeorm'; -import { v4 as uuid } from 'uuid'; import { MediaRequestStatus, MediaType } from '../constants/media'; import { UserType } from '../constants/user'; import { QuotaResponse } from '../interfaces/api/userInterfaces'; @@ -189,7 +189,7 @@ export class User { } public async resetPassword(): Promise { - const guid = uuid(); + const guid = randomUUID(); this.resetPasswordGuid = guid; // 24 hours into the future diff --git a/server/lib/email/openpgpEncrypt.ts b/server/lib/email/openpgpEncrypt.ts index 020e2e493..263f2b1f2 100644 --- a/server/lib/email/openpgpEncrypt.ts +++ b/server/lib/email/openpgpEncrypt.ts @@ -1,4 +1,4 @@ -import crypto from 'crypto'; +import { randomBytes } from 'crypto'; import * as openpgp from 'openpgp'; import { Transform, TransformCallback } from 'stream'; @@ -107,7 +107,7 @@ class PGPEncryptor extends Transform { } // Generate a new boundary for the email content - const boundary = 'nm_' + crypto.randomBytes(14).toString('hex'); + const boundary = 'nm_' + randomBytes(14).toString('hex'); /** * Concatenate everything into single strings * and add pgp headers to the email headers diff --git a/server/lib/scanners/baseScanner.ts b/server/lib/scanners/baseScanner.ts index ac76d61cd..a39279c97 100644 --- a/server/lib/scanners/baseScanner.ts +++ b/server/lib/scanners/baseScanner.ts @@ -1,5 +1,5 @@ +import { randomUUID } from 'crypto'; import { getRepository } from 'typeorm'; -import { v4 as uuid } from 'uuid'; import TheMovieDb from '../../api/themoviedb'; import { MediaStatus, MediaType } from '../../constants/media'; import Media from '../../entity/Media'; @@ -512,7 +512,7 @@ class BaseScanner { */ protected startRun(): string { const settings = getSettings(); - const sessionId = uuid(); + const sessionId = randomUUID(); this.sessionId = sessionId; this.log('Scan starting', 'info', { sessionId }); diff --git a/server/lib/settings.ts b/server/lib/settings.ts index 656be8680..dc00f80cb 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -1,7 +1,7 @@ +import { randomUUID } from 'crypto'; import fs from 'fs'; import { merge } from 'lodash'; import path from 'path'; -import { v4 as uuidv4 } from 'uuid'; import webpush from 'web-push'; import { Permission } from './permissions'; @@ -234,7 +234,7 @@ class Settings { constructor(initialSettings?: AllSettings) { this.data = { - clientId: uuidv4(), + clientId: randomUUID(), vapidPrivate: '', vapidPublic: '', main: { @@ -428,7 +428,7 @@ class Settings { get clientId(): string { if (!this.data.clientId) { - this.data.clientId = uuidv4(); + this.data.clientId = randomUUID(); this.save(); } @@ -454,7 +454,7 @@ class Settings { } private generateApiKey(): string { - return Buffer.from(`${Date.now()}${uuidv4()})`).toString('base64'); + return Buffer.from(`${Date.now()}${randomUUID()})`).toString('base64'); } private generateVapidKeys(force = false): void { diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 0f03c059b..ecb8712ad 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -11,7 +11,7 @@ confinement: strict parts: overseerr: plugin: nodejs - nodejs-version: '14.16.1' + nodejs-version: '14.17.0' nodejs-package-manager: 'yarn' nodejs-yarn-version: v1.22.10 build-packages: diff --git a/yarn.lock b/yarn.lock index ce9c51a10..25b0da55c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2556,11 +2556,6 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== -"@types/uuid@^8.3.0": - version "8.3.0" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" - integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== - "@types/web-push@^3.3.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@types/web-push/-/web-push-3.3.0.tgz#459eb722c9585b84a149e7020606d4f65f64f0ca" From a41245c703688743ec24f9b4a53e70f3340daa0f Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Thu, 17 Jun 2021 00:49:52 -0400 Subject: [PATCH 09/45] fix(lang): minor changes to password reset strings (#1798) --- src/components/ResetPassword/RequestResetLink.tsx | 2 +- src/components/ResetPassword/index.tsx | 5 ++++- src/i18n/locale/en.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/ResetPassword/RequestResetLink.tsx b/src/components/ResetPassword/RequestResetLink.tsx index 49fc5afef..496f423d1 100644 --- a/src/components/ResetPassword/RequestResetLink.tsx +++ b/src/components/ResetPassword/RequestResetLink.tsx @@ -13,7 +13,7 @@ import LanguagePicker from '../Layout/LanguagePicker'; const messages = defineMessages({ passwordreset: 'Password Reset', resetpassword: 'Reset your password', - emailresetlink: 'Email a Recovery Link', + emailresetlink: 'Email Recovery Link', email: 'Email Address', validationemailrequired: 'You must provide a valid email address', gobacklogin: 'Return to Sign-In Page', diff --git a/src/components/ResetPassword/index.tsx b/src/components/ResetPassword/index.tsx index 5d18164d5..3b7b5849a 100644 --- a/src/components/ResetPassword/index.tsx +++ b/src/components/ResetPassword/index.tsx @@ -5,6 +5,7 @@ import { useRouter } from 'next/router'; import React, { useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; import * as Yup from 'yup'; +import globalMessages from '../../i18n/globalMessages'; import Button from '../Common/Button'; import ImageFader from '../Common/ImageFader'; import SensitiveInput from '../Common/SensitiveInput'; @@ -163,7 +164,9 @@ const ResetPassword: React.FC = () => { type="submit" disabled={isSubmitting || !isValid} > - {intl.formatMessage(messages.resetpassword)} + {isSubmitting + ? intl.formatMessage(globalMessages.saving) + : intl.formatMessage(globalMessages.save)} diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index c3768e7df..6ba6e46a5 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -246,7 +246,7 @@ "components.RequestModal.selectseason": "Select Season(s)", "components.ResetPassword.confirmpassword": "Confirm Password", "components.ResetPassword.email": "Email Address", - "components.ResetPassword.emailresetlink": "Email a Recovery Link", + "components.ResetPassword.emailresetlink": "Email Recovery Link", "components.ResetPassword.gobacklogin": "Return to Sign-In Page", "components.ResetPassword.password": "Password", "components.ResetPassword.passwordreset": "Password Reset", From 42e45f38e5ede7df0fc4bdb20a970917b2361569 Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Thu, 17 Jun 2021 00:54:36 -0400 Subject: [PATCH 10/45] fix(notif): truncate media overviews (#1800) --- server/entity/MediaRequest.ts | 38 +++++++++++++++++++++++----- server/subscriber/MediaSubscriber.ts | 13 ++++++++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index 21852f22d..a935b13f1 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -1,4 +1,4 @@ -import { isEqual } from 'lodash'; +import { isEqual, truncate } from 'lodash'; import { AfterInsert, AfterRemove, @@ -145,7 +145,11 @@ export class MediaRequest { subject: `${movie.title}${ movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : '' }`, - message: movie.overview, + message: truncate(movie.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, media, request: this, @@ -158,7 +162,11 @@ export class MediaRequest { subject: `${tv.name}${ tv.first_air_date ? ` (${tv.first_air_date.slice(0, 4)})` : '' }`, - message: tv.overview, + message: truncate(tv.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, media, extra: [ @@ -217,7 +225,11 @@ export class MediaRequest { subject: `${movie.title}${ movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : '' }`, - message: movie.overview, + message: truncate(movie.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, notifyUser: autoApproved ? undefined : this.requestedBy, media, @@ -236,7 +248,11 @@ export class MediaRequest { subject: `${tv.name}${ tv.first_air_date ? ` (${tv.first_air_date.slice(0, 4)})` : '' }`, - message: tv.overview, + message: truncate(tv.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, notifyUser: autoApproved ? undefined : this.requestedBy, media, @@ -495,7 +511,11 @@ export class MediaRequest { subject: `${movie.title}${ movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : '' }`, - message: movie.overview, + message: truncate(movie.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), media, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, request: this, @@ -707,7 +727,11 @@ export class MediaRequest { ? ` (${series.first_air_date.slice(0, 4)})` : '' }`, - message: series.overview, + message: truncate(series.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${series.poster_path}`, media, extra: [ diff --git a/server/subscriber/MediaSubscriber.ts b/server/subscriber/MediaSubscriber.ts index 32c0193e1..342c5ca54 100644 --- a/server/subscriber/MediaSubscriber.ts +++ b/server/subscriber/MediaSubscriber.ts @@ -1,3 +1,4 @@ +import { truncate } from 'lodash'; import { EntitySubscriberInterface, EventSubscriber, @@ -34,7 +35,11 @@ export class MediaSubscriber implements EntitySubscriberInterface { subject: `${movie.title}${ movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : '' }`, - message: movie.overview, + message: truncate(movie.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), media: entity, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, request: request, @@ -89,7 +94,11 @@ export class MediaSubscriber implements EntitySubscriberInterface { subject: `${tv.name}${ tv.first_air_date ? ` (${tv.first_air_date.slice(0, 4)})` : '' }`, - message: tv.overview, + message: truncate(tv.overview, { + length: 500, + separator: /\s/, + omission: '…', + }), notifyUser: request.requestedBy, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, media: entity, From 910d00c19522a70125bfb5e5081a7ef4000e7f54 Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Thu, 17 Jun 2021 00:59:20 -0400 Subject: [PATCH 11/45] fix(ui): do not allow submission of invalid form inputs (#1799) --- src/components/Settings/SettingsMain.tsx | 11 +++++++++-- src/components/Settings/SettingsPlex.tsx | 3 ++- .../UserSettings/UserPasswordChange/index.tsx | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/Settings/SettingsMain.tsx b/src/components/Settings/SettingsMain.tsx index 2913f5b7d..25751115f 100644 --- a/src/components/Settings/SettingsMain.tsx +++ b/src/components/Settings/SettingsMain.tsx @@ -178,7 +178,14 @@ const SettingsMain: React.FC = () => { } }} > - {({ errors, touched, isSubmitting, values, setFieldValue }) => { + {({ + errors, + touched, + isSubmitting, + isValid, + values, + setFieldValue, + }) => { return (
{userHasPermission(Permission.ADMIN) && ( @@ -397,7 +404,7 @@ const SettingsMain: React.FC = () => { + )} )} diff --git a/src/i18n/locale/en.json b/src/i18n/locale/en.json index e1ccbb868..4d4bae4e5 100644 --- a/src/i18n/locale/en.json +++ b/src/i18n/locale/en.json @@ -83,6 +83,8 @@ "components.MovieDetails.releasedate": "Release Date", "components.MovieDetails.revenue": "Revenue", "components.MovieDetails.runtime": "{minutes} minutes", + "components.MovieDetails.showless": "Show Less", + "components.MovieDetails.showmore": "Show More", "components.MovieDetails.similar": "Similar Titles", "components.MovieDetails.studio": "{studioCount, plural, one {Studio} other {Studios}}", "components.MovieDetails.viewfullcrew": "View Full Crew", diff --git a/src/styles/globals.css b/src/styles/globals.css index e7829896c..939e415bd 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -160,7 +160,8 @@ ul.media-crew > li { } a.crew-name, -.media-fact-value a { +.media-fact-value a, +.media-fact-value button { @apply font-normal text-gray-400 transition duration-300 hover:underline hover:text-gray-100; } @@ -173,11 +174,11 @@ a.crew-name, } .media-fact { - @apply flex px-4 py-2 border-b border-gray-700 last:border-b-0; + @apply flex justify-between px-4 py-2 border-b border-gray-700 last:border-b-0; } .media-fact-value { - @apply flex-1 text-sm font-normal text-right text-gray-400; + @apply text-sm font-normal text-right text-gray-400; } .media-ratings { From 1133a34ffdf95c4d036be0264fe7f94f64007e8f Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Tue, 13 Jul 2021 05:32:37 -0400 Subject: [PATCH 28/45] fix(email): omit links when application URL is not configured (#1806) Co-authored-by: sct --- server/entity/User.ts | 2 +- .../email/generatedpassword/html.pug | 22 +---------- server/templates/email/media-request/html.pug | 26 ++----------- server/templates/email/resetpassword/html.pug | 37 ++++++------------- server/templates/email/test-email/html.pug | 22 +---------- 5 files changed, 20 insertions(+), 89 deletions(-) diff --git a/server/entity/User.ts b/server/entity/User.ts index 766ef76f0..fc2729a5f 100644 --- a/server/entity/User.ts +++ b/server/entity/User.ts @@ -212,7 +212,7 @@ export class User { }, locals: { resetPasswordLink, - applicationUrl: resetPasswordLink, + applicationUrl, applicationTitle, }, }); diff --git a/server/templates/email/generatedpassword/html.pug b/server/templates/email/generatedpassword/html.pug index b9bc2a2e6..109729bf0 100644 --- a/server/templates/email/generatedpassword/html.pug +++ b/server/templates/email/generatedpassword/html.pug @@ -75,23 +75,5 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') margin-bottom: 20px;\ color: #51545e;\ ') - a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} -tr - td - table.sm-w-full(align='center' style='\ - margin-left: auto;\ - margin-right: auto;\ - text-align: center;\ - width: 570px;\ - ' width='570' cellpadding='0' cellspacing='0' role='presentation') - tr - td(align='center' style='font-size: 16px; padding: 45px') - p(style='\ - font-size: 13px;\ - line-height: 24px;\ - margin-top: 6px;\ - margin-bottom: 20px;\ - text-align: center;\ - color: #a8aaaf;\ - ') - | #{applicationTitle} + if applicationUrl + a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} diff --git a/server/templates/email/media-request/html.pug b/server/templates/email/media-request/html.pug index 73985a3e7..2b2f2b4e7 100644 --- a/server/templates/email/media-request/html.pug +++ b/server/templates/email/media-request/html.pug @@ -77,9 +77,9 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') | #{extra.value} table(align='center' cellpadding='0' cellspacing='0' role='presentation') tr - td + td(style='text-align: center') a(href=actionUrl style='color: #3869d4') - img(src=imageUrl alt='') + img(src=imageUrl alt='' style='max-width: 50%') p(style='\ font-size: 16px;\ line-height: 24px;\ @@ -95,23 +95,5 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') margin-bottom: 20px;\ color: #51545e;\ ') - a(href=actionUrl style='color: #3869d4') Open in #{applicationTitle} -tr - td - table.sm-w-full(align='center' style='\ - margin-left: auto;\ - margin-right: auto;\ - text-align: center;\ - width: 570px;\ - ' width='570' cellpadding='0' cellspacing='0' role='presentation') - tr - td(align='center' style='font-size: 16px; padding: 45px') - p(style='\ - font-size: 13px;\ - line-height: 24px;\ - margin-top: 6px;\ - margin-bottom: 20px;\ - text-align: center;\ - color: #a8aaaf;\ - ') - | #{applicationTitle} + if actionUrl + a(href=actionUrl style='color: #3869d4') Open in #{applicationTitle} diff --git a/server/templates/email/resetpassword/html.pug b/server/templates/email/resetpassword/html.pug index 718a0495a..63e07e937 100644 --- a/server/templates/email/resetpassword/html.pug +++ b/server/templates/email/resetpassword/html.pug @@ -64,12 +64,15 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') ' width='570' bgcolor='#ffffff' cellpadding='0' cellspacing='0' role='presentation') tr td(style='padding: 45px') - div(style='font-size: 16px; text-align: center; padding-bottom: 14px;') - | A request to reset the password was made. Click - a(href=applicationUrl style='color: #3869d4; padding: 0px 5px;') here - | to set a new password. - div(style='font-size: 16px; text-align: center; padding-bottom: 14px;') - | If you did not request this recovery link you can safely ignore this email. + div(style='font-size: 16px; padding-bottom: 14px;') + p + | We received a request to reset your password. + p + | Please + a(href=resetPasswordLink style='color: #3869d4; padding: 0px 5px;') click here + | to change your #{applicationTitle} password. + p + | If you did not request that your password be reset, you can safely ignore this email. p(style='\ font-size: 13px;\ line-height: 24px;\ @@ -77,23 +80,5 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') margin-bottom: 20px;\ color: #51545e;\ ') - a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} -tr - td - table.sm-w-full(align='center' style='\ - margin-left: auto;\ - margin-right: auto;\ - text-align: center;\ - width: 570px;\ - ' width='570' cellpadding='0' cellspacing='0' role='presentation') - tr - td(align='center' style='font-size: 16px; padding: 45px') - p(style='\ - font-size: 13px;\ - line-height: 24px;\ - margin-top: 6px;\ - margin-bottom: 20px;\ - text-align: center;\ - color: #a8aaaf;\ - ') - | #{applicationTitle}. + if applicationUrl + a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} diff --git a/server/templates/email/test-email/html.pug b/server/templates/email/test-email/html.pug index f1b21b36e..03eee48c9 100644 --- a/server/templates/email/test-email/html.pug +++ b/server/templates/email/test-email/html.pug @@ -73,23 +73,5 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en') margin-bottom: 20px;\ color: #51545e;\ ') - a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} -tr - td - table.sm-w-full(align='center' style='\ - margin-left: auto;\ - margin-right: auto;\ - text-align: center;\ - width: 570px;\ - ' width='570' cellpadding='0' cellspacing='0' role='presentation') - tr - td(align='center' style='font-size: 16px; padding: 45px') - p(style='\ - font-size: 13px;\ - line-height: 24px;\ - margin-top: 6px;\ - margin-bottom: 20px;\ - text-align: center;\ - color: #a8aaaf;\ - ') - | #{applicationTitle} + if applicationUrl + a(href=applicationUrl style='color: #3869d4') Open #{applicationTitle} From 8b960acf73350c4df5966e22e461e268efecd559 Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Tue, 13 Jul 2021 05:44:15 -0400 Subject: [PATCH 29/45] refactor(ui): add/tweak icons (#1819) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(ui): add prev/next button icons * refactor(ui): use mail icon instead of at symbol icon for email * refactor(ui): use ↻ symbol instead of ⤾ for reload button * refactor(ui): add missing icons to password reset pages * refactor(ui): add icons for save & test buttons Co-authored-by: sct --- public/offline.html | 2 +- src/components/RequestList/index.tsx | 13 ++++++++++--- .../ResetPassword/RequestResetLink.tsx | 7 ++++--- src/components/ResetPassword/index.tsx | 10 +++++++--- .../Notifications/NotificationsDiscord.tsx | 19 +++++++++++++------ .../Notifications/NotificationsEmail.tsx | 19 +++++++++++++------ .../NotificationsLunaSea/index.tsx | 19 +++++++++++++------ .../NotificationsPushbullet/index.tsx | 19 +++++++++++++------ .../NotificationsPushover/index.tsx | 19 +++++++++++++------ .../NotificationsSlack/index.tsx | 19 +++++++++++++------ .../Notifications/NotificationsTelegram.tsx | 19 +++++++++++++------ .../NotificationsWebPush/index.tsx | 19 +++++++++++++------ .../NotificationsWebhook/index.tsx | 19 +++++++++++++------ .../Settings/SettingsLogs/index.tsx | 8 ++++++-- src/components/Settings/SettingsMain.tsx | 10 +++++++--- .../Settings/SettingsNotifications.tsx | 5 ++--- src/components/Settings/SettingsPlex.tsx | 10 +++++++--- .../Settings/SettingsUsers/index.tsx | 10 +++++++--- src/components/UserList/index.tsx | 8 ++++++-- .../UserGeneralSettings/index.tsx | 10 +++++++--- .../UserNotificationsDiscord.tsx | 10 +++++++--- .../UserNotificationsEmail.tsx | 10 +++++++--- .../UserNotificationsTelegram.tsx | 10 +++++++--- .../UserNotificationsWebPush.tsx | 10 +++++++--- .../UserNotificationSettings/index.tsx | 5 ++--- .../UserSettings/UserPasswordChange/index.tsx | 10 +++++++--- .../UserSettings/UserPermissions/index.tsx | 10 +++++++--- src/styles/globals.css | 4 ++-- 28 files changed, 227 insertions(+), 106 deletions(-) diff --git a/public/offline.html b/public/offline.html index 01658360f..12c6c29f5 100644 --- a/public/offline.html +++ b/public/offline.html @@ -31,7 +31,7 @@

You are offline

- +