1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-06-27 16:36:00 +00:00

feat(integration)!: remove Pocket integration

BREAKING CHANGE: Pocket will no longer be available after July 8, 2025.

https://support.mozilla.org/en-US/kb/future-of-pocket#w_when-is-pocket-shutting-down
This commit is contained in:
jvoisin 2025-06-10 17:05:25 +02:00 committed by Frédéric Guillot
parent 70b513b8db
commit e9c1e90b81
41 changed files with 105 additions and 710 deletions

View file

@ -70,7 +70,7 @@ Features
### Integrations
- 25+ integrations with third-party services: [Apprise](https://github.com/caronc/apprise), [Betula](https://sr.ht/~bouncepaw/betula/), [Cubox](https://cubox.cc/), [Discord](https://discord.com/), [Espial](https://github.com/jonschoning/espial), [Instapaper](https://www.instapaper.com/), [LinkAce](https://www.linkace.org/), [Linkding](https://github.com/sissbruecker/linkding), [LinkWarden](https://linkwarden.app/), [Matrix](https://matrix.org), [Notion](https://www.notion.com/), [Ntfy](https://ntfy.sh/), [Nunux Keeper](https://keeper.nunux.org/), [Pinboard](https://pinboard.in/), [Pocket](https://getpocket.com/), [Pushover](https://pushover.net), [RainDrop](https://raindrop.io/), [Readeck](https://readeck.org/en/), [Readwise Reader](https://readwise.io/read), [RssBridge](https://rss-bridge.org/), [Shaarli](https://github.com/shaarli/Shaarli), [Shiori](https://github.com/go-shiori/shiori), [Slack](https://slack.com/), [Telegram](https://telegram.org), [Wallabag](https://www.wallabag.org/), etc.
- 25+ integrations with third-party services: [Apprise](https://github.com/caronc/apprise), [Betula](https://sr.ht/~bouncepaw/betula/), [Cubox](https://cubox.cc/), [Discord](https://discord.com/), [Espial](https://github.com/jonschoning/espial), [Instapaper](https://www.instapaper.com/), [LinkAce](https://www.linkace.org/), [Linkding](https://github.com/sissbruecker/linkding), [LinkWarden](https://linkwarden.app/), [Matrix](https://matrix.org), [Notion](https://www.notion.com/), [Ntfy](https://ntfy.sh/), [Nunux Keeper](https://keeper.nunux.org/), [Pinboard](https://pinboard.in/), [Pushover](https://pushover.net), [RainDrop](https://raindrop.io/), [Readeck](https://readeck.org/en/), [Readwise Reader](https://readwise.io/read), [RssBridge](https://rss-bridge.org/), [Shaarli](https://github.com/shaarli/Shaarli), [Shiori](https://github.com/go-shiori/shiori), [Slack](https://slack.com/), [Telegram](https://telegram.org), [Wallabag](https://www.wallabag.org/), etc.
- Bookmarklet for subscribing to websites directly from any web browser.
- Webhooks for real-time notifications or custom integrations.
- Compatibility with existing mobile applications using the Fever or Google Reader API.

View file

@ -1466,41 +1466,6 @@ func TestCreateAdmin(t *testing.T) {
}
}
func TestPocketConsumerKeyFromEnvVariable(t *testing.T) {
os.Clearenv()
os.Setenv("POCKET_CONSUMER_KEY", "something")
parser := NewParser()
opts, err := parser.ParseEnvironmentVariables()
if err != nil {
t.Fatalf(`Parsing failure: %v`, err)
}
expected := "something"
result := opts.PocketConsumerKey("default")
if result != expected {
t.Fatalf(`Unexpected POCKET_CONSUMER_KEY value, got %q instead of %q`, result, expected)
}
}
func TestPocketConsumerKeyFromUserPrefs(t *testing.T) {
os.Clearenv()
parser := NewParser()
opts, err := parser.ParseEnvironmentVariables()
if err != nil {
t.Fatalf(`Parsing failure: %v`, err)
}
expected := "default"
result := opts.PocketConsumerKey("default")
if result != expected {
t.Fatalf(`Unexpected POCKET_CONSUMER_KEY value, got %q instead of %q`, result, expected)
}
}
func TestMediaProxyMode(t *testing.T) {
os.Clearenv()
os.Setenv("MEDIA_PROXY_MODE", "all")
@ -1968,8 +1933,6 @@ func TestParseConfigFile(t *testing.T) {
DEBUG = yes
POCKET_CONSUMER_KEY= >#1234
Invalid text
`)
@ -1994,12 +1957,6 @@ Invalid text
t.Errorf(`Unexpected debug mode value, got %q`, opts.LogLevel())
}
expected := ">#1234"
result := opts.PocketConsumerKey("default")
if result != expected {
t.Errorf(`Unexpected POCKET_CONSUMER_KEY value, got %q instead of %q`, result, expected)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}

View file

@ -75,7 +75,6 @@ const (
defaultOauth2OidcProviderName = "OpenID Connect"
defaultOAuth2Provider = ""
defaultDisableLocalAuth = false
defaultPocketConsumerKey = ""
defaultHTTPClientTimeout = 20
defaultHTTPClientMaxBodySize = 15
defaultHTTPClientProxy = ""
@ -163,7 +162,6 @@ type Options struct {
oidcProviderName string
oauth2Provider string
disableLocalAuth bool
pocketConsumerKey string
httpClientTimeout int
httpClientMaxBodySize int64
httpClientProxyURL *url.URL
@ -245,7 +243,6 @@ func NewOptions() *Options {
oidcProviderName: defaultOauth2OidcProviderName,
oauth2Provider: defaultOAuth2Provider,
disableLocalAuth: defaultDisableLocalAuth,
pocketConsumerKey: defaultPocketConsumerKey,
httpClientTimeout: defaultHTTPClientTimeout,
httpClientMaxBodySize: defaultHTTPClientMaxBodySize * 1024 * 1024,
httpClientProxyURL: nil,
@ -579,14 +576,6 @@ func (o *Options) HasSchedulerService() bool {
return o.schedulerService
}
// PocketConsumerKey returns the Pocket Consumer Key if configured.
func (o *Options) PocketConsumerKey(defaultValue string) string {
if o.pocketConsumerKey != "" {
return o.pocketConsumerKey
}
return defaultValue
}
// HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
func (o *Options) HTTPClientTimeout() int {
return o.httpClientTimeout
@ -769,7 +758,6 @@ func (o *Options) SortedOptions(redactSecret bool) []*Option {
"OAUTH2_REDIRECT_URL": o.oauth2RedirectURL,
"OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
"DISABLE_LOCAL_AUTH": o.disableLocalAuth,
"POCKET_CONSUMER_KEY": redactSecretValue(o.pocketConsumerKey, redactSecret),
"POLLING_FREQUENCY": o.pollingFrequency,
"FORCE_REFRESH_INTERVAL": o.forceRefreshInterval,
"POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,

View file

@ -213,10 +213,6 @@ func (p *Parser) parseLines(lines []string) (err error) {
p.opts.adminPassword = parseString(value, defaultAdminPassword)
case "ADMIN_PASSWORD_FILE":
p.opts.adminPassword = readSecretFile(value, defaultAdminPassword)
case "POCKET_CONSUMER_KEY":
p.opts.pocketConsumerKey = parseString(value, defaultPocketConsumerKey)
case "POCKET_CONSUMER_KEY_FILE":
p.opts.pocketConsumerKey = readSecretFile(value, defaultPocketConsumerKey)
case "OAUTH2_USER_CREATION":
p.opts.oauth2UserCreationAllowed = parseBool(value, defaultOAuth2UserCreation)
case "OAUTH2_CLIENT_ID":

View file

@ -1090,4 +1090,13 @@ var migrations = []func(tx *sql.Tx, driver string) error{
_, err = tx.Exec(`ALTER TABLE users ADD COLUMN open_external_links_in_new_tab bool default 't'`)
return err
},
func(tx *sql.Tx, _ string) (err error) {
sql := `
ALTER TABLE integrations DROP COLUMN pocket_enabled;
ALTER TABLE integrations DROP COLUMN pocket_access_token;
ALTER TABLE integrations DROP COLUMN pocket_consumer_key;
`
_, err = tx.Exec(sql)
return err
},
}

View file

@ -29,7 +29,6 @@ const (
OAuth2CodeVerifierContextKey
FlashMessageContextKey
FlashErrorMessageContextKey
PocketRequestTokenContextKey
LastForceRefreshContextKey
ClientIPContextKey
GoogleReaderToken
@ -135,11 +134,6 @@ func FlashErrorMessage(r *http.Request) string {
return getContextStringValue(r, FlashErrorMessageContextKey)
}
// PocketRequestToken returns the Pocket Request Token if any.
func PocketRequestToken(r *http.Request) string {
return getContextStringValue(r, PocketRequestTokenContextKey)
}
// LastForceRefresh returns the last force refresh timestamp.
func LastForceRefresh(r *http.Request) int64 {
jsonStringValue := getContextStringValue(r, LastForceRefreshContextKey)

View file

@ -390,28 +390,6 @@ func TestFlashErrorMessage(t *testing.T) {
}
}
func TestPocketRequestToken(t *testing.T) {
r, _ := http.NewRequest("GET", "http://example.org", nil)
result := PocketRequestToken(r)
expected := ""
if result != expected {
t.Errorf(`Unexpected context value, got %q instead of %q`, result, expected)
}
ctx := r.Context()
ctx = context.WithValue(ctx, PocketRequestTokenContextKey, "request token")
r = r.WithContext(ctx)
result = PocketRequestToken(r)
expected = "request token"
if result != expected {
t.Errorf(`Unexpected context value, got %q instead of %q`, result, expected)
}
}
func TestClientIP(t *testing.T) {
r, _ := http.NewRequest("GET", "http://example.org", nil)

View file

@ -6,7 +6,6 @@ package integration // import "miniflux.app/v2/internal/integration"
import (
"log/slog"
"miniflux.app/v2/internal/config"
"miniflux.app/v2/internal/integration/apprise"
"miniflux.app/v2/internal/integration/betula"
"miniflux.app/v2/internal/integration/cubox"
@ -23,7 +22,6 @@ import (
"miniflux.app/v2/internal/integration/nunuxkeeper"
"miniflux.app/v2/internal/integration/omnivore"
"miniflux.app/v2/internal/integration/pinboard"
"miniflux.app/v2/internal/integration/pocket"
"miniflux.app/v2/internal/integration/pushover"
"miniflux.app/v2/internal/integration/raindrop"
"miniflux.app/v2/internal/integration/readeck"
@ -197,24 +195,6 @@ func SendEntry(entry *model.Entry, userIntegrations *model.Integration) {
}
}
if userIntegrations.PocketEnabled {
slog.Debug("Sending entry to Pocket",
slog.Int64("user_id", userIntegrations.UserID),
slog.Int64("entry_id", entry.ID),
slog.String("entry_url", entry.URL),
)
client := pocket.NewClient(config.Opts.PocketConsumerKey(userIntegrations.PocketConsumerKey), userIntegrations.PocketAccessToken)
if err := client.AddURL(entry.URL, entry.Title); err != nil {
slog.Error("Unable to send entry to Pocket",
slog.Int64("user_id", userIntegrations.UserID),
slog.Int64("entry_id", entry.ID),
slog.String("entry_url", entry.URL),
slog.Any("error", err),
)
}
}
if userIntegrations.LinkAceEnabled {
slog.Debug("Sending entry to LinkAce",
slog.Int64("user_id", userIntegrations.UserID),

View file

@ -1,132 +0,0 @@
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package pocket // import "miniflux.app/v2/internal/integration/pocket"
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"miniflux.app/v2/internal/version"
)
// Connector manages the authorization flow with Pocket to get a personal access token.
type Connector struct {
consumerKey string
}
// NewConnector returns a new Pocket Connector.
func NewConnector(consumerKey string) *Connector {
return &Connector{consumerKey}
}
// RequestToken fetches a new request token from Pocket API.
func (c *Connector) RequestToken(redirectURL string) (string, error) {
apiEndpoint := "https://getpocket.com/v3/oauth/request"
requestBody, err := json.Marshal(&createTokenRequest{ConsumerKey: c.consumerKey, RedirectURI: redirectURL})
if err != nil {
return "", fmt.Errorf("pocket: unable to encode request body: %v", err)
}
request, err := http.NewRequest(http.MethodPost, apiEndpoint, bytes.NewReader(requestBody))
if err != nil {
return "", fmt.Errorf("pocket: unable to create request: %v", err)
}
request.Header.Set("Content-Type", "application/json")
request.Header.Set("X-Accept", "application/json")
request.Header.Set("User-Agent", "Miniflux/"+version.Version)
httpClient := &http.Client{Timeout: defaultClientTimeout}
response, err := httpClient.Do(request)
if err != nil {
return "", fmt.Errorf("pocket: unable to send request: %v", err)
}
defer response.Body.Close()
if response.StatusCode >= 400 {
return "", fmt.Errorf("pocket: unable get request token: url=%s status=%d", apiEndpoint, response.StatusCode)
}
var result createTokenResponse
if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
return "", fmt.Errorf("pocket: unable to decode response: %v", err)
}
if result.Code == "" {
return "", errors.New("pocket: request token is empty")
}
return result.Code, nil
}
// AccessToken fetches a new access token once the end-user authorized the application.
func (c *Connector) AccessToken(requestToken string) (string, error) {
apiEndpoint := "https://getpocket.com/v3/oauth/authorize"
requestBody, err := json.Marshal(&authorizeRequest{ConsumerKey: c.consumerKey, Code: requestToken})
if err != nil {
return "", fmt.Errorf("pocket: unable to encode request body: %v", err)
}
request, err := http.NewRequest(http.MethodPost, apiEndpoint, bytes.NewReader(requestBody))
if err != nil {
return "", fmt.Errorf("pocket: unable to create request: %v", err)
}
request.Header.Set("Content-Type", "application/json")
request.Header.Set("X-Accept", "application/json")
request.Header.Set("User-Agent", "Miniflux/"+version.Version)
httpClient := &http.Client{Timeout: defaultClientTimeout}
response, err := httpClient.Do(request)
if err != nil {
return "", fmt.Errorf("pocket: unable to send request: %v", err)
}
defer response.Body.Close()
if response.StatusCode >= 400 {
return "", fmt.Errorf("pocket: unable get access token: url=%s status=%d", apiEndpoint, response.StatusCode)
}
var result authorizeReponse
if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
return "", fmt.Errorf("pocket: unable to decode response: %v", err)
}
if result.AccessToken == "" {
return "", errors.New("pocket: access token is empty")
}
return result.AccessToken, nil
}
// AuthorizationURL returns the authorization URL for the end-user.
func (c *Connector) AuthorizationURL(requestToken, redirectURL string) string {
return fmt.Sprintf(
"https://getpocket.com/auth/authorize?request_token=%s&redirect_uri=%s",
requestToken,
redirectURL,
)
}
type createTokenRequest struct {
ConsumerKey string `json:"consumer_key"`
RedirectURI string `json:"redirect_uri"`
}
type createTokenResponse struct {
Code string `json:"code"`
}
type authorizeRequest struct {
ConsumerKey string `json:"consumer_key"`
Code string `json:"code"`
}
type authorizeReponse struct {
AccessToken string `json:"access_token"`
Username string `json:"username"`
}

View file

@ -1,70 +0,0 @@
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package pocket // import "miniflux.app/v2/internal/integration/pocket"
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
"miniflux.app/v2/internal/version"
)
const defaultClientTimeout = 10 * time.Second
type Client struct {
consumerKey string
accessToken string
}
func NewClient(consumerKey, accessToken string) *Client {
return &Client{consumerKey, accessToken}
}
func (c *Client) AddURL(entryURL, entryTitle string) error {
if c.consumerKey == "" || c.accessToken == "" {
return fmt.Errorf("pocket: missing consumer key or access token")
}
apiEndpoint := "https://getpocket.com/v3/add"
requestBody, err := json.Marshal(&createItemRequest{
AccessToken: c.accessToken,
ConsumerKey: c.consumerKey,
Title: entryTitle,
URL: entryURL,
})
if err != nil {
return fmt.Errorf("pocket: unable to encode request body: %v", err)
}
request, err := http.NewRequest(http.MethodPost, apiEndpoint, bytes.NewReader(requestBody))
if err != nil {
return fmt.Errorf("pocket: unable to create request: %v", err)
}
request.Header.Set("Content-Type", "application/json")
request.Header.Set("User-Agent", "Miniflux/"+version.Version)
httpClient := &http.Client{Timeout: defaultClientTimeout}
response, err := httpClient.Do(request)
if err != nil {
return fmt.Errorf("pocket: unable to send request: %v", err)
}
defer response.Body.Close()
if response.StatusCode >= 400 {
return fmt.Errorf("pocket: unable to create item: url=%s status=%d", apiEndpoint, response.StatusCode)
}
return nil
}
type createItemRequest struct {
AccessToken string `json:"access_token"`
ConsumerKey string `json:"consumer_key"`
Title string `json:"title,omitempty"`
URL string `json:"url"`
}

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Es gibt keine Artikel, die diesem Tag entsprechen.",
"alert.no_unread_entry": "Es existiert kein ungelesener Artikel.",
"alert.no_user": "Sie sind der einzige Benutzer.",
"alert.pocket_linked": "Ihr Pocket-Konto ist jetzt verknüpft!",
"alert.prefs_saved": "Einstellungen gespeichert!",
"alert.too_many_feeds_refresh": [
"Sie haben zu viele Aktualisierungen ausgelöst. Bitte warten Sie %d Minute, bevor Sie es erneut versuchen.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux kann die Webseite aufgrund eines Netzwerk-Fehlers nicht erreichen: %v",
"error.network_timeout": "Die Webseite ist zu langsam und die Anfrage ist abgelaufen: %v.",
"error.password_min_length": "Wenigstens 6 Zeichen müssen genutzt werden.",
"error.pocket_access_token": "Zugriffstoken konnte nicht von Pocket abgerufen werden!",
"error.pocket_request_token": "Anfrage-Token konnte nicht von Pocket abgerufen werden!",
"error.proxy_url_not_empty": "Die Proxy-URL darf nicht leer sein.",
"error.settings_block_rule_fieldname_invalid": "Ungültige Blockierregel: Regel #%d hat keinen gültigen Feldnamen (Optionen: %s)",
"error.settings_block_rule_invalid_regex": "Ungültige Blockierregel: Das Muster für Regel #%d ist kein zulässiger regulärer Ausdruck",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Lesezeichen als ungelesen markieren",
"form.integration.pinboard_tags": "Pinboard-Tags",
"form.integration.pinboard_token": "Pinboard-API-Token",
"form.integration.pocket_access_token": "Pocket-Zugangstoken",
"form.integration.pocket_activate": "Einträge in Pocket speichern",
"form.integration.pocket_connect_link": "Verbinden Sie Ihr Pocket-Konto",
"form.integration.pocket_consumer_key": "Pocket-Verbraucher-Schlüssel",
"form.integration.pushover_activate": "Einträge an Pushover senden",
"form.integration.pushover_device": "Pushovergerät (optional)",
"form.integration.pushover_prefix": "Pushover-URL-Präfix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Δεν υπάρχουν αντικείμενα που να ταιριάζουν με αυτή την ετικέτα.",
"alert.no_unread_entry": "Δεν υπάρχουν μη αναγνωσμένα άρθρα.",
"alert.no_user": "Είστε ο μόνος χρήστης.",
"alert.pocket_linked": "Ο λογαριασμός Pocket είναι τώρα συνδεδεμένος!",
"alert.prefs_saved": "Οι προτιμήσεις αποθηκεύτηκαν!",
"alert.too_many_feeds_refresh": [
"Έχετε ενεργοποιήσει πάρα πολλές ανανεώσεις ροών. Παρακαλώ περιμένετε %d λεπτό πριν προσπαθήσετε ξανά.",
@ -133,8 +132,6 @@
"error.network_operation": "Το Miniflux δεν μπορεί να φτάσει σε αυτόν τον ιστότοπο λόγω σφάλματος δικτύου: %v.",
"error.network_timeout": "Αυτός ο ιστότοπος είναι πολύ αργός και το αίτημα έληξε: %v",
"error.password_min_length": "Ο κωδικός πρόσβασης πρέπει να έχει τουλάχιστον 6 χαρακτήρες.",
"error.pocket_access_token": "Δεν είναι δυνατή η λήψη του access token από το Pocket!",
"error.pocket_request_token": "Δεν είναι δυνατή η λήψη του request token από το Pocket!",
"error.proxy_url_not_empty": "Η διεύθυνση URL του διακομιστή μεσολάβησης δεν μπορεί να είναι κενή.",
"error.settings_block_rule_fieldname_invalid": "Μη έγκυρος κανόνας αποκλεισμού: ο κανόνας #%d λείπει ένα έγκυρο όνομα πεδίου (Επιλογές: %s)",
"error.settings_block_rule_invalid_regex": "Μη έγκυρος κανόνας αποκλεισμού: το μοτίβο του κανόνα #%d δεν είναι έγκυρη κανονική έκφραση",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Σημείωση του σελιδοδείκτη ως μη αναγνωσμένου",
"form.integration.pinboard_tags": "Ετικέτες Pinboard",
"form.integration.pinboard_token": "Pinboard API Token",
"form.integration.pocket_access_token": "Pocket Access Token",
"form.integration.pocket_activate": "Αποθήκευση άρθρων στο Pocket",
"form.integration.pocket_connect_link": "Συνδέστε τον λογαριασμό Pocket σας",
"form.integration.pocket_consumer_key": "Pocket Consumer Key",
"form.integration.pushover_activate": "Προώθηση καταχωρήσεων στο Pushover",
"form.integration.pushover_device": "Συσκευή Pushover (προαιρετικό)",
"form.integration.pushover_prefix": "Πρόθεμα διεύθυνσης URL Pushover (προαιρετικό)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "There are no entries matching this tag.",
"alert.no_unread_entry": "There are no unread entries.",
"alert.no_user": "You are the only user.",
"alert.pocket_linked": "Your Pocket account is now linked!",
"alert.prefs_saved": "Preferences saved!",
"alert.too_many_feeds_refresh": [
"You have triggered too many feed refreshes. Please wait %d minute before trying again.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux is not able to reach this website due to a network error: %v.",
"error.network_timeout": "This website is too slow and the request timed out: %v",
"error.password_min_length": "The password must have at least 6 characters.",
"error.pocket_access_token": "Unable to fetch access token from Pocket!",
"error.pocket_request_token": "Unable to fetch request token from Pocket!",
"error.proxy_url_not_empty": "The proxy URL cannot be empty.",
"error.settings_block_rule_fieldname_invalid": "Invalid Block rule: rule #%d is missing a valid field name (Options: %s)",
"error.settings_block_rule_invalid_regex": "Invalid Block rule: rule #%d's pattern is not a valid regex",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Mark bookmark as unread",
"form.integration.pinboard_tags": "Pinboard Tags",
"form.integration.pinboard_token": "Pinboard API Token",
"form.integration.pocket_access_token": "Pocket Access Token",
"form.integration.pocket_activate": "Save entries to Pocket",
"form.integration.pocket_connect_link": "Connect your Pocket account",
"form.integration.pocket_consumer_key": "Pocket Consumer Key",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "No hay artículos con esta etiqueta.",
"alert.no_unread_entry": "No hay artículos sin leer.",
"alert.no_user": "Eres el único usuario.",
"alert.pocket_linked": "¡Tu cuenta de Pocket ya está vinculada!",
"alert.prefs_saved": "¡Las preferencias se han guardado!",
"alert.too_many_feeds_refresh": [
"Has activado demasiadas actualizaciones del feed. Espere %d minuto antes de volver a intentarlo.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux no puede acceder a este sitio web debido a un error de red: %v.",
"error.network_timeout": "Este sitio web es demasiado lento y se agotó el tiempo de espera de la solicitud: %v",
"error.password_min_length": "La contraseña debería tener al menos 6 caracteres.",
"error.pocket_access_token": "Incapaz de obtener un token de acceso de Pocket!",
"error.pocket_request_token": "Incapaz de obtener un token de solicitud de Pocket!",
"error.proxy_url_not_empty": "The proxy URL cannot be empty.",
"error.settings_block_rule_fieldname_invalid": "Regla de bloqueo no válida: a la regla #%d le falta un nombre de campo válido (Opciones: %s)",
"error.settings_block_rule_invalid_regex": "Regla de bloqueo no válida: el patrón de la regla #%d no es una expresión regular válida",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Marcar marcador como no leído",
"form.integration.pinboard_tags": "Etiquetas de Pinboard",
"form.integration.pinboard_token": "Token de API de Pinboard",
"form.integration.pocket_access_token": "Token de acceso de Pocket",
"form.integration.pocket_activate": "Enviar artículos a Pocket",
"form.integration.pocket_connect_link": "Conectar a la cuenta de Pocket",
"form.integration.pocket_consumer_key": "Clave del consumidor de Pocket",
"form.integration.pushover_activate": "Enviar artículos a Pushover",
"form.integration.pushover_device": "Dispositivo Pushover (opcional)",
"form.integration.pushover_prefix": "Prefijo de URL de Pushover (opcional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Tätä tunnistetta vastaavia merkintöjä ei ole.",
"alert.no_unread_entry": "Ei ole lukemattomia artikkeleita.",
"alert.no_user": "Olet ainoa käyttäjä.",
"alert.pocket_linked": "Pocket-tilisi on nyt linkitetty!",
"alert.prefs_saved": "Asetukset tallennettu!",
"alert.too_many_feeds_refresh": [
"Olet käynnistänyt liian monta syötteen päivitystä. Odota %d minuutti ennen kuin yrität uudelleen.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux is not able to reach this website due to a network error: %v.",
"error.network_timeout": "This website is too slow and the request timed out: %v",
"error.password_min_length": "Salasanassa on oltava vähintään 6 merkkiä.",
"error.pocket_access_token": "Unable to fetch access token from Pocket!",
"error.pocket_request_token": "Unable to fetch request token from Pocket!",
"error.proxy_url_not_empty": "The proxy URL cannot be empty.",
"error.settings_block_rule_fieldname_invalid": "Invalid Block rule: rule #%d is missing a valid field name (Options: %s)",
"error.settings_block_rule_invalid_regex": "Invalid Block rule: rule #%d's pattern is not a valid regex",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Merkitse kirjanmerkki lukemattomaksi",
"form.integration.pinboard_tags": "Pinboard-tagit",
"form.integration.pinboard_token": "Pinboard API-tunnus",
"form.integration.pocket_access_token": "Pocket-käyttöoikeustunnus",
"form.integration.pocket_activate": "Tallenna artikkelit Pocketiin",
"form.integration.pocket_connect_link": "Yhdistä Pocket-tilisi",
"form.integration.pocket_consumer_key": "Pocket Consumer Key",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Il n'y a aucun article correspondant à ce tag.",
"alert.no_unread_entry": "Il n'y a rien de nouveau à lire.",
"alert.no_user": "Vous êtes le seul utilisateur.",
"alert.pocket_linked": "Votre compte Pocket est maintenant connecté !",
"alert.prefs_saved": "Préférences sauvegardées !",
"alert.too_many_feeds_refresh": [
"Vous avez déclenché trop d'actualisations de flux. Veuillez attendre %d minute avant de réessayer.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux n'est pas en mesure de se connecter à ce site web à cause d'un problème réseau : %v.",
"error.network_timeout": "Ce site web est trop lent à répondre : %v.",
"error.password_min_length": "Vous devez utiliser au moins 6 caractères pour le mot de passe.",
"error.pocket_access_token": "Impossible de récupérer le jeton d'accès depuis Pocket !",
"error.pocket_request_token": "Impossible de récupérer le jeton d'accès depuis Pocket !",
"error.proxy_url_not_empty": "L'URL du proxy ne peut pas être vide.",
"error.settings_block_rule_fieldname_invalid": "Règle de blocage invalide : la règle n°%d ne contient pas un nom de champ valide (Options : %s)",
"error.settings_block_rule_invalid_regex": "Règle de blocage invalide : le motif de la règle n°%d n'est pas une expression régulière valide",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Marquer le lien comme non lu",
"form.integration.pinboard_tags": "Libellés de Pinboard",
"form.integration.pinboard_token": "Jeton de sécurité de l'API de Pinboard",
"form.integration.pocket_access_token": "Jeton d'accès de l'API de Pocket",
"form.integration.pocket_activate": "Sauvegarder les articles vers Pocket",
"form.integration.pocket_connect_link": "Connectez votre compte Pocket",
"form.integration.pocket_consumer_key": "Clé de l'API de Pocket",
"form.integration.pushover_activate": "Envoyer les articles vers Pushover",
"form.integration.pushover_device": "Nom de l'appareil Pushover (facultatif)",
"form.integration.pushover_prefix": "URL de préfixe Pushover (facultatif)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "इस टैग से मेल खाती कोई प्रविष्टियाँ नहीं हैं।",
"alert.no_unread_entry": "कोई अपठित वस्तुत नहीं है।",
"alert.no_user": "आप एकमात्र उपयोगकर्ता हैं।",
"alert.pocket_linked": "आपका पॉकेट खाता अब लिंक हो गया है!",
"alert.prefs_saved": "प्राथमिकताएं सहेजी गईं!",
"alert.too_many_feeds_refresh": [
"आपने बहुत अधिक फ़ीड ताज़ा करने की प्रक्रिया शुरू कर दी है। कृपया पुनः प्रयास करने से पहले %d मिनट प्रतीक्षा करें।",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux is not able to reach this website due to a network error: %v.",
"error.network_timeout": "This website is too slow and the request timed out: %v",
"error.password_min_length": "पासवर्ड में कम से कम 6 अक्षर होने चाहिए।",
"error.pocket_access_token": "पॉकेट से एक्सेस टोकन प्राप्त करने में असमर्थ!",
"error.pocket_request_token": "पॉकेट से अनुरोध टोकन लाने में असमर्थ!",
"error.proxy_url_not_empty": "The proxy URL cannot be empty.",
"error.settings_block_rule_fieldname_invalid": "Invalid Block rule: rule #%d is missing a valid field name (Options: %s)",
"error.settings_block_rule_invalid_regex": "Invalid Block rule: rule #%d's pattern is not a valid regex",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "बुकमार्क को अपठित के रूप में चिह्नित करें",
"form.integration.pinboard_tags": "पिनबोर्ड टैग",
"form.integration.pinboard_token": "पिनबोर्ड एपीआई टोकन",
"form.integration.pocket_access_token": "पॉकेट एक्सेस टोकन",
"form.integration.pocket_activate": "विषय-कविता को पॉकेट में सहेजें",
"form.integration.pocket_connect_link": "अपना पॉकेट खाता कनेक्ट करें",
"form.integration.pocket_consumer_key": "पॉकेट उपभोक्ता कुंजी",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Tidak ada entri yang cocok dengan tag ini.",
"alert.no_unread_entry": "Belum ada artikel yang dibaca.",
"alert.no_user": "Anda adalah satu-satunya pengguna.",
"alert.pocket_linked": "Akun Pocket Anda sudah terhubung!",
"alert.prefs_saved": "Preferensi disimpan!",
"alert.too_many_feeds_refresh": [
"Anda terlalu banyak menyegarkan umpan. Mohon tunggu %d menit sebelum mencoba lagi."
@ -130,8 +129,6 @@
"error.network_operation": "Miniflux tidak dapat menjangkau situs ini dikarenakan galat jaringan: %v.",
"error.network_timeout": "Situs ini terlalu lambat dan permintaan ke situs terlalu lama: %v",
"error.password_min_length": "Kata sandi harus memiliki setidaknya 6 karakter.",
"error.pocket_access_token": "Tidak bisa mendapatkan token akses dari Pocket!",
"error.pocket_request_token": "Tidak bisa mendapatkan token permintaan dari Pocket!",
"error.proxy_url_not_empty": "URL proksi tidak boleh kosong.",
"error.settings_block_rule_fieldname_invalid": "Aturan blokir tidak valid: aturan #%d tidak mempunyai nama bidang yang valid (Opsi: %s)",
"error.settings_block_rule_invalid_regex": "Aturan blokir tidak valid: aturan pola #%d bukan ekspresi regular (regex) yang valid",
@ -277,10 +274,6 @@
"form.integration.pinboard_bookmark": "Tandai markah sebagai belum dibaca",
"form.integration.pinboard_tags": "Tanda di Pinboard",
"form.integration.pinboard_token": "Token API Pinboard",
"form.integration.pocket_access_token": "Token Akses Pocket",
"form.integration.pocket_activate": "Simpan artikel ke Pocket",
"form.integration.pocket_connect_link": "Hubungkan akun Pocket Anda",
"form.integration.pocket_consumer_key": "Kunci Pelanggan Pocket",
"form.integration.pushover_activate": "Kirim artikel ke Pushover",
"form.integration.pushover_device": "Perangkat Pushover (opsional)",
"form.integration.pushover_prefix": "Prefiks URL Pushover (opsional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Non ci sono voci corrispondenti a questo tag.",
"alert.no_unread_entry": "Nessun articolo da leggere.",
"alert.no_user": "Tu sei l'unico utente.",
"alert.pocket_linked": "Il tuo account Pocket ora è collegato!",
"alert.prefs_saved": "Preferenze salvate!",
"alert.too_many_feeds_refresh": [
"Hai richiesto troppi aggiornamenti dei feed. Attendi %d minuto prima di riprovare.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux non riesce a raggiungere questo sito web a causa di un errore di rete: %v.",
"error.network_timeout": "Questo sito web è troppo lento e la richiesta è scaduta: %v",
"error.password_min_length": "La password deve contenere almeno 6 caratteri.",
"error.pocket_access_token": "Non sono riuscito ad ottenere l'access token da Pocket!",
"error.pocket_request_token": "Non sono riuscito ad ottenere il request token da Pocket!",
"error.proxy_url_not_empty": "L'URL del proxy non può essere vuoto.",
"error.settings_block_rule_fieldname_invalid": "Invalid Block rule: rule #%d is missing a valid field name (Options: %s)",
"error.settings_block_rule_invalid_regex": "Invalid Block rule: rule #%d's pattern is not a valid regex",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Segna i preferiti come non letti",
"form.integration.pinboard_tags": "Tag di Pinboard",
"form.integration.pinboard_token": "Token dell'API di Pinboard",
"form.integration.pocket_access_token": "Access token dell'account Pocket",
"form.integration.pocket_activate": "Salva gli articoli su Pocket",
"form.integration.pocket_connect_link": "Collega il tuo account Pocket",
"form.integration.pocket_consumer_key": "Consumer key dell'account Pocket",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "このタグに一致するエントリーはありません。",
"alert.no_unread_entry": "未読の記事はありません。",
"alert.no_user": "あなたが唯一のユーザーです。",
"alert.pocket_linked": "Pocket アカウントとリンクされました!",
"alert.prefs_saved": "設定情報は保存されました!",
"alert.too_many_feeds_refresh": [
"フィードの更新を要求しすぎました。%d 分後に再度お試しください。"
@ -130,8 +129,6 @@
"error.network_operation": "Miniflux はネットワークエラーのためこのウェブサイトに到達できません: %v.",
"error.network_timeout": "このウェブサイトは応答が遅すぎるためタイムアウトしました: %v",
"error.password_min_length": "パスワードは6文字以上である必要があります。",
"error.pocket_access_token": "Pocket の access token が取得できません!",
"error.pocket_request_token": "Pocket の request token が取得できません!",
"error.proxy_url_not_empty": "プロキシURLを空にすることはできません。",
"error.settings_block_rule_fieldname_invalid": "Invalid Block rule: rule #%d is missing a valid field name (Options: %s)",
"error.settings_block_rule_invalid_regex": "Invalid Block rule: rule #%d's pattern is not a valid regex",
@ -277,10 +274,6 @@
"form.integration.pinboard_bookmark": "ブックマークを未読にする",
"form.integration.pinboard_tags": "Pinboard の Tag",
"form.integration.pinboard_token": "Pinboard の API Token",
"form.integration.pocket_access_token": "Pocket の Access Token",
"form.integration.pocket_activate": "Pocket に記事を保存する",
"form.integration.pocket_connect_link": "Pocket account に接続",
"form.integration.pocket_consumer_key": "Pocket の Consumer Key",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Bô kah chit ê khan-á ū hû-ha̍p ê siau-sit",
"alert.no_unread_entry": "Chit-má ah-bô tha̍k kè ê siau-sit",
"alert.no_user": "Lí sī ûi-it ê sú-iōng-lâng",
"alert.pocket_linked": "Í-keng kā lí ê Pocket kháu-chō kiat chòe-hé--ah!",
"alert.prefs_saved": "Siat-tēng í-keng pó-chûn--ah!",
"alert.too_many_feeds_refresh": [
"Lí í-keng ín-khí siuⁿ chōe pái siau-sit lâi-goân ōaⁿ-sin, chhiáⁿ tán-hāu %d hun-cheng āu koh chhì-khòaⁿ-māi."
@ -130,8 +129,6 @@
"error.network_operation": "Miniflux bô-hoat-tō͘ liân kàu chit ê bāng-chām, ū khó-lêng sī bāng-lō͘ būn-tôe: %v.",
"error.network_timeout": "Chit ê bāng-chām ê hôe-èng siuⁿ bān, chhéng-kiû chhiau-kè sî-kan: %v.",
"error.password_min_length": "Chhiáⁿ chì-chió ài su-li̍p la̍k ê lī goân.",
"error.pocket_access_token": "Bô-hoat-tō͘ ùi Pocket thê tio̍h access token",
"error.pocket_request_token": "Bô-hoat-tō͘ ùi Pocket thê tio̍h request token",
"error.proxy_url_not_empty": "Proxy URL bōe-sái sī khang--ê.",
"error.settings_block_rule_fieldname_invalid": "Bô-hāu ê hong-só kui-chek: kui-chek #%d khiàm ū-hāu ê lân-ūi miâ (e-sai ê soán-hāng: %s)",
"error.settings_block_rule_invalid_regex": "Bô-hāu ê hong-só kui-chek: kui-chek #%d ê bô͘-sek m̄ sī ha̍p-hoat ê chiàⁿ-kui piáu-ta̍t sek",
@ -277,10 +274,6 @@
"form.integration.pinboard_bookmark": "Chù chòe ah-bōe tha̍k",
"form.integration.pinboard_tags": "Pinboard khan-á",
"form.integration.pinboard_token": "Pinboard API Token",
"form.integration.pocket_access_token": "Pocket token",
"form.integration.pocket_activate": "Pó-chûn siau-sit kàu Pocket",
"form.integration.pocket_connect_link": "Kah Pocket kháu-chō kiat chòe-hé",
"form.integration.pocket_consumer_key": "Pocket sú-iōng-lâng só-sî",
"form.integration.pushover_activate": "Pó-chûn siau-sit kàu Pushover",
"form.integration.pushover_device": "Pushover ki-hì (soán thiⁿ)",
"form.integration.pushover_prefix": "Pushover URL tó͘-bí (soán thiⁿ)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Er zijn geen artikelen die overeenkomen met deze tag.",
"alert.no_unread_entry": "Er zijn geen ongelezen artikelen.",
"alert.no_user": "Je bent de enige gebruiker.",
"alert.pocket_linked": "Jouw Pocket-account is nu gekoppeld!",
"alert.prefs_saved": "Instellingen opgeslagen!",
"alert.too_many_feeds_refresh": [
"Je hebt te veel feed-vernieuwingen getriggered. Wacht aub %d minuut voor opnieuw proberen.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux kan deze website niet bereiken vanwege een netwerkfout: %v.",
"error.network_timeout": "Deze website is te traag en de aanvraag gaf timeout: %v",
"error.password_min_length": "Minimaal 6 tekens gebruiken.",
"error.pocket_access_token": "Kon geen toegangstoken ophalen van Pocket!",
"error.pocket_request_token": "Kon geen aanvraagtoken ophalen van Pocket!",
"error.proxy_url_not_empty": "De proxy-URL mag niet leeg zijn.",
"error.settings_block_rule_fieldname_invalid": "Ongeldige blokkeerregel: regel #%d mist een geldige veldnaam (Opties: %s)",
"error.settings_block_rule_invalid_regex": "Ongeldige blokkeerregel: het patroon van regel #%d is geen geldige regex",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Markeer favoriet als ongelezen",
"form.integration.pinboard_tags": "Pinboard tags",
"form.integration.pinboard_token": "Pinboard API token",
"form.integration.pocket_access_token": "Pocket Access Token",
"form.integration.pocket_activate": "Artikelen opslaan in Pocket",
"form.integration.pocket_connect_link": "Verbind je Pocket-account",
"form.integration.pocket_consumer_key": "Pocket Consumer Key",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Brak wpisów pasujących do tego znacznika.",
"alert.no_unread_entry": "Nie ma żadnych nieprzeczytanych wpisów.",
"alert.no_user": "Jesteś jedynym użytkownikiem.",
"alert.pocket_linked": "Twoje konto Pocket jest teraz połączone!",
"alert.prefs_saved": "Ustawienia zapisane!",
"alert.too_many_feeds_refresh": [
"Wykonano zbyt wiele odświeżeń kanału. Poczekaj %d minutę przed ponowną próbą.",
@ -136,8 +135,6 @@
"error.network_operation": "Miniflux nie może połączyć się z tą witryną z powodu błędu sieci: %v.",
"error.network_timeout": "Ta witryna internetowa jest zbyt wolna i upłynął limit czasu żądania: %v",
"error.password_min_length": "Musisz użyć co najmniej 6 znaków.",
"error.pocket_access_token": "Nie można pobrać tokena dostępu z Pocket!",
"error.pocket_request_token": "Nie można pobrać tokena żądania z Pocket!",
"error.proxy_url_not_empty": "Adres URL serwera proxy nie może być pusty.",
"error.settings_block_rule_fieldname_invalid": "Nieprawidłowa reguła blokowania: w regule #%d brakuje prawidłowej nazwy pola (opcje: %s)",
"error.settings_block_rule_invalid_regex": "Nieprawidłowa reguła blokowania: wzór reguły #%d nie jest prawidłowym wyrażeniem regularnym",
@ -283,10 +280,6 @@
"form.integration.pinboard_bookmark": "Zaznacz zakładkę jako nieprzeczytaną",
"form.integration.pinboard_tags": "Znaczniki Pinboard",
"form.integration.pinboard_token": "Token API do Pinboard",
"form.integration.pocket_access_token": "Token dostępu do Pocket",
"form.integration.pocket_activate": "Zapisuj wpisy w Pocket",
"form.integration.pocket_connect_link": "Połącz swoje konto Pocket",
"form.integration.pocket_consumer_key": "Klucz klienta do Pocket",
"form.integration.pushover_activate": "Prześlij wpisy do Pushover",
"form.integration.pushover_device": "Urządzenie Pushover (opcjonalne)",
"form.integration.pushover_prefix": "Prefiks adresu URL Pushover (opcjonalny)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Não há itens que correspondam a esta etiqueta.",
"alert.no_unread_entry": "Não há itens não lidos.",
"alert.no_user": "Você é o único usuário.",
"alert.pocket_linked": "Sua conta do Pocket está vinculada!",
"alert.prefs_saved": "Suas preferências foram salvas!",
"alert.too_many_feeds_refresh": [
"Você acionou muitas atualizações de fontes. Por favor, aguarde %d minuto antes de tentar novamente.",
@ -133,8 +132,6 @@
"error.network_operation": "O Miniflux não conseguiu acessar este site devido a um erro de rede: %v.",
"error.network_timeout": "Este site está muito lento e a solicitação expirou: %v",
"error.password_min_length": "A senha deve ter no mínimo 6 caracteres.",
"error.pocket_access_token": "Não foi possível obter um token de acesso no Pocket!",
"error.pocket_request_token": "Não foi possível obter um pedido de token no Pocket!",
"error.proxy_url_not_empty": "A URL do proxy não pode estar vazia.",
"error.settings_block_rule_fieldname_invalid": "Regra de bloqueio inválida: a regra #%d está sem um nome de campo válido (Opções: %s)",
"error.settings_block_rule_invalid_regex": "Regra de bloqueio inválida: o padrão da regra #%d não é uma expressão regular válida",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Salvar marcador como não lido",
"form.integration.pinboard_tags": "Etiquetas (tags) do Pinboard",
"form.integration.pinboard_token": "Token de API do Pinboard",
"form.integration.pocket_access_token": "Token de acesso do Pocket",
"form.integration.pocket_activate": "Salvar itens no Pocket",
"form.integration.pocket_connect_link": "Conectar a conta do Pocket",
"form.integration.pocket_consumer_key": "Chave de consumo (Consumer Key) do Pocket",
"form.integration.pushover_activate": "Enviar itens para o Pushover",
"form.integration.pushover_device": "Dispositivo Pushover (opcional)",
"form.integration.pushover_prefix": "Prefixo da URL do Pushover (opcional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Nu sunt înregistrări pentru această etichetă.",
"alert.no_unread_entry": "Nu sunt intrări necitite.",
"alert.no_user": "Sunteți singurul utilizator.",
"alert.pocket_linked": "Contul dvs. Pocket este atașat!",
"alert.prefs_saved": "Preferințe salvate!",
"alert.too_many_feeds_refresh": [
"Ați activat actualizarea a prea multe fluxuri de informații. Vă rog să așteptați %d minut înainte de a reîncerca.",
@ -136,8 +135,6 @@
"error.network_operation": "Miniflux nu poate ajunge la acest site din cauza unei erori de rețea: %v.",
"error.network_timeout": "Acest site web este prea lent și conexiunea nu s-a realizat: %v",
"error.password_min_length": "Parola trebuie să aibă cel puțin 6 caractere.",
"error.pocket_access_token": "Nu poate obține token-ul de acces de la Pocket!",
"error.pocket_request_token": "Nu poate obține token-ul solicitat de la Pocket!",
"error.proxy_url_not_empty": "URL-ul proxy nu poate fi gol.",
"error.settings_block_rule_fieldname_invalid": "Regulă de bloc invalidă: regulii #%d îi lipsește un nume valid de câmp (Opțiuni: %s)",
"error.settings_block_rule_invalid_regex": "Regulă de bloc invalidă: modelul regulii #%d's nu este regex valid",
@ -283,10 +280,6 @@
"form.integration.pinboard_bookmark": "Marchează bookmark ca necitit",
"form.integration.pinboard_tags": "Etichete Pinboard",
"form.integration.pinboard_token": "Token API Pinboard",
"form.integration.pocket_access_token": "Token Acces Pocket",
"form.integration.pocket_activate": "Salvează înregistrările în Pocket",
"form.integration.pocket_connect_link": "Conectează contul Pocket personal",
"form.integration.pocket_consumer_key": "Cheie Consumator Pocket",
"form.integration.pushover_activate": "Activează Pushover",
"form.integration.pushover_device": "Dispozitiv Pushover (opțional)",
"form.integration.pushover_prefix": "Prefix Pushover (opțional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Нет записей, соответствующих этому тегу.",
"alert.no_unread_entry": "Нет непрочитанных статей.",
"alert.no_user": "Вы единственный пользователь.",
"alert.pocket_linked": "Ваш Pocket аккаунт теперь привязан!",
"alert.prefs_saved": "Предпочтения сохранены!",
"alert.too_many_feeds_refresh": [
"Вы запустили слишком много обновлений подписок. Подождите %d минуту для нового запуска",
@ -136,8 +135,6 @@
"error.network_operation": "Miniflux не может открыть сайт из-за ошибки сети: %v.",
"error.network_timeout": "Этот сайт слишком медленный и время ожидания запроса истекло: %v",
"error.password_min_length": "Вы должны использовать минимум 6 символов.",
"error.pocket_access_token": "Не удалось получить ключ доступа от Pocket!",
"error.pocket_request_token": "Не удалось получить request token от Pocket!",
"error.proxy_url_not_empty": "URL прокси не может быть пустым.",
"error.settings_block_rule_fieldname_invalid": "Недопустимое правило блокировки: у правила #%d отсутствует корректное имя поля (Возможные варианты: %s)",
"error.settings_block_rule_invalid_regex": "Недопустимое правило блокировки: шаблон правила #%d не является корректным регулярным выражением",
@ -283,10 +280,6 @@
"form.integration.pinboard_bookmark": "Помечать закладки как непрочитанное",
"form.integration.pinboard_tags": "Теги Pinboard",
"form.integration.pinboard_token": "Токен Pinboard API",
"form.integration.pocket_access_token": "Ключ доступа к Pocket",
"form.integration.pocket_activate": "Сохранять статьи в Pocket",
"form.integration.pocket_connect_link": "Подключить аккаунт Pocket",
"form.integration.pocket_consumer_key": "Ключ пользователя Pocket",
"form.integration.pushover_activate": "Отправлять статьи Pushover",
"form.integration.pushover_device": "Устройство Pushover (опционально)",
"form.integration.pushover_prefix": "URL-префикс Pushover (опционально)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Bu etiketle eşleşen hiçbir giriş yok.",
"alert.no_unread_entry": "Okunmamış makele yok",
"alert.no_user": "Tek kullanıcı sizsiniz",
"alert.pocket_linked": "Pocket hesabınız artık bağlandı.",
"alert.prefs_saved": "Tercihler kaydedildi!",
"alert.too_many_feeds_refresh": [
"Çok fazla besleme yenilemesi başlattınız. Tekrar denemeden önce lütfen %d dakika bekleyin.",
@ -133,8 +132,6 @@
"error.network_operation": "Miniflux bir ağ hatası nedeniyle bu websitesine erişemiyor: %v.",
"error.network_timeout": "Bu websitesi çok yavaş ve istek zaman aşımına uğradı: %v",
"error.password_min_length": "Parola en az 6 karakter içermeli.",
"error.pocket_access_token": "Pocket'tan access tokeni alınamıyor!",
"error.pocket_request_token": "Pocket'tan request tokeni alınamıyor!",
"error.proxy_url_not_empty": "Proxy URL'si boş olamaz.",
"error.settings_block_rule_fieldname_invalid": "Geçersiz Engelleme kuralı: #%d kuralında geçerli bir alan adı eksik (Seçenekler: %s)",
"error.settings_block_rule_invalid_regex": "Geçersiz Engelleme kuralı: #%d kuralı modeli geçerli bir düzenli ifade değil",
@ -280,10 +277,6 @@
"form.integration.pinboard_bookmark": "Yer imini okunmadı olarak işaretle",
"form.integration.pinboard_tags": "Pinboard Etiketleri",
"form.integration.pinboard_token": "Pinboard API Token",
"form.integration.pocket_access_token": "Pocket Access Token",
"form.integration.pocket_activate": "Makaleleri Pocket'a kaydet",
"form.integration.pocket_connect_link": "Pocket hesabını bağla",
"form.integration.pocket_consumer_key": "Pocket Consumer Anahtarı",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "Немає записів, що відповідають цьому тегу.",
"alert.no_unread_entry": "Немає непрочитаних статей.",
"alert.no_user": "Ви єдиний користувач.",
"alert.pocket_linked": "Тепер ваш обліковий запис Pocket підключено!",
"alert.prefs_saved": "Уподобання збережено!",
"alert.too_many_feeds_refresh": [
"Ви запустили надто багато оновлень стрічок. Будь ласка, зачекайте %d хвилину перед повторною спробою.",
@ -136,8 +135,6 @@
"error.network_operation": "Miniflux не може отримати доступ до цього сайту через помилку мережі: %v.",
"error.network_timeout": "Цей сайт занадто повільний і запит перевищив час очікування: %v",
"error.password_min_length": "Пароль має складати щонайменше 6 символів.",
"error.pocket_access_token": "Не вдалося отримати токен доступу з Pocket!",
"error.pocket_request_token": "Не вдалося отримати токен доступу з Pocket!",
"error.proxy_url_not_empty": "Proxy URL не може бути порожнім.",
"error.settings_block_rule_fieldname_invalid": "Недійсне правило блокування: у правилі #%d відсутнє коректне ім’я поля (Опції: %s)",
"error.settings_block_rule_invalid_regex": "Недійсне правило блокування: шаблон правила #%d не є коректним регулярним виразом",
@ -283,10 +280,6 @@
"form.integration.pinboard_bookmark": "Відмічати закладку як непрочитану",
"form.integration.pinboard_tags": "Теги для Pinboard",
"form.integration.pinboard_token": "API ключ від Pinboard",
"form.integration.pocket_access_token": "Pocket Access Token",
"form.integration.pocket_activate": "Зберігати статті до Pocket",
"form.integration.pocket_connect_link": "Підключити ваш обліковий запис Pocket",
"form.integration.pocket_consumer_key": "Pocket Consumer Key",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "没有与此标签匹配的条目。",
"alert.no_unread_entry": "目前没有未读文章",
"alert.no_user": "您是目前仅有的用户",
"alert.pocket_linked": "您的 Pocket 帐户现已关联",
"alert.prefs_saved": "设置已存储!",
"alert.too_many_feeds_refresh": [
"多次触发订阅源更新,请等待 %d 分钟后重试。"
@ -130,8 +129,6 @@
"error.network_operation": "Miniflux 无法访问该网站由于网络错误: %v。",
"error.network_timeout": "该网站响应过慢,请求超时: %v",
"error.password_min_length": "请至少输入 6 个字符",
"error.pocket_access_token": "无法从 Pocket 获取访问令牌!",
"error.pocket_request_token": "无法从 Pocket 获取请求令牌!",
"error.proxy_url_not_empty": "代理 URL 不能为空。",
"error.settings_block_rule_fieldname_invalid": "无效的阻止规则: 规则 #%d 缺少合法的字段名 (可选: %s)",
"error.settings_block_rule_invalid_regex": "无效的阻止规则: 规则 #%d 的模式字符不是合法的正则表达式。",
@ -277,10 +274,6 @@
"form.integration.pinboard_bookmark": "标记为未读",
"form.integration.pinboard_tags": "Pinboard 标签",
"form.integration.pinboard_token": "Pinboard API 令牌",
"form.integration.pocket_access_token": "Pocket 访问令牌",
"form.integration.pocket_activate": "将文章保存到 Pocket",
"form.integration.pocket_connect_link": "连接您的 Pocket 帐户",
"form.integration.pocket_consumer_key": "Pocket 用户密钥",
"form.integration.pushover_activate": "将条目推送至 Pushover",
"form.integration.pushover_device": "Pushover 装置(可选)",
"form.integration.pushover_prefix": "Pushover URL 前缀(可选)",

View file

@ -27,7 +27,6 @@
"alert.no_tag_entry": "沒有與此標籤相符的文章。",
"alert.no_unread_entry": "目前沒有未讀文章",
"alert.no_user": "您是唯一的使用者",
"alert.pocket_linked": "您的 Pocket 帳戶已關聯",
"alert.prefs_saved": "設定已儲存!",
"alert.too_many_feeds_refresh": [
"您已觸發過太多次 Feed 更新,請等待 %d 分鐘後再嘗試。"
@ -130,8 +129,6 @@
"error.network_operation": "Miniflux 無法連線到該網站,可能是網路問題:%v。",
"error.network_timeout": "該網站回應過慢,請求逾時:%v。",
"error.password_min_length": "請至少輸入 6 個字元",
"error.pocket_access_token": "無法從 Pocket 取得存取金鑰!",
"error.pocket_request_token": "無法從 Pocket 取得請求金鑰!",
"error.proxy_url_not_empty": "代理伺服器網址不能為空。",
"error.settings_block_rule_fieldname_invalid": "無效的封鎖規則:規則 #%d 缺少有效的欄位名稱 (可用選項:%s)",
"error.settings_block_rule_invalid_regex": "無效的封鎖規則:規則 #%d 的模式不是合法的正規表示式",
@ -277,10 +274,6 @@
"form.integration.pinboard_bookmark": "標記為未讀",
"form.integration.pinboard_tags": "Pinboard 標籤",
"form.integration.pinboard_token": "Pinboard API Token",
"form.integration.pocket_access_token": "Pocket 存取金鑰",
"form.integration.pocket_activate": "儲存文章到 Pocket",
"form.integration.pocket_connect_link": "連線您的 Pocket 帳戶",
"form.integration.pocket_consumer_key": "Pocket 使用者金鑰",
"form.integration.pushover_activate": "Push entries to Pushover",
"form.integration.pushover_device": "Pushover device (optional)",
"form.integration.pushover_prefix": "Pushover URL prefix (optional)",

View file

@ -19,13 +19,12 @@ type SessionData struct {
FlashErrorMessage string `json:"flash_error_message"`
Language string `json:"language"`
Theme string `json:"theme"`
PocketRequestToken string `json:"pocket_request_token"`
LastForceRefresh string `json:"last_force_refresh"`
WebAuthnSessionData WebAuthnSession `json:"webauthn_session_data"`
}
func (s *SessionData) String() string {
return fmt.Sprintf(`CSRF=%q, OAuth2State=%q, OAuth2CodeVerifier=%q, FlashMsg=%q, FlashErrMsg=%q, Lang=%q, Theme=%q, PocketTkn=%q, LastForceRefresh=%s, WebAuthnSession=%q`,
return fmt.Sprintf(`CSRF=%q, OAuth2State=%q, OAuth2CodeVerifier=%q, FlashMsg=%q, FlashErrMsg=%q, Lang=%q, Theme=%q, LastForceRefresh=%s, WebAuthnSession=%q`,
s.CSRF,
s.OAuth2State,
s.OAuth2CodeVerifier,
@ -33,7 +32,6 @@ func (s *SessionData) String() string {
s.FlashErrorMessage,
s.Language,
s.Theme,
s.PocketRequestToken,
s.LastForceRefresh,
s.WebAuthnSessionData,
)

View file

@ -41,9 +41,6 @@ type Integration struct {
EspialTags string
ReadwiseEnabled bool
ReadwiseAPIKey string
PocketEnabled bool
PocketAccessToken string
PocketConsumerKey string
TelegramBotEnabled bool
TelegramBotToken string
TelegramBotChatID string

View file

@ -142,9 +142,6 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
espial_tags,
readwise_enabled,
readwise_api_key,
pocket_enabled,
pocket_access_token,
pocket_consumer_key,
telegram_bot_enabled,
telegram_bot_token,
telegram_bot_chat_id,
@ -264,9 +261,6 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
&integration.EspialTags,
&integration.ReadwiseEnabled,
&integration.ReadwiseAPIKey,
&integration.PocketEnabled,
&integration.PocketAccessToken,
&integration.PocketConsumerKey,
&integration.TelegramBotEnabled,
&integration.TelegramBotToken,
&integration.TelegramBotChatID,
@ -383,102 +377,99 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
nunux_keeper_enabled=$18,
nunux_keeper_url=$19,
nunux_keeper_api_key=$20,
pocket_enabled=$21,
pocket_access_token=$22,
pocket_consumer_key=$23,
googlereader_enabled=$24,
googlereader_username=$25,
googlereader_password=$26,
telegram_bot_enabled=$27,
telegram_bot_token=$28,
telegram_bot_chat_id=$29,
telegram_bot_topic_id=$30,
telegram_bot_disable_web_page_preview=$31,
telegram_bot_disable_notification=$32,
telegram_bot_disable_buttons=$33,
espial_enabled=$34,
espial_url=$35,
espial_api_key=$36,
espial_tags=$37,
linkace_enabled=$38,
linkace_url=$39,
linkace_api_key=$40,
linkace_tags=$41,
linkace_is_private=$42,
linkace_check_disabled=$43,
linkding_enabled=$44,
linkding_url=$45,
linkding_api_key=$46,
linkding_tags=$47,
linkding_mark_as_unread=$48,
matrix_bot_enabled=$49,
matrix_bot_user=$50,
matrix_bot_password=$51,
matrix_bot_url=$52,
matrix_bot_chat_id=$53,
notion_enabled=$54,
notion_token=$55,
notion_page_id=$56,
readwise_enabled=$57,
readwise_api_key=$58,
apprise_enabled=$59,
apprise_url=$60,
apprise_services_url=$61,
readeck_enabled=$62,
readeck_url=$63,
readeck_api_key=$64,
readeck_labels=$65,
readeck_only_url=$66,
shiori_enabled=$67,
shiori_url=$68,
shiori_username=$69,
shiori_password=$70,
shaarli_enabled=$71,
shaarli_url=$72,
shaarli_api_secret=$73,
webhook_enabled=$74,
webhook_url=$75,
webhook_secret=$76,
rssbridge_enabled=$77,
rssbridge_url=$78,
omnivore_enabled=$79,
omnivore_api_key=$80,
omnivore_url=$81,
linkwarden_enabled=$82,
linkwarden_url=$83,
linkwarden_api_key=$84,
raindrop_enabled=$85,
raindrop_token=$86,
raindrop_collection_id=$87,
raindrop_tags=$88,
betula_enabled=$89,
betula_url=$90,
betula_token=$91,
ntfy_enabled=$92,
ntfy_topic=$93,
ntfy_url=$94,
ntfy_api_token=$95,
ntfy_username=$96,
ntfy_password=$97,
ntfy_icon_url=$98,
ntfy_internal_links=$99,
cubox_enabled=$100,
cubox_api_link=$101,
discord_enabled=$102,
discord_webhook_link=$103,
slack_enabled=$104,
slack_webhook_link=$105,
pushover_enabled=$106,
pushover_user=$107,
pushover_token=$108,
pushover_device=$109,
pushover_prefix=$110,
rssbridge_token=$111,
karakeep_enabled=$112,
karakeep_api_key=$113,
karakeep_url=$114
googlereader_enabled=$21,
googlereader_username=$22,
googlereader_password=$23,
telegram_bot_enabled=$24,
telegram_bot_token=$25,
telegram_bot_chat_id=$26,
telegram_bot_topic_id=$27,
telegram_bot_disable_web_page_preview=$28,
telegram_bot_disable_notification=$29,
telegram_bot_disable_buttons=$30,
espial_enabled=$31,
espial_url=$32,
espial_api_key=$33,
espial_tags=$34,
linkace_enabled=$35,
linkace_url=$36,
linkace_api_key=$37,
linkace_tags=$38,
linkace_is_private=$39,
linkace_check_disabled=$40,
linkding_enabled=$41,
linkding_url=$42,
linkding_api_key=$43,
linkding_tags=$44,
linkding_mark_as_unread=$45,
matrix_bot_enabled=$46,
matrix_bot_user=$47,
matrix_bot_password=$48,
matrix_bot_url=$49,
matrix_bot_chat_id=$50,
notion_enabled=$51,
notion_token=$52,
notion_page_id=$53,
readwise_enabled=$54,
readwise_api_key=$55,
apprise_enabled=$56,
apprise_url=$57,
apprise_services_url=$58,
readeck_enabled=$59,
readeck_url=$60,
readeck_api_key=$61,
readeck_labels=$62,
readeck_only_url=$63,
shiori_enabled=$64,
shiori_url=$65,
shiori_username=$66,
shiori_password=$67,
shaarli_enabled=$68,
shaarli_url=$69,
shaarli_api_secret=$70,
webhook_enabled=$71,
webhook_url=$72,
webhook_secret=$73,
rssbridge_enabled=$74,
rssbridge_url=$75,
omnivore_enabled=$76,
omnivore_api_key=$77,
omnivore_url=$78,
linkwarden_enabled=$79,
linkwarden_url=$80,
linkwarden_api_key=$81,
raindrop_enabled=$82,
raindrop_token=$83,
raindrop_collection_id=$84,
raindrop_tags=$85,
betula_enabled=$86,
betula_url=$87,
betula_token=$88,
ntfy_enabled=$89,
ntfy_topic=$90,
ntfy_url=$91,
ntfy_api_token=$92,
ntfy_username=$93,
ntfy_password=$94,
ntfy_icon_url=$95,
ntfy_internal_links=$96,
cubox_enabled=$97,
cubox_api_link=$98,
discord_enabled=$99,
discord_webhook_link=$100,
slack_enabled=$101,
slack_webhook_link=$102,
pushover_enabled=$103,
pushover_user=$104,
pushover_token=$105,
pushover_device=$106,
pushover_prefix=$107,
rssbridge_token=$108,
karakeep_enabled=$109,
karakeep_api_key=$110,
karakeep_url=$111
WHERE
user_id=$115
user_id=$112
`
_, err := s.db.Exec(
query,
@ -502,9 +493,6 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error {
integration.NunuxKeeperEnabled,
integration.NunuxKeeperURL,
integration.NunuxKeeperAPIKey,
integration.PocketEnabled,
integration.PocketAccessToken,
integration.PocketConsumerKey,
integration.GoogleReaderEnabled,
integration.GoogleReaderUsername,
integration.GoogleReaderPassword,
@ -624,7 +612,6 @@ func (s *Storage) HasSaveEntry(userID int64) (result bool) {
nunux_keeper_enabled='t' OR
espial_enabled='t' OR
readwise_enabled='t' OR
pocket_enabled='t' OR
linkace_enabled='t' OR
linkding_enabled='t' OR
linkwarden_enabled='t' OR

View file

@ -406,31 +406,6 @@
</div>
</details>
<details {{ if .form.PocketEnabled }}open{{ end }}>
<summary>Pocket</summary>
<div class="form-section">
<label>
<input type="checkbox" name="pocket_enabled" value="1" {{ if .form.PocketEnabled }}checked{{ end }}> {{ t "form.integration.pocket_activate" }}
</label>
{{ if not .hasPocketConsumerKeyConfigured }}
<label for="form-pocket-consumer-key">{{ t "form.integration.pocket_consumer_key" }}</label>
<input type="text" name="pocket_consumer_key" id="form-pocket-consumer-key" value="{{ .form.PocketConsumerKey }}" spellcheck="false">
{{ end }}
<label for="form-pocket-access-token">{{ t "form.integration.pocket_access_token" }}</label>
<input type="password" name="pocket_access_token" id="form-pocket-access-token" value="{{ .form.PocketAccessToken }}" autocomplete="new-password">
{{ if not .form.PocketAccessToken }}
<p><a href="{{ route "pocketAuthorize" }}">{{ t "form.integration.pocket_connect_link" }}</a></p>
{{ end }}
<div class="buttons">
<button type="submit" class="button button-primary" data-label-loading="{{ t "form.submit.saving" }}">{{ t "action.update" }}</button>
</div>
</div>
</details>
<details {{ if .form.PushoverEnabled }}open{{ end }}>
<summary>Pushover</summary>
<div class="form-section">

View file

@ -44,9 +44,6 @@ type IntegrationForm struct {
EspialTags string
ReadwiseEnabled bool
ReadwiseAPIKey string
PocketEnabled bool
PocketAccessToken string
PocketConsumerKey string
TelegramBotEnabled bool
TelegramBotToken string
TelegramBotChatID string
@ -160,9 +157,6 @@ func (i IntegrationForm) Merge(integration *model.Integration) {
integration.EspialTags = i.EspialTags
integration.ReadwiseEnabled = i.ReadwiseEnabled
integration.ReadwiseAPIKey = i.ReadwiseAPIKey
integration.PocketEnabled = i.PocketEnabled
integration.PocketAccessToken = i.PocketAccessToken
integration.PocketConsumerKey = i.PocketConsumerKey
integration.TelegramBotEnabled = i.TelegramBotEnabled
integration.TelegramBotToken = i.TelegramBotToken
integration.TelegramBotChatID = i.TelegramBotChatID
@ -278,9 +272,6 @@ func NewIntegrationForm(r *http.Request) *IntegrationForm {
EspialTags: r.FormValue("espial_tags"),
ReadwiseEnabled: r.FormValue("readwise_enabled") == "1",
ReadwiseAPIKey: r.FormValue("readwise_api_key"),
PocketEnabled: r.FormValue("pocket_enabled") == "1",
PocketAccessToken: r.FormValue("pocket_access_token"),
PocketConsumerKey: r.FormValue("pocket_consumer_key"),
TelegramBotEnabled: r.FormValue("telegram_bot_enabled") == "1",
TelegramBotToken: r.FormValue("telegram_bot_token"),
TelegramBotChatID: r.FormValue("telegram_bot_chat_id"),

View file

@ -1,90 +0,0 @@
// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package ui // import "miniflux.app/v2/internal/ui"
import (
"log/slog"
"net/http"
"miniflux.app/v2/internal/config"
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/http/route"
"miniflux.app/v2/internal/integration/pocket"
"miniflux.app/v2/internal/locale"
"miniflux.app/v2/internal/ui/session"
)
func (h *handler) pocketAuthorize(w http.ResponseWriter, r *http.Request) {
printer := locale.NewPrinter(request.UserLanguage(r))
user, err := h.store.UserByID(request.UserID(r))
if err != nil {
html.ServerError(w, r, err)
return
}
integration, err := h.store.Integration(user.ID)
if err != nil {
html.ServerError(w, r, err)
return
}
sess := session.New(h.store, request.SessionID(r))
connector := pocket.NewConnector(config.Opts.PocketConsumerKey(integration.PocketConsumerKey))
redirectURL := config.Opts.RootURL() + route.Path(h.router, "pocketCallback")
requestToken, err := connector.RequestToken(redirectURL)
if err != nil {
slog.Warn("Pocket authorization request failed",
slog.Any("user_id", user.ID),
slog.Any("error", err),
)
sess.NewFlashErrorMessage(printer.Print("error.pocket_request_token"))
html.Redirect(w, r, route.Path(h.router, "integrations"))
return
}
sess.SetPocketRequestToken(requestToken)
html.Redirect(w, r, connector.AuthorizationURL(requestToken, redirectURL))
}
func (h *handler) pocketCallback(w http.ResponseWriter, r *http.Request) {
printer := locale.NewPrinter(request.UserLanguage(r))
sess := session.New(h.store, request.SessionID(r))
user, err := h.store.UserByID(request.UserID(r))
if err != nil {
html.ServerError(w, r, err)
return
}
integration, err := h.store.Integration(user.ID)
if err != nil {
html.ServerError(w, r, err)
return
}
connector := pocket.NewConnector(config.Opts.PocketConsumerKey(integration.PocketConsumerKey))
accessToken, err := connector.AccessToken(request.PocketRequestToken(r))
if err != nil {
slog.Warn("Unable to get Pocket access token",
slog.Any("user_id", user.ID),
slog.Any("error", err),
)
sess.NewFlashErrorMessage(printer.Print("error.pocket_access_token"))
html.Redirect(w, r, route.Path(h.router, "integrations"))
return
}
sess.SetPocketRequestToken("")
integration.PocketAccessToken = accessToken
err = h.store.UpdateIntegration(integration)
if err != nil {
html.ServerError(w, r, err)
return
}
sess.NewFlashMessage(printer.Print("alert.pocket_linked"))
html.Redirect(w, r, route.Path(h.router, "integrations"))
}

View file

@ -6,7 +6,6 @@ package ui // import "miniflux.app/v2/internal/ui"
import (
"net/http"
"miniflux.app/v2/internal/config"
"miniflux.app/v2/internal/http/request"
"miniflux.app/v2/internal/http/response/html"
"miniflux.app/v2/internal/ui/form"
@ -58,9 +57,6 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) {
EspialTags: integration.EspialTags,
ReadwiseEnabled: integration.ReadwiseEnabled,
ReadwiseAPIKey: integration.ReadwiseAPIKey,
PocketEnabled: integration.PocketEnabled,
PocketAccessToken: integration.PocketAccessToken,
PocketConsumerKey: integration.PocketConsumerKey,
TelegramBotEnabled: integration.TelegramBotEnabled,
TelegramBotToken: integration.TelegramBotToken,
TelegramBotChatID: integration.TelegramBotChatID,
@ -149,7 +145,6 @@ func (h *handler) showIntegrationPage(w http.ResponseWriter, r *http.Request) {
view.Set("user", user)
view.Set("countUnread", h.store.CountUnreadEntries(user.ID))
view.Set("countErrorFeeds", h.store.CountUserFeedsWithErrors(user.ID))
view.Set("hasPocketConsumerKeyConfigured", config.Opts.PocketConsumerKey("") != "")
html.OK(w, r, view.Render("integrations"))
}

View file

@ -126,7 +126,6 @@ func (m *middleware) handleAppSession(next http.Handler) http.Handler {
ctx = context.WithValue(ctx, request.FlashErrorMessageContextKey, session.Data.FlashErrorMessage)
ctx = context.WithValue(ctx, request.UserLanguageContextKey, session.Data.Language)
ctx = context.WithValue(ctx, request.UserThemeContextKey, session.Data.Theme)
ctx = context.WithValue(ctx, request.PocketRequestTokenContextKey, session.Data.PocketRequestToken)
ctx = context.WithValue(ctx, request.LastForceRefreshContextKey, session.Data.LastForceRefresh)
ctx = context.WithValue(ctx, request.WebAuthnDataContextKey, session.Data.WebAuthnSessionData)
next.ServeHTTP(w, r.WithContext(ctx))

View file

@ -69,11 +69,6 @@ func (s *Session) SetTheme(theme string) {
s.store.UpdateAppSessionField(s.sessionID, "theme", theme)
}
// SetPocketRequestToken updates Pocket Request Token.
func (s *Session) SetPocketRequestToken(requestToken string) {
s.store.UpdateAppSessionField(s.sessionID, "pocket_request_token", requestToken)
}
func (s *Session) SetWebAuthnSessionData(sessionData *model.WebAuthnSession) {
s.store.UpdateAppSessionObjectField(s.sessionID, "webauthn_session_data", sessionData)
}

View file

@ -126,8 +126,6 @@ func Serve(router *mux.Router, store *storage.Storage, pool *worker.Pool) {
uiRouter.HandleFunc("/settings", handler.updateSettings).Name("updateSettings").Methods(http.MethodPost)
uiRouter.HandleFunc("/integrations", handler.showIntegrationPage).Name("integrations").Methods(http.MethodGet)
uiRouter.HandleFunc("/integration", handler.updateIntegration).Name("updateIntegration").Methods(http.MethodPost)
uiRouter.HandleFunc("/integration/pocket/authorize", handler.pocketAuthorize).Name("pocketAuthorize").Methods(http.MethodGet)
uiRouter.HandleFunc("/integration/pocket/callback", handler.pocketCallback).Name("pocketCallback").Methods(http.MethodGet)
uiRouter.HandleFunc("/about", handler.showAboutPage).Name("about").Methods(http.MethodGet)
// Session pages.

View file

@ -1,5 +1,5 @@
.\" Manpage for miniflux.
.TH "MINIFLUX" "1" "April 11, 2025" "\ \&" "\ \&"
.TH "MINIFLUX" "1" "June 15, 2025" "\ \&" "\ \&"
.SH NAME
miniflux \- Minimalist and opinionated feed reader
@ -483,16 +483,6 @@ Set to 1 to authorize OAuth2 user creation\&.
.br
Disabled by default\&.
.TP
.B POCKET_CONSUMER_KEY
Pocket consumer API key for all users\&.
.br
Default is empty\&.
.TP
.B POCKET_CONSUMER_KEY_FILE
Path to a secret key exposed as a file, it should contain $POCKET_CONSUMER_KEY value\&.
.br
Default is empty\&.
.TP
.B POLLING_FREQUENCY
Refresh interval in minutes for feeds\&.
.br