summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Batischev <eual.jp@gmail.com>2024-03-19 19:02:12 +0300
committerGitHub <noreply@github.com>2024-03-19 19:02:12 +0300
commit9d1edf9a0500eb52c74e9959882b198117cb2d79 (patch)
tree7f42f47592afd3ddefc949adf4a11bf97caf5ad2
parent880247bb4964aa3f6d765bf5910d6085c5214e87 (diff)
parent915b9ae7880aedb53531413f00bc5a7c370a0825 (diff)
Merge pull request #2693 from gilcu3/miniflux-starred
added support for starring in miniflux
-rw-r--r--doc/configcommands.dsv2
-rw-r--r--doc/newsboat.asciidoc19
-rw-r--r--include/minifluxapi.h1
-rw-r--r--include/minifluxurlreader.h3
-rw-r--r--src/configcontainer.cpp4
-rw-r--r--src/controller.cpp3
-rw-r--r--src/minifluxapi.cpp43
-rw-r--r--src/minifluxurlreader.cpp18
8 files changed, 80 insertions, 13 deletions
diff --git a/doc/configcommands.dsv b/doc/configcommands.dsv
index 609b1c34..07efa712 100644
--- a/doc/configcommands.dsv
+++ b/doc/configcommands.dsv
@@ -84,11 +84,13 @@ mark-as-read-on-hover||[yes/no]||no||If set to `yes`, then all articles that get
max-browser-tabs||<number>||10||Set the maximum number of articles to open in a browser when using the <<open-all-unread-in-browser,`open-all-unread-in-browser`>> or <<open-all-unread-in-browser-and-mark-read,`open-all-unread-in-browser-and-mark-read`>> commands.||max-browser-tabs 4
max-download-speed||<number>||0||If set to a number greater than 0, the download speed per download is set to that limit (in KB/s).||max-download-speed 50
max-items||<number>||0||Set the maximum number of articles a feed can contain. When the threshold is crossed, old articles are dropped. If the number is set to 0, then all articles are kept.||max-items 100
+miniflux-flag-star||<flag>||""||If set and Miniflux support is used, then all articles that are flagged with the specified flag are being "starred" in Miniflux and appear in the list of "Starred items".||miniflux-flag-star "b"
miniflux-login||<username>||""||Sets the username for use with Miniflux.||miniflux-login "admin"
miniflux-min-items||<number>||100||This variable sets the number of articles that are loaded from Miniflux per feed.||miniflux-min-items 20
miniflux-password||<password>||""||Configures the password for use with Miniflux. Double quotes and backslashes within it <<#_using_double_quotes,should be escaped>>.||miniflux-password "here_goesAquote:\""
miniflux-passwordeval||<command>||""||A more secure alternative to the above, is providing your password from an external command that is evaluated during login. This can be used to read your password from a gpg encrypted file or your system keyring.||miniflux-passwordeval "gpg --decrypt ~/.newsboat/miniflux-password.gpg"
miniflux-passwordfile||<path>||""||Another alternative, by storing your plaintext password elsewhere in your system.||miniflux-passwordfile "~/.newsboat/miniflux-pw.txt"
+miniflux-show-special-feeds||[yes/no]||yes||If set and Miniflux support is used, then a "Starred items" feed (containing your starred/favourited articles) appears in your subscription list.||miniflux-show-special-feeds "no"
miniflux-token||<API Token>||""||Sets the API Token for use with Miniflux.||miniflux-token "E-uTqU8r55KucuHz26tJbXfrZVRndwY_mZAsEfcC8Bg="
miniflux-tokeneval||<command>||""||A more secure alternative to the above, is providing your API token from an external command that is evaluated during login. This can be used to read your token from a gpg encrypted file or your system keyring.||miniflux-tokeneval "gpg --decrypt ~/.newsboat/miniflux-token.gpg"
miniflux-tokenfile||<API Token>||""||Another alternative, by storing your plaintext token elsewhere in your system.||miniflux-tokenfile "~/.newsboat/miniflux-token.txt"
diff --git a/doc/newsboat.asciidoc b/doc/newsboat.asciidoc
index 8d1cb0c5..47d9a4b4 100644
--- a/doc/newsboat.asciidoc
+++ b/doc/newsboat.asciidoc
@@ -684,8 +684,23 @@ It is also possible to specify an API token instead of the username/password com
See also <<miniflux-tokenfile,`miniflux-tokenfile`>>, and
<<miniflux-tokeneval,`miniflux-tokeneval`>>.
-Unlike with other backends, Miniflux's starring/bookmarking feature is not
-currently supported in Newsboat.
+In addition, Miniflux provides the ability to "star"
+articles. Starred articles are basically bookmarks. Newsboat allows the
+use of this feature by mapping its powerful "flags" to the "star"/"unstar"
+operations.
+
+In order to use this mapping, all you need to do is to configure the flags
+that shall be used:
+
+ miniflux-flag-star "a"
+
+After that, use these flags when you edit flags for an article, and these
+articles will be starred.
+
+By default a "Starred Items" feed is included in the feed list. This can be
+removed with:
+
+ miniflux-show-special-feeds "no"
Miniflux categories are converted into Newsboat tags. You can select and filter
feeds by tags; see <<_tagging>> and <<_filter_language>> for details.
diff --git a/include/minifluxapi.h b/include/minifluxapi.h
index 26da26c8..b8ae681b 100644
--- a/include/minifluxapi.h
+++ b/include/minifluxapi.h
@@ -43,6 +43,7 @@ private:
bool update_articles(const std::vector<std::string> guids,
nlohmann::json& args);
bool update_article(const std::string& guid, nlohmann::json& args);
+ bool star_article(const std::string& guid, bool star);
std::string auth_info;
std::string auth_token;
std::string server;
diff --git a/include/minifluxurlreader.h b/include/minifluxurlreader.h
index 2d86f901..232892ed 100644
--- a/include/minifluxurlreader.h
+++ b/include/minifluxurlreader.h
@@ -9,12 +9,13 @@ class RemoteApi;
class MinifluxUrlReader : public UrlReader {
public:
- MinifluxUrlReader(const std::string& url_file, RemoteApi* a);
+ MinifluxUrlReader(ConfigContainer* c, const std::string& url_file, RemoteApi* a);
~MinifluxUrlReader() override;
nonstd::optional<utils::ReadTextFileError> reload() override;
std::string get_source() override;
private:
+ ConfigContainer* cfg;
std::string file;
RemoteApi* api;
};
diff --git a/src/configcontainer.cpp b/src/configcontainer.cpp
index 93420416..6e27cd2c 100644
--- a/src/configcontainer.cpp
+++ b/src/configcontainer.cpp
@@ -267,11 +267,15 @@ ConfigContainer::ConfigContainer()
{"ocnews-passwordeval", ConfigData("", ConfigDataType::STR)},
{"ocnews-flag-star", ConfigData("", ConfigDataType::STR)},
{"ocnews-url", ConfigData("", ConfigDataType::STR)},
+ {"miniflux-flag-star", ConfigData("", ConfigDataType::STR)},
{"miniflux-login", ConfigData("", ConfigDataType::STR)},
{"miniflux-min-items", ConfigData("100", ConfigDataType::INT)},
{"miniflux-password", ConfigData("", ConfigDataType::STR)},
{"miniflux-passwordfile", ConfigData("", ConfigDataType::PATH)},
{"miniflux-passwordeval", ConfigData("", ConfigDataType::STR)},
+ {
+ "miniflux-show-special-feeds",
+ ConfigData("yes", ConfigDataType::BOOL)},
{"miniflux-token", ConfigData("", ConfigDataType::STR)},
{"miniflux-tokenfile", ConfigData("", ConfigDataType::PATH)},
{"miniflux-tokeneval", ConfigData("", ConfigDataType::STR)},
diff --git a/src/controller.cpp b/src/controller.cpp
index b77bab7b..f0d90d25 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -357,7 +357,7 @@ int Controller::run(const CliArgsParser& args)
}
api = new MinifluxApi(cfg);
- urlcfg = new MinifluxUrlReader(configpaths.url_file(), api);
+ urlcfg = new MinifluxUrlReader(&cfg, configpaths.url_file(), api);
} else if (type == "inoreader") {
const auto all_set = !cfg.get_configvalue("inoreader-app-id").empty()
&& !cfg.get_configvalue("inoreader-app-key").empty();
@@ -507,7 +507,6 @@ int Controller::run(const CliArgsParser& args)
return EXIT_SUCCESS;
}
-
// if configured, we fill all query feeds with some data; no need to
// sort it, it will be refilled when actually opening it.
if (cfg.get_configvalue_as_bool("prepopulate-query-feeds")) {
diff --git a/src/minifluxapi.cpp b/src/minifluxapi.cpp
index 89458611..b21df56e 100644
--- a/src/minifluxapi.cpp
+++ b/src/minifluxapi.cpp
@@ -139,11 +139,41 @@ bool MinifluxApi::mark_article_read(const std::string& guid, bool read)
return true;
}
-bool MinifluxApi::update_article_flags(const std::string& /* oldflags */,
- const std::string& /* newflags */,
- const std::string& /* guid */)
+bool MinifluxApi::star_article(const std::string& guid, bool star)
{
- return false;
+ std::string getstate;
+ getstate = strprintf::fmt(
+ "/v1/entries/%s",
+ guid);
+ const json status = run_op(getstate, json(), HTTPMethod::GET);
+ bool current_star = status["starred"];
+
+ if (star != current_star) {
+ std::string putcontent;
+ putcontent = strprintf::fmt(
+ "/v1/entries/%s/bookmark",
+ guid);
+ const json content = run_op(putcontent, json(), HTTPMethod::PUT);
+ return content.is_null();
+ } else {
+ return true;
+ }
+}
+
+bool MinifluxApi::update_article_flags(const std::string& oldflags,
+ const std::string& newflags,
+ const std::string& guid )
+{
+ std::string star_flag = cfg.get_configvalue("miniflux-flag-star");
+ bool success = true;
+
+ if (star_flag.length() > 0) {
+ update_flag(oldflags, newflags, star_flag[0], [&](bool added) {
+ success = star_article(guid, added);
+ });
+ }
+
+ return success;
}
rsspp::Feed MinifluxApi::fetch_feed(const std::string& id)
@@ -158,7 +188,9 @@ rsspp::Feed MinifluxApi::fetch_feed(const std::string& id, CurlHandle& cached_ha
feed.rss_version = rsspp::Feed::MINIFLUX_JSON;
const std::string query =
- strprintf::fmt("/v1/feeds/%s/entries?order=published_at&direction=desc&limit=%u",
+ id == "starred" ?
+ "/v1/entries?starred=true"
+ : strprintf::fmt("/v1/feeds/%s/entries?order=published_at&direction=desc&limit=%u",
id,
cfg.get_configvalue_as_int("miniflux-min-items"));
@@ -268,7 +300,6 @@ json MinifluxApi::run_op(const std::string& path,
const std::string result = utils::retrieve_url(
url, easyhandle, cfg, auth_info, body, method);
-
LOG(Level::DEBUG,
"MinifluxApi::run_op(%s %s,...): body=%s reply = %s",
utils::http_method_str(method),
diff --git a/src/minifluxurlreader.cpp b/src/minifluxurlreader.cpp
index cc5bda5f..bfd26ebc 100644
--- a/src/minifluxurlreader.cpp
+++ b/src/minifluxurlreader.cpp
@@ -1,5 +1,6 @@
#include "minifluxurlreader.h"
+#include "configcontainer.h"
#include "fileurlreader.h"
#include "logger.h"
#include "remoteapi.h"
@@ -7,8 +8,11 @@
namespace newsboat {
-MinifluxUrlReader::MinifluxUrlReader(const std::string& url_file, RemoteApi* a)
- : file(url_file)
+MinifluxUrlReader::MinifluxUrlReader(ConfigContainer* c,
+ const std::string& url_file,
+ RemoteApi* a)
+ : cfg(c)
+ , file(url_file)
, api(a)
{
}
@@ -21,6 +25,16 @@ nonstd::optional<utils::ReadTextFileError> MinifluxUrlReader::reload()
tags.clear();
alltags.clear();
+ if (cfg->get_configvalue_as_bool("miniflux-show-special-feeds")) {
+ std::vector<std::string> tmptags;
+ const std::string star_url = "starred";
+ urls.push_back(star_url);
+ std::string star_tag = std::string("~") + _("Starred items");
+ tmptags.push_back(star_tag);
+ alltags.insert(star_tag);
+ tags[star_url] = tmptags;
+ }
+
FileUrlReader ur(file);
const auto error_message = ur.reload();
if (error_message.has_value()) {