diff --git a/database/migrations.go b/database/migrations.go index 9803ed4d..10bf76c6 100644 --- a/database/migrations.go +++ b/database/migrations.go @@ -572,4 +572,14 @@ var migrations = []func(tx *sql.Tx) error{ _, err = tx.Exec(sql) return err }, + func(tx *sql.Tx) (err error) { + sql := ` + ALTER TABLE integrations ADD COLUMN espial_enabled bool default 'f'; + ALTER TABLE integrations ADD COLUMN espial_url text default ''; + ALTER TABLE integrations ADD COLUMN espial_api_key text default ''; + ALTER TABLE integrations ADD COLUMN espial_tags text default 'miniflux'; + ` + _, err = tx.Exec(sql) + return err + }, } diff --git a/integration/espial/espial.go b/integration/espial/espial.go new file mode 100644 index 00000000..0ae8f0d5 --- /dev/null +++ b/integration/espial/espial.go @@ -0,0 +1,69 @@ +package espial // import "miniflux.app/integration/espial" + +import ( + "fmt" + "net/url" + "path" + + "miniflux.app/http/client" +) + +// Document structure of an Espial document +type Document struct { + Title string `json:"title,omitempty"` + Url string `json:"url,omitempty"` + ToRead bool `json:"toread,omitempty"` + Tags string `json:"tags,omitempty"` +} + +// Client represents an Espial client. +type Client struct { + baseURL string + apiKey string +} + +// NewClient returns a new Espial client. +func NewClient(baseURL, apiKey string) *Client { + return &Client{baseURL: baseURL, apiKey: apiKey} +} + +// AddEntry sends an entry to Espial. +func (c *Client) AddEntry(link, title, content, tags string) error { + if c.baseURL == "" || c.apiKey == "" { + return fmt.Errorf("espial: missing credentials") + } + + doc := &Document{ + Title: title, + Url: link, + ToRead: true, + Tags: tags, + } + + apiURL, err := getAPIEndpoint(c.baseURL, "/api/add") + if err != nil { + return err + } + + clt := client.New(apiURL) + clt.WithAuthorization("ApiKey " + c.apiKey) + response, err := clt.PostJSON(doc) + if err != nil { + return fmt.Errorf("espial: unable to send entry: %v", err) + } + + if response.HasServerFailure() { + return fmt.Errorf("espial: unable to send entry, status=%d", response.StatusCode) + } + + return nil +} + +func getAPIEndpoint(baseURL, pathURL string) (string, error) { + u, err := url.Parse(baseURL) + if err != nil { + return "", fmt.Errorf("espial: invalid API endpoint: %v", err) + } + u.Path = path.Join(u.Path, pathURL) + return u.String(), nil +} diff --git a/integration/integration.go b/integration/integration.go index db850f6c..19f3ebcf 100644 --- a/integration/integration.go +++ b/integration/integration.go @@ -6,6 +6,7 @@ package integration // import "miniflux.app/integration" import ( "miniflux.app/config" + "miniflux.app/integration/espial" "miniflux.app/integration/instapaper" "miniflux.app/integration/nunuxkeeper" "miniflux.app/integration/pinboard" @@ -72,6 +73,19 @@ func SendEntry(entry *model.Entry, integration *model.Integration) { } } + if integration.EspialEnabled { + logger.Debug("[Integration] Sending Entry #%d %q for User #%d to Espial", entry.ID, entry.URL, integration.UserID) + + client := espial.NewClient( + integration.EspialURL, + integration.EspialAPIKey, + ) + + if err := client.AddEntry(entry.URL, entry.Title, entry.Content, integration.EspialTags); err != nil { + logger.Error("[Integration] UserID #%d: %v", integration.UserID, err) + } + } + if integration.PocketEnabled { logger.Debug("[Integration] Sending Entry #%d %q for User #%d to Pocket", entry.ID, entry.URL, integration.UserID) diff --git a/locale/translations/de_DE.json b/locale/translations/de_DE.json index 14410d20..692c0c91 100644 --- a/locale/translations/de_DE.json +++ b/locale/translations/de_DE.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Artikel in Nunux Keeper speichern", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API-Endpunkt", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-Schlüssel", + "form.integration.espial_activate": "Artikel in Espial speichern", + "form.integration.espial_endpoint": "Espial API-Endpunkt", + "form.integration.espial_api_key": "Espial API-Schlüssel", + "form.integration.espial_tags": "Espial tags", "form.integration.telegram_bot_activate": "Pushen Sie neue Artikel in den Telegram-Chat", "form.integration.telegram_bot_token": "Bot token", "form.integration.telegram_chat_id": "Chat ID", diff --git a/locale/translations/el_EL.json b/locale/translations/el_EL.json index 79c8c50d..6cb4dec7 100644 --- a/locale/translations/el_EL.json +++ b/locale/translations/el_EL.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Αποθήκευση άρθρων στο Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Τελικό σημείο Nunux Keeper API", "form.integration.nunux_keeper_api_key": "Κλειδί API Nunux Keeper", + "form.integration.espial_activate": "Αποθήκευση άρθρων στο Espial", + "form.integration.espial_endpoint": "Τελικό σημείο Espial API", + "form.integration.espial_api_key": "Κλειδί API Espial", + "form.integration.espial_tags": "Ετικέτες Espial", "form.integration.telegram_bot_activate": "Προωθήστε νέα άρθρα στη συνομιλία Telegram", "form.integration.telegram_bot_token": "Διακριτικό bot", "form.integration.telegram_chat_id": "Αναγνωριστικό συνομιλίας", diff --git a/locale/translations/en_US.json b/locale/translations/en_US.json index 5b303f35..c799240a 100644 --- a/locale/translations/en_US.json +++ b/locale/translations/en_US.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Save articles to Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API Endpoint", "form.integration.nunux_keeper_api_key": "Nunux Keeper API key", + "form.integration.espial_activate": "Save articles to Espial", + "form.integration.espial_endpoint": "Espial API Endpoint", + "form.integration.espial_api_key": "Espial API key", + "form.integration.espial_tags": "Espial Tags", "form.integration.telegram_bot_activate": "Push new articles to Telegram chat", "form.integration.telegram_bot_token": "Bot token", "form.integration.telegram_chat_id": "Chat ID", diff --git a/locale/translations/es_ES.json b/locale/translations/es_ES.json index cc9a0fee..d90525d4 100644 --- a/locale/translations/es_ES.json +++ b/locale/translations/es_ES.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Guardar artículos a Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Extremo de API de Nunux Keeper", "form.integration.nunux_keeper_api_key": "Clave de API de Nunux Keeper", + "form.integration.espial_activate": "Guardar artículos a Espial", + "form.integration.espial_endpoint": "Extremo de API de Espial", + "form.integration.espial_api_key": "Clave de API de Espial", + "form.integration.espial_tags": "Etiquetas de Espial", "form.integration.telegram_bot_activate": "Envíe nuevos artículos al chat de Telegram", "form.integration.telegram_bot_token": "Token de bot", "form.integration.telegram_chat_id": "ID de chat", diff --git a/locale/translations/fi_FI.json b/locale/translations/fi_FI.json index 1b40b326..21d641dc 100644 --- a/locale/translations/fi_FI.json +++ b/locale/translations/fi_FI.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Tallenna artikkelit Nunux Keeperiin", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API-päätepiste", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-avain", + "form.integration.espial_activate": "Tallenna artikkelit Espialiin", + "form.integration.espial_endpoint": "Espial API-päätepiste", + "form.integration.espial_api_key": "Espial API-avain", + "form.integration.espial_tags": "Espial-tagit", "form.integration.telegram_bot_activate": "Lähetä uusia artikkeleita Telegram-chatiin", "form.integration.telegram_bot_token": "Bot-tunnus", "form.integration.telegram_chat_id": "Chat ID", diff --git a/locale/translations/fr_FR.json b/locale/translations/fr_FR.json index 27879e5a..7fb00661 100644 --- a/locale/translations/fr_FR.json +++ b/locale/translations/fr_FR.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Sauvegarder les articles vers Nunux Keeper", "form.integration.nunux_keeper_endpoint": "URL de l'API de Nunux Keeper", "form.integration.nunux_keeper_api_key": "Clé d'API de Nunux Keeper", + "form.integration.espial_activate": "Sauvegarder les articles vers Espial", + "form.integration.espial_endpoint": "URL de l'API de Espial", + "form.integration.espial_api_key": "Clé d'API de Espial", + "form.integration.espial_tags": "Libellés de Espial", "form.integration.telegram_bot_activate": "Envoyer les nouveaux articles vers Telegram", "form.integration.telegram_bot_token": "Jeton de sécurité de l'API du Bot Telegram", "form.integration.telegram_chat_id": "Identifiant de discussion", diff --git a/locale/translations/it_IT.json b/locale/translations/it_IT.json index 6713f4c5..87e41481 100644 --- a/locale/translations/it_IT.json +++ b/locale/translations/it_IT.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Salva gli articoli su Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Endpoint dell'API di Nunux Keeper", "form.integration.nunux_keeper_api_key": "API key dell'account Nunux Keeper", + "form.integration.espial_activate": "Salva gli articoli su Espial", + "form.integration.espial_endpoint": "Endpoint dell'API di Espial", + "form.integration.espial_api_key": "API key dell'account Espial", + "form.integration.espial_tags": "Tag di Espial", "form.integration.telegram_bot_activate": "Invia nuovi articoli alla chat di Telegram", "form.integration.telegram_bot_token": "Token bot", "form.integration.telegram_chat_id": "ID chat", diff --git a/locale/translations/ja_JP.json b/locale/translations/ja_JP.json index 4caaef57..16336198 100644 --- a/locale/translations/ja_JP.json +++ b/locale/translations/ja_JP.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Nunux Keeper に記事を保存する", "form.integration.nunux_keeper_endpoint": "Nunux Keeper の API Endpoint", "form.integration.nunux_keeper_api_key": "Nunux Keeper の API key", + "form.integration.espial_activate": "Espial に記事を保存する", + "form.integration.espial_endpoint": "Espial の API Endpoint", + "form.integration.espial_api_key": "Espial の API key", + "form.integration.espial_tags": "Espial の Tag", "form.integration.telegram_bot_activate": "新しい記事をTelegramチャットにプッシュする", "form.integration.telegram_bot_token": "ボットトークン", "form.integration.telegram_chat_id": "チャットID", diff --git a/locale/translations/nl_NL.json b/locale/translations/nl_NL.json index 951ed13d..0f185d8b 100644 --- a/locale/translations/nl_NL.json +++ b/locale/translations/nl_NL.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Opslaan naar Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper URL", "form.integration.nunux_keeper_api_key": "Nunux Keeper API-sleutel", + "form.integration.espial_activate": "Opslaan naar Espial", + "form.integration.espial_endpoint": "Espial URL", + "form.integration.espial_api_key": "Espial API-sleutel", + "form.integration.espial_tags": "Espial tags", "form.integration.telegram_bot_activate": "Push nieuwe artikelen naar Telegram-chat", "form.integration.telegram_bot_token": "Bot token", "form.integration.telegram_chat_id": "Chat ID", diff --git a/locale/translations/pl_PL.json b/locale/translations/pl_PL.json index b96cefb3..859e2fee 100644 --- a/locale/translations/pl_PL.json +++ b/locale/translations/pl_PL.json @@ -337,6 +337,10 @@ "form.integration.nunux_keeper_activate": "Zapisz artykuly do Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper URL", "form.integration.nunux_keeper_api_key": "Nunux Keeper API key", + "form.integration.espial_activate": "Zapisz artykuly do Espial", + "form.integration.espial_endpoint": "Espial URL", + "form.integration.espial_api_key": "Espial API key", + "form.integration.espial_tags": "Espial Tags", "form.integration.telegram_bot_activate": "Przesyłaj nowe artykuły do czatu Telegram", "form.integration.telegram_bot_token": "Token bota", "form.integration.telegram_chat_id": "Identyfikator czatu", diff --git a/locale/translations/pt_BR.json b/locale/translations/pt_BR.json index 6c85f858..2ddaafba 100644 --- a/locale/translations/pt_BR.json +++ b/locale/translations/pt_BR.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Salvar itens no Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Endpoint de API do Nunux Keeper", "form.integration.nunux_keeper_api_key": "Chave de API do Nunux Keeper", + "form.integration.espial_activate": "Salvar itens no Espial", + "form.integration.espial_endpoint": "Endpoint de API do Espial", + "form.integration.espial_api_key": "Chave de API do Espial", + "form.integration.espial_tags": "Etiquetas (tags) do Espial", "form.integration.telegram_bot_activate": "Envie novos artigos para o chat do Telegram", "form.integration.telegram_bot_token": "Token de bot", "form.integration.telegram_chat_id": "ID de bate-papo", diff --git a/locale/translations/ru_RU.json b/locale/translations/ru_RU.json index 622df04d..f6ba8e8b 100644 --- a/locale/translations/ru_RU.json +++ b/locale/translations/ru_RU.json @@ -337,6 +337,10 @@ "form.integration.nunux_keeper_activate": "Сохранять статьи в Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Конечная точка Nunux Keeper API", "form.integration.nunux_keeper_api_key": "Nunux Keeper API Key", + "form.integration.espial_activate": "Сохранять статьи в Espial", + "form.integration.espial_endpoint": "Конечная точка Espial API", + "form.integration.espial_api_key": "Espial API key", + "form.integration.espial_tags": "Теги Espial", "form.integration.telegram_bot_activate": "Публикуйте новые статьи в Telegram-чате", "form.integration.telegram_bot_token": "Токен бота", "form.integration.telegram_chat_id": "ID чата", diff --git a/locale/translations/tr_TR.json b/locale/translations/tr_TR.json index 131af760..a422e83d 100644 --- a/locale/translations/tr_TR.json +++ b/locale/translations/tr_TR.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "Makaleleri Nunux Keeper'a kaydet", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API Uç Noktası", "form.integration.nunux_keeper_api_key": "Nunux Keeper API anahtarı", + "form.integration.espial_activate": "Makaleleri Espial'e kaydet", + "form.integration.espial_endpoint": "Espial API Uç Noktası", + "form.integration.espial_api_key": "Espial API Anahtarı", + "form.integration.espial_tags": "Espial Etiketleri", "form.integration.telegram_bot_activate": "Yeni makaleleri Telegram sohbetine gönderin", "form.integration.telegram_bot_token": "Bot jetonu", "form.integration.telegram_chat_id": "Sohbet kimliği", diff --git a/locale/translations/zh_CN.json b/locale/translations/zh_CN.json index 520ff5f7..a523ae13 100644 --- a/locale/translations/zh_CN.json +++ b/locale/translations/zh_CN.json @@ -333,6 +333,10 @@ "form.integration.nunux_keeper_activate": "保存文章到 Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端点", "form.integration.nunux_keeper_api_key": "Nunux Keeper API 密钥", + "form.integration.espial_activate": "保存文章到 Espial", + "form.integration.espial_endpoint": "Espial API 端点", + "form.integration.espial_api_key": "Espial API 密钥", + "form.integration.espial_tags": "Espial 标签", "form.integration.telegram_bot_activate": "将新文章推送到 Telegram", "form.integration.telegram_bot_token": "机器人令牌", "form.integration.telegram_chat_id": "聊天ID", diff --git a/locale/translations/zh_TW.json b/locale/translations/zh_TW.json index 3a55ea4e..df7cea00 100644 --- a/locale/translations/zh_TW.json +++ b/locale/translations/zh_TW.json @@ -335,6 +335,10 @@ "form.integration.nunux_keeper_activate": "儲存文章到 Nunux Keeper", "form.integration.nunux_keeper_endpoint": "Nunux Keeper API 端點", "form.integration.nunux_keeper_api_key": "Nunux Keeper API 金鑰", + "form.integration.espial_activate": "儲存文章到 Espial", + "form.integration.espial_endpoint": "Espial API 端點", + "form.integration.espial_api_key": "Espial API 金鑰", + "form.integration.espial_tags": "Espial 標籤", "form.integration.telegram_bot_activate": "將新文章推送到 Telegram", "form.integration.telegram_bot_token": "Bot token", "form.integration.telegram_chat_id": "Chat ID", diff --git a/model/integration.go b/model/integration.go index d06582ec..3efed7cf 100644 --- a/model/integration.go +++ b/model/integration.go @@ -29,6 +29,10 @@ type Integration struct { NunuxKeeperEnabled bool NunuxKeeperURL string NunuxKeeperAPIKey string + EspialEnabled bool + EspialURL string + EspialAPIKey string + EspialTags string PocketEnabled bool PocketAccessToken string PocketConsumerKey string diff --git a/storage/integration.go b/storage/integration.go index f7e58687..05fb074b 100644 --- a/storage/integration.go +++ b/storage/integration.go @@ -133,6 +133,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { nunux_keeper_enabled, nunux_keeper_url, nunux_keeper_api_key, + espial_enabled, + espial_url, + espial_api_key, + espial_tags, pocket_enabled, pocket_access_token, pocket_consumer_key, @@ -169,6 +173,10 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) { &integration.NunuxKeeperEnabled, &integration.NunuxKeeperURL, &integration.NunuxKeeperAPIKey, + &integration.EspialEnabled, + &integration.EspialURL, + &integration.EspialAPIKey, + &integration.EspialTags, &integration.PocketEnabled, &integration.PocketAccessToken, &integration.PocketConsumerKey, @@ -225,9 +233,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { googlereader_password=$25, telegram_bot_enabled=$26, telegram_bot_token=$27, - telegram_bot_chat_id=$28 + telegram_bot_chat_id=$28, + espial_enabled=$29, + espial_url=$30, + espial_api_key=$31, + espial_tags=$32, WHERE - user_id=$29 + user_id=$33 ` _, err = s.db.Exec( query, @@ -259,6 +271,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.TelegramBotEnabled, integration.TelegramBotToken, integration.TelegramBotChatID, + integration.EspialEnabled, + integration.EspialURL, + integration.EspialAPIKey, + integration.EspialTags, integration.UserID, ) } else { @@ -293,9 +309,13 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { googlereader_password=$25, telegram_bot_enabled=$26, telegram_bot_token=$27, - telegram_bot_chat_id=$28 + telegram_bot_chat_id=$28, + espial_enabled=$29, + espial_url=$30, + espial_api_key=$31, + espial_tags=$32 WHERE - user_id=$29 + user_id=$33 ` _, err = s.db.Exec( query, @@ -327,6 +347,10 @@ func (s *Storage) UpdateIntegration(integration *model.Integration) error { integration.TelegramBotEnabled, integration.TelegramBotToken, integration.TelegramBotChatID, + integration.EspialEnabled, + integration.EspialURL, + integration.EspialAPIKey, + integration.EspialTags, integration.UserID, ) } @@ -348,7 +372,7 @@ func (s *Storage) HasSaveEntry(userID int64) (result bool) { WHERE user_id=$1 AND - (pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR nunux_keeper_enabled='t' OR pocket_enabled='t') + (pinboard_enabled='t' OR instapaper_enabled='t' OR wallabag_enabled='t' OR nunux_keeper_enabled='t' OR espial_enabled='t' OR pocket_enabled='t') ` if err := s.db.QueryRow(query, userID).Scan(&result); err != nil { result = false diff --git a/template/templates/views/integrations.html b/template/templates/views/integrations.html index b48115cd..9f7e0c0e 100644 --- a/template/templates/views/integrations.html +++ b/template/templates/views/integrations.html @@ -156,6 +156,26 @@ +

Espial

+
+ + + + + + + + + + + +
+ +
+
+

Telegram Bot