Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/jangernert/FeedReader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrendan Long <self@brendanlong.com>2019-02-20 21:05:48 +0300
committerBrendan Long <self@brendanlong.com>2019-02-20 21:12:04 +0300
commit898bdfd2a3afcd164a4b0b8b03a0efa97a8fcb47 (patch)
treece286260e0f8105754d59f0b6071135b61e5557a /plugins
parentd919c675a3fc221ca289a43476c92f338275c11c (diff)
Cleanup Vala indentation
This isn't perfect but it's way better than what Uncrustify generated
Diffstat (limited to 'plugins')
-rw-r--r--plugins/backend/bazqux/bazquxAPI.vala770
-rw-r--r--plugins/backend/bazqux/bazquxConnection.vala236
-rw-r--r--plugins/backend/bazqux/bazquxInterface.vala744
-rw-r--r--plugins/backend/bazqux/bazquxUtils.vala148
-rw-r--r--plugins/backend/decsync/decsyncInterface.vala1104
-rw-r--r--plugins/backend/decsync/decsyncListeners.vala526
-rw-r--r--plugins/backend/decsync/decsyncUtils.vala214
-rw-r--r--plugins/backend/decsync/libdecsync/src/Decsync.vala728
-rw-r--r--plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala156
-rw-r--r--plugins/backend/decsync/libdecsync/src/FileUtils.vala408
-rw-r--r--plugins/backend/decsync/libdecsync/src/Log.vala84
-rw-r--r--plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala102
-rw-r--r--plugins/backend/decsync/libdecsync/src/Utils.vala36
-rw-r--r--plugins/backend/demo/demoInterface.vala1172
-rw-r--r--plugins/backend/feedbin/TestFeedbin.vala218
-rw-r--r--plugins/backend/feedbin/feedbinAPI.vala752
-rw-r--r--plugins/backend/feedbin/feedbinInterface.vala1220
-rw-r--r--plugins/backend/feedbin/feedbinUtils.vala90
-rw-r--r--plugins/backend/feedhq/feedhqAPI.vala754
-rw-r--r--plugins/backend/feedhq/feedhqConnection.vala272
-rw-r--r--plugins/backend/feedhq/feedhqInterface.vala760
-rw-r--r--plugins/backend/feedhq/feedhqUtils.vala186
-rw-r--r--plugins/backend/feedly/feedlyAPI.vala1330
-rw-r--r--plugins/backend/feedly/feedlyConnection.vala486
-rw-r--r--plugins/backend/feedly/feedlyInterface.vala682
-rw-r--r--plugins/backend/feedly/feedlyUtils.vala162
-rw-r--r--plugins/backend/fresh/freshAPI.vala558
-rw-r--r--plugins/backend/fresh/freshConnection.vala232
-rw-r--r--plugins/backend/fresh/freshInterface.vala870
-rw-r--r--plugins/backend/fresh/freshUtils.vala226
-rw-r--r--plugins/backend/inoreader/InoReaderAPI.vala758
-rw-r--r--plugins/backend/inoreader/InoReaderConnection.vala288
-rw-r--r--plugins/backend/inoreader/InoReaderInterface.vala718
-rw-r--r--plugins/backend/inoreader/InoReaderUtils.vala218
-rw-r--r--plugins/backend/local/SuggestedFeedRow.vala170
-rw-r--r--plugins/backend/local/TestLocalRSS.vala42
-rw-r--r--plugins/backend/local/localInterface.vala1060
-rw-r--r--plugins/backend/local/localUtils.vala170
-rw-r--r--plugins/backend/oldreader/oldreaderAPI.vala718
-rw-r--r--plugins/backend/oldreader/oldreaderConnection.vala164
-rw-r--r--plugins/backend/oldreader/oldreaderInterface.vala802
-rw-r--r--plugins/backend/oldreader/oldreaderUtils.vala132
-rw-r--r--plugins/backend/owncloud/OwncloudNewsAPI.vala962
-rw-r--r--plugins/backend/owncloud/OwncloudNewsInterface.vala844
-rw-r--r--plugins/backend/owncloud/OwncloudNewsMessage.vala322
-rw-r--r--plugins/backend/owncloud/OwncloudNewsUtils.vala238
-rw-r--r--plugins/backend/ttrss/UntypedJson.vala80
-rw-r--r--plugins/backend/ttrss/ttrssAPI.vala1706
-rw-r--r--plugins/backend/ttrss/ttrssInterface.vala946
-rw-r--r--plugins/backend/ttrss/ttrssMessage.vala402
-rw-r--r--plugins/backend/ttrss/ttrssUtils.vala230
-rw-r--r--plugins/share/Browser/Browser.vala156
-rw-r--r--plugins/share/Email/Email.vala176
-rw-r--r--plugins/share/Email/EmailForm.vala144
-rw-r--r--plugins/share/Instapaper/InstapaperAPI.vala508
-rw-r--r--plugins/share/Instapaper/InstapaperSetup.vala188
-rw-r--r--plugins/share/Pocket/PocketAPI.vala464
-rw-r--r--plugins/share/Pocket/PocketSetup.vala128
-rw-r--r--plugins/share/Telegram/Telegram.vala164
-rw-r--r--plugins/share/Telegram/TelegramForm.vala114
-rw-r--r--plugins/share/Telegram/TelegramSetup.vala84
-rw-r--r--plugins/share/Twitter/TwitterAPI.vala484
-rw-r--r--plugins/share/Twitter/TwitterForm.vala222
-rw-r--r--plugins/share/Twitter/TwitterSetup.vala148
-rw-r--r--plugins/share/Wallabag/WallabagAPI.vala554
-rw-r--r--plugins/share/Wallabag/WallabagSetup.vala352
66 files changed, 15041 insertions, 15041 deletions
diff --git a/plugins/backend/bazqux/bazquxAPI.vala b/plugins/backend/bazqux/bazquxAPI.vala
index a55ee589..e153fb74 100644
--- a/plugins/backend/bazqux/bazquxAPI.vala
+++ b/plugins/backend/bazqux/bazquxAPI.vala
@@ -14,423 +14,423 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.bazquxAPI : GLib.Object {
-
-public enum bazquxSubscriptionAction {
- EDIT,
- SUBSCRIBE,
- UNSUBSCRIBE
-}
-
-private bazquxConnection m_connection;
-private bazquxUtils m_utils;
-private string m_userID;
-
-public bazquxAPI(bazquxUtils utils)
-{
- m_utils = utils;
- m_connection = new bazquxConnection(utils);
-}
-
-public LoginResponse login()
-{
- if(m_utils.getAccessToken() == "")
- {
- var result = m_connection.getToken();
- if(getUserID())
+
+ public enum bazquxSubscriptionAction {
+ EDIT,
+ SUBSCRIBE,
+ UNSUBSCRIBE
+ }
+
+ private bazquxConnection m_connection;
+ private bazquxUtils m_utils;
+ private string m_userID;
+
+ public bazquxAPI(bazquxUtils utils)
+ {
+ m_utils = utils;
+ m_connection = new bazquxConnection(utils);
+ }
+
+ public LoginResponse login()
+ {
+ if(m_utils.getAccessToken() == "")
{
- return result;
+ var result = m_connection.getToken();
+ if(getUserID())
+ {
+ return result;
+ }
}
+ else if(getUserID())
+ {
+ return LoginResponse.SUCCESS;
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
}
- else if(getUserID())
- {
- return LoginResponse.SUCCESS;
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-public bool ping()
-{
- return m_connection.ping();
-}
-
-private bool getUserID()
-{
- Logger.debug("getUserID: getting user info");
- var msg = new bazquxMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("user-info", msg.get());
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getUserID: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- if(root.has_member("userId"))
- {
- m_userID = root.get_string_member("userId");
- m_utils.setUserID(m_userID);
- Logger.info("bazqux: userID = " + m_userID);
-
- return true;
- }
-
- return false;
-}
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
- var msg = new bazquxMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("subscription/list", msg.get());
-
- if(response.status != 200)
- {
- return false;
- }
-
- Logger.debug(response.data);
- var parser = new Json.Parser();
- try
+
+ public bool ping()
{
- parser.load_from_data(response.data, -1);
+ return m_connection.ping();
}
- catch(Error e)
+
+ private bool getUserID()
{
- Logger.error("getFeeds: Could not load message response");
- Logger.error(e.message);
+ Logger.debug("getUserID: getting user info");
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("user-info", msg.get());
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getUserID: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ if(root.has_member("userId"))
+ {
+ m_userID = root.get_string_member("userId");
+ m_utils.setUserID(m_userID);
+ Logger.info("bazqux: userID = " + m_userID);
+
+ return true;
+ }
+
return false;
}
- var root = parser.get_root().get_object();
- var array = root.get_array_member("subscriptions");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- Json.Object object = array.get_object_element(i);
-
- string feedID = object.get_string_member("id");
- string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
- string? icon_url = object.get_string_member("iconUrl");
-
- uint catCount = object.get_array_member("categories").get_length();
- var categories = new Gee.ArrayList<string>();
- for(uint j = 0; j < catCount; ++j)
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("subscription/list", msg.get());
+
+ if(response.status != 200)
{
- categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ return false;
}
- feeds.add(
- new Feed(
- feedID,
- object.get_string_member("title"),
- url,
- 0,
- categories,
- icon_url,
- object.get_string_member("url")
+
+ Logger.debug(response.data);
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getFeeds: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("subscriptions");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ string feedID = object.get_string_member("id");
+ string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+ string? icon_url = object.get_string_member("iconUrl");
+
+ uint catCount = object.get_array_member("categories").get_length();
+ var categories = new Gee.ArrayList<string>();
+ for(uint j = 0; j < catCount; ++j)
+ {
+ categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ }
+ feeds.add(
+ new Feed(
+ feedID,
+ object.get_string_member("title"),
+ url,
+ 0,
+ categories,
+ icon_url,
+ object.get_string_member("url")
)
);
+ }
+ return true;
}
- return true;
-}
-
-public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-{
- var msg = new bazquxMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("tag/list", msg.get());
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- var array = root.get_array_member("tags");
- uint length = array.get_length();
- int orderID = 0;
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++)
+
+ public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- int start = id.last_index_of_char('/') + 1;
- string title = id.substring(start);
-
- if(id.contains("/label/"))
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("tag/list", msg.get());
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("tags");
+ uint length = array.get_length();
+ int orderID = 0;
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++)
{
- if(m_utils.tagIsCat(id, feeds))
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ int start = id.last_index_of_char('/') + 1;
+ string title = id.substring(start);
+
+ if(id.contains("/label/"))
{
- categories.add(
- new Category(
- id,
- title,
- 0,
- orderID,
- CategoryID.MASTER.to_string(),
- 1
+ if(m_utils.tagIsCat(id, feeds))
+ {
+ categories.add(
+ new Category(
+ id,
+ title,
+ 0,
+ orderID,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
- ++orderID;
- }
- else
- {
- tags.add(
- new Tag(
- id,
- title,
- db.getTagColor()
+ ++orderID;
+ }
+ else
+ {
+ tags.add(
+ new Tag(
+ id,
+ title,
+ db.getTagColor()
)
);
+ }
}
}
+ return true;
}
- return true;
-}
-
-
-public int getTotalUnread()
-{
- var msg = new bazquxMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("unread-count", msg.get());
-
- if(response.status != 200)
- {
- return 0;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getTotalUnread: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("unreadcounts");
- uint length = array.get_length();
- int count = 0;
-
- for (uint i = 0; i < length; i++)
+
+
+ public int getTotalUnread()
{
- Json.Object object = array.get_object_element(i);
- if(object.get_string_member("id").has_prefix("feed/"))
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("unread-count", msg.get());
+
+ if(response.status != 200)
{
- count += (int)object.get_int_member("count");
+ return 0;
}
-
- }
-
- Logger.debug("getTotalUnread %i".printf(count));
- return count;
-}
-
-
-public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
-{
- var msg = new bazquxMessage();
- msg.add("output", "json");
- msg.add("n", count.to_string());
- msg.add("xt", "user/-/state/com.google/read");
- if(continuation != null)
- {
- msg.add("c", continuation);
- }
-
- var response = m_connection.send_get_request("stream/items/ids", msg.get());
-
- if(response.status != 200)
- {
- return null;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("updateArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("itemRefs");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- ids.add(object.get_string_member("id"));
- }
-
- if(root.has_member("continuation") && root.get_string_member("continuation") != "")
- {
- return root.get_string_member("continuation");
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getTotalUnread: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("unreadcounts");
+ uint length = array.get_length();
+ int count = 0;
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ if(object.get_string_member("id").has_prefix("feed/"))
+ {
+ count += (int)object.get_int_member("count");
+ }
+
+ }
+
+ Logger.debug("getTotalUnread %i".printf(count));
+ return count;
}
-
- return null;
-}
-
-public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
-{
- var msg = new bazquxMessage();
- msg.add("output", "json");
- msg.add("n", count.to_string());
-
- if(whatToGet == ArticleStatus.UNREAD)
+
+
+ public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
{
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ msg.add("n", count.to_string());
msg.add("xt", "user/-/state/com.google/read");
- }
- if(whatToGet == ArticleStatus.READ)
- {
- msg.add("s", "user/-/state/com.google/read");
- }
- else if(whatToGet == ArticleStatus.MARKED)
- {
- msg.add("s", "user/-/state/com.google/starred");
- }
-
- if( continuation != null )
- {
- msg.add("c", continuation);
- }
-
- string api_endpoint = "stream/contents";
- if(feed_id != null)
- {
- api_endpoint += "/" + feed_id;
- }
- else if(tagID != null)
- {
- api_endpoint += "/" + tagID;
- }
- var response = m_connection.send_get_request(api_endpoint, msg.get());
-
- if(response.status != 200)
- {
+ if(continuation != null)
+ {
+ msg.add("c", continuation);
+ }
+
+ var response = m_connection.send_get_request("stream/items/ids", msg.get());
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("updateArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("itemRefs");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ ids.add(object.get_string_member("id"));
+ }
+
+ if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+ {
+ return root.get_string_member("continuation");
+ }
+
return null;
}
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("items");
- uint length = array.get_length();
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++)
+
+ public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- id = id.substring(id.last_index_of_char('/') + 1);
- bool marked = false;
- bool read = false;
- var cats = object.get_array_member("categories");
- uint cat_length = cats.get_length();
-
- var tags = new Gee.ArrayList<string>();
- for (uint j = 0; j < cat_length; j++)
+ var msg = new bazquxMessage();
+ msg.add("output", "json");
+ msg.add("n", count.to_string());
+
+ if(whatToGet == ArticleStatus.UNREAD)
{
- string cat = cats.get_string_element(j);
- if(cat.has_suffix("com.google/starred"))
- {
- marked = true;
- }
- else if(cat.has_suffix("com.google/read"))
- {
- read = true;
- }
- else if(cat.contains("/label/") && db.getTagName(cat) != null)
- {
- tags.add(cat);
- }
+ msg.add("xt", "user/-/state/com.google/read");
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+ if(whatToGet == ArticleStatus.READ)
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ msg.add("s", "user/-/state/com.google/read");
+ }
+ else if(whatToGet == ArticleStatus.MARKED)
+ {
+ msg.add("s", "user/-/state/com.google/starred");
+ }
+
+ if( continuation != null )
+ {
+ msg.add("c", continuation);
+ }
+
+ string api_endpoint = "stream/contents";
+ if(feed_id != null)
+ {
+ api_endpoint += "/" + feed_id;
+ }
+ else if(tagID != null)
+ {
+ api_endpoint += "/" + tagID;
+ }
+ var response = m_connection.send_get_request(api_endpoint, msg.get());
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("items");
+ uint length = array.get_length();
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ id = id.substring(id.last_index_of_char('/') + 1);
+ bool marked = false;
+ bool read = false;
+ var cats = object.get_array_member("categories");
+ uint cat_length = cats.get_length();
+
+ var tags = new Gee.ArrayList<string>();
+ for (uint j = 0; j < cat_length; j++)
{
- mediaCount = attachments.get_length();
+ string cat = cats.get_string_element(j);
+ if(cat.has_suffix("com.google/starred"))
+ {
+ marked = true;
+ }
+ else if(cat.has_suffix("com.google/read"))
+ {
+ read = true;
+ }
+ else if(cat.contains("/label/") && db.getTagName(cat) != null)
+ {
+ tags.add(cat);
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
{
- var attachment = attachments.get_object_element(j);
-
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(attachment.get_string_member("type")))
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(attachment.get_string_member("type")))
);
+ }
}
- }
-
- articles.add(new Article(
- id,
- object.get_string_member("title"),
- object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
- object.get_object_member("origin").get_string_member("streamId"),
- read ? ArticleStatus.READ : ArticleStatus.UNREAD,
- marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- object.get_object_member("summary").get_string_member("content"),
- "",
- object.get_string_member("author"),
- new DateTime.from_unix_local(object.get_int_member("published")),
- -1,
- tags,
- enclosures
- )
- );
- }
-
+
+ articles.add(new Article(
+ id,
+ object.get_string_member("title"),
+ object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+ object.get_object_member("origin").get_string_member("streamId"),
+ read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+ marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ object.get_object_member("summary").get_string_member("content"),
+ "",
+ object.get_string_member("author"),
+ new DateTime.from_unix_local(object.get_int_member("published")),
+ -1,
+ tags,
+ enclosures
+ )
+ );
+ }
+
if(root.has_member("continuation") && root.get_string_member("continuation") != "")
{
return root.get_string_member("continuation");
}
-
+
return null;
}
@@ -439,7 +439,7 @@ public void edidTag(string articleID, string tagID, bool add = true)
{
var msg = new bazquxMessage();
msg.add("output", "json");
-
+
if(add)
{
msg.add("a", tagID);
@@ -448,7 +448,7 @@ public void edidTag(string articleID, string tagID, bool add = true)
{
msg.add("r", tagID);
}
-
+
msg.add("i", "tag:google.com,2005:reader/item/" + articleID);
m_connection.send_post_request("edit-tag", msg.get());
}
@@ -488,40 +488,40 @@ public bool editSubscription(bazquxSubscriptionAction action, string feedID, str
{
var msg = new bazquxMessage();
msg.add("output", "json");
-
+
switch(action)
{
- case bazquxSubscriptionAction.EDIT:
+ case bazquxSubscriptionAction.EDIT:
msg.add("ac", "edit");
break;
- case bazquxSubscriptionAction.SUBSCRIBE:
+ case bazquxSubscriptionAction.SUBSCRIBE:
msg.add("ac", "subscribe");
break;
- case bazquxSubscriptionAction.UNSUBSCRIBE:
+ case bazquxSubscriptionAction.UNSUBSCRIBE:
msg.add("ac", "unsubscribe");
break;
}
-
+
msg.add("s", feedID);
-
+
if(title != null)
{
msg.add("t", title);
}
-
+
if(add != null)
{
msg.add("a", add);
}
-
+
if(remove != null)
{
msg.add("r", remove);
}
-
-
+
+
var response = m_connection.send_post_request("subscription/edit", msg.get());
-
+
return response.status == 200;
}
}
diff --git a/plugins/backend/bazqux/bazquxConnection.vala b/plugins/backend/bazqux/bazquxConnection.vala
index 90c5d0aa..16c4f385 100644
--- a/plugins/backend/bazqux/bazquxConnection.vala
+++ b/plugins/backend/bazqux/bazquxConnection.vala
@@ -14,141 +14,141 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.bazquxConnection {
-private string m_username;
-private string m_api_code;
-private string m_passwd;
-private bazquxUtils m_utils;
-private Soup.Session m_session;
-
-public bazquxConnection(bazquxUtils utils)
-{
- m_utils = utils;
- m_username = m_utils.getUser();
- m_api_code = m_utils.getAccessToken();
- m_passwd = m_utils.getPasswd();
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
-}
-
-public LoginResponse getToken()
-{
- Logger.debug("bazqux Connection: getToken()");
-
- if(m_username == "" && m_passwd == "")
+ private string m_username;
+ private string m_api_code;
+ private string m_passwd;
+ private bazquxUtils m_utils;
+ private Soup.Session m_session;
+
+ public bazquxConnection(bazquxUtils utils)
{
- return LoginResponse.ALL_EMPTY;
+ m_utils = utils;
+ m_username = m_utils.getUser();
+ m_api_code = m_utils.getAccessToken();
+ m_passwd = m_utils.getPasswd();
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
}
- if(m_username == "")
+
+ public LoginResponse getToken()
{
- return LoginResponse.MISSING_USER;
- }
- if(m_passwd == "")
- {
- return LoginResponse.MISSING_PASSWD;
- }
-
- var message = new Soup.Message("POST", "https://bazqux.com/accounts/ClientLogin/");
- string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
- string response = (string)message.response_body.flatten().data;
- try{
-
- var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
- if(regex.match(response))
+ Logger.debug("bazqux Connection: getToken()");
+
+ if(m_username == "" && m_passwd == "")
+ {
+ return LoginResponse.ALL_EMPTY;
+ }
+ if(m_username == "")
{
- Logger.error("Regex bazqux - %s".printf(response));
- string split = regex.replace( response, -1,0,"");
- Logger.error("authcode"+split);
- m_utils.setAccessToken(split.strip());
- return LoginResponse.SUCCESS;
+ return LoginResponse.MISSING_USER;
+ }
+ if(m_passwd == "")
+ {
+ return LoginResponse.MISSING_PASSWD;
+ }
+
+ var message = new Soup.Message("POST", "https://bazqux.com/accounts/ClientLogin/");
+ string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+ string response = (string)message.response_body.flatten().data;
+ try{
+
+ var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+ if(regex.match(response))
+ {
+ Logger.error("Regex bazqux - %s".printf(response));
+ string split = regex.replace( response, -1,0,"");
+ Logger.error("authcode"+split);
+ m_utils.setAccessToken(split.strip());
+ return LoginResponse.SUCCESS;
+ }
+ else
+ {
+ Logger.debug(response);
+ return LoginResponse.WRONG_LOGIN;
+ }
}
- else
+ catch(Error e)
{
- Logger.debug(response);
- return LoginResponse.WRONG_LOGIN;
+ Logger.error("bazquxConnection - getToken: Could not load message response");
+ Logger.error(e.message);
+ return LoginResponse.UNKNOWN_ERROR;
}
}
- catch(Error e)
+
+ public Response send_get_request(string path, string? message_string = null)
{
- Logger.error("bazquxConnection - getToken: Could not load message response");
- Logger.error(e.message);
- return LoginResponse.UNKNOWN_ERROR;
+ return send_request(path, "GET", message_string);
}
-}
-
-public Response send_get_request(string path, string? message_string = null)
-{
- return send_request(path, "GET", message_string);
-}
-
-public Response send_post_request(string path, string? message_string = null)
-{
- return send_request(path, "POST", message_string);
-}
-
-private Response send_request(string path, string type, string? message_string = null)
-{
-
- var message = new Soup.Message(type, bazquxSecret.base_uri + path);
-
- string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
- message.request_headers.append("Authorization", oldauth);
-
- if(message_string != null)
+
+ public Response send_post_request(string path, string? message_string = null)
{
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ return send_request(path, "POST", message_string);
}
-
- m_session.send_message(message);
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
-public bool ping()
-{
- var message = new Soup.Message("GET", "https://www.bazqux.com/reader/ping");
-
- string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
- message.request_headers.append("Authorization", oldauth);
- m_session.send_message(message);
-
- if((string)message.response_body.data == "OK")
+
+ private Response send_request(string path, string type, string? message_string = null)
{
- return true;
+
+ var message = new Soup.Message(type, bazquxSecret.base_uri + path);
+
+ string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", oldauth);
+
+ if(message_string != null)
+ {
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ }
+
+ m_session.send_message(message);
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return false;
-}
-
+
+ public bool ping()
+ {
+ var message = new Soup.Message("GET", "https://www.bazqux.com/reader/ping");
+
+ string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", oldauth);
+ m_session.send_message(message);
+
+ if((string)message.response_body.data == "OK")
+ {
+ return true;
+ }
+
+ return false;
+ }
+
}
public class FeedReader.bazquxMessage {
-
-string request = "";
-
-public bazquxMessage()
-{
-
-}
-
-public void add(string parameter, string val)
-{
- if(request != "")
+
+ string request = "";
+
+ public bazquxMessage()
{
- request += "&";
+
+ }
+
+ public void add(string parameter, string val)
+ {
+ if(request != "")
+ {
+ request += "&";
+ }
+
+ request += parameter;
+ request += "=";
+ request += GLib.Uri.escape_string(val);
+ }
+
+ public string get()
+ {
+ return request;
}
-
- request += parameter;
- request += "=";
- request += GLib.Uri.escape_string(val);
-}
-
-public string get()
-{
- return request;
-}
}
diff --git a/plugins/backend/bazqux/bazquxInterface.vala b/plugins/backend/bazqux/bazquxInterface.vala
index ad4dcfca..a9d70c47 100644
--- a/plugins/backend/bazqux/bazquxInterface.vala
+++ b/plugins/backend/bazqux/bazquxInterface.vala
@@ -14,423 +14,423 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.bazquxInterface : FeedServerInterface {
-
-private bazquxAPI m_api;
-private bazquxUtils m_utils;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new bazquxUtils(settings_backend, secrets);
- m_api = new bazquxAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://bazqux.com/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
-}
-
-public override string getID()
-{
- return "bazqux";
-}
-
-public override string iconName()
-{
- return "feed-service-bazqux";
-}
-
-public override string serviceName()
-{
- return "BazQux";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_userEntry.activate.connect(() => { tryLogin(); });
- m_passwordEntry.activate.connect(() => { tryLogin(); });
-
- m_passwordEntry.set_invisible_char('*');
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(user_label, 0, 0, 1, 1);
- grid.attach(m_userEntry, 1, 0, 1, 1);
- grid.attach(password_label, 0, 1, 1, 1);
- grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
- var logo = new Gtk.Image.from_icon_name("feed-service-bazqux", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override void writeData()
-{
- m_utils.setUser(m_userEntry.get_text());
- m_utils.setPassword(m_passwordEntry.get_text());
-}
-
-public override bool supportTags()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-bazqux-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return "https://bazqux.com/";
-}
-
-public override string uncategorizedID()
-{
- return "";
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-public override bool hideCategoryWhenEmpty(string cadID)
-{
- return false;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- if(read == ArticleStatus.READ)
+
+ private bazquxAPI m_api;
+ private bazquxUtils m_utils;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ m_utils = new bazquxUtils(settings_backend, secrets);
+ m_api = new bazquxAPI(m_utils);
}
- else
+
+ public override string getWebsite()
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+ return "https://bazqux.com/";
}
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override BackendFlags getFlags()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
}
- else
+
+ public override string getID()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ return "bazqux";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markAsRead(feedID);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markAsRead(catID);
-}
-
-public override void markAllItemsRead()
-{
- var db = DataBase.readOnly();
- var categories = db.read_categories();
- foreach(Category cat in categories)
+
+ public override string iconName()
{
- m_api.markAsRead(cat.getCatID());
+ return "feed-service-bazqux";
}
-
- var feeds = db.read_feeds_without_cat();
- foreach(Feed feed in feeds)
+
+ public override string serviceName()
{
- m_api.markAsRead(feed.getFeedID());
+ return "BazQux";
}
- m_api.markAsRead();
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, true);
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, false);
-}
-
-public override string createTag(string caption)
-{
- return m_api.composeTagID(caption);
-}
-
-public override void deleteTag(string tagID)
-{
- m_api.deleteTag(tagID);
-}
-
-public override void renameTag(string tagID, string title)
-{
- m_api.renameTag(tagID, title);
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- feedID = "feed/" + feedURL;
- bool success = false;
- errmsg = "";
-
- if(catID == null && newCatName != null)
+
+ public override bool needWebLogin()
{
- string newCatID = m_api.composeTagID(newCatName);
- success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, newCatID);
+ return false;
}
- else
+
+ public override Gtk.Box? getWidget()
{
- success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, catID);
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_userEntry.activate.connect(() => { tryLogin(); });
+ m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+ m_passwordEntry.set_invisible_char('*');
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(user_label, 0, 0, 1, 1);
+ grid.attach(m_userEntry, 1, 0, 1, 1);
+ grid.attach(password_label, 0, 1, 1, 1);
+ grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-bazqux", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
}
-
- if(!success)
+
+ public override void writeData()
{
- errmsg = @"bazqux could not subscribe to $feedURL";
+ m_utils.setUser(m_userEntry.get_text());
+ m_utils.setPassword(m_passwordEntry.get_text());
}
-
- return success;
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.UNSUBSCRIBE, feedID);
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, title);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, null, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.composeTagID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameTag(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.deleteTag(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getFeeds(feeds))
+
+ public override bool supportTags()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-bazqux-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return "https://bazqux.com/";
+ }
+
+ public override string uncategorizedID()
+ {
+ return "";
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+ public override bool hideCategoryWhenEmpty(string cadID)
+ {
+ return false;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(read == ArticleStatus.READ)
{
- return false;
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read");
}
-
- if(m_api.getCategoriesAndTags(feeds, categories, tags))
+ else
{
- return true;
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
}
}
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getTotalUnread();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- if(whatToGet == ArticleStatus.READ)
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
+ {
+ if(marked == ArticleStatus.MARKED)
+ {
+ m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ }
+ else
+ {
+ m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ }
+ }
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.markAsRead(feedID);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markAsRead(catID);
+ }
+
+ public override void markAllItemsRead()
+ {
+ var db = DataBase.readOnly();
+ var categories = db.read_categories();
+ foreach(Category cat in categories)
+ {
+ m_api.markAsRead(cat.getCatID());
+ }
+
+ var feeds = db.read_feeds_without_cat();
+ foreach(Feed feed in feeds)
+ {
+ m_api.markAsRead(feed.getFeedID());
+ }
+ m_api.markAsRead();
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, true);
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, false);
+ }
+
+ public override string createTag(string caption)
+ {
+ return m_api.composeTagID(caption);
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ m_api.deleteTag(tagID);
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ m_api.renameTag(tagID, title);
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ feedID = "feed/" + feedURL;
+ bool success = false;
+ errmsg = "";
+
+ if(catID == null && newCatName != null)
+ {
+ string newCatID = m_api.composeTagID(newCatName);
+ success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, newCatID);
+ }
+ else
+ {
+ success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, catID);
+ }
+
+ if(!success)
+ {
+ errmsg = @"bazqux could not subscribe to $feedURL";
+ }
+
+ return success;
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.UNSUBSCRIBE, feedID);
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, title);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, null, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.composeTagID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameTag(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
{
return;
}
- else if(whatToGet == ArticleStatus.ALL)
+
+ public override void deleteCategory(string catID)
{
- var unreadIDs = new Gee.LinkedList<string>();
- string? continuation = null;
- int left = 4*count;
-
- while(left > 0)
+ m_api.deleteTag(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getFeeds(feeds))
{
if(cancellable != null && cancellable.is_cancelled())
{
- return;
- }
-
- if(left > 1000)
- {
- continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
- left -= 1000;
+ return false;
}
- else
+
+ if(m_api.getCategoriesAndTags(feeds, categories, tags))
{
- m_api.updateArticles(unreadIDs, left, continuation);
- left = 0;
+ return true;
}
}
- DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+ return false;
}
-
- var articles = new Gee.LinkedList<Article>();
- string? continuation = null;
- int left = count;
- string? bazqux_feedID = (isTagID) ? null : feedID;
- string? bazqux_tagID = (isTagID) ? feedID : null;
-
- while(left > 0)
+
+ public override int getUnreadCount()
{
- if(cancellable != null && cancellable.is_cancelled())
+ return m_api.getTotalUnread();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ if(whatToGet == ArticleStatus.READ)
{
return;
}
-
- if(left > 1000)
+ else if(whatToGet == ArticleStatus.ALL)
{
- continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
- left -= 1000;
+ var unreadIDs = new Gee.LinkedList<string>();
+ string? continuation = null;
+ int left = 4*count;
+
+ while(left > 0)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
+ left -= 1000;
+ }
+ else
+ {
+ m_api.updateArticles(unreadIDs, left, continuation);
+ left = 0;
+ }
+ }
+ DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
}
- else
+
+ var articles = new Gee.LinkedList<Article>();
+ string? continuation = null;
+ int left = count;
+ string? bazqux_feedID = (isTagID) ? null : feedID;
+ string? bazqux_tagID = (isTagID) ? feedID : null;
+
+ while(left > 0)
{
- continuation = m_api.getArticles(articles, left, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
- left = 0;
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+ left -= 1000;
+ }
+ else
+ {
+ continuation = m_api.getArticles(articles, left, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+ left = 0;
+ }
}
+ writeArticles(articles);
}
- writeArticles(articles);
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/bazqux/bazquxUtils.vala b/plugins/backend/bazqux/bazquxUtils.vala
index f33ef0bf..d7ef39bf 100644
--- a/plugins/backend/bazqux/bazquxUtils.vala
+++ b/plugins/backend/bazqux/bazquxUtils.vala
@@ -14,91 +14,91 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.bazquxSecret {
-const string base_uri = "https://www.bazqux.com/reader/api/0/";
+ const string base_uri = "https://www.bazqux.com/reader/api/0/";
}
public class FeedReader.bazquxUtils : GLib.Object {
-
-private GLib.Settings m_settings;
-private Password m_password;
-
-public bazquxUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
- {
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.bazqux", settings_backend);
- }
- else
+
+ private GLib.Settings m_settings;
+ private Password m_password;
+
+ public bazquxUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings("org.gnome.feedreader.bazqux");
- }
-
- var password_schema = new Secret.Schema ("org.gnome.feedreader.bazqux", Secret.SchemaFlags.NONE,
- "type", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, password_schema, "Feedserver login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.bazqux", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.bazqux");
+ }
+
+ var password_schema = new Secret.Schema ("org.gnome.feedreader.bazqux", Secret.SchemaFlags.NONE,
+ "type", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, password_schema, "Feedserver login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["type"] = "BazQux";
attributes["Username"] = getUser();
return attributes;
});
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getAccessToken()
-{
- return Utils.gsettingReadString(m_settings, "access-token");
-}
-
-public void setAccessToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "access-token", token);
-}
-
-public string getUserID()
-{
- return Utils.gsettingReadString(m_settings, "user-id");
-}
-
-public void setUserID(string id)
-{
- Utils.gsettingWriteString(m_settings, "user-id", id);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
-
-public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
-{
- foreach(Feed feed in feeds)
+ }
+
+ public string getUser()
{
- if(feed.hasCat(tagID))
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getAccessToken()
+ {
+ return Utils.gsettingReadString(m_settings, "access-token");
+ }
+
+ public void setAccessToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "access-token", token);
+ }
+
+ public string getUserID()
+ {
+ return Utils.gsettingReadString(m_settings, "user-id");
+ }
+
+ public void setUserID(string id)
+ {
+ Utils.gsettingWriteString(m_settings, "user-id", id);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
+ }
+
+ public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+ {
+ foreach(Feed feed in feeds)
{
- return true;
+ if(feed.hasCat(tagID))
+ {
+ return true;
+ }
}
+ return false;
}
- return false;
-}
}
diff --git a/plugins/backend/decsync/decsyncInterface.vala b/plugins/backend/decsync/decsyncInterface.vala
index 55821183..e2f0113e 100644
--- a/plugins/backend/decsync/decsyncInterface.vala
+++ b/plugins/backend/decsync/decsyncInterface.vala
@@ -14,586 +14,586 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.decsyncInterface : FeedServerInterface {
-
-internal DecsyncUtils m_utils;
-private Soup.Session m_session;
-internal Decsync<Unit> m_sync;
-private string m_loginDir;
-private Gtk.Button loginButton;
-private Gtk.Spinner waitingSpinner;
-private Gtk.Stack loginStack;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new DecsyncUtils(settings_backend);
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_session.timeout = 5;
-}
-
-private bool initDecsync()
-{
- var decsyncDir = m_utils.getDecsyncDir();
- if (decsyncDir == "")
+
+ internal DecsyncUtils m_utils;
+ private Soup.Session m_session;
+ internal Decsync<Unit> m_sync;
+ private string m_loginDir;
+ private Gtk.Button loginButton;
+ private Gtk.Spinner waitingSpinner;
+ private Gtk.Stack loginStack;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- return false;
+ m_utils = new DecsyncUtils(settings_backend);
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_session.timeout = 5;
}
- var dir = getDecsyncSubdir(decsyncDir, "rss");
- var ownAppId = getAppId("FeedReader");
- var listeners = new Gee.ArrayList<OnEntryUpdateListener>();
- listeners.add(new DecsyncListeners.ReadMarkListener(true, this));
- listeners.add(new DecsyncListeners.ReadMarkListener(false, this));
- listeners.add(new DecsyncListeners.SubscriptionsListener(this));
- listeners.add(new DecsyncListeners.FeedNamesListener(this));
- listeners.add(new DecsyncListeners.CategoriesListener(this));
- listeners.add(new DecsyncListeners.CategoryNamesListener(this));
- listeners.add(new DecsyncListeners.CategoryParentsListener(this));
- m_sync = new Decsync<Unit>(dir, ownAppId, listeners);
- m_sync.syncComplete.connect((extra) => {
+
+ private bool initDecsync()
+ {
+ var decsyncDir = m_utils.getDecsyncDir();
+ if (decsyncDir == "")
+ {
+ return false;
+ }
+ var dir = getDecsyncSubdir(decsyncDir, "rss");
+ var ownAppId = getAppId("FeedReader");
+ var listeners = new Gee.ArrayList<OnEntryUpdateListener>();
+ listeners.add(new DecsyncListeners.ReadMarkListener(true, this));
+ listeners.add(new DecsyncListeners.ReadMarkListener(false, this));
+ listeners.add(new DecsyncListeners.SubscriptionsListener(this));
+ listeners.add(new DecsyncListeners.FeedNamesListener(this));
+ listeners.add(new DecsyncListeners.CategoriesListener(this));
+ listeners.add(new DecsyncListeners.CategoryNamesListener(this));
+ listeners.add(new DecsyncListeners.CategoryParentsListener(this));
+ m_sync = new Decsync<Unit>(dir, ownAppId, listeners);
+ m_sync.syncComplete.connect((extra) => {
FeedReaderBackend.get_default().updateBadge();
refreshFeedListCounter();
newFeedList();
updateArticleList();
});
- m_sync.initMonitor(new Unit());
- return true;
-}
-
-public override string getWebsite()
-{
- return "https://github.com/39aldo39/DecSync";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-}
-
-public override string getID()
-{
- return "decsync";
-}
-
-public override string iconName()
-{
- return "feed-service-decsync";
-}
-
-public override string serviceName()
-{
- return "DecSync";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var doneLabel = new Gtk.Label(_("Done"));
- var waitingLabel = new Gtk.Label(_("Adding Feeds"));
- waitingSpinner = new Gtk.Spinner();
- var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
- waitingBox.pack_start(waitingSpinner, false, false, 0);
- waitingBox.pack_start(waitingLabel, true, false, 0);
- loginStack = new Gtk.Stack();
- loginStack.add_named(doneLabel, "label");
- loginStack.add_named(waitingBox, "waiting");
- var dirLabel = new Gtk.Label(_("DecSync directory:"));
- dirLabel.set_alignment(1.0f, 0.5f);
- dirLabel.set_hexpand(true);
- m_loginDir = m_utils.getDecsyncDir();
- var buttonLabel = m_loginDir;
- if (buttonLabel == "")
- {
- buttonLabel = _("Select...");
- }
- var dirButton = new Gtk.Button.with_label(buttonLabel);
- dirButton.clicked.connect(() => {
+ m_sync.initMonitor(new Unit());
+ return true;
+ }
+
+ public override string getWebsite()
+ {
+ return "https://github.com/39aldo39/DecSync";
+ }
+
+ public override BackendFlags getFlags()
+ {
+ return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+ }
+
+ public override string getID()
+ {
+ return "decsync";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-decsync";
+ }
+
+ public override string serviceName()
+ {
+ return "DecSync";
+ }
+
+ public override bool needWebLogin()
+ {
+ return false;
+ }
+
+ public override Gtk.Box? getWidget()
+ {
+ var doneLabel = new Gtk.Label(_("Done"));
+ var waitingLabel = new Gtk.Label(_("Adding Feeds"));
+ waitingSpinner = new Gtk.Spinner();
+ var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+ waitingBox.pack_start(waitingSpinner, false, false, 0);
+ waitingBox.pack_start(waitingLabel, true, false, 0);
+ loginStack = new Gtk.Stack();
+ loginStack.add_named(doneLabel, "label");
+ loginStack.add_named(waitingBox, "waiting");
+ var dirLabel = new Gtk.Label(_("DecSync directory:"));
+ dirLabel.set_alignment(1.0f, 0.5f);
+ dirLabel.set_hexpand(true);
+ m_loginDir = m_utils.getDecsyncDir();
+ var buttonLabel = m_loginDir;
+ if (buttonLabel == "")
+ {
+ buttonLabel = _("Select...");
+ }
+ var dirButton = new Gtk.Button.with_label(buttonLabel);
+ dirButton.clicked.connect(() => {
var chooser = new Gtk.FileChooserDialog("Select Directory",
- null,
- Gtk.FileChooserAction.SELECT_FOLDER,
- _("_Cancel"),
- Gtk.ResponseType.CANCEL,
- _("_Select"),
- Gtk.ResponseType.ACCEPT);
+ null,
+ Gtk.FileChooserAction.SELECT_FOLDER,
+ _("_Cancel"),
+ Gtk.ResponseType.CANCEL,
+ _("_Select"),
+ Gtk.ResponseType.ACCEPT);
chooser.set_show_hidden(true);
chooser.set_current_folder(m_utils.getDecsyncDir());
if (chooser.run() == Gtk.ResponseType.ACCEPT)
{
- m_loginDir = chooser.get_filename();
- dirButton.set_label(m_loginDir);
+ m_loginDir = chooser.get_filename();
+ dirButton.set_label(m_loginDir);
}
chooser.close();
});
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(dirLabel, 0, 0, 1, 1);
- grid.attach(dirButton, 1, 0, 1, 1);
-
- //---------------------------------------------------------------------
-
- var logo = new Gtk.Image.from_icon_name("feed-service-decsync", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please select your DecSync directory and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- loginButton = new Gtk.Button();
- loginButton.add(loginStack);
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- return box;
-}
-
-public override void writeData()
-{
- m_utils.setDecsyncDir(m_loginDir);
-}
-
-public override async void postLoginAction()
-{
- loginButton.set_sensitive(false);
- waitingSpinner.start();
- loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginStack.set_visible_child_name("waiting");
- SourceFunc callback = postLoginAction.callback;
- new Thread<void*>(null, () => {
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(dirLabel, 0, 0, 1, 1);
+ grid.attach(dirButton, 1, 0, 1, 1);
+
+ //---------------------------------------------------------------------
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-decsync", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please select your DecSync directory and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ loginButton = new Gtk.Button();
+ loginButton.add(loginStack);
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ return box;
+ }
+
+ public override void writeData()
+ {
+ m_utils.setDecsyncDir(m_loginDir);
+ }
+
+ public override async void postLoginAction()
+ {
+ loginButton.set_sensitive(false);
+ waitingSpinner.start();
+ loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginStack.set_visible_child_name("waiting");
+ SourceFunc callback = postLoginAction.callback;
+ new Thread<void*>(null, () => {
m_sync.initStoredEntries();
m_sync.executeStoredEntries({"feeds", "subscriptions"}, new Unit());
Idle.add((owned) callback);
return null;
});
- yield;
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool doInitSync()
-{
- return false;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-decsync-symbolic";
-}
-
-public override string accountName()
-{
- return "DecSync";
-}
-
-public override string getServerURL()
-{
- return "http://localhost/";
-}
-
-public override string uncategorizedID()
-{
- return "0";
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return true;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return false;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return false;
-}
-
-public override void resetAccount()
-{
- return;
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- if (initDecsync())
+ yield;
+ }
+
+ public override bool supportTags()
{
- return LoginResponse.SUCCESS;
+ return false;
}
- else
+
+ public override bool doInitSync()
{
- return LoginResponse.ALL_EMPTY;
+ return false;
}
-}
-
-public override bool serverAvailable()
-{
- return Utils.ping("https://duckduckgo.com/");
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus readStatus)
-{
- var read = readStatus == ArticleStatus.READ;
- Logger.debug("Mark " + articleIDs + " as " + (read ? "read" : "unread"));
- var entries = new Gee.ArrayList<Decsync.EntryWithPath>();
- var db = DataBase.readOnly();
- foreach (var articleID in articleIDs.split(","))
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-decsync-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return "DecSync";
+ }
+
+ public override string getServerURL()
+ {
+ return "http://localhost/";
+ }
+
+ public override string uncategorizedID()
{
- Article? article = db.read_article(articleID);
+ return "0";
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return false;
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return true;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return false;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return false;
+ }
+
+ public override void resetAccount()
+ {
+ return;
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ if (initDecsync())
+ {
+ return LoginResponse.SUCCESS;
+ }
+ else
+ {
+ return LoginResponse.ALL_EMPTY;
+ }
+ }
+
+ public override bool serverAvailable()
+ {
+ return Utils.ping("https://duckduckgo.com/");
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus readStatus)
+ {
+ var read = readStatus == ArticleStatus.READ;
+ Logger.debug("Mark " + articleIDs + " as " + (read ? "read" : "unread"));
+ var entries = new Gee.ArrayList<Decsync.EntryWithPath>();
+ var db = DataBase.readOnly();
+ foreach (var articleID in articleIDs.split(","))
+ {
+ Article? article = db.read_article(articleID);
+ if (article != null)
+ {
+ var path = articleToPath(article, "read");
+ var key = stringToNode(article.getArticleID());
+ entries.add(new Decsync.EntryWithPath.now(path, key, boolToNode(read)));
+ }
+ }
+ m_sync.setEntries(entries);
+ }
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus markedStatus)
+ {
+ var marked = markedStatus == ArticleStatus.MARKED;
+ Logger.debug("Mark " + articleID + " as " + (marked ? "marked" : "unmarked"));
+ Article? article = DataBase.readOnly().read_article(articleID);
if (article != null)
{
- var path = articleToPath(article, "read");
+ var path = articleToPath(article, "marked");
var key = stringToNode(article.getArticleID());
- entries.add(new Decsync.EntryWithPath.now(path, key, boolToNode(read)));
+ m_sync.setEntry(path, key, boolToNode(marked));
}
}
- m_sync.setEntries(entries);
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus markedStatus)
-{
- var marked = markedStatus == ArticleStatus.MARKED;
- Logger.debug("Mark " + articleID + " as " + (marked ? "marked" : "unmarked"));
- Article? article = DataBase.readOnly().read_article(articleID);
- if (article != null)
+
+ public override bool alwaysSetReadByID()
{
- var path = articleToPath(article, "marked");
- var key = stringToNode(article.getArticleID());
- m_sync.setEntry(path, key, boolToNode(marked));
+ return true;
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return true;
-}
-
-public override void setFeedRead(string feedID)
-{
- return;
-}
-
-public override void setCategoryRead(string catID)
-{
- return;
-}
-
-public override void markAllItemsRead()
-{
- return;
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- return;
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- return "";
-}
-
-public override void deleteTag(string tagID)
-{
- return;
-}
-
-public override void renameTag(string tagID, string title)
-{
- return;
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- return addFeedWithDecsync(feedURL, catID, newCatName, out feedID, out errmsg);
-}
-
-public bool addFeedWithDecsync(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg, bool updateDecsync = true)
-{
- var db = DataBase.writeAccess();
- var catIDs = new Gee.ArrayList<string>();
- if(catID == null && newCatName != null)
+
+ public override void setFeedRead(string feedID)
{
- string cID = createCategory(newCatName, null);
- var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
- db.write_categories(ListUtils.single(cat));
- catIDs.add(cID);
+ return;
}
- else if(catID != null && newCatName == null)
+
+ public override void setCategoryRead(string catID)
{
- catIDs.add(catID);
+ return;
}
- else
+
+ public override void markAllItemsRead()
{
- catIDs.add(uncategorizedID());
+ return;
}
-
- feedID = feedURL;
-
- Logger.info(@"addFeed: ID = $feedID");
- Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
-
- if(feed != null)
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override string createTag(string caption)
+ {
+ return "";
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ return;
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ return;
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ return addFeedWithDecsync(feedURL, catID, newCatName, out feedID, out errmsg);
+ }
+
+ public bool addFeedWithDecsync(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg, bool updateDecsync = true)
{
- if(!db.feed_exists(feed.getURL()))
+ var db = DataBase.writeAccess();
+ var catIDs = new Gee.ArrayList<string>();
+ if(catID == null && newCatName != null)
{
- db.write_feeds(ListUtils.single(feed));
-
- if (updateDecsync)
+ string cID = createCategory(newCatName, null);
+ var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
+ db.write_categories(ListUtils.single(cat));
+ catIDs.add(cID);
+ }
+ else if(catID != null && newCatName == null)
+ {
+ catIDs.add(catID);
+ }
+ else
+ {
+ catIDs.add(uncategorizedID());
+ }
+
+ feedID = feedURL;
+
+ Logger.info(@"addFeed: ID = $feedID");
+ Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
+
+ if(feed != null)
+ {
+ if(!db.feed_exists(feed.getURL()))
{
- m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(true));
- renameFeed(feedID, feed.getTitle());
- moveFeed(feedID, feed.getCatString(), null);
+ db.write_feeds(ListUtils.single(feed));
+
+ if (updateDecsync)
+ {
+ m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(true));
+ renameFeed(feedID, feed.getTitle());
+ moveFeed(feedID, feed.getCatString(), null);
+ }
+
+ m_sync.executeStoredEntries({"feeds", "names"}, new Unit(),
+ stringEquals(feedID)
+ );
+ m_sync.executeStoredEntries({"feeds", "categories"}, new Unit(),
+ stringEquals(feedID)
+ );
+ return true;
}
-
- m_sync.executeStoredEntries({"feeds", "names"}, new Unit(),
- stringEquals(feedID)
- );
- m_sync.executeStoredEntries({"feeds", "categories"}, new Unit(),
- stringEquals(feedID)
- );
- return true;
}
+
+ return false;
}
-
- return false;
-}
-
-public override void removeFeed(string feedID)
-{
- m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(false));
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_sync.setEntry({"feeds", "names"}, stringToNode(feedID), stringToNode(title));
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- string? value = newCatID == uncategorizedID() ? null : newCatID;
- m_sync.setEntry({"feeds", "categories"}, stringToNode(feedID), stringToNode(value));
-}
-
-public override string createCategory(string title, string? parentID)
-{
- var db = DataBase.readOnly();
- string? catID = db.getCategoryID(title);
- while (catID == null || db.read_category(catID) != null)
+
+ public override void removeFeed(string feedID)
{
- catID = "catID%05d".printf(Random.int_range(0, 100000));
+ m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(false));
}
- renameCategory(catID, title);
- moveCategory(catID, parentID ?? CategoryID.MASTER.to_string());
- Logger.info("createCategory: ID = " + catID);
- return catID;
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_sync.setEntry({"categories", "names"}, stringToNode(catID), stringToNode(title));
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- string? value = newParentID == CategoryID.MASTER.to_string() ? null : newParentID;
- m_sync.setEntry({"categories", "parents"}, stringToNode(catID), stringToNode(value));
-}
-
-public override void deleteCategory(string catID)
-{
- Logger.info("Delete category " + catID);
- var feedIDs = DataBase.readOnly().getFeedIDofCategorie(catID);
- foreach (var feedID in feedIDs)
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_sync.setEntry({"feeds", "names"}, stringToNode(feedID), stringToNode(title));
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ string? value = newCatID == uncategorizedID() ? null : newCatID;
+ m_sync.setEntry({"feeds", "categories"}, stringToNode(feedID), stringToNode(value));
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ var db = DataBase.readOnly();
+ string? catID = db.getCategoryID(title);
+ while (catID == null || db.read_category(catID) != null)
+ {
+ catID = "catID%05d".printf(Random.int_range(0, 100000));
+ }
+ renameCategory(catID, title);
+ moveCategory(catID, parentID ?? CategoryID.MASTER.to_string());
+ Logger.info("createCategory: ID = " + catID);
+ return catID;
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_sync.setEntry({"categories", "names"}, stringToNode(catID), stringToNode(title));
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ string? value = newParentID == CategoryID.MASTER.to_string() ? null : newParentID;
+ m_sync.setEntry({"categories", "parents"}, stringToNode(catID), stringToNode(value));
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ Logger.info("Delete category " + catID);
+ var feedIDs = DataBase.readOnly().getFeedIDofCategorie(catID);
+ foreach (var feedID in feedIDs)
+ {
+ moveFeed(feedID, uncategorizedID(), catID);
+ }
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
{
moveFeed(feedID, uncategorizedID(), catID);
}
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- moveFeed(feedID, uncategorizedID(), catID);
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- return true;
-}
-
-public override int getUnreadCount()
-{
- return 0;
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- var feeds = DataBase.readOnly().read_feeds();
- var articles = new Gee.ArrayList<Article>();
- GLib.Mutex mutex = GLib.Mutex();
- var now = new GLib.DateTime.now_local();
- int? weeks = ((DropArticles)Settings.general().get_enum("drop-articles-after")).to_weeks();
- var dropDate = weeks == null ? null : now.add_weeks(-(int)weeks);
-
- try
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ return true;
+ }
+
+ public override int getUnreadCount()
{
- var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
+ return 0;
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ var feeds = DataBase.readOnly().read_feeds();
+ var articles = new Gee.ArrayList<Article>();
+ GLib.Mutex mutex = GLib.Mutex();
+ var now = new GLib.DateTime.now_local();
+ int? weeks = ((DropArticles)Settings.general().get_enum("drop-articles-after")).to_weeks();
+ var dropDate = weeks == null ? null : now.add_weeks(-(int)weeks);
+
+ try
+ {
+ var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
if(cancellable != null && cancellable.is_cancelled())
{
- return;
+ return;
}
-
+
Logger.debug("getArticles for feed: " + feed.getTitle());
string url = feed.getXmlUrl().escape("");
-
+
if(url == null || url == "" || GLib.Uri.parse_scheme(url) == null)
{
- Logger.error("no valid URL");
- return;
+ Logger.error("no valid URL");
+ return;
}
-
+
var msg = new Soup.Message("GET", url);
var session = new Soup.Session();
session.user_agent = Constants.USER_AGENT;
session.timeout = 5;
session.send_message(msg);
string xml = (string)msg.response_body.flatten().data;
-
+
// parse
Rss.Parser parser = new Rss.Parser();
try
{
- parser.load_from_data(xml, xml.length);
+ parser.load_from_data(xml, xml.length);
}
catch(GLib.Error e)
{
- Logger.error("decsyncInterface.getArticles: %s".printf(e.message));
- return;
+ Logger.error("decsyncInterface.getArticles: %s".printf(e.message));
+ return;
}
var doc = parser.get_document();
-
+
string? locale = null;
if(doc.encoding != null
- && doc.encoding != "")
+ && doc.encoding != "")
{
- locale = doc.encoding;
+ locale = doc.encoding;
}
-
+
Logger.debug("Got %u articles".printf(doc.get_items().length()));
var newArticles = new Gee.ArrayList<Article>();
var db = DataBase.readOnly();
foreach(Rss.Item item in doc.get_items())
{
- string? articleID = item.guid;
-
- if(articleID == null)
- {
- if(item.link == null)
- {
- Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
- continue;
+ string? articleID = item.guid;
+
+ if(articleID == null)
+ {
+ if(item.link == null)
+ {
+ Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
+ continue;
}
-
- articleID = item.link;
+
+ articleID = item.link;
}
-
- if (db.read_article(articleID) != null)
- {
- continue;
+
+ if (db.read_article(articleID) != null)
+ {
+ continue;
}
-
- var date = Rfc822.parseDate(item.pub_date);
- if (date != null)
- {
- Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
+
+ var date = Rfc822.parseDate(item.pub_date);
+ if (date != null)
+ {
+ Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
}
- else
- {
- if (item.pub_date != null)
- {
- Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
+ else
+ {
+ if (item.pub_date != null)
+ {
+ Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
}
- date = new DateTime.now_local();
+ date = new DateTime.now_local();
}
-
- if (dropDate != null && date.compare(dropDate) == -1)
- {
- continue;
+
+ if (dropDate != null && date.compare(dropDate) == -1)
+ {
+ continue;
}
-
- //Logger.info("Got content: " + item.description);
- string? content = m_utils.convert(item.description, locale);
- //Logger.info("Converted to: " + item.description);
- if(content == null)
- {
- content = _("Nothing to read here.");
+
+ //Logger.info("Got content: " + item.description);
+ string? content = m_utils.convert(item.description, locale);
+ //Logger.info("Converted to: " + item.description);
+ if(content == null)
+ {
+ content = _("Nothing to read here.");
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
-
- if(item.enclosure_url != null)
- {
- // FIXME: check what type of media we actually got
- enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+
+ if(item.enclosure_url != null)
+ {
+ // FIXME: check what type of media we actually got
+ enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
}
-
- string articleURL = item.link;
- if(articleURL.has_prefix("/"))
- {
- articleURL = feed.getURL() + articleURL.substring(1);
+
+ string articleURL = item.link;
+ if(articleURL.has_prefix("/"))
+ {
+ articleURL = feed.getURL() + articleURL.substring(1);
}
-
- var article = new Article(
+
+ var article = new Article(
articleID,
(item.title != null) ? m_utils.convert(item.title, locale) : null,
articleURL,
@@ -607,90 +607,90 @@ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? s
0,
null,
enclosures
- );
-
- Logger.debug("Got new article: " + article.getTitle());
-
- newArticles.add(article);
+ );
+
+ Logger.debug("Got new article: " + article.getTitle());
+
+ newArticles.add(article);
}
mutex.lock();
articles.add_all(newArticles);
mutex.unlock();
}, (int)GLib.get_num_processors(), true);
-
- foreach(Feed feed in feeds)
- {
- try
+
+ foreach(Feed feed in feeds)
{
- threads.add(feed);
- }
- catch(GLib.Error e)
- {
- Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
+ try
+ {
+ threads.add(feed);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
+ }
}
+
+ bool immediate = false; // allow to queue up additional tasks
+ bool wait = true; // function will block until all tasks are done
+ ThreadPool.free((owned)threads, immediate, wait);
}
-
- bool immediate = false; // allow to queue up additional tasks
- bool wait = true; // function will block until all tasks are done
- ThreadPool.free((owned)threads, immediate, wait);
- }
- catch(Error e)
- {
- Logger.error("Error creating threads to download Feeds: " + e.message);
- }
-
- articles.sort((a, b) => {
+ catch(Error e)
+ {
+ Logger.error("Error creating threads to download Feeds: " + e.message);
+ }
+
+ articles.sort((a, b) => {
return strcmp(a.getArticleID(), b.getArticleID());
});
-
- if(articles.size > 0)
- {
- DataBase.writeAccess().write_articles(articles);
- Logger.debug("decsyncInterface: %i articles written".printf(articles.size));
-
- var multiMap = groupBy<Article, Gee.List<string>, Article>(
- articles,
- article => { return articleToBasePath(article); }
+
+ if(articles.size > 0)
+ {
+ DataBase.writeAccess().write_articles(articles);
+ Logger.debug("decsyncInterface: %i articles written".printf(articles.size));
+
+ var multiMap = groupBy<Article, Gee.List<string>, Article>(
+ articles,
+ article => { return articleToBasePath(article); }
);
- multiMap.get_keys().@foreach(basePath => {
+ multiMap.get_keys().@foreach(basePath => {
var articleIDs = multiMap.@get(basePath).map<Json.Node>(article => {
return stringToNode(article.getArticleID());
});
foreach (var type in toList({"read","marked"}))
{
- m_sync.executeStoredEntries(basePathToPath(basePath, type), new Unit(),
- key => { return articleIDs.any_match(articleID => { return articleID.equal(key); }); }
- );
+ m_sync.executeStoredEntries(basePathToPath(basePath, type), new Unit(),
+ key => { return articleIDs.any_match(articleID => { return articleID.equal(key); }); }
+ );
}
return true;
});
+ }
+
+ m_sync.executeAllNewEntries(new Unit());
+ }
+
+ private string[] articleToPath(Article article, string type)
+ {
+ return basePathToPath(articleToBasePath(article), type);
+ }
+
+ private string[] basePathToPath(Gee.List<string> basePath, string type)
+ {
+ var path = new Gee.ArrayList<string>();
+ path.add("articles");
+ path.add(type);
+ path.add_all(basePath);
+ return path.to_array();
+ }
+
+ private Gee.List<string> articleToBasePath(Article article)
+ {
+ var datetime = article.getDate().to_utc();
+ var year = datetime.format("%Y");
+ var month = datetime.format("%m");
+ var day = datetime.format("%d");
+ return toList({year, month, day});
}
-
- m_sync.executeAllNewEntries(new Unit());
-}
-
-private string[] articleToPath(Article article, string type)
-{
- return basePathToPath(articleToBasePath(article), type);
-}
-
-private string[] basePathToPath(Gee.List<string> basePath, string type)
-{
- var path = new Gee.ArrayList<string>();
- path.add("articles");
- path.add(type);
- path.add_all(basePath);
- return path.to_array();
-}
-
-private Gee.List<string> articleToBasePath(Article article)
-{
- var datetime = article.getDate().to_utc();
- var year = datetime.format("%Y");
- var month = datetime.format("%m");
- var day = datetime.format("%d");
- return toList({year, month, day});
-}
}
[ModuleInit]
diff --git a/plugins/backend/decsync/decsyncListeners.vala b/plugins/backend/decsync/decsyncListeners.vala
index d223aab6..8d6b6cf7 100644
--- a/plugins/backend/decsync/decsyncListeners.vala
+++ b/plugins/backend/decsync/decsyncListeners.vala
@@ -14,275 +14,275 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.DecsyncListeners : GLib.Object {
-
-public class ReadMarkListener : OnSubdirEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subdir;
-private bool m_is_read_entry;
-private decsyncInterface m_plugin;
-
-public ReadMarkListener(bool is_read_entry, decsyncInterface plugin)
-{
- this.m_subdir = toList({"articles", is_read_entry ? "read" : "marked"});
- this.m_is_read_entry = is_read_entry;
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subdir()
-{
- return m_subdir;
-}
-
-public override void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, Unit extra)
-{
- var articleID = entry.key.get_string();
- if (articleID == null)
- {
- Logger.warning("Invalid articleID " + Json.to_string(entry.key, false));
- return;
- }
- var added = entry.value.get_boolean();
- if (m_is_read_entry)
- {
- Logger.debug((added ? "read " : "unread ") + articleID);
- }
- else
- {
- Logger.debug((added ? "mark " : "unmark ") + articleID);
- }
- var db = DataBase.writeAccess();
- Article? article = db.read_article(articleID);
- if (article == null)
- {
- Logger.info("Unkown article " + articleID);
- return;
- }
- if (m_is_read_entry)
- {
- article.setUnread(added ? ArticleStatus.READ : ArticleStatus.UNREAD);
- }
- else
- {
- article.setMarked(added ? ArticleStatus.MARKED : ArticleStatus.UNMARKED);
- }
- db.update_article(article);
-}
-}
-
-public class SubscriptionsListener : OnSubfileEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subfile;
-private decsyncInterface m_plugin;
-
-public SubscriptionsListener(decsyncInterface plugin)
-{
- this.m_subfile = toList({"feeds", "subscriptions"});
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subfile()
-{
- return m_subfile;
-}
-
-public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-{
- var feedID = entry.key.get_string();
- if (feedID == null)
- {
- Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
- return;
- }
- var subscribed = entry.value.get_boolean();
- if (subscribed)
- {
- string outFeedID, errmsg;
- m_plugin.addFeedWithDecsync(feedID, null, null, out outFeedID, out errmsg, false);
- }
- else
- {
- DataBase.writeAccess().delete_feed(feedID);
- }
-}
-}
-
-public class FeedNamesListener : OnSubfileEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subfile;
-private decsyncInterface m_plugin;
-
-public FeedNamesListener(decsyncInterface plugin)
-{
- this.m_subfile = toList({"feeds", "names"});
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subfile()
-{
- return m_subfile;
-}
-
-public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-{
- var feedID = entry.key.get_string();
- if (feedID == null)
- {
- Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
- return;
- }
- var name = entry.value.get_string();
- if (name == null)
- {
- Logger.warning("Invalid name " + Json.to_string(entry.value, false));
- return;
- }
- DataBase.writeAccess().rename_feed(feedID, name);
-}
-}
-
-public class CategoriesListener : OnSubfileEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subfile;
-private decsyncInterface m_plugin;
-
-public CategoriesListener(decsyncInterface plugin)
-{
- this.m_subfile = toList({"feeds", "categories"});
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subfile()
-{
- return m_subfile;
-}
-
-public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-{
- var feedID = entry.key.get_string();
- if (feedID == null)
- {
- Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
- return;
+
+ public class ReadMarkListener : OnSubdirEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subdir;
+ private bool m_is_read_entry;
+ private decsyncInterface m_plugin;
+
+ public ReadMarkListener(bool is_read_entry, decsyncInterface plugin)
+ {
+ this.m_subdir = toList({"articles", is_read_entry ? "read" : "marked"});
+ this.m_is_read_entry = is_read_entry;
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subdir()
+ {
+ return m_subdir;
+ }
+
+ public override void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, Unit extra)
+ {
+ var articleID = entry.key.get_string();
+ if (articleID == null)
+ {
+ Logger.warning("Invalid articleID " + Json.to_string(entry.key, false));
+ return;
+ }
+ var added = entry.value.get_boolean();
+ if (m_is_read_entry)
+ {
+ Logger.debug((added ? "read " : "unread ") + articleID);
+ }
+ else
+ {
+ Logger.debug((added ? "mark " : "unmark ") + articleID);
+ }
+ var db = DataBase.writeAccess();
+ Article? article = db.read_article(articleID);
+ if (article == null)
+ {
+ Logger.info("Unkown article " + articleID);
+ return;
+ }
+ if (m_is_read_entry)
+ {
+ article.setUnread(added ? ArticleStatus.READ : ArticleStatus.UNREAD);
+ }
+ else
+ {
+ article.setMarked(added ? ArticleStatus.MARKED : ArticleStatus.UNMARKED);
+ }
+ db.update_article(article);
+ }
}
- var db = DataBase.writeAccess();
- var feed = db.read_feed(feedID);
- if (feed == null)
- {
- return;
+
+ public class SubscriptionsListener : OnSubfileEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subfile;
+ private decsyncInterface m_plugin;
+
+ public SubscriptionsListener(decsyncInterface plugin)
+ {
+ this.m_subfile = toList({"feeds", "subscriptions"});
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subfile()
+ {
+ return m_subfile;
+ }
+
+ public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+ {
+ var feedID = entry.key.get_string();
+ if (feedID == null)
+ {
+ Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+ return;
+ }
+ var subscribed = entry.value.get_boolean();
+ if (subscribed)
+ {
+ string outFeedID, errmsg;
+ m_plugin.addFeedWithDecsync(feedID, null, null, out outFeedID, out errmsg, false);
+ }
+ else
+ {
+ DataBase.writeAccess().delete_feed(feedID);
+ }
+ }
}
- var currentCatID = feed.getCatString();
- string newCatID;
- if (entry.value.is_null())
- {
- newCatID = m_plugin.uncategorizedID();
+
+ public class FeedNamesListener : OnSubfileEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subfile;
+ private decsyncInterface m_plugin;
+
+ public FeedNamesListener(decsyncInterface plugin)
+ {
+ this.m_subfile = toList({"feeds", "names"});
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subfile()
+ {
+ return m_subfile;
+ }
+
+ public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+ {
+ var feedID = entry.key.get_string();
+ if (feedID == null)
+ {
+ Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+ return;
+ }
+ var name = entry.value.get_string();
+ if (name == null)
+ {
+ Logger.warning("Invalid name " + Json.to_string(entry.value, false));
+ return;
+ }
+ DataBase.writeAccess().rename_feed(feedID, name);
+ }
}
- else
- {
- newCatID = entry.value.get_string();
+
+ public class CategoriesListener : OnSubfileEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subfile;
+ private decsyncInterface m_plugin;
+
+ public CategoriesListener(decsyncInterface plugin)
+ {
+ this.m_subfile = toList({"feeds", "categories"});
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subfile()
+ {
+ return m_subfile;
+ }
+
+ public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+ {
+ var feedID = entry.key.get_string();
+ if (feedID == null)
+ {
+ Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+ return;
+ }
+ var db = DataBase.writeAccess();
+ var feed = db.read_feed(feedID);
+ if (feed == null)
+ {
+ return;
+ }
+ var currentCatID = feed.getCatString();
+ string newCatID;
+ if (entry.value.is_null())
+ {
+ newCatID = m_plugin.uncategorizedID();
+ }
+ else
+ {
+ newCatID = entry.value.get_string();
+ }
+ if (newCatID == null)
+ {
+ Logger.warning("Invalid catID " + Json.to_string(entry.value, false));
+ return;
+ }
+ addCategory(m_plugin, newCatID);
+ db.move_feed(feedID, currentCatID, newCatID);
+ }
}
- if (newCatID == null)
- {
- Logger.warning("Invalid catID " + Json.to_string(entry.value, false));
- return;
+
+ public class CategoryNamesListener : OnSubfileEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subfile;
+ private decsyncInterface m_plugin;
+
+ public CategoryNamesListener(decsyncInterface plugin)
+ {
+ this.m_subfile = toList({"categories", "names"});
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subfile()
+ {
+ return m_subfile;
+ }
+
+ public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+ {
+ var catID = entry.key.get_string();
+ if (catID == null)
+ {
+ Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
+ return;
+ }
+ var name = entry.value.get_string();
+ if (name == null)
+ {
+ Logger.warning("Invalid name " + Json.to_string(entry.value, false));
+ return;
+ }
+ DataBase.writeAccess().rename_category(catID, name);
+ Logger.debug("Renamed category " + catID + " to " + name);
+ }
}
- addCategory(m_plugin, newCatID);
- db.move_feed(feedID, currentCatID, newCatID);
-}
-}
-
-public class CategoryNamesListener : OnSubfileEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subfile;
-private decsyncInterface m_plugin;
-
-public CategoryNamesListener(decsyncInterface plugin)
-{
- this.m_subfile = toList({"categories", "names"});
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subfile()
-{
- return m_subfile;
-}
-
-public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-{
- var catID = entry.key.get_string();
- if (catID == null)
- {
- Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
- return;
+
+ public class CategoryParentsListener : OnSubfileEntryUpdateListener<Unit> {
+
+ private Gee.List<string> m_subfile;
+ private decsyncInterface m_plugin;
+
+ public CategoryParentsListener(decsyncInterface plugin)
+ {
+ this.m_subfile = toList({"categories", "parents"});
+ this.m_plugin = plugin;
+ }
+
+ public override Gee.List<string> subfile()
+ {
+ return m_subfile;
+ }
+
+ public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+ {
+ var catID = entry.key.get_string();
+ if (catID == null)
+ {
+ Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
+ return;
+ }
+ string parentID;
+ if (entry.value.is_null())
+ {
+ parentID = CategoryID.MASTER.to_string();
+ }
+ else
+ {
+ parentID = entry.value.get_string();
+ }
+ if (parentID == null)
+ {
+ Logger.warning("Invalid parentID " + Json.to_string(entry.value, false));
+ return;
+ }
+ addCategory(m_plugin, parentID);
+ DataBase.writeAccess().move_category(catID, parentID);
+ Logger.debug("Moved category " + catID + " to " + parentID);
+ }
}
- var name = entry.value.get_string();
- if (name == null)
+
+ private static void addCategory(decsyncInterface plugin, string catID)
{
- Logger.warning("Invalid name " + Json.to_string(entry.value, false));
- return;
+ if (catID == plugin.uncategorizedID() || catID == CategoryID.MASTER.to_string() || DataBase.readOnly().read_category(catID) != null)
+ {
+ return;
+ }
+ var cat = new Category(catID, catID, 0, 99, CategoryID.MASTER.to_string(), 1);
+ DataBase.writeAccess().write_categories(ListUtils.single(cat));
+ plugin.m_sync.executeStoredEntries({"categories", "names"}, new Unit(),
+ stringEquals(catID)
+ );
+ plugin.m_sync.executeStoredEntries({"categories", "parents"}, new Unit(),
+ stringEquals(catID)
+ );
+ Logger.debug("Added category " + catID);
}
- DataBase.writeAccess().rename_category(catID, name);
- Logger.debug("Renamed category " + catID + " to " + name);
-}
-}
-
-public class CategoryParentsListener : OnSubfileEntryUpdateListener<Unit> {
-
-private Gee.List<string> m_subfile;
-private decsyncInterface m_plugin;
-
-public CategoryParentsListener(decsyncInterface plugin)
-{
- this.m_subfile = toList({"categories", "parents"});
- this.m_plugin = plugin;
-}
-
-public override Gee.List<string> subfile()
-{
- return m_subfile;
-}
-
-public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-{
- var catID = entry.key.get_string();
- if (catID == null)
- {
- Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
- return;
- }
- string parentID;
- if (entry.value.is_null())
- {
- parentID = CategoryID.MASTER.to_string();
- }
- else
- {
- parentID = entry.value.get_string();
- }
- if (parentID == null)
- {
- Logger.warning("Invalid parentID " + Json.to_string(entry.value, false));
- return;
- }
- addCategory(m_plugin, parentID);
- DataBase.writeAccess().move_category(catID, parentID);
- Logger.debug("Moved category " + catID + " to " + parentID);
-}
-}
-
-private static void addCategory(decsyncInterface plugin, string catID)
-{
- if (catID == plugin.uncategorizedID() || catID == CategoryID.MASTER.to_string() || DataBase.readOnly().read_category(catID) != null)
- {
- return;
- }
- var cat = new Category(catID, catID, 0, 99, CategoryID.MASTER.to_string(), 1);
- DataBase.writeAccess().write_categories(ListUtils.single(cat));
- plugin.m_sync.executeStoredEntries({"categories", "names"}, new Unit(),
- stringEquals(catID)
- );
- plugin.m_sync.executeStoredEntries({"categories", "parents"}, new Unit(),
- stringEquals(catID)
- );
- Logger.debug("Added category " + catID);
-}
}
diff --git a/plugins/backend/decsync/decsyncUtils.vala b/plugins/backend/decsync/decsyncUtils.vala
index c0b9061f..5ad2557d 100644
--- a/plugins/backend/decsync/decsyncUtils.vala
+++ b/plugins/backend/decsync/decsyncUtils.vala
@@ -14,127 +14,127 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.DecsyncUtils : GLib.Object {
-
-GLib.Settings m_settings;
-
-public DecsyncUtils(GLib.SettingsBackend? settings_backend)
-{
- if(settings_backend != null)
- {
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.decsync", settings_backend);
- }
- else
- {
- m_settings = new GLib.Settings("org.gnome.feedreader.decsync");
- }
-}
-
-public string getDecsyncDir()
-{
- var dir = Utils.gsettingReadString(m_settings, "decsync-dir");
- if (dir == "")
- {
- return GLib.Environment.get_variable("DECSYNC_DIR") ?? getDefaultDecsyncBaseDir();
- }
- else
- {
- return dir;
- }
-}
-
-public void setDecsyncDir(string decsyncDir)
-{
- Utils.gsettingWriteString(m_settings, "decsync-dir", decsyncDir);
-}
-
-public Feed? downloadFeed(Soup.Session session, string feed_url, string feedID, Gee.List<string> catIDs, out string errmsg)
-{
- var error = new StringBuilder(_("Failed to add feed"));
- error.append_printf(" %s\n", feed_url);
-
- var msg = new Soup.Message("GET", feed_url);
- if (msg == null)
- {
- error.append(_("Failed to parse URL."));
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
- }
-
- uint status = session.send_message(msg);
- if(status < 100 || status >= 400)
+
+ GLib.Settings m_settings;
+
+ public DecsyncUtils(GLib.SettingsBackend? settings_backend)
{
- if(status < 100)
+ if(settings_backend != null)
{
- error.append(_("Network error connecting to the server."));
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.decsync", settings_backend);
}
else
{
- error.append(_("Got HTTP error code"));
- error.append_printf(" %u %s", status, Soup.Status.get_phrase(status));
+ m_settings = new GLib.Settings("org.gnome.feedreader.decsync");
}
-
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
}
- string xml = (string)msg.response_body.flatten().data;
- string? url = null;
-
- // parse
- Rss.Parser parser = new Rss.Parser();
- try
+
+ public string getDecsyncDir()
{
- parser.load_from_data(xml, xml.length);
+ var dir = Utils.gsettingReadString(m_settings, "decsync-dir");
+ if (dir == "")
+ {
+ return GLib.Environment.get_variable("DECSYNC_DIR") ?? getDefaultDecsyncBaseDir();
+ }
+ else
+ {
+ return dir;
+ }
}
- catch(Error e)
+
+ public void setDecsyncDir(string decsyncDir)
{
- error.append(_("Could not parse feed as RSS or ATOM."));
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
+ Utils.gsettingWriteString(m_settings, "decsync-dir", decsyncDir);
}
-
- var doc = parser.get_document();
-
- if(doc.link != null
- && doc.link != "")
+
+ public Feed? downloadFeed(Soup.Session session, string feed_url, string feedID, Gee.List<string> catIDs, out string errmsg)
{
- url = doc.link;
- }
-
- errmsg = "";
- return new Feed(
- feedID,
- doc.title,
- url,
- 0,
- catIDs,
- doc.image_url,
+ var error = new StringBuilder(_("Failed to add feed"));
+ error.append_printf(" %s\n", feed_url);
+
+ var msg = new Soup.Message("GET", feed_url);
+ if (msg == null)
+ {
+ error.append(_("Failed to parse URL."));
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
+ }
+
+ uint status = session.send_message(msg);
+ if(status < 100 || status >= 400)
+ {
+ if(status < 100)
+ {
+ error.append(_("Network error connecting to the server."));
+ }
+ else
+ {
+ error.append(_("Got HTTP error code"));
+ error.append_printf(" %u %s", status, Soup.Status.get_phrase(status));
+ }
+
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
+ }
+ string xml = (string)msg.response_body.flatten().data;
+ string? url = null;
+
+ // parse
+ Rss.Parser parser = new Rss.Parser();
+ try
+ {
+ parser.load_from_data(xml, xml.length);
+ }
+ catch(Error e)
+ {
+ error.append(_("Could not parse feed as RSS or ATOM."));
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
+ }
+
+ var doc = parser.get_document();
+
+ if(doc.link != null
+ && doc.link != "")
+ {
+ url = doc.link;
+ }
+
+ errmsg = "";
+ return new Feed(
+ feedID,
+ doc.title,
+ url,
+ 0,
+ catIDs,
+ doc.image_url,
feed_url);
-}
-
-public string? convert(string? text, string? locale)
-{
- if(text == null)
- {
- return null;
- }
-
- if(locale == null)
- {
- return text;
- }
-
- try
- {
- return GLib.convert(text, -1, "utf-8", locale);
}
- catch(ConvertError e)
+
+ public string? convert(string? text, string? locale)
{
- Logger.error(e.message);
+ if(text == null)
+ {
+ return null;
+ }
+
+ if(locale == null)
+ {
+ return text;
+ }
+
+ try
+ {
+ return GLib.convert(text, -1, "utf-8", locale);
+ }
+ catch(ConvertError e)
+ {
+ Logger.error(e.message);
+ }
+
+ return "";
}
-
- return "";
-}
}
diff --git a/plugins/backend/decsync/libdecsync/src/Decsync.vala b/plugins/backend/decsync/libdecsync/src/Decsync.vala
index d18c3b1e..ba4ca131 100644
--- a/plugins/backend/decsync/libdecsync/src/Decsync.vala
+++ b/plugins/backend/decsync/libdecsync/src/Decsync.vala
@@ -1,71 +1,71 @@
/**
- * libdecsync-vala - Decsync.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - Decsync.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public class Unit { public Unit() {
- }
+}
}
/**
- * The `DecSync` class represents an interface to synchronized key-value mappings stored on the file
- * system.
- *
- * The mappings can be synchronized by synchronizing the directory [dir]. The stored mappings are
- * stored in a conflict-free way. When the same keys are updated independently, the most recent
- * value is taken. This should not cause problems when the individual values contain as little
- * information as possible.
- *
- * Every entry consists of a path, a key and a value. The path is a list of strings which contains
- * the location to the used mapping. This can make interacting with the data easier. It is also used
- * to construct a path in the file system. All characters are allowed in the path. However, other
- * limitations of the file system may apply. For example, there may be a maximum length or the file
- * system may be case insensitive.
- *
- * To update an entry, use the method [setEntry]. When multiple keys in the same path are updated
- * simultaneous, it is encouraged to use the more efficient methods [setEntriesForPath] and
- * [setEntries].
- *
- * To get notified about updated entries, use the method [executeAllNewEntries] to get all updated
- * entries and execute the corresponding actions. The method [initObserver] creates a file observer
- * which is notified about the updated entries immediately.
- *
- * Sometimes, updates cannot be execute immediately. For example, if the name of a category is
- * updated when the category does not exist yet, the name cannot be changed. In such cases, the
- * updates have to be executed retroactively. In the example, the update can be executed when the
- * category is created. For such cases, use the method [executeStoredEntries].
- *
- * Finally, to initialize the stored entries to the most recent values, use the method
- * [initStoredEntries]. This method is almost exclusively used when the application is installed. It
- * is almost always followed by a call to [executeStoredEntries].
- *
- * @param T the type of the extra data passed to the [listeners] and [syncComplete].
- * @property dir the directory in which the synchronized DecSync files are stored.
- * For the default location, use [getDecsyncSubdir].
- * @property ownAppId the unique appId corresponding to the stored data by the application. There
- * must not be two simultaneous instances with the same appId. However, if an application is
- * reinstalled, it may reuse its old appId. In that case, it has to call [initStoredEntries] and
- * [executeStoredEntries]. Even if the old appId is not reused, it is still recommended call these.
- * For the default appId, use [getAppId].
- * @property listeners a list of listeners describing the actions to execute on every updated entry.
- * When an entry is updated, the method [OnEntryUpdateListener.onEntriesUpdate] is called on the
- * listener whose method [OnEntryUpdateListener.matchesPath] returns true.
- * @property syncComplete an optional function which is called when a sync is complete. For example,
- * it can be used to update the UI.
- */
+* The `DecSync` class represents an interface to synchronized key-value mappings stored on the file
+* system.
+*
+* The mappings can be synchronized by synchronizing the directory [dir]. The stored mappings are
+* stored in a conflict-free way. When the same keys are updated independently, the most recent
+* value is taken. This should not cause problems when the individual values contain as little
+* information as possible.
+*
+* Every entry consists of a path, a key and a value. The path is a list of strings which contains
+* the location to the used mapping. This can make interacting with the data easier. It is also used
+* to construct a path in the file system. All characters are allowed in the path. However, other
+* limitations of the file system may apply. For example, there may be a maximum length or the file
+* system may be case insensitive.
+*
+* To update an entry, use the method [setEntry]. When multiple keys in the same path are updated
+* simultaneous, it is encouraged to use the more efficient methods [setEntriesForPath] and
+* [setEntries].
+*
+* To get notified about updated entries, use the method [executeAllNewEntries] to get all updated
+* entries and execute the corresponding actions. The method [initObserver] creates a file observer
+* which is notified about the updated entries immediately.
+*
+* Sometimes, updates cannot be execute immediately. For example, if the name of a category is
+* updated when the category does not exist yet, the name cannot be changed. In such cases, the
+* updates have to be executed retroactively. In the example, the update can be executed when the
+* category is created. For such cases, use the method [executeStoredEntries].
+*
+* Finally, to initialize the stored entries to the most recent values, use the method
+* [initStoredEntries]. This method is almost exclusively used when the application is installed. It
+* is almost always followed by a call to [executeStoredEntries].
+*
+* @param T the type of the extra data passed to the [listeners] and [syncComplete].
+* @property dir the directory in which the synchronized DecSync files are stored.
+* For the default location, use [getDecsyncSubdir].
+* @property ownAppId the unique appId corresponding to the stored data by the application. There
+* must not be two simultaneous instances with the same appId. However, if an application is
+* reinstalled, it may reuse its old appId. In that case, it has to call [initStoredEntries] and
+* [executeStoredEntries]. Even if the old appId is not reused, it is still recommended call these.
+* For the default appId, use [getAppId].
+* @property listeners a list of listeners describing the actions to execute on every updated entry.
+* When an entry is updated, the method [OnEntryUpdateListener.onEntriesUpdate] is called on the
+* listener whose method [OnEntryUpdateListener.matchesPath] returns true.
+* @property syncComplete an optional function which is called when a sync is complete. For example,
+* it can be used to update the UI.
+*/
public class Decsync<T> : GLib.Object {
string dir;
@@ -75,8 +75,8 @@ Gee.Iterable<OnEntryUpdateListener<T>> listeners;
DirectoryMonitor? monitor = null;
/**
- * Signal which is called when a sync is complete. For example, it can be used to update the UI.
- */
+* Signal which is called when a sync is complete. For example, it can be used to update the UI.
+*/
public signal void syncComplete(T extra);
public Decsync(string dir, string ownAppId, Gee.Iterable<OnEntryUpdateListener<T>> listeners)
@@ -88,115 +88,115 @@ public Decsync(string dir, string ownAppId, Gee.Iterable<OnEntryUpdateListener<T
}
/**
- * Represents an [Entry] with its path.
- */
+* Represents an [Entry] with its path.
+*/
public class EntryWithPath {
-public Gee.List<string> path;
-public Entry entry;
-
-public EntryWithPath(string[] path, Entry entry)
-{
- this.path = toList(path);
- this.entry = entry;
-}
-
-public EntryWithPath.now(string[] path, Json.Node key, Json.Node value)
-{
- this.path = toList(path);
- this.entry = new Entry.now(key, value);
-}
+ public Gee.List<string> path;
+ public Entry entry;
+
+ public EntryWithPath(string[] path, Entry entry)
+ {
+ this.path = toList(path);
+ this.entry = entry;
+ }
+
+ public EntryWithPath.now(string[] path, Json.Node key, Json.Node value)
+ {
+ this.path = toList(path);
+ this.entry = new Entry.now(key, value);
+ }
}
/**
- * Represents a key/value pair stored by DecSync. Additionally, it has a datetime property
- * indicating the most recent update. It does not store its path, see [EntryWithPath].
- */
+* Represents a key/value pair stored by DecSync. Additionally, it has a datetime property
+* indicating the most recent update. It does not store its path, see [EntryWithPath].
+*/
public class Entry {
-internal string datetime;
-public Json.Node key;
-public Json.Node value;
-
-public Entry(string datetime, Json.Node key, Json.Node value)
-{
- this.datetime = datetime;
- this.key = key;
- this.value = value;
-}
-
-public Entry.now(Json.Node key, Json.Node value)
-{
- this.datetime = new GLib.DateTime.now_utc().format("%FT%T");
- this.key = key;
- this.value = value;
-}
-
-internal string toLine()
-{
- var json = new Json.Node(Json.NodeType.ARRAY);
- var array = new Json.Array();
- array.add_string_element(this.datetime);
- array.add_element(this.key);
- array.add_element(this.value);
- json.set_array(array);
- return Json.to_string(json, false);
-}
-
-internal static Entry? fromLine(string line)
-{
- try {
- var json = Json.from_string(line);
- var array = json.get_array();
- if (array == null || array.get_length() != 3)
- {
- Log.w("Invalid entry " + line);
- return null;
- }
- var datetime = array.get_string_element(0);
- if (datetime == null)
- {
- Log.w("Invalid entry " + line);
+ internal string datetime;
+ public Json.Node key;
+ public Json.Node value;
+
+ public Entry(string datetime, Json.Node key, Json.Node value)
+ {
+ this.datetime = datetime;
+ this.key = key;
+ this.value = value;
+ }
+
+ public Entry.now(Json.Node key, Json.Node value)
+ {
+ this.datetime = new GLib.DateTime.now_utc().format("%FT%T");
+ this.key = key;
+ this.value = value;
+ }
+
+ internal string toLine()
+ {
+ var json = new Json.Node(Json.NodeType.ARRAY);
+ var array = new Json.Array();
+ array.add_string_element(this.datetime);
+ array.add_element(this.key);
+ array.add_element(this.value);
+ json.set_array(array);
+ return Json.to_string(json, false);
+ }
+
+ internal static Entry? fromLine(string line)
+ {
+ try {
+ var json = Json.from_string(line);
+ var array = json.get_array();
+ if (array == null || array.get_length() != 3)
+ {
+ Log.w("Invalid entry " + line);
+ return null;
+ }
+ var datetime = array.get_string_element(0);
+ if (datetime == null)
+ {
+ Log.w("Invalid entry " + line);
+ return null;
+ }
+ var key = array.get_element(1);
+ var value = array.get_element(2);
+ return new Entry(datetime, key, value);
+ } catch (GLib.Error e) {
+ Log.w("Invalid JSON: " + line + "\n" + e.message);
return null;
}
- var key = array.get_element(1);
- var value = array.get_element(2);
- return new Entry(datetime, key, value);
- } catch (GLib.Error e) {
- Log.w("Invalid JSON: " + line + "\n" + e.message);
- return null;
}
}
-}
private class EntriesLocation {
-public Gee.List<string> path;
-public File newEntriesFile;
-public File? storedEntriesFile;
-public File? readBytesFile;
-
-public EntriesLocation.getNewEntriesLocation(Decsync decsync, Gee.List<string> path, string appId)
-{
- var pathString = FileUtils.pathToString(path);
- var appIdEncoded = FileUtils.urlencode(appId);
- this.path = path;
- this.newEntriesFile = File.new_for_path(decsync.dir + "/new-entries/" + appIdEncoded + "/" + pathString);
- this.storedEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
- this.readBytesFile = File.new_for_path(decsync.dir + "/read-bytes/" + decsync.ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
-}
-
-public EntriesLocation.getStoredEntriesLocation(Decsync decsync, Gee.List<string> path)
-{
- var pathString = FileUtils.pathToString(path);
- this.path = path;
- this.newEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
- this.storedEntriesFile = null;
- this.readBytesFile = null;
-}
+ public Gee.List<string> path;
+ public File newEntriesFile;
+ public File? storedEntriesFile;
+ public File? readBytesFile;
+
+ public EntriesLocation.getNewEntriesLocation(Decsync decsync, Gee.List<string> path, string appId)
+ {
+ var pathString = FileUtils.pathToString(path);
+ var appIdEncoded = FileUtils.urlencode(appId);
+ this.path = path;
+ this.newEntriesFile = File.new_for_path(decsync.dir + "/new-entries/" + appIdEncoded + "/" + pathString);
+ this.storedEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
+ this.readBytesFile = File.new_for_path(decsync.dir + "/read-bytes/" + decsync.ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
+ }
+
+ public EntriesLocation.getStoredEntriesLocation(Decsync decsync, Gee.List<string> path)
+ {
+ var pathString = FileUtils.pathToString(path);
+ this.path = path;
+ this.newEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
+ this.storedEntriesFile = null;
+ this.readBytesFile = null;
+ }
}
/**
- * Associates the given [value] with the given [key] in the map corresponding to the given
- * [path]. This update is sent to synchronized devices.
- */
+* Associates the given [value] with the given [key] in the map corresponding to the given
+* [path]. This update is sent to synchronized devices.
+*/
public void setEntry(string[] pathArray, Json.Node key, Json.Node value)
{
var entries = new Gee.ArrayList<Entry>();
@@ -205,36 +205,36 @@ public void setEntry(string[] pathArray, Json.Node key, Json.Node value)
}
/**
- * Like [setEntry], but allows multiple entries to be set. This is more efficient if multiple
- * entries share the same path.
- *
- * @param entriesWithPath entries with path which are inserted.
- */
+* Like [setEntry], but allows multiple entries to be set. This is more efficient if multiple
+* entries share the same path.
+*
+* @param entriesWithPath entries with path which are inserted.
+*/
public void setEntries(Gee.Collection<EntryWithPath> entriesWithPath)
{
var multiMap = groupBy<EntryWithPath, Gee.List<string>, Entry>(
entriesWithPath,
entryWithPath => { return entryWithPath.path; },
entryWithPath => { return entryWithPath.entry; }
- );
+ );
multiMap.get_keys().@foreach(path => {
- setEntriesForPath(path, multiMap.@get(path));
- return true;
- });
+ setEntriesForPath(path, multiMap.@get(path));
+ return true;
+ });
}
/**
- * Like [setEntries], but only allows the entries to have the same path. Consequently, it can
- * be slightly more convenient since the path has to be specified just once.
- *
- * @param path path to the map in which the entries are inserted.
- * @param entries entries which are inserted.
- */
+* Like [setEntries], but only allows the entries to have the same path. Consequently, it can
+* be slightly more convenient since the path has to be specified just once.
+*
+* @param path path to the map in which the entries are inserted.
+* @param entries entries which are inserted.
+*/
public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entries)
{
Log.d("Write to path " + FileUtils.pathToString(path));
var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId);
-
+
// Write new entries
var builder = new StringBuilder();
foreach (var entry in entries) {
@@ -245,13 +245,13 @@ public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entri
} catch (Error e) {
Log.w(e.message);
}
-
+
// Update .decsync-sequence files
while (!path.is_empty) {
path.remove_at(path.size - 1);
var dir = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId).newEntriesFile;
var file = dir.get_child(".decsync-sequence");
-
+
// Get the old version
int64 version = 0;
if (file.query_exists())
@@ -263,7 +263,7 @@ public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entri
Log.w(e.message);
}
}
-
+
// Write the new version
try {
FileUtils.writeFile(file, (version + 1).to_string());
@@ -271,17 +271,17 @@ public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entri
Log.w(e.message);
}
}
-
+
// Update stored entries
updateStoredEntries(entriesLocation, entries);
}
/**
- * Initializes the monitor which watches the filesystem for updated entries and executes the
- * corresponding actions.
- *
- * @param extra extra data passed to the [listeners].
- */
+* Initializes the monitor which watches the filesystem for updated entries and executes the
+* corresponding actions.
+*
+* @param extra extra data passed to the [listeners].
+*/
public void initMonitor(T extra)
{
try {
@@ -293,29 +293,29 @@ public void initMonitor(T extra)
}
monitor = new DirectoryMonitor(newEntriesDir);
monitor.changed.connect(pathString => {
- var pathEncoded = new Gee.ArrayList<string>.wrap(pathString.split("/"));
- pathEncoded.remove("");
- if (pathEncoded.is_empty || pathEncoded.last()[0] == '.')
- {
- return;
- }
- var path = new Gee.ArrayList<string>();
- path.add_all_iterator(pathEncoded.map<string>(part => { return FileUtils.urldecode(part); }));
- if (path.any_match(part => { return part == null; }))
- {
- Log.w("Cannot decode path " + pathString);
- return;
- }
- var appId = path.first();
- path.remove_at(0);
- var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, appId);
- if (appId != ownAppId && entriesLocation.newEntriesFile.query_file_type(FileQueryInfoFlags.NONE) == FileType.REGULAR)
- {
- executeEntriesLocation(entriesLocation, extra);
- Log.d("Sync complete");
- syncComplete(extra);
- }
- });
+ var pathEncoded = new Gee.ArrayList<string>.wrap(pathString.split("/"));
+ pathEncoded.remove("");
+ if (pathEncoded.is_empty || pathEncoded.last()[0] == '.')
+ {
+ return;
+ }
+ var path = new Gee.ArrayList<string>();
+ path.add_all_iterator(pathEncoded.map<string>(part => { return FileUtils.urldecode(part); }));
+ if (path.any_match(part => { return part == null; }))
+ {
+ Log.w("Cannot decode path " + pathString);
+ return;
+ }
+ var appId = path.first();
+ path.remove_at(0);
+ var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, appId);
+ if (appId != ownAppId && entriesLocation.newEntriesFile.query_file_type(FileQueryInfoFlags.NONE) == FileType.REGULAR)
+ {
+ executeEntriesLocation(entriesLocation, extra);
+ Log.d("Sync complete");
+ syncComplete(extra);
+ }
+ });
Log.d("Initialized folder monitor for " + dir + "/new-entries");
} catch (GLib.Error e) {
Log.w(e.message);
@@ -323,10 +323,10 @@ public void initMonitor(T extra)
}
/**
- * Gets all updated entries and executes the corresponding actions.
- *
- * @param extra extra data passed to the [listeners].
- */
+* Gets all updated entries and executes the corresponding actions.
+*
+* @param extra extra data passed to the [listeners].
+*/
public void executeAllNewEntries(T extra)
{
Log.d("Execute all new entries in " + dir);
@@ -336,9 +336,9 @@ public void executeAllNewEntries(T extra)
FileUtils.listFilesRecursiveRelative(newEntriesDir, readBytesDir, pathPred)
.map<EntriesLocation>(path => { return new EntriesLocation.getNewEntriesLocation(this, path.slice(1, path.size), path.first()); })
.@foreach (entriesLocation => {
- executeEntriesLocation(entriesLocation, extra);
- return true;
- });
+ executeEntriesLocation(entriesLocation, extra);
+ return true;
+ });
Log.d("Sync complete");
syncComplete(extra);
}
@@ -356,7 +356,7 @@ private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Ge
Log.w(e.message);
}
}
-
+
// Write the new number of read bytes (= size of the entry file)
if (entriesLocation.readBytesFile != null)
{
@@ -371,14 +371,14 @@ private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Ge
Log.w(e.message);
}
}
-
+
Log.d("Execute entries of " + entriesLocation.newEntriesFile.get_path());
-
+
// Execute the entries
var entriesMap = new Gee.HashMap<Json.Node, Entry>(
a => { return a.hash(); },
(a, b) => { return a.equal(b); }
- );
+ );
try {
var stream = new DataInputStream(entriesLocation.newEntriesFile.read());
stream.seek(readBytes, SeekType.SET);
@@ -390,7 +390,7 @@ private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Ge
continue;
}
if ((keyPred == null || keyPred(entryLine.key)) &&
- (valuePred == null || valuePred(entryLine.value)))
+ (valuePred == null || valuePred(entryLine.value)))
{
var key = entryLine.key;
var entry = entriesMap.@get(key);
@@ -411,14 +411,14 @@ private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Ge
private void executeEntries(EntriesLocation entriesLocation, Gee.Collection<Entry> entries, T extra)
{
updateStoredEntries(entriesLocation, entries);
-
+
var listener = getListener(entriesLocation.path);
if (listener == null)
{
Log.e("Unknown action for path " + FileUtils.pathToString(entriesLocation.path));
return;
}
-
+
listener.onEntriesUpdate(entriesLocation.path, entries, extra);
}
@@ -428,7 +428,7 @@ private void updateStoredEntries(EntriesLocation entriesLocation, Gee.Collection
{
return;
}
-
+
try {
var haveToFilterFile = false;
if (entriesLocation.storedEntriesFile.query_exists())
@@ -459,24 +459,24 @@ private void updateStoredEntries(EntriesLocation entriesLocation, Gee.Collection
}
}
}
-
+
if (haveToFilterFile)
{
FileUtils.filterFile(entriesLocation.storedEntriesFile, line => {
- var entryLine = Entry.fromLine(line);
- if (entryLine == null)
- {
- return false;
- }
- return !entries.any_match(entry => { return entry.key.equal(entryLine.key); });
- });
+ var entryLine = Entry.fromLine(line);
+ if (entryLine == null)
+ {
+ return false;
+ }
+ return !entries.any_match(entry => { return entry.key.equal(entryLine.key); });
+ });
}
-
+
var builder = new StringBuilder();
entries.@foreach(entry => {
- builder.append(entry.toLine() + "\n");
- return true;
- });
+ builder.append(entry.toLine() + "\n");
+ return true;
+ });
FileUtils.writeFile(entriesLocation.storedEntriesFile, builder.str, true);
}
catch (GLib.Error e)
@@ -486,41 +486,41 @@ private void updateStoredEntries(EntriesLocation entriesLocation, Gee.Collection
}
/**
- * Gets all stored entries satisfying the predicates and executes the corresponding actions.
- *
- * @param executePath path to the entries to executes. This can be either a file or a directory.
- * If it specifies a file, the entries in that file are executed. If it specifies a directory,
- * all entries in all subfiles are executed.
- * @param extra extra data passed to the [listeners].
- * @param keyPred optional predicate on the keys. The key has to satisfy this predicate to be
- * executed.
- * @param valuePred optional predicate on the values. The value has to satisfy this predicate to
- * be executed.
- * @param pathPred optional predicate on the subpaths. Each subpath has to satisfy this
- * predicate to be executed. This holds for directories as well. Furthermore, the path of
- * specified in [executePath] is not part of the argument.
- */
+* Gets all stored entries satisfying the predicates and executes the corresponding actions.
+*
+* @param executePath path to the entries to executes. This can be either a file or a directory.
+* If it specifies a file, the entries in that file are executed. If it specifies a directory,
+* all entries in all subfiles are executed.
+* @param extra extra data passed to the [listeners].
+* @param keyPred optional predicate on the keys. The key has to satisfy this predicate to be
+* executed.
+* @param valuePred optional predicate on the values. The value has to satisfy this predicate to
+* be executed.
+* @param pathPred optional predicate on the subpaths. Each subpath has to satisfy this
+* predicate to be executed. This holds for directories as well. Furthermore, the path of
+* specified in [executePath] is not part of the argument.
+*/
public void executeStoredEntries(string[] executePathArray, T extra,
- Gee.Predicate<Json.Node>? keyPred = null,
- Gee.Predicate<Json.Node>? valuePred = null,
- Gee.Predicate<Gee.List<string>>? pathPred = null)
+ Gee.Predicate<Json.Node>? keyPred = null,
+ Gee.Predicate<Json.Node>? valuePred = null,
+Gee.Predicate<Gee.List<string>>? pathPred = null)
{
var executePath = toList(executePathArray);
var executePathString = FileUtils.pathToString(executePath);
var executeDir = File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded + "/" + executePathString);
FileUtils.listFilesRecursiveRelative(executeDir, null, pathPred)
.@foreach(path => {
- path.insert_all(0, executePath);
- var entriesLocation = new EntriesLocation.getStoredEntriesLocation(this, path);
- executeEntriesLocation(entriesLocation, extra, keyPred, valuePred);
- return true;
- });
+ path.insert_all(0, executePath);
+ var entriesLocation = new EntriesLocation.getStoredEntriesLocation(this, path);
+ executeEntriesLocation(entriesLocation, extra, keyPred, valuePred);
+ return true;
+ });
}
/**
- * Initializes the stored entries. This method does not execute any actions. This is often
- * followed with a call to [executeStoredEntries].
- */
+* Initializes the stored entries. This method does not execute any actions. This is often
+* followed with a call to [executeStoredEntries].
+*/
public void initStoredEntries()
{
// Get the most up-to-date appId
@@ -529,47 +529,47 @@ public void initStoredEntries()
FileUtils.listFilesRecursiveRelative(File.new_for_path(dir + "/stored-entries"))
.filter(path => { return !path.is_empty; })
.@foreach(path => {
- var pathString = FileUtils.pathToString(path);
- try {
- var file = File.new_for_path(dir + "/stored-entries/" + pathString);
- var stream = new DataInputStream(file.read());
- string line;
- while ((line = stream.read_line(null)) != null) {
- var entry = Entry.fromLine(line);
- if (entry == null)
- {
- continue;
- }
- if (maxDatetime == null || entry.datetime > maxDatetime ||
- path.first() == ownAppId && entry.datetime == maxDatetime) // Prefer own appId
- {
- maxDatetime = entry.datetime;
- appId = path.first();
- }
+ var pathString = FileUtils.pathToString(path);
+ try {
+ var file = File.new_for_path(dir + "/stored-entries/" + pathString);
+ var stream = new DataInputStream(file.read());
+ string line;
+ while ((line = stream.read_line(null)) != null) {
+ var entry = Entry.fromLine(line);
+ if (entry == null)
+ {
+ continue;
+ }
+ if (maxDatetime == null || entry.datetime > maxDatetime ||
+ path.first() == ownAppId && entry.datetime == maxDatetime) // Prefer own appId
+ {
+ maxDatetime = entry.datetime;
+ appId = path.first();
}
- } catch (GLib.Error e) {
- Log.w(e.message);
}
- return true;
- });
+ } catch (GLib.Error e) {
+ Log.w(e.message);
+ }
+ return true;
+ });
if (appId == null)
{
Log.i("No appId found for initialization");
return;
}
-
+
// Copy the stored files and update the read bytes
if (appId != ownAppId)
{
var appIdEncoded = FileUtils.urlencode(appId);
-
+
try {
FileUtils.@delete(File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
FileUtils.copy(File.new_for_path(dir + "/stored-entries/" + appIdEncoded), File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
} catch (GLib.Error e) {
Log.w(e.message);
}
-
+
try {
FileUtils.@delete(File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
FileUtils.copy(File.new_for_path(dir + "/read-bytes/" + appIdEncoded), File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
@@ -579,26 +579,26 @@ public void initStoredEntries()
var newEntriesDir = File.new_for_path(dir + "/new-entries/" + appIdEncoded);
var ownReadBytesDir = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded);
FileUtils.listFilesRecursiveRelative(newEntriesDir, ownReadBytesDir).@foreach(path => {
- var pathString = FileUtils.pathToString(path);
- try {
- var newEntriesFile = File.new_for_path(dir + "/new-entries/" + appIdEncoded + "/" + pathString);
- var size = newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
- var readBytesFile = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
- FileUtils.writeFile(readBytesFile, size.to_string());
- } catch (GLib.Error e) {
- Log.w(e.message);
- }
- return true;
- });
+ var pathString = FileUtils.pathToString(path);
+ try {
+ var newEntriesFile = File.new_for_path(dir + "/new-entries/" + appIdEncoded + "/" + pathString);
+ var size = newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
+ var readBytesFile = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
+ FileUtils.writeFile(readBytesFile, size.to_string());
+ } catch (GLib.Error e) {
+ Log.w(e.message);
+ }
+ return true;
+ });
}
}
/**
- * Returns the value of the given [key] in the map of the given [path], and in the given
- * [DecSync directory][decsyncDir] without specifying an appId, or `null` if there is no
- * such value. The use of this method is discouraged. It is recommended to use the method
- * [executeStoredEntries] when possible.
- */
+* Returns the value of the given [key] in the map of the given [path], and in the given
+* [DecSync directory][decsyncDir] without specifying an appId, or `null` if there is no
+* such value. The use of this method is discouraged. It is recommended to use the method
+* [executeStoredEntries] when possible.
+*/
public static Json.Node? getStoredStaticValue(string decsyncDir, string[] pathArray, Json.Node key)
{
Log.d("Get value for key " + Json.to_string(key, false) + " for path " + string.joinv("/", pathArray) + " in " + decsyncDir);
@@ -615,14 +615,14 @@ public static Json.Node? getStoredStaticValue(string decsyncDir, string[] pathAr
{
continue;
}
-
+
var appIdEncoded = info.get_name();
var file = File.new_for_path(decsyncDir + "/stored-entries/" + appIdEncoded + "/" + pathString);
if (!file.query_exists() || file.query_file_type(FileQueryInfoFlags.NONE) != FileType.REGULAR)
{
continue;
}
-
+
var stream = new DataInputStream(file.read());
string line;
while ((line = stream.read_line(null)) != null) {
@@ -641,7 +641,7 @@ public static Json.Node? getStoredStaticValue(string decsyncDir, string[] pathAr
} catch (GLib.Error e) {
Log.w(e.message);
}
-
+
return result;
}
@@ -658,87 +658,87 @@ private OnEntryUpdateListener<T>? getListener(Gee.List<string> path)
}
/**
- * Returns the path to the DecSync subdirectory in a [decsyncBaseDir] for a [syncType] and
- * optionally with a [collection].
- *
- * @param decsyncBaseDir the path to the main DecSync directory, or null for the default one.
- * @param syncType the type of data to sync. For example, "rss", "contacts" or "calendars".
- * @param collection an optional collection identifier when multiple instances of the [syncType] are
- * supported. For example, this is the case for "contacts" and "calendars", but not for "rss".
- */
+* Returns the path to the DecSync subdirectory in a [decsyncBaseDir] for a [syncType] and
+* optionally with a [collection].
+*
+* @param decsyncBaseDir the path to the main DecSync directory, or null for the default one.
+* @param syncType the type of data to sync. For example, "rss", "contacts" or "calendars".
+* @param collection an optional collection identifier when multiple instances of the [syncType] are
+* supported. For example, this is the case for "contacts" and "calendars", but not for "rss".
+*/
public string getDecsyncSubdir(string? decsyncBaseDir, string syncType, string? collection = null)
{
- string dir = decsyncBaseDir ?? getDefaultDecsyncBaseDir();
- dir += "/" + FileUtils.urlencode(syncType);
- if (collection != null)
- {
- dir += "/" + FileUtils.urlencode(collection);
- }
- return dir;
+string dir = decsyncBaseDir ?? getDefaultDecsyncBaseDir();
+dir += "/" + FileUtils.urlencode(syncType);
+if (collection != null)
+{
+ dir += "/" + FileUtils.urlencode(collection);
+}
+return dir;
}
/**
- * Returns the default DecSync directory. This is the "decsync" subdirectory on the user data dir
- * ("~/.local/share" by default).
- */
+* Returns the default DecSync directory. This is the "decsync" subdirectory on the user data dir
+* ("~/.local/share" by default).
+*/
public string getDefaultDecsyncBaseDir()
{
- return GLib.Environment.get_user_data_dir() + "/decsync";
+return GLib.Environment.get_user_data_dir() + "/decsync";
}
/**
- * Returns a list of DecSync collections inside a [decsyncBaseDir] for a [syncType]. This function
- * does not apply for sync types with single instances.
- *
- * @param decsyncBaseDir the path to the main DecSync directory, or null for the default one.
- * @param syncType the type of data to sync. For example, "contacts" or "calendars".
- * @param ignoreDeleted `true` to ignore deleted collections. A collection is considered deleted if
- * the most recent value of the key "deleted" with the path ["info"] is set to `true`.
- */
+* Returns a list of DecSync collections inside a [decsyncBaseDir] for a [syncType]. This function
+* does not apply for sync types with single instances.
+*
+* @param decsyncBaseDir the path to the main DecSync directory, or null for the default one.
+* @param syncType the type of data to sync. For example, "contacts" or "calendars".
+* @param ignoreDeleted `true` to ignore deleted collections. A collection is considered deleted if
+* the most recent value of the key "deleted" with the path ["info"] is set to `true`.
+*/
public Gee.ArrayList<string> listDecsyncCollections(string? decsyncBaseDir, string syncType, bool ignoreDeleted = true) throws GLib.Error
{
- var decsyncSubdir = File.new_for_path(getDecsyncSubdir(decsyncBaseDir, syncType));
- var enumerator = decsyncSubdir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
- FileInfo info;
- Gee.ArrayList<string> result = new Gee.ArrayList<string>();
- while ((info = enumerator.next_file(null)) != null) {
- if (info.get_file_type() != FileType.DIRECTORY || info.get_name()[0] == '.')
+var decsyncSubdir = File.new_for_path(getDecsyncSubdir(decsyncBaseDir, syncType));
+var enumerator = decsyncSubdir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
+FileInfo info;
+Gee.ArrayList<string> result = new Gee.ArrayList<string>();
+while ((info = enumerator.next_file(null)) != null) {
+ if (info.get_file_type() != FileType.DIRECTORY || info.get_name()[0] == '.')
+ {
+ continue;
+ }
+ if (ignoreDeleted)
+ {
+ var deleted = Decsync.getStoredStaticValue(decsyncSubdir.get_child(info.get_name()).get_path(), {"info"}, stringToNode("deleted"));
+ if (deleted != null && deleted.get_boolean())
{
continue;
}
- if (ignoreDeleted)
- {
- var deleted = Decsync.getStoredStaticValue(decsyncSubdir.get_child(info.get_name()).get_path(), {"info"}, stringToNode("deleted"));
- if (deleted != null && deleted.get_boolean())
- {
- continue;
- }
- }
- var collection = FileUtils.urldecode(info.get_name());
- if (collection != null)
- {
- result.add(collection);
- }
}
- return result;
+ var collection = FileUtils.urldecode(info.get_name());
+ if (collection != null)
+ {
+ result.add(collection);
+ }
+}
+return result;
}
/**
- * Returns the appId of the current device and application combination.
- *
- * @param appName the name of the application.
- * @param id an optional integer (between 0 and 100000 exclusive) to distinguish different instances
- * on the same device and application.
- */
+* Returns the appId of the current device and application combination.
+*
+* @param appName the name of the application.
+* @param id an optional integer (between 0 and 100000 exclusive) to distinguish different instances
+* on the same device and application.
+*/
public string getAppId(string appName, int? id = null)
{
- string appId = GLib.Environment.get_host_name() + "-" + appName;
- if (id == null)
- {
- return appId;
- }
- else
- {
- return appId + "-" + "%05d".printf(id);
- }
+string appId = GLib.Environment.get_host_name() + "-" + appName;
+if (id == null)
+{
+ return appId;
+}
+else
+{
+ return appId + "-" + "%05d".printf(id);
+}
}
diff --git a/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala b/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala
index 8a3bc44a..4342bd61 100644
--- a/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala
+++ b/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala
@@ -1,96 +1,96 @@
/**
- * libdecsync-vala - DirectoryMonitor.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - DirectoryMonitor.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public class DirectoryMonitor : GLib.Object {
-
-private File mDir;
-private string mPath;
-private FileMonitor mMonitor;
-private Gee.ArrayList<DirectoryMonitor> mChilds = new Gee.ArrayList<DirectoryMonitor>();
-
-public signal void changed(string path);
-
-public DirectoryMonitor(File dir) throws GLib.Error
-{
- this.withPath(dir, "");
-}
-
-private DirectoryMonitor.withPath(File dir, string path) throws GLib.Error
-{
- mDir = dir;
- mPath = path;
- var currentDir = File.new_for_path(dir.get_path() + path);
- mMonitor = currentDir.monitor_directory(FileMonitorFlags.NONE);
- mMonitor.changed.connect((file, otherFile, event) => {
+
+ private File mDir;
+ private string mPath;
+ private FileMonitor mMonitor;
+ private Gee.ArrayList<DirectoryMonitor> mChilds = new Gee.ArrayList<DirectoryMonitor>();
+
+ public signal void changed(string path);
+
+ public DirectoryMonitor(File dir) throws GLib.Error
+ {
+ this.withPath(dir, "");
+ }
+
+ private DirectoryMonitor.withPath(File dir, string path) throws GLib.Error
+ {
+ mDir = dir;
+ mPath = path;
+ var currentDir = File.new_for_path(dir.get_path() + path);
+ mMonitor = currentDir.monitor_directory(FileMonitorFlags.NONE);
+ mMonitor.changed.connect((file, otherFile, event) => {
if (file.get_path() != mDir.get_path() + path)
{
- onEvent(path + "/" + file.get_basename(), event);
+ onEvent(path + "/" + file.get_basename(), event);
}
});
- Log.d("Monitor created for " + currentDir.get_path() + " (folder " + dir.get_path() + ")");
-
- var enumerator = currentDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
- FileInfo info = null;
- while (((info = enumerator.next_file(null)) != null)) {
- if (info.get_file_type() == FileType.DIRECTORY)
- {
- var childMonitor = new DirectoryMonitor.withPath(mDir, path + "/" + info.get_name());
- childMonitor.changed.connect((path) => {
+ Log.d("Monitor created for " + currentDir.get_path() + " (folder " + dir.get_path() + ")");
+
+ var enumerator = currentDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
+ FileInfo info = null;
+ while (((info = enumerator.next_file(null)) != null)) {
+ if (info.get_file_type() == FileType.DIRECTORY)
+ {
+ var childMonitor = new DirectoryMonitor.withPath(mDir, path + "/" + info.get_name());
+ childMonitor.changed.connect((path) => {
changed(path);
});
- mChilds.add(childMonitor);
+ mChilds.add(childMonitor);
+ }
}
}
-}
-
-private void onEvent(string path, FileMonitorEvent event)
-{
- Log.d("Received inotify event " + event.to_string() + " at " + mDir.get_path() + "/" + path);
- switch (event) {
- case FileMonitorEvent.DELETED:
- foreach (var c in mChilds) {
- if (c.mPath == path)
- {
- mChilds.remove(c);
- break;
+
+ private void onEvent(string path, FileMonitorEvent event)
+ {
+ Log.d("Received inotify event " + event.to_string() + " at " + mDir.get_path() + "/" + path);
+ switch (event) {
+ case FileMonitorEvent.DELETED:
+ foreach (var c in mChilds) {
+ if (c.mPath == path)
+ {
+ mChilds.remove(c);
+ break;
+ }
}
- }
- break;
- case FileMonitorEvent.CREATED:
- case FileMonitorEvent.CHANGED:
- var file = File.new_for_path(mDir.get_path() + path);
- if (file.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY)
- {
- try {
- var childMonitor = new DirectoryMonitor.withPath(mDir, path);
- childMonitor.changed.connect((path) => {
+ break;
+ case FileMonitorEvent.CREATED:
+ case FileMonitorEvent.CHANGED:
+ var file = File.new_for_path(mDir.get_path() + path);
+ if (file.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY)
+ {
+ try {
+ var childMonitor = new DirectoryMonitor.withPath(mDir, path);
+ childMonitor.changed.connect((path) => {
changed(path);
});
- mChilds.add(childMonitor);
- } catch (GLib.Error e) {
- Log.w(e.message);
+ mChilds.add(childMonitor);
+ } catch (GLib.Error e) {
+ Log.w(e.message);
+ }
}
+ else
+ {
+ changed(path);
+ }
+ break;
}
- else
- {
- changed(path);
- }
- break;
}
}
-}
diff --git a/plugins/backend/decsync/libdecsync/src/FileUtils.vala b/plugins/backend/decsync/libdecsync/src/FileUtils.vala
index 20008264..c447e523 100644
--- a/plugins/backend/decsync/libdecsync/src/FileUtils.vala
+++ b/plugins/backend/decsync/libdecsync/src/FileUtils.vala
@@ -1,250 +1,250 @@
/**
- * libdecsync-vala - FileUtils.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - FileUtils.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public class FileUtils : GLib.Object {
-
-public static void writeFile(File file, string content, bool append = false) throws GLib.Error
-{
- var parent = file.get_parent();
- if (!parent.query_exists())
- {
- parent.make_directory_with_parents();
- }
-
- GLib.FileOutputStream stream;
- if (append)
- {
- stream = file.append_to(FileCreateFlags.NONE);
- }
- else
- {
- if (file.query_exists())
- {
- file.@delete();
- }
- stream = file.create(FileCreateFlags.REPLACE_DESTINATION);
- }
- stream.write(content.data);
-}
-
-public static void @delete(File src) throws GLib.Error
-{
- if (!src.query_exists())
- {
- return;
- }
- if (src.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY)
+
+ public static void writeFile(File file, string content, bool append = false) throws GLib.Error
{
- var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
- FileInfo info;
- while ((info = enumerator.next_file(null)) != null) {
- var name = info.get_name();
- @delete(src.get_child(name));
- }
- }
- src.@delete();
-}
-
-public static void copy(File src, File dst, bool overwrite = false) throws GLib.Error
-{
- switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
- case FileType.REGULAR:
- var parent = dst.get_parent();
+ var parent = file.get_parent();
if (!parent.query_exists())
{
parent.make_directory_with_parents();
}
- src.copy(dst, overwrite ? FileCopyFlags.OVERWRITE : FileCopyFlags.NONE);
- return;
- case FileType.DIRECTORY:
- dst.make_directory_with_parents();
- var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
- FileInfo info;
- while ((info = enumerator.next_file(null)) != null) {
- var name = info.get_name();
- copy(src.get_child(name), dst.get_child(name), overwrite);
+
+ GLib.FileOutputStream stream;
+ if (append)
+ {
+ stream = file.append_to(FileCreateFlags.NONE);
}
- return;
- }
-}
-
-public static void filterFile(File file, Gee.Predicate<string> linePred) throws GLib.Error
-{
- var tempFile = File.new_for_path(file.get_parent().get_path() + "." + file.get_basename() + ".tmp");
- var instream = new DataInputStream(file.read());
- var outstream = new DataOutputStream(tempFile.create(FileCreateFlags.NONE));
- string line;
- while ((line = instream.read_line(null)) != null) {
- if (linePred(line))
+ else
{
- outstream.put_string(line + "\n");
+ if (file.query_exists())
+ {
+ file.@delete();
+ }
+ stream = file.create(FileCreateFlags.REPLACE_DESTINATION);
}
+ stream.write(content.data);
}
- tempFile.move(file, FileCopyFlags.OVERWRITE);
-}
-
-public static Gee.ArrayList<Gee.ArrayList<string>> listFilesRecursiveRelative(File src, File? readBytesSrc = null, Gee.Predicate<Gee.List<string>>? pathPred = null)
-{
- if (src.get_basename()[0] == '.')
+
+ public static void @delete(File src) throws GLib.Error
{
- return new Gee.ArrayList<Gee.ArrayList<string>>();
+ if (!src.query_exists())
+ {
+ return;
+ }
+ if (src.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY)
+ {
+ var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
+ FileInfo info;
+ while ((info = enumerator.next_file(null)) != null) {
+ var name = info.get_name();
+ @delete(src.get_child(name));
+ }
+ }
+ src.@delete();
}
- if (pathPred != null && !pathPred(new Gee.ArrayList<string>()))
+
+ public static void copy(File src, File dst, bool overwrite = false) throws GLib.Error
{
- return new Gee.ArrayList<Gee.ArrayList<string>>();
- }
-
- switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
- case FileType.REGULAR:
- var result = new Gee.ArrayList<Gee.ArrayList<string>>();
- result.add(new Gee.ArrayList<string>());
- return result;
- case FileType.DIRECTORY:
- // Skip same versions
- if (readBytesSrc != null)
- {
- var file = src.get_child(".decsync-sequence");
- string? version = null;
- if (file.query_exists())
+ switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
+ case FileType.REGULAR:
+ var parent = dst.get_parent();
+ if (!parent.query_exists())
{
- try {
- version = new DataInputStream(file.read()).read_line();
- } catch (GLib.Error e) {
- Log.w(e.message);
- }
+ parent.make_directory_with_parents();
+ }
+ src.copy(dst, overwrite ? FileCopyFlags.OVERWRITE : FileCopyFlags.NONE);
+ return;
+ case FileType.DIRECTORY:
+ dst.make_directory_with_parents();
+ var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
+ FileInfo info;
+ while ((info = enumerator.next_file(null)) != null) {
+ var name = info.get_name();
+ copy(src.get_child(name), dst.get_child(name), overwrite);
}
- var readBytesFile = readBytesSrc.get_child(".decsync-sequence");
- string? readBytesVersion = null;
- if (readBytesFile.query_exists())
+ return;
+ }
+ }
+
+ public static void filterFile(File file, Gee.Predicate<string> linePred) throws GLib.Error
+ {
+ var tempFile = File.new_for_path(file.get_parent().get_path() + "." + file.get_basename() + ".tmp");
+ var instream = new DataInputStream(file.read());
+ var outstream = new DataOutputStream(tempFile.create(FileCreateFlags.NONE));
+ string line;
+ while ((line = instream.read_line(null)) != null) {
+ if (linePred(line))
{
- try {
- readBytesVersion = new DataInputStream(readBytesFile.read()).read_line();
- } catch (GLib.Error e) {
- Log.w(e.message);
- }
+ outstream.put_string(line + "\n");
}
- if (version != null)
+ }
+ tempFile.move(file, FileCopyFlags.OVERWRITE);
+ }
+
+ public static Gee.ArrayList<Gee.ArrayList<string>> listFilesRecursiveRelative(File src, File? readBytesSrc = null, Gee.Predicate<Gee.List<string>>? pathPred = null)
+ {
+ if (src.get_basename()[0] == '.')
+ {
+ return new Gee.ArrayList<Gee.ArrayList<string>>();
+ }
+ if (pathPred != null && !pathPred(new Gee.ArrayList<string>()))
+ {
+ return new Gee.ArrayList<Gee.ArrayList<string>>();
+ }
+
+ switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
+ case FileType.REGULAR:
+ var result = new Gee.ArrayList<Gee.ArrayList<string>>();
+ result.add(new Gee.ArrayList<string>());
+ return result;
+ case FileType.DIRECTORY:
+ // Skip same versions
+ if (readBytesSrc != null)
{
- if (version == readBytesVersion)
- {
- return new Gee.ArrayList<Gee.ArrayList<string>>();
- }
- else
+ var file = src.get_child(".decsync-sequence");
+ string? version = null;
+ if (file.query_exists())
{
try {
- copy(file, readBytesFile, true);
+ version = new DataInputStream(file.read()).read_line();
} catch (GLib.Error e) {
Log.w(e.message);
}
}
- }
- }
-
- var result = new Gee.ArrayList<Gee.ArrayList<string>>();
- try {
- var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
- FileInfo info;
- while ((info = enumerator.next_file(null)) != null) {
- string name = info.get_name();
- string? nameDecoded = urldecode(name);
- if (nameDecoded == null)
+ var readBytesFile = readBytesSrc.get_child(".decsync-sequence");
+ string? readBytesVersion = null;
+ if (readBytesFile.query_exists())
{
- Log.w("Cannot decode name " + name);
- continue;
+ try {
+ readBytesVersion = new DataInputStream(readBytesFile.read()).read_line();
+ } catch (GLib.Error e) {
+ Log.w(e.message);
+ }
}
-
- var newReadBytesSrc = readBytesSrc == null ? null : readBytesSrc.get_child(name);
- Gee.Predicate<Gee.List<string>>? newPathPred = null;
- if (pathPred != null)
+ if (version != null)
{
- newPathPred = path => { path.insert(0, nameDecoded); return pathPred(path); };
+ if (version == readBytesVersion)
+ {
+ return new Gee.ArrayList<Gee.ArrayList<string>>();
+ }
+ else
+ {
+ try {
+ copy(file, readBytesFile, true);
+ } catch (GLib.Error e) {
+ Log.w(e.message);
+ }
+ }
}
- var paths = listFilesRecursiveRelative(src.get_child(name), newReadBytesSrc, newPathPred);
- foreach (var path in paths) {
- path.insert(0, nameDecoded);
+ }
+
+ var result = new Gee.ArrayList<Gee.ArrayList<string>>();
+ try {
+ var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
+ FileInfo info;
+ while ((info = enumerator.next_file(null)) != null) {
+ string name = info.get_name();
+ string? nameDecoded = urldecode(name);
+ if (nameDecoded == null)
+ {
+ Log.w("Cannot decode name " + name);
+ continue;
+ }
+
+ var newReadBytesSrc = readBytesSrc == null ? null : readBytesSrc.get_child(name);
+ Gee.Predicate<Gee.List<string>>? newPathPred = null;
+ if (pathPred != null)
+ {
+ newPathPred = path => { path.insert(0, nameDecoded); return pathPred(path); };
+ }
+ var paths = listFilesRecursiveRelative(src.get_child(name), newReadBytesSrc, newPathPred);
+ foreach (var path in paths) {
+ path.insert(0, nameDecoded);
+ }
+ result.add_all(paths);
}
- result.add_all(paths);
+ } catch (GLib.Error e) {
+ Log.w(e.message);
}
- } catch (GLib.Error e) {
- Log.w(e.message);
+ return result;
+ default:
+ return new Gee.ArrayList<Gee.ArrayList<string>>();
}
- return result;
- default:
- return new Gee.ArrayList<Gee.ArrayList<string>>();
}
-}
-
-public static string pathToString(Gee.List<string> path)
-{
- var encodedPath = new Gee.ArrayList<string>();
- encodedPath.add_all_iterator(path.map<string>(part => { return urlencode(part); }));
- return string.joinv("/", encodedPath.to_array());
-}
-
-public static string urlencode(string input)
-{
- var builder = new StringBuilder();
- for (int i = 0; i < input.length; i++) {
- char byte = input[i];
- if (byte.isalnum() || "-_.~".contains(byte.to_string()))
- {
- builder.append_c(byte);
+
+ public static string pathToString(Gee.List<string> path)
+ {
+ var encodedPath = new Gee.ArrayList<string>();
+ encodedPath.add_all_iterator(path.map<string>(part => { return urlencode(part); }));
+ return string.joinv("/", encodedPath.to_array());
+ }
+
+ public static string urlencode(string input)
+ {
+ var builder = new StringBuilder();
+ for (int i = 0; i < input.length; i++) {
+ char byte = input[i];
+ if (byte.isalnum() || "-_.~".contains(byte.to_string()))
+ {
+ builder.append_c(byte);
+ }
+ else
+ {
+ builder.append("%%%2X".printf(byte));
+ }
}
- else
+ var output = builder.str;
+
+ if (output != "" && output[0] == '.')
{
- builder.append("%%%2X".printf(byte));
+ output = "%2E" + output.substring(1);
}
+
+ return output;
}
- var output = builder.str;
-
- if (output != "" && output[0] == '.')
+
+ public static string? urldecode(string input)
{
- output = "%2E" + output.substring(1);
- }
-
- return output;
-}
-
-public static string? urldecode(string input)
-{
- var builder = new StringBuilder();
- for (int i = 0; i < input.length; i++) {
- char byte = input[i];
- if (byte != '%')
- {
- builder.append_c(byte);
- }
- else
- {
- if (i + 2 >= input.length)
+ var builder = new StringBuilder();
+ for (int i = 0; i < input.length; i++) {
+ char byte = input[i];
+ if (byte != '%')
{
- return null;
+ builder.append_c(byte);
}
- if (!input[i+1].isxdigit() || !input[i+2].isxdigit())
+ else
{
- return null;
+ if (i + 2 >= input.length)
+ {
+ return null;
+ }
+ if (!input[i+1].isxdigit() || !input[i+2].isxdigit())
+ {
+ return null;
+ }
+ char value1 = (char)input[i+1].xdigit_value();
+ char value2 = (char)input[i+2].xdigit_value();
+ builder.append_c(16 * value1 + value2);
+ i += 2;
}
- char value1 = (char)input[i+1].xdigit_value();
- char value2 = (char)input[i+2].xdigit_value();
- builder.append_c(16 * value1 + value2);
- i += 2;
}
+ return builder.str;
}
- return builder.str;
-}
}
diff --git a/plugins/backend/decsync/libdecsync/src/Log.vala b/plugins/backend/decsync/libdecsync/src/Log.vala
index 46c935ad..67106597 100644
--- a/plugins/backend/decsync/libdecsync/src/Log.vala
+++ b/plugins/backend/decsync/libdecsync/src/Log.vala
@@ -1,46 +1,46 @@
/**
- * libdecsync-vala - Log.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - Log.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public class Log : GLib.Object {
-const string TAG = "DecSync";
-
-private static void log(LogLevelFlags level, string message)
-{
- GLib.log_structured(TAG, level, "MESSAGE", "%s", message);
-}
-
-public static void e(string message)
-{
- log(GLib.LogLevelFlags.LEVEL_CRITICAL, message);
-}
-
-public static void w(string message)
-{
- log(GLib.LogLevelFlags.LEVEL_WARNING, message);
-}
-
-public static void i(string message)
-{
- log(GLib.LogLevelFlags.LEVEL_INFO, message);
-}
-
-public static void d(string message)
-{
- log(GLib.LogLevelFlags.LEVEL_DEBUG, message);
-}
+ const string TAG = "DecSync";
+
+ private static void log(LogLevelFlags level, string message)
+ {
+ GLib.log_structured(TAG, level, "MESSAGE", "%s", message);
+ }
+
+ public static void e(string message)
+ {
+ log(GLib.LogLevelFlags.LEVEL_CRITICAL, message);
+ }
+
+ public static void w(string message)
+ {
+ log(GLib.LogLevelFlags.LEVEL_WARNING, message);
+ }
+
+ public static void i(string message)
+ {
+ log(GLib.LogLevelFlags.LEVEL_INFO, message);
+ }
+
+ public static void d(string message)
+ {
+ log(GLib.LogLevelFlags.LEVEL_DEBUG, message);
+ }
}
diff --git a/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala b/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala
index 6057ca64..15706e9e 100644
--- a/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala
+++ b/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala
@@ -1,65 +1,65 @@
/**
- * libdecsync-vala - Subpath.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - Subpath.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public interface OnEntryUpdateListener<T> : GLib.Object {
-public abstract bool matchesPath(Gee.List<string> path);
-public abstract void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra);
+ public abstract bool matchesPath(Gee.List<string> path);
+ public abstract void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra);
}
public abstract class OnSubdirEntryUpdateListener<T> : GLib.Object, OnEntryUpdateListener<T> {
-
-public abstract Gee.List<string> subdir();
-public abstract void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, T extra);
-
-public bool matchesPath(Gee.List<string> path)
-{
- return path.size >= subdir().size && pathEquals(path.slice(0, subdir().size), subdir());
-}
-
-public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
-{
- foreach (var entry in entries) {
- onSubdirEntryUpdate(convertPath(path), entry, extra);
+
+ public abstract Gee.List<string> subdir();
+ public abstract void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, T extra);
+
+ public bool matchesPath(Gee.List<string> path)
+ {
+ return path.size >= subdir().size && pathEquals(path.slice(0, subdir().size), subdir());
+ }
+
+ public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
+ {
+ foreach (var entry in entries) {
+ onSubdirEntryUpdate(convertPath(path), entry, extra);
+ }
+ }
+
+ private Gee.List<string> convertPath(Gee.List<string> path)
+ {
+ return path.slice(subdir().size, path.size);
}
-}
-
-private Gee.List<string> convertPath(Gee.List<string> path)
-{
- return path.slice(subdir().size, path.size);
-}
}
public abstract class OnSubfileEntryUpdateListener<T> : GLib.Object, OnEntryUpdateListener<T> {
-
-public abstract Gee.List<string> subfile();
-public abstract void onSubfileEntryUpdate(Decsync.Entry entry, T extra);
-
-public bool matchesPath(Gee.List<string> path)
-{
- return pathEquals(path, subfile());
-}
-
-public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
-{
- foreach (var entry in entries) {
- onSubfileEntryUpdate(entry, extra);
+
+ public abstract Gee.List<string> subfile();
+ public abstract void onSubfileEntryUpdate(Decsync.Entry entry, T extra);
+
+ public bool matchesPath(Gee.List<string> path)
+ {
+ return pathEquals(path, subfile());
+ }
+
+ public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
+ {
+ foreach (var entry in entries) {
+ onSubfileEntryUpdate(entry, extra);
+ }
}
-}
}
private bool pathEquals(Gee.List<string> path1, Gee.List<string> path2)
diff --git a/plugins/backend/decsync/libdecsync/src/Utils.vala b/plugins/backend/decsync/libdecsync/src/Utils.vala
index 603d5fca..1946b999 100644
--- a/plugins/backend/decsync/libdecsync/src/Utils.vala
+++ b/plugins/backend/decsync/libdecsync/src/Utils.vala
@@ -1,20 +1,20 @@
/**
- * libdecsync-vala - Utils.vala
- *
- * Copyright (C) 2018 Aldo Gunsing
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
+* libdecsync-vala - Utils.vala
+*
+* Copyright (C) 2018 Aldo Gunsing
+*
+* This library is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation.
+*
+* This library is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
public Gee.List<string> toList(string[] input)
{
@@ -24,7 +24,7 @@ public Gee.List<string> toList(string[] input)
public Gee.Predicate<Json.Node> stringEquals(string input)
{
return json => {
- return json.get_string() == input;
+ return json.get_string() == input;
};
}
@@ -66,6 +66,6 @@ public Gee.MultiMap<K, V> groupBy<T, K, V>(Gee.Collection<T> inputs, Gee.MapFunc
var value = f == null ? input : f(input);
resultsMap.@set(key, value);
}
-
+
return resultsMap;
}
diff --git a/plugins/backend/demo/demoInterface.vala b/plugins/backend/demo/demoInterface.vala
index b96372d8..40554c1a 100644
--- a/plugins/backend/demo/demoInterface.vala
+++ b/plugins/backend/demo/demoInterface.vala
@@ -5,592 +5,592 @@
//--------------------------------------------------------------------------------------
public class FeedReader.demoInterface : Peas.ExtensionBase, FeedServerInterface {
-
-//--------------------------------------------------------------------------------------
-// This method gets executed right after the plugin is loaded. Do everything
-// you need to set up the plugin here.
-//--------------------------------------------------------------------------------------
-public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Return the the website/homepage of the project
-//--------------------------------------------------------------------------------------
-public string getWebsite()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return an unique id for the backend. Basically a short form of the name:
-// Tiny Tiny RSS -> "ttrss"
-// Local Backend -> "local"
-//--------------------------------------------------------------------------------------
-public string getID()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return flags describing the type of Service
-// - LOCAL
-// - HOSTED
-// - SELF_HOSTED
-// - FREE_SOFTWARE
-// - PROPRIETARY
-// - FREE
-// - PAID_PREMIUM
-// - PAID
-//--------------------------------------------------------------------------------------
-public BackendFlags getFlags()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return the login UI inside a Gtk.Box (username- and password-entries)
-// Return 'null' if use web-login
-//--------------------------------------------------------------------------------------
-public Gtk.Box? getWidget()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return the name of the service-icon (non-symbolic).
-//--------------------------------------------------------------------------------------
-public string iconName()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return the name of the service as displayed to the user
-//--------------------------------------------------------------------------------------
-public string serviceName()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return wheather the plugin needs a webview to log in via oauth.
-//--------------------------------------------------------------------------------------
-public bool needWebLogin()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Only important for self-hosted services.
-// If the server is secured by htaccess and a second username and password
-// is required, show the UI to enter those in this methode.
-// If htaccess won't be needed do nothing here.
-//--------------------------------------------------------------------------------------
-public void showHtAccess()
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Methode gets executed before logging in. Write all the data gathered
-// into gsettings (password, username, access-key).
-//--------------------------------------------------------------------------------------
-public void writeData()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Do stuff after a successful login
-//--------------------------------------------------------------------------------------
-public async void postLoginAction()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Only needed if "needWebLogin()" retruned true. Return URL that should be
-// loaded to log in via website.
-//--------------------------------------------------------------------------------------
-public string buildLoginURL()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Extract access-key from redirect-URL from webview after loggin in with
-// the webview.
-// Return "true" if extracted sucessfuly, "false" otherwise.
-//--------------------------------------------------------------------------------------
-public bool extractCode(string redirectURL)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Does the service you are implementing support tags?
-// If so return "true", otherwise return "false".
-//--------------------------------------------------------------------------------------
-public bool supportTags()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// If the daemon should to an initial sync after logging in.
-// For all online services: true
-// Only for local backend: false
-//--------------------------------------------------------------------------------------
-public bool doInitSync()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// What is the symbolic icon-name of the service-logo?
-// Return a string with the name, not the complete path.
-// For example: "feed-service-demo-symbolic"
-//--------------------------------------------------------------------------------------
-public string symbolicIcon()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return a name the account of the user can be identified with.
-// This can be the real name of the user, the email-address
-// or any other personal information that identifies the account.
-//--------------------------------------------------------------------------------------
-public string accountName()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// If the service can be self-hosted or has multiple providers
-// you can return the URL of the server here. Preferably without "http://www."
-//--------------------------------------------------------------------------------------
-public string getServerURL()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Many services have different ways of telling if a feed is uncategorized.
-// OwnCloud-News and Tiny Tiny RSS use the id "0", while feedly and InoReader
-// use an empty string ("").
-// Return what this service uses to indicate that the feed does not belong
-// to any category.
-//--------------------------------------------------------------------------------------
-public string uncategorizedID()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Sone services have special categories that should not be visible when empty
-// e.g. feedly has a category called "Must Read".
-// Argument: ID of a category
-// Return: wheather the category should be visible when empty
-//--------------------------------------------------------------------------------------
-public bool hideCategoryWhenEmpty(string catID)
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Does the service support categories at all? (feedbin is weird :P)
-//--------------------------------------------------------------------------------------
-public bool supportCategories()
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Does the service support add/remove/rename of categories and feeds?
-//--------------------------------------------------------------------------------------
-public bool supportFeedManipulation()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Does the service allow categories as children of other categories?
-// If so return "true", otherwise return "false".
-//--------------------------------------------------------------------------------------
-public bool supportMultiLevelCategories()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Can one feed be part of more than one category?
-// If so return "true", otherwise return "false".
-//--------------------------------------------------------------------------------------
-public bool supportMultiCategoriesPerFeed()
-{
-
-}
-
-public bool syncFeedsAndCategories()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Does changing the name of a tag also change it's ID?
-// InoReader tagID's for example look like this:
-// "user/1005921515/label/tagName"
-// So if the name changes the ID changes accordingly. This needs special treatment.
-// Return "true" if this is the case, otherwise return "false".
-//--------------------------------------------------------------------------------------
-public bool tagIDaffectedByNameChange()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Delete all passwords, keys and user-information.
-// Do not delete feeds or articles from the data-base.
-//--------------------------------------------------------------------------------------
-public void resetAccount()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// State wheater the service syncs articles based on a maximum count
-// or uses something else (OwnCloud uses the last synced articleID)
-//--------------------------------------------------------------------------------------
-public bool useMaxArticles()
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Log in to the account of the service. If there is no need or API to sign in,
-// check all passwords or keys and make sure the service is reachable and works.
-// Possible return values are:
-// - SUCCESS
-// - MISSING_USER
-// - MISSING_PASSWD
-// - MISSING_URL
-// - ALL_EMPTY
-// - UNKNOWN_ERROR
-// - FIRST_TRY
-// - NO_BACKEND
-// - WRONG_LOGIN
-// - NO_CONNECTION
-// - NO_API_ACCESS
-// - UNAUTHORIZED
-// - CA_ERROR
-// - PLUGIN_NEEDED
-//--------------------------------------------------------------------------------------
-public LoginResponse login()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// If it is possible to log out of the account of the service, do so here.
-// If not, do nothing and return "true".
-//--------------------------------------------------------------------------------------
-public bool logout()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Check if the service is reachable.
-// You can use the method Utils.ping() if the service doesn't provide anything.
-//--------------------------------------------------------------------------------------
-public bool serverAvailable()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Method to set the state of articles to read or unread
-// "articleIDs": comma separated string of articleIDs e.g. "id1,id2,id3"
-// "read": the state to apply. ArticleStatus.READ or ArticleStatus.UNREAD
-//--------------------------------------------------------------------------------------
-public void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Method to set the state of articles to marked or unmarked
-// "articleID": single articleID
-// "read": the state to apply. ArticleStatus.MARKED or ArticleStatus.UNMARKED
-//--------------------------------------------------------------------------------------
-public void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
-
-}
-
-//--------------------------------------------------------------------------------------
-// Should setArticleIsRead always be used instead of setFeedRead, setCategoryRead or
-// markAllItemsRead?
-// By using IDs as identifier, the articles are known, but it may be less efficient.
-// If "true", the methods setFeedRead/setCategoryRead/markAllItemsRead never get called.
-//--------------------------------------------------------------------------------------
-public bool alwaysSetReadByID()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Mark all articles of the feed as read
-//--------------------------------------------------------------------------------------
-public void setFeedRead(string feedID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Mark all articles of the feeds that are part of the category as read
-//--------------------------------------------------------------------------------------
-public void setCategoryRead(string catID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Mark ALL articles as read
-//--------------------------------------------------------------------------------------
-public void markAllItemsRead()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Add an existing tag to the article
-//--------------------------------------------------------------------------------------
-public void tagArticle(string articleID, string tagID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Remove an existing tag from the article
-//--------------------------------------------------------------------------------------
-public void removeArticleTag(string articleID, string tagID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Create a new tag with the title of "caption" and return the id of the
-// newly added tag.
-// Hint: some services don't have API to create tags, but instead create them
-// on the fly when tagging articles. In this case just compose the tagID
-// following the schema tha service uses and return it.
-//--------------------------------------------------------------------------------------
-public string createTag(string caption)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Delete a tag completely
-//--------------------------------------------------------------------------------------
-public void deleteTag(string tagID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Rename the tag with the id "tagID" to the new name "title"
-//--------------------------------------------------------------------------------------
-public void renameTag(string tagID, string title)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Subscribe to the URL "feedURL"
-// "catID": the category the feed should be placed into, "null" otherwise
-// "newCatName": the name of a new category the feed should be put in, "null" otherwise
-//--------------------------------------------------------------------------------------
-public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Remove the feed with the id "feedID" completely
-//--------------------------------------------------------------------------------------
-public void removeFeed(string feedID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Rename the feed with the id "feedID" to "title"
-//--------------------------------------------------------------------------------------
-public void renameFeed(string feedID, string title)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Move the feed with the id "feedID" from its current category
-// to any other category. "currentCatID" is only needed if the
-// feed can be part of multiple categories at once.
-//--------------------------------------------------------------------------------------
-public void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Create a new category
-// "title": title of the new category
-// "parentID": only needed if multi-level-categories are supported
-// Hint: some services don't have API to create categories, but instead create them
-// on the fly when movin feeds over to them. In this case just compose the categoryID
-// following the schema tha service uses and return it.
-//--------------------------------------------------------------------------------------
-public string createCategory(string title, string? parentID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Rename the category with the id "catID" to "title"
-//--------------------------------------------------------------------------------------
-public void renameCategory(string catID, string title)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Move the category with the id "catID" into another category
-// with the id "newParentID"
-// This method is only used if multi-level-categories are supported
-//--------------------------------------------------------------------------------------
-public void moveCategory(string catID, string newParentID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Delete the category with the id "catID"
-//--------------------------------------------------------------------------------------
-public void deleteCategory(string catID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Rename the feed with the id "feedID" from the category with the id "catID"
-// Don't delete the feed entirely, just remove it from the category.
-// Only useful if feed can be part of multiple categories.
-//--------------------------------------------------------------------------------------
-public void removeCatFromFeed(string feedID, string catID)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Import the content of "opml"
-// If the service doesn't provide API to import OPML you can use the
-// OPMLparser-class
-//--------------------------------------------------------------------------------------
-public void importOPML(string opml)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Get all feeds, categories and tags from the service
-// Fill up the emtpy LinkedList's that are provided with instances of the
-// model-classes category, feed and article
-//--------------------------------------------------------------------------------------
-public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Return the total count of unread articles on the server
-//--------------------------------------------------------------------------------------
-public int getUnreadCount()
-{
-
-}
-
-
-//--------------------------------------------------------------------------------------
-// Get the requested articles and write them to the data-base
-//
-// "count": the number of articles to get
-// "whatToGet": the kind of articles to get (all/unread/marked/etc.)
-// "since": how far back to sync articles (null = no limit)
-// "feedID": get only articles of a secific feed or tag
-// "isTagID": false if "feedID" is a feed-ID, true if "feedID" is a tag-ID
-//
-// It is recommended after getting the articles from the server to use the signal
-// "writeArticles(Gee.List<Article> articles)"
-// to automatically process them in the content-grabber, write them to the
-// data-base and send all the signals to the UI to update accordingly.
-// But if the API suggests a different approach you can everything on your
-// own (see ttrss-backend).
-//--------------------------------------------------------------------------------------
-public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
-
-}
-
+
+ //--------------------------------------------------------------------------------------
+ // This method gets executed right after the plugin is loaded. Do everything
+ // you need to set up the plugin here.
+ //--------------------------------------------------------------------------------------
+ public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Return the the website/homepage of the project
+ //--------------------------------------------------------------------------------------
+ public string getWebsite()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return an unique id for the backend. Basically a short form of the name:
+ // Tiny Tiny RSS -> "ttrss"
+ // Local Backend -> "local"
+ //--------------------------------------------------------------------------------------
+ public string getID()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return flags describing the type of Service
+ // - LOCAL
+ // - HOSTED
+ // - SELF_HOSTED
+ // - FREE_SOFTWARE
+ // - PROPRIETARY
+ // - FREE
+ // - PAID_PREMIUM
+ // - PAID
+ //--------------------------------------------------------------------------------------
+ public BackendFlags getFlags()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return the login UI inside a Gtk.Box (username- and password-entries)
+ // Return 'null' if use web-login
+ //--------------------------------------------------------------------------------------
+ public Gtk.Box? getWidget()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return the name of the service-icon (non-symbolic).
+ //--------------------------------------------------------------------------------------
+ public string iconName()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return the name of the service as displayed to the user
+ //--------------------------------------------------------------------------------------
+ public string serviceName()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return wheather the plugin needs a webview to log in via oauth.
+ //--------------------------------------------------------------------------------------
+ public bool needWebLogin()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Only important for self-hosted services.
+ // If the server is secured by htaccess and a second username and password
+ // is required, show the UI to enter those in this methode.
+ // If htaccess won't be needed do nothing here.
+ //--------------------------------------------------------------------------------------
+ public void showHtAccess()
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Methode gets executed before logging in. Write all the data gathered
+ // into gsettings (password, username, access-key).
+ //--------------------------------------------------------------------------------------
+ public void writeData()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Do stuff after a successful login
+ //--------------------------------------------------------------------------------------
+ public async void postLoginAction()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Only needed if "needWebLogin()" retruned true. Return URL that should be
+ // loaded to log in via website.
+ //--------------------------------------------------------------------------------------
+ public string buildLoginURL()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Extract access-key from redirect-URL from webview after loggin in with
+ // the webview.
+ // Return "true" if extracted sucessfuly, "false" otherwise.
+ //--------------------------------------------------------------------------------------
+ public bool extractCode(string redirectURL)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Does the service you are implementing support tags?
+ // If so return "true", otherwise return "false".
+ //--------------------------------------------------------------------------------------
+ public bool supportTags()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // If the daemon should to an initial sync after logging in.
+ // For all online services: true
+ // Only for local backend: false
+ //--------------------------------------------------------------------------------------
+ public bool doInitSync()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // What is the symbolic icon-name of the service-logo?
+ // Return a string with the name, not the complete path.
+ // For example: "feed-service-demo-symbolic"
+ //--------------------------------------------------------------------------------------
+ public string symbolicIcon()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return a name the account of the user can be identified with.
+ // This can be the real name of the user, the email-address
+ // or any other personal information that identifies the account.
+ //--------------------------------------------------------------------------------------
+ public string accountName()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // If the service can be self-hosted or has multiple providers
+ // you can return the URL of the server here. Preferably without "http://www."
+ //--------------------------------------------------------------------------------------
+ public string getServerURL()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Many services have different ways of telling if a feed is uncategorized.
+ // OwnCloud-News and Tiny Tiny RSS use the id "0", while feedly and InoReader
+ // use an empty string ("").
+ // Return what this service uses to indicate that the feed does not belong
+ // to any category.
+ //--------------------------------------------------------------------------------------
+ public string uncategorizedID()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Sone services have special categories that should not be visible when empty
+ // e.g. feedly has a category called "Must Read".
+ // Argument: ID of a category
+ // Return: wheather the category should be visible when empty
+ //--------------------------------------------------------------------------------------
+ public bool hideCategoryWhenEmpty(string catID)
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Does the service support categories at all? (feedbin is weird :P)
+ //--------------------------------------------------------------------------------------
+ public bool supportCategories()
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Does the service support add/remove/rename of categories and feeds?
+ //--------------------------------------------------------------------------------------
+ public bool supportFeedManipulation()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Does the service allow categories as children of other categories?
+ // If so return "true", otherwise return "false".
+ //--------------------------------------------------------------------------------------
+ public bool supportMultiLevelCategories()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Can one feed be part of more than one category?
+ // If so return "true", otherwise return "false".
+ //--------------------------------------------------------------------------------------
+ public bool supportMultiCategoriesPerFeed()
+ {
+
+ }
+
+ public bool syncFeedsAndCategories()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Does changing the name of a tag also change it's ID?
+ // InoReader tagID's for example look like this:
+ // "user/1005921515/label/tagName"
+ // So if the name changes the ID changes accordingly. This needs special treatment.
+ // Return "true" if this is the case, otherwise return "false".
+ //--------------------------------------------------------------------------------------
+ public bool tagIDaffectedByNameChange()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Delete all passwords, keys and user-information.
+ // Do not delete feeds or articles from the data-base.
+ //--------------------------------------------------------------------------------------
+ public void resetAccount()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // State wheater the service syncs articles based on a maximum count
+ // or uses something else (OwnCloud uses the last synced articleID)
+ //--------------------------------------------------------------------------------------
+ public bool useMaxArticles()
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Log in to the account of the service. If there is no need or API to sign in,
+ // check all passwords or keys and make sure the service is reachable and works.
+ // Possible return values are:
+ // - SUCCESS
+ // - MISSING_USER
+ // - MISSING_PASSWD
+ // - MISSING_URL
+ // - ALL_EMPTY
+ // - UNKNOWN_ERROR
+ // - FIRST_TRY
+ // - NO_BACKEND
+ // - WRONG_LOGIN
+ // - NO_CONNECTION
+ // - NO_API_ACCESS
+ // - UNAUTHORIZED
+ // - CA_ERROR
+ // - PLUGIN_NEEDED
+ //--------------------------------------------------------------------------------------
+ public LoginResponse login()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // If it is possible to log out of the account of the service, do so here.
+ // If not, do nothing and return "true".
+ //--------------------------------------------------------------------------------------
+ public bool logout()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Check if the service is reachable.
+ // You can use the method Utils.ping() if the service doesn't provide anything.
+ //--------------------------------------------------------------------------------------
+ public bool serverAvailable()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Method to set the state of articles to read or unread
+ // "articleIDs": comma separated string of articleIDs e.g. "id1,id2,id3"
+ // "read": the state to apply. ArticleStatus.READ or ArticleStatus.UNREAD
+ //--------------------------------------------------------------------------------------
+ public void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Method to set the state of articles to marked or unmarked
+ // "articleID": single articleID
+ // "read": the state to apply. ArticleStatus.MARKED or ArticleStatus.UNMARKED
+ //--------------------------------------------------------------------------------------
+ public void setArticleIsMarked(string articleID, ArticleStatus marked)
+ {
+
+ }
+
+ //--------------------------------------------------------------------------------------
+ // Should setArticleIsRead always be used instead of setFeedRead, setCategoryRead or
+ // markAllItemsRead?
+ // By using IDs as identifier, the articles are known, but it may be less efficient.
+ // If "true", the methods setFeedRead/setCategoryRead/markAllItemsRead never get called.
+ //--------------------------------------------------------------------------------------
+ public bool alwaysSetReadByID()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Mark all articles of the feed as read
+ //--------------------------------------------------------------------------------------
+ public void setFeedRead(string feedID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Mark all articles of the feeds that are part of the category as read
+ //--------------------------------------------------------------------------------------
+ public void setCategoryRead(string catID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Mark ALL articles as read
+ //--------------------------------------------------------------------------------------
+ public void markAllItemsRead()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Add an existing tag to the article
+ //--------------------------------------------------------------------------------------
+ public void tagArticle(string articleID, string tagID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Remove an existing tag from the article
+ //--------------------------------------------------------------------------------------
+ public void removeArticleTag(string articleID, string tagID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Create a new tag with the title of "caption" and return the id of the
+ // newly added tag.
+ // Hint: some services don't have API to create tags, but instead create them
+ // on the fly when tagging articles. In this case just compose the tagID
+ // following the schema tha service uses and return it.
+ //--------------------------------------------------------------------------------------
+ public string createTag(string caption)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Delete a tag completely
+ //--------------------------------------------------------------------------------------
+ public void deleteTag(string tagID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Rename the tag with the id "tagID" to the new name "title"
+ //--------------------------------------------------------------------------------------
+ public void renameTag(string tagID, string title)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Subscribe to the URL "feedURL"
+ // "catID": the category the feed should be placed into, "null" otherwise
+ // "newCatName": the name of a new category the feed should be put in, "null" otherwise
+ //--------------------------------------------------------------------------------------
+ public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Remove the feed with the id "feedID" completely
+ //--------------------------------------------------------------------------------------
+ public void removeFeed(string feedID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Rename the feed with the id "feedID" to "title"
+ //--------------------------------------------------------------------------------------
+ public void renameFeed(string feedID, string title)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Move the feed with the id "feedID" from its current category
+ // to any other category. "currentCatID" is only needed if the
+ // feed can be part of multiple categories at once.
+ //--------------------------------------------------------------------------------------
+ public void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Create a new category
+ // "title": title of the new category
+ // "parentID": only needed if multi-level-categories are supported
+ // Hint: some services don't have API to create categories, but instead create them
+ // on the fly when movin feeds over to them. In this case just compose the categoryID
+ // following the schema tha service uses and return it.
+ //--------------------------------------------------------------------------------------
+ public string createCategory(string title, string? parentID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Rename the category with the id "catID" to "title"
+ //--------------------------------------------------------------------------------------
+ public void renameCategory(string catID, string title)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Move the category with the id "catID" into another category
+ // with the id "newParentID"
+ // This method is only used if multi-level-categories are supported
+ //--------------------------------------------------------------------------------------
+ public void moveCategory(string catID, string newParentID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Delete the category with the id "catID"
+ //--------------------------------------------------------------------------------------
+ public void deleteCategory(string catID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Rename the feed with the id "feedID" from the category with the id "catID"
+ // Don't delete the feed entirely, just remove it from the category.
+ // Only useful if feed can be part of multiple categories.
+ //--------------------------------------------------------------------------------------
+ public void removeCatFromFeed(string feedID, string catID)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Import the content of "opml"
+ // If the service doesn't provide API to import OPML you can use the
+ // OPMLparser-class
+ //--------------------------------------------------------------------------------------
+ public void importOPML(string opml)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Get all feeds, categories and tags from the service
+ // Fill up the emtpy LinkedList's that are provided with instances of the
+ // model-classes category, feed and article
+ //--------------------------------------------------------------------------------------
+ public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Return the total count of unread articles on the server
+ //--------------------------------------------------------------------------------------
+ public int getUnreadCount()
+ {
+
+ }
+
+
+ //--------------------------------------------------------------------------------------
+ // Get the requested articles and write them to the data-base
+ //
+ // "count": the number of articles to get
+ // "whatToGet": the kind of articles to get (all/unread/marked/etc.)
+ // "since": how far back to sync articles (null = no limit)
+ // "feedID": get only articles of a secific feed or tag
+ // "isTagID": false if "feedID" is a feed-ID, true if "feedID" is a tag-ID
+ //
+ // It is recommended after getting the articles from the server to use the signal
+ // "writeArticles(Gee.List<Article> articles)"
+ // to automatically process them in the content-grabber, write them to the
+ // data-base and send all the signals to the UI to update accordingly.
+ // But if the API suggests a different approach you can everything on your
+ // own (see ttrss-backend).
+ //--------------------------------------------------------------------------------------
+ public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+
+ }
+
}
diff --git a/plugins/backend/feedbin/TestFeedbin.vala b/plugins/backend/feedbin/TestFeedbin.vala
index 87f5e83f..5ff779ca 100644
--- a/plugins/backend/feedbin/TestFeedbin.vala
+++ b/plugins/backend/feedbin/TestFeedbin.vala
@@ -24,201 +24,201 @@ void add_login_tests(string host)
{
return;
}
-
+
// Stick a random number at the end of Feed URL's to ensure that they're
// unique, even if we run two tests against the same account
uint nonce = Random.next_int();
-
+
Test.add_data_func ("/feedbinapi/login", () => {
-
+
var api = new FeedbinAPI(username, password, null, host);
assert(api.login());
-
+
api = new FeedbinAPI("wrong", "password", null, host);
assert(!api.login());
-
+
api.username = username;
assert(!api.login());
-
+
api.password = password;
assert(api.login());
});
-
+
Test.add_data_func ("/feedbinapi/subscription", () => {
if(username == null || password == null)
{
- Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
- return;
+ Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+ return;
}
-
+
var api = new FeedbinAPI(username, password, null, host);
-
+
var url = "https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-subscribe-$(nonce)";
delete_subscription(api, url);
-
+
var subscription = api.add_subscription(url);
assert(subscription.id != 0);
-
+
{
- var got_subscription = api.get_subscription(subscription.id);
- assert(got_subscription.id == subscription.id);
+ var got_subscription = api.get_subscription(subscription.id);
+ assert(got_subscription.id == subscription.id);
}
-
+
bool found_subscription = false;
foreach(var got_subscription in api.get_subscriptions())
{
- if(got_subscription.id == subscription.id)
- {
- assert(got_subscription.feed_id == subscription.feed_id);
- assert(got_subscription.feed_url == subscription.feed_url);
- assert(got_subscription.site_url == subscription.site_url);
- assert(got_subscription.title == subscription.title);
- found_subscription = true;
+ if(got_subscription.id == subscription.id)
+ {
+ assert(got_subscription.feed_id == subscription.feed_id);
+ assert(got_subscription.feed_url == subscription.feed_url);
+ assert(got_subscription.site_url == subscription.site_url);
+ assert(got_subscription.title == subscription.title);
+ found_subscription = true;
}
}
assert(found_subscription);
-
+
string title = "Rename test";
api.rename_subscription(subscription.id, title);
var renamed_subscription = api.get_subscription(subscription.id);
assert(renamed_subscription.title == title);
-
+
api.delete_subscription(subscription.id);
foreach(var got_subscription in api.get_subscriptions())
{
- assert(got_subscription.id != subscription.id);
- assert(got_subscription.feed_url != url);
+ assert(got_subscription.id != subscription.id);
+ assert(got_subscription.feed_url != url);
}
});
-
+
Test.add_data_func ("/feedbinapi/taggings", () => {
if(username == null || password == null)
{
- Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
- return;
+ Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+ return;
}
-
+
var api = new FeedbinAPI(username, password, null, host);
-
+
var url = @"https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-taggings-$(nonce)";
delete_subscription(api, url);
-
+
var subscription = api.add_subscription(url);
-
+
// The subscription is new so it shouldn't have any taggings
var taggings = api.get_taggings();
foreach(var tagging in taggings)
{
- assert(tagging.feed_id != subscription.feed_id);
+ assert(tagging.feed_id != subscription.feed_id);
}
-
+
string category = "Taggings Test";
api.add_tagging(subscription.feed_id, category);
-
+
// Check taggings
int64? tagging_id = null;
foreach(var tagging in api.get_taggings())
{
- if(tagging.feed_id == subscription.feed_id)
- {
- assert(tagging.name == category);
- tagging_id = tagging.id;
- break;
+ if(tagging.feed_id == subscription.feed_id)
+ {
+ assert(tagging.name == category);
+ tagging_id = tagging.id;
+ break;
}
}
assert(tagging_id != null);
-
+
// Delete the tag and verify that it's gone
api.delete_tagging(tagging_id);
foreach(var tagging in api.get_taggings())
{
- assert(tagging.feed_id != subscription.feed_id);
+ assert(tagging.feed_id != subscription.feed_id);
}
-
+
// cleanup
api.delete_subscription(subscription.id);
});
-
+
Test.add_data_func ("/feedbinapi/entries", () => {
if(username == null || password == null)
{
- Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
- return;
+ Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+ return;
}
-
+
var api = new FeedbinAPI(username, password, null, host);
-
+
// Note: This one shouldn't be deleted or recreated, since we want the entries to be available
var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-entries";
-
+
var subscription = api.add_subscription(url);
-
+
/* FIXME: Figure out why this next line is failing
- var entries = api.get_entries(1, false, null, subscription.feed_id);
- foreach(var entry in entries)
- {
- assert(entry.feed_id == subscription.feed_id);
- }
-
- assert(entries.size > 0);
- int i = Random.int_range(0, entries.size);
- var entry = entries.to_array()[i];
- var entry_ids = new Gee.ArrayList<int64?>();
- entry_ids.add(entry.id);
-
- // read status
- api.set_entries_read(entry_ids, true);
- var unread_entries = api.get_unread_entries();
- assert(!unread_entries.contains(entry.id));
-
- api.set_entries_read(entry_ids, false);
- unread_entries = api.get_unread_entries();
- assert(unread_entries.contains(entry.id));
-
- api.set_entries_read(entry_ids, true);
- unread_entries = api.get_unread_entries();
- assert(!unread_entries.contains(entry.id));
-
- // starred status
- api.set_entries_starred(entry_ids, true);
- var starred_entries = api.get_starred_entries();
- assert(starred_entries.contains(entry.id));
-
- api.set_entries_starred(entry_ids, false);
- starred_entries = api.get_starred_entries();
- assert(!starred_entries.contains(entry.id));
-
- api.set_entries_starred(entry_ids, true);
- starred_entries = api.get_starred_entries();
- assert(starred_entries.contains(entry.id));
- */
+ var entries = api.get_entries(1, false, null, subscription.feed_id);
+ foreach(var entry in entries)
+ {
+ assert(entry.feed_id == subscription.feed_id);
+ }
+
+ assert(entries.size > 0);
+ int i = Random.int_range(0, entries.size);
+ var entry = entries.to_array()[i];
+ var entry_ids = new Gee.ArrayList<int64?>();
+ entry_ids.add(entry.id);
+
+ // read status
+ api.set_entries_read(entry_ids, true);
+ var unread_entries = api.get_unread_entries();
+ assert(!unread_entries.contains(entry.id));
+
+ api.set_entries_read(entry_ids, false);
+ unread_entries = api.get_unread_entries();
+ assert(unread_entries.contains(entry.id));
+
+ api.set_entries_read(entry_ids, true);
+ unread_entries = api.get_unread_entries();
+ assert(!unread_entries.contains(entry.id));
+
+ // starred status
+ api.set_entries_starred(entry_ids, true);
+ var starred_entries = api.get_starred_entries();
+ assert(starred_entries.contains(entry.id));
+
+ api.set_entries_starred(entry_ids, false);
+ starred_entries = api.get_starred_entries();
+ assert(!starred_entries.contains(entry.id));
+
+ api.set_entries_starred(entry_ids, true);
+ starred_entries = api.get_starred_entries();
+ assert(starred_entries.contains(entry.id));
+ */
});
-
+
Test.add_data_func ("/feedbinapi/favicons", () => {
if(username == null || password == null)
{
- Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
- return;
+ Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+ return;
}
-
+
var api = new FeedbinAPI(username, password, null, host);
-
+
// Note: This one shouldn't be deleted or recreated, since we want the entries to be available
var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-favicons";
-
+
var subscription = api.add_subscription(url);
var favicons = api.get_favicons();
bool found_favicon = false;
foreach(var i in favicons.entries)
{
- if(i.key != "www.brendanlong.com")
- {
- continue;
+ if(i.key != "www.brendanlong.com")
+ {
+ continue;
}
- // Don't check the contents of the Favicon because Feedbin doesn't
- // seem to neccessarily return the exact icon we gave it
- found_favicon = true;
- break;
+ // Don't check the contents of the Favicon because Feedbin doesn't
+ // seem to neccessarily return the exact icon we gave it
+ found_favicon = true;
+ break;
}
// FIXME: We don't download icons on the test server because favicon downloading
// is handled by a different service
@@ -229,26 +229,26 @@ void add_login_tests(string host)
void main(string[] args)
{
Test.init(ref args);
-
+
string? host = Environment.get_variable(host_env);
if(host == null)
{
host = "https://api.feedbin.com";
}
-
+
// Tests that don't need a login
Test.add_data_func ("/feedbinapi/construct", () => {
var api = new FeedbinAPI("user", "password", null, host);
assert(api != null);
});
-
+
Test.add_data_func ("/feedbinapi/bad login", () => {
var api = new FeedbinAPI("user", "password", null, host);
-
+
assert(!api.login());
});
-
+
add_login_tests(host);
-
+
Test.run ();
}
diff --git a/plugins/backend/feedbin/feedbinAPI.vala b/plugins/backend/feedbin/feedbinAPI.vala
index 27603b79..ecb94892 100644
--- a/plugins/backend/feedbin/feedbinAPI.vala
+++ b/plugins/backend/feedbin/feedbinAPI.vala
@@ -24,447 +24,447 @@ public errordomain FeedbinError {
}
public class FeedbinAPI : Object {
-private const string BASE_URI_FORMAT = "%s/v2/";
-
-private Soup.Session m_session;
-private string m_base_uri;
-public string username { get; set; }
-public string password { get; set; }
-
-public FeedbinAPI(string username, string password, string? user_agent = null, string? host = "https://api.feedbin.com")
-{
- this.username = username;
- this.password = password;
- m_base_uri = BASE_URI_FORMAT.printf(host);
- m_session = new Soup.Session();
-
- if(user_agent != null)
+ private const string BASE_URI_FORMAT = "%s/v2/";
+
+ private Soup.Session m_session;
+ private string m_base_uri;
+ public string username { get; set; }
+ public string password { get; set; }
+
+ public FeedbinAPI(string username, string password, string? user_agent = null, string? host = "https://api.feedbin.com")
{
- m_session.user_agent = user_agent;
- }
-
- m_session.authenticate.connect(authenticate);
-}
-
-~FeedbinAPI()
-{
- m_session.authenticate.disconnect(authenticate);
-}
-
-private void authenticate(Soup.Message msg, Soup.Auth auth, bool retrying)
-{
- if(!retrying)
- {
- auth.authenticate(this.username, this.password);
+ this.username = username;
+ this.password = password;
+ m_base_uri = BASE_URI_FORMAT.printf(host);
+ m_session = new Soup.Session();
+
+ if(user_agent != null)
+ {
+ m_session.user_agent = user_agent;
+ }
+
+ m_session.authenticate.connect(authenticate);
}
-}
-
-private Soup.Message request(string method, string last_part, string? input = null) throws FeedbinError
-requires (method == "DELETE" || method == "GET" || method == "POST")
-requires (input == null || method != "GET")
-ensures (result.status_code >= 200)
-ensures (result.status_code < 400)
-{
- var path = m_base_uri + last_part;
- var message = new Soup.Message(method, path);
-
- if(method == "POST")
+
+ ~FeedbinAPI()
{
- message.request_headers.append("Content-Type", "application/json; charset=utf-8");
+ m_session.authenticate.disconnect(authenticate);
}
-
- if(input != null)
+
+ private void authenticate(Soup.Message msg, Soup.Auth auth, bool retrying)
{
- message.request_body.append_take(input.data);
+ if(!retrying)
+ {
+ auth.authenticate(this.username, this.password);
+ }
}
-
- m_session.send_message(message);
- var status = message.status_code;
- if(status < 200 || status >= 400)
+
+ private Soup.Message request(string method, string last_part, string? input = null) throws FeedbinError
+ requires (method == "DELETE" || method == "GET" || method == "POST")
+ requires (input == null || method != "GET")
+ ensures (result.status_code >= 200)
+ ensures (result.status_code < 400)
{
- switch(status)
+ var path = m_base_uri + last_part;
+ var message = new Soup.Message(method, path);
+
+ if(method == "POST")
+ {
+ message.request_headers.append("Content-Type", "application/json; charset=utf-8");
+ }
+
+ if(input != null)
{
- case Soup.Status.CANT_RESOLVE:
- case Soup.Status.CANT_RESOLVE_PROXY:
- case Soup.Status.CANT_CONNECT:
- case Soup.Status.CANT_CONNECT_PROXY:
- throw new FeedbinError.NO_CONNECTION(@"Connection to $m_base_uri failed");
- case Soup.Status.UNAUTHORIZED:
- throw new FeedbinError.NOT_AUTHORIZED(@"Not authorized to $method $path");
- case Soup.Status.NOT_FOUND:
- throw new FeedbinError.NOT_FOUND(@"$method $path not found");
+ message.request_body.append_take(input.data);
}
- string phrase = Soup.Status.get_phrase(status);
- throw new FeedbinError.UNKNOWN_ERROR(@"Unexpected status $status ($phrase) for $method $path");
+
+ m_session.send_message(message);
+ var status = message.status_code;
+ if(status < 200 || status >= 400)
+ {
+ switch(status)
+ {
+ case Soup.Status.CANT_RESOLVE:
+ case Soup.Status.CANT_RESOLVE_PROXY:
+ case Soup.Status.CANT_CONNECT:
+ case Soup.Status.CANT_CONNECT_PROXY:
+ throw new FeedbinError.NO_CONNECTION(@"Connection to $m_base_uri failed");
+ case Soup.Status.UNAUTHORIZED:
+ throw new FeedbinError.NOT_AUTHORIZED(@"Not authorized to $method $path");
+ case Soup.Status.NOT_FOUND:
+ throw new FeedbinError.NOT_FOUND(@"$method $path not found");
+ }
+ string phrase = Soup.Status.get_phrase(status);
+ throw new FeedbinError.UNKNOWN_ERROR(@"Unexpected status $status ($phrase) for $method $path");
+ }
+ return message;
}
- return message;
-}
-
-// TODO: Move to DateUtils
-private static DateTime string_to_datetime(string s) throws FeedbinError
-{
- var time = TimeVal();
- if(!time.from_iso8601(s))
+
+ // TODO: Move to DateUtils
+ private static DateTime string_to_datetime(string s) throws FeedbinError
{
- throw new FeedbinError.INVALID_FORMAT(@"Expected date but got $s");
+ var time = TimeVal();
+ if(!time.from_iso8601(s))
+ {
+ throw new FeedbinError.INVALID_FORMAT(@"Expected date but got $s");
+ }
+ return new DateTime.from_timeval_utc(time);
}
- return new DateTime.from_timeval_utc(time);
-}
-
-// TODO: JSON utils?
-private static DateTime get_datetime_member(Json.Object obj, string name) throws FeedbinError
-requires (name != "")
-{
- var s = obj.get_string_member(name);
- return string_to_datetime(s);
-}
-
-private Soup.Message post_request(string path, string input) throws FeedbinError
-requires (input != "")
-{
- return request("POST", path, input);
-}
-
-private Soup.Message delete_request(string path) throws FeedbinError
-{
- return request("DELETE", path);
-}
-
-private Soup.Message get_request(string path) throws FeedbinError
-{
- return request("GET", path);
-}
-
-private static Json.Node parse_json(Soup.Message response) throws FeedbinError
-{
- var method = response.method;
- var uri = response.uri.to_string(false);
- string content = (string)response.response_body.flatten().data;
- if(content == null)
+
+ // TODO: JSON utils?
+ private static DateTime get_datetime_member(Json.Object obj, string name) throws FeedbinError
+ requires (name != "")
{
- throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned no content but expected JSON");
+ var s = obj.get_string_member(name);
+ return string_to_datetime(s);
}
-
- var parser = new Json.Parser();
- try
+
+ private Soup.Message post_request(string path, string input) throws FeedbinError
+ requires (input != "")
{
- parser.load_from_data(content, -1);
+ return request("POST", path, input);
}
- catch (Error e)
+
+ private Soup.Message delete_request(string path) throws FeedbinError
{
- throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned invalid JSON: " + e.message + "\nContent is: $content");
+ return request("DELETE", path);
}
- return parser.get_root();
-}
-
-private Json.Node get_json(string path) throws FeedbinError
-requires (path != "")
-{
- var response = get_request(path);
- return parse_json(response);
-}
-
-private Soup.Message post_json_object(string path, Json.Object obj) throws FeedbinError
-{
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(obj);
-
- var gen = new Json.Generator();
- gen.set_root(root);
- var data = gen.to_data(null);
-
- return post_request(path, data);
-}
-
-public bool login() throws FeedbinError
-{
- try
+
+ private Soup.Message get_request(string path) throws FeedbinError
{
- var res = get_request("authentication.json");
- return res.status_code == Soup.Status.OK;
+ return request("GET", path);
}
- catch(FeedbinError.NOT_AUTHORIZED e)
+
+ private static Json.Node parse_json(Soup.Message response) throws FeedbinError
{
- return false;
+ var method = response.method;
+ var uri = response.uri.to_string(false);
+ string content = (string)response.response_body.flatten().data;
+ if(content == null)
+ {
+ throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned no content but expected JSON");
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(content, -1);
+ }
+ catch (Error e)
+ {
+ throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned invalid JSON: " + e.message + "\nContent is: $content");
+ }
+ return parser.get_root();
}
-}
-
-public struct Subscription {
- int64 id;
- DateTime created_at;
- int64 feed_id;
- string? title;
- string? feed_url;
- string? site_url;
-
- public Subscription.from_json(Json.Object object) throws FeedbinError
+
+ private Json.Node get_json(string path) throws FeedbinError
+ requires (path != "")
{
- id = object.get_int_member("id");
- created_at = get_datetime_member(object, "created_at");
- feed_id = object.get_int_member("feed_id");
- title = object.get_string_member("title");
- feed_url = object.get_string_member("feed_url");
- site_url = object.get_string_member("site_url");
+ var response = get_request(path);
+ return parse_json(response);
}
-}
-
-public Subscription get_subscription(int64 subscription_id) throws FeedbinError
-{
- var root = get_json(@"subscriptions/$subscription_id.json");
- return Subscription.from_json(root.get_object());
-}
-
-public Gee.List<Subscription?> get_subscriptions() throws FeedbinError
-ensures (!result.contains(null))
-{
- var root = get_json("subscriptions.json");
- var subscriptions = new Gee.ArrayList<Subscription?>();
- var array = root.get_array();
- for(var i = 0; i < array.get_length(); ++i)
+
+ private Soup.Message post_json_object(string path, Json.Object obj) throws FeedbinError
{
- var node = array.get_object_element(i);
- subscriptions.add(Subscription.from_json(node));
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(obj);
+
+ var gen = new Json.Generator();
+ gen.set_root(root);
+ var data = gen.to_data(null);
+
+ return post_request(path, data);
}
- return subscriptions;
-}
-
-public void delete_subscription(int64 subscription_id) throws FeedbinError
-{
- delete_request(@"subscriptions/$subscription_id.json");
-}
-
-public Subscription? add_subscription(string url) throws FeedbinError
-{
- Json.Object object = new Json.Object();
- object.set_string_member("feed_url", url);
-
- try
+
+ public bool login() throws FeedbinError
{
- var response = post_json_object("subscriptions.json", object);
- if(response.status_code == 300)
+ try
{
- throw new FeedbinError.MULTIPLE_CHOICES("Site $url has multiple feeds to subscribe to");
+ var res = get_request("authentication.json");
+ return res.status_code == Soup.Status.OK;
+ }
+ catch(FeedbinError.NOT_AUTHORIZED e)
+ {
+ return false;
}
-
- var root = parse_json(response);
- return Subscription.from_json(root.get_object());
}
- catch (FeedbinError.NOT_FOUND e)
- {
- return null;
+
+ public struct Subscription {
+ int64 id;
+ DateTime created_at;
+ int64 feed_id;
+ string? title;
+ string? feed_url;
+ string? site_url;
+
+ public Subscription.from_json(Json.Object object) throws FeedbinError
+ {
+ id = object.get_int_member("id");
+ created_at = get_datetime_member(object, "created_at");
+ feed_id = object.get_int_member("feed_id");
+ title = object.get_string_member("title");
+ feed_url = object.get_string_member("feed_url");
+ site_url = object.get_string_member("site_url");
+ }
}
-}
-
-public void rename_subscription(int64 subscription_id, string title) throws FeedbinError
-{
- Json.Object object = new Json.Object();
- object.set_string_member("title", title);
- post_json_object(@"subscriptions/$subscription_id/update.json", object);
-}
-
-public struct Tagging
-{
- int64 id;
- int64 feed_id;
- string name;
-
- public Tagging.from_json(Json.Object object)
+
+ public Subscription get_subscription(int64 subscription_id) throws FeedbinError
{
- id = object.get_int_member("id");
- feed_id = object.get_int_member("feed_id");
- name = object.get_string_member("name");
+ var root = get_json(@"subscriptions/$subscription_id.json");
+ return Subscription.from_json(root.get_object());
}
-}
-
-public void add_tagging(int64 feed_id, string tag_name) throws FeedbinError
-{
- Json.Object object = new Json.Object();
- object.set_int_member("feed_id", feed_id);
- object.set_string_member("name", tag_name);
-
- post_json_object("taggings.json", object);
- // TODO: Return id
-}
-
-public void delete_tagging(int64 tagging_id) throws FeedbinError
-{
- delete_request(@"taggings/$tagging_id.json");
-}
-
-public Gee.List<Tagging?> get_taggings() throws FeedbinError
-ensures (!result.contains(null))
-{
- var root = get_json("taggings.json");
- var taggings = new Gee.ArrayList<Tagging?>();
- var array = root.get_array();
- for(var i = 0; i < array.get_length(); ++i)
+
+ public Gee.List<Subscription?> get_subscriptions() throws FeedbinError
+ ensures (!result.contains(null))
{
- var object = array.get_object_element(i);
- taggings.add(Tagging.from_json(object));
+ var root = get_json("subscriptions.json");
+ var subscriptions = new Gee.ArrayList<Subscription?>();
+ var array = root.get_array();
+ for(var i = 0; i < array.get_length(); ++i)
+ {
+ var node = array.get_object_element(i);
+ subscriptions.add(Subscription.from_json(node));
+ }
+ return subscriptions;
}
- return taggings;
-}
-
-public struct Entry
-{
- int64 id;
- int64 feed_id;
- string? title;
- string? url;
- string? author;
- string? content;
- string? summary;
- DateTime published;
- DateTime created_at;
-
- public Entry.from_json(Json.Object object) throws FeedbinError
+
+ public void delete_subscription(int64 subscription_id) throws FeedbinError
{
- id = object.get_int_member("id");
- feed_id = object.get_int_member("feed_id");
- title = object.get_string_member("title");
- url = object.get_string_member("url");
- author = object.get_string_member("author");
- content = object.get_string_member("content");
- summary = object.get_string_member("summary");
- published = get_datetime_member(object, "published");
- created_at = get_datetime_member(object, "created_at");
+ delete_request(@"subscriptions/$subscription_id.json");
}
-}
-
-public Gee.List<Entry?> get_entries(int page, bool only_starred, DateTime? since, int64? feed_id = null) throws FeedbinError
-requires (page >= 0)
-ensures (!result.contains(null))
-{
- string starred = only_starred ? "true" : "false";
- string path = @"entries.json?per_page=100&page=$page&starred=$starred&include_enclosure=true";
- if(since != null)
+
+ public Subscription? add_subscription(string url) throws FeedbinError
{
- var t = GLib.TimeVal();
- if(since.to_timeval(out t))
+ Json.Object object = new Json.Object();
+ object.set_string_member("feed_url", url);
+
+ try
{
- path += "&since=" + t.to_iso8601();
+ var response = post_json_object("subscriptions.json", object);
+ if(response.status_code == 300)
+ {
+ throw new FeedbinError.MULTIPLE_CHOICES("Site $url has multiple feeds to subscribe to");
+ }
+
+ var root = parse_json(response);
+ return Subscription.from_json(root.get_object());
+ }
+ catch (FeedbinError.NOT_FOUND e)
+ {
+ return null;
}
}
-
- if(feed_id != null)
+
+ public void rename_subscription(int64 subscription_id, string title) throws FeedbinError
{
- path = @"feeds/$feed_id/$path";
+ Json.Object object = new Json.Object();
+ object.set_string_member("title", title);
+ post_json_object(@"subscriptions/$subscription_id/update.json", object);
}
-
- Json.Node root;
- try
+
+ public struct Tagging
{
- root = get_json(path);
+ int64 id;
+ int64 feed_id;
+ string name;
+
+ public Tagging.from_json(Json.Object object)
+ {
+ id = object.get_int_member("id");
+ feed_id = object.get_int_member("feed_id");
+ name = object.get_string_member("name");
+ }
}
- catch(FeedbinError.NOT_FOUND e)
+
+ public void add_tagging(int64 feed_id, string tag_name) throws FeedbinError
{
- return Gee.List.empty<Entry?>();
+ Json.Object object = new Json.Object();
+ object.set_int_member("feed_id", feed_id);
+ object.set_string_member("name", tag_name);
+
+ post_json_object("taggings.json", object);
+ // TODO: Return id
}
-
- var entries = new Gee.ArrayList<Entry?>();
- var array = root.get_array();
- for(var i = 0; i < array.get_length(); ++i)
+
+ public void delete_tagging(int64 tagging_id) throws FeedbinError
{
- var object = array.get_object_element(i);
- entries.add(Entry.from_json(object));
+ delete_request(@"taggings/$tagging_id.json");
}
- return entries;
-}
-
-private Gee.Set<int64?> get_x_entries(string path) throws FeedbinError
-{
- var root = get_json(path);
- var array = root.get_array();
- // We have to set the hash function here manually or contains() won't
- // work right -- presumably because it's trying to do pointer comparisons?
- var ids = new Gee.HashSet<int64?>(
- (n) => { return int64_hash(n); },
- (a, b) => { return int64_equal(a, b); });
- for(var i = 0; i < array.get_length(); ++i)
+
+ public Gee.List<Tagging?> get_taggings() throws FeedbinError
+ ensures (!result.contains(null))
{
- ids.add(array.get_int_element(i));
+ var root = get_json("taggings.json");
+ var taggings = new Gee.ArrayList<Tagging?>();
+ var array = root.get_array();
+ for(var i = 0; i < array.get_length(); ++i)
+ {
+ var object = array.get_object_element(i);
+ taggings.add(Tagging.from_json(object));
+ }
+ return taggings;
}
- return ids;
-}
-
-public Gee.Set<int64?> get_unread_entries() throws FeedbinError
-{
- return get_x_entries("unread_entries.json");
-}
-
-public Gee.Set<int64?> get_starred_entries() throws FeedbinError
-{
- return get_x_entries("starred_entries.json");
-}
-
-private void set_entries_status(string type, Gee.Collection<int64?> entry_ids, bool create) throws FeedbinError
-requires (!entry_ids.contains(null))
-{
- Json.Array array = new Json.Array();
- foreach(var id in entry_ids)
+
+ public struct Entry
{
- array.add_int_element(id);
+ int64 id;
+ int64 feed_id;
+ string? title;
+ string? url;
+ string? author;
+ string? content;
+ string? summary;
+ DateTime published;
+ DateTime created_at;
+
+ public Entry.from_json(Json.Object object) throws FeedbinError
+ {
+ id = object.get_int_member("id");
+ feed_id = object.get_int_member("feed_id");
+ title = object.get_string_member("title");
+ url = object.get_string_member("url");
+ author = object.get_string_member("author");
+ content = object.get_string_member("content");
+ summary = object.get_string_member("summary");
+ published = get_datetime_member(object, "published");
+ created_at = get_datetime_member(object, "created_at");
+ }
}
-
- Json.Object object = new Json.Object();
- object.set_array_member(type, array);
-
- string path = create ? @"$type.json" : @"$type/delete.json";
- post_json_object(path, object);
-}
-
-public void set_entries_read(Gee.Collection<int64?> entry_ids, bool read) throws FeedbinError
-requires (!entry_ids.contains(null))
-{
- set_entries_status("unread_entries", entry_ids, !read);
-}
-
-public void set_entries_starred(Gee.Collection<int64?> entry_ids, bool starred) throws FeedbinError
-requires (!entry_ids.contains(null))
-{
- set_entries_status("starred_entries", entry_ids, starred);
-}
-
-public Gee.Map<string, Bytes?> get_favicons() throws FeedbinError
-{
- // The favicon API isn't public right now; make sure to handle it
- // suddenly changing or disappearing
- try
+
+ public Gee.List<Entry?> get_entries(int page, bool only_starred, DateTime? since, int64? feed_id = null) throws FeedbinError
+ requires (page >= 0)
+ ensures (!result.contains(null))
{
- var root = get_json("favicons.json");
- if(root == null)
+ string starred = only_starred ? "true" : "false";
+ string path = @"entries.json?per_page=100&page=$page&starred=$starred&include_enclosure=true";
+ if(since != null)
{
- return Gee.Map.empty<string, Bytes?>();
+ var t = GLib.TimeVal();
+ if(since.to_timeval(out t))
+ {
+ path += "&since=" + t.to_iso8601();
+ }
}
-
+
+ if(feed_id != null)
+ {
+ path = @"feeds/$feed_id/$path";
+ }
+
+ Json.Node root;
+ try
+ {
+ root = get_json(path);
+ }
+ catch(FeedbinError.NOT_FOUND e)
+ {
+ return Gee.List.empty<Entry?>();
+ }
+
+ var entries = new Gee.ArrayList<Entry?>();
var array = root.get_array();
- if(array == null)
+ for(var i = 0; i < array.get_length(); ++i)
{
- return Gee.Map.empty<string, Bytes?>();
+ var object = array.get_object_element(i);
+ entries.add(Entry.from_json(object));
}
-
- var favicons = new Gee.HashMap<string, Bytes?>();
+ return entries;
+ }
+
+ private Gee.Set<int64?> get_x_entries(string path) throws FeedbinError
+ {
+ var root = get_json(path);
+ var array = root.get_array();
+ // We have to set the hash function here manually or contains() won't
+ // work right -- presumably because it's trying to do pointer comparisons?
+ var ids = new Gee.HashSet<int64?>(
+ (n) => { return int64_hash(n); },
+ (a, b) => { return int64_equal(a, b); });
for(var i = 0; i < array.get_length(); ++i)
{
- var obj = array.get_object_element(i);
- string host = obj.get_string_member("host");
- if(host == null)
+ ids.add(array.get_int_element(i));
+ }
+ return ids;
+ }
+
+ public Gee.Set<int64?> get_unread_entries() throws FeedbinError
+ {
+ return get_x_entries("unread_entries.json");
+ }
+
+ public Gee.Set<int64?> get_starred_entries() throws FeedbinError
+ {
+ return get_x_entries("starred_entries.json");
+ }
+
+ private void set_entries_status(string type, Gee.Collection<int64?> entry_ids, bool create) throws FeedbinError
+ requires (!entry_ids.contains(null))
+ {
+ Json.Array array = new Json.Array();
+ foreach(var id in entry_ids)
+ {
+ array.add_int_element(id);
+ }
+
+ Json.Object object = new Json.Object();
+ object.set_array_member(type, array);
+
+ string path = create ? @"$type.json" : @"$type/delete.json";
+ post_json_object(path, object);
+ }
+
+ public void set_entries_read(Gee.Collection<int64?> entry_ids, bool read) throws FeedbinError
+ requires (!entry_ids.contains(null))
+ {
+ set_entries_status("unread_entries", entry_ids, !read);
+ }
+
+ public void set_entries_starred(Gee.Collection<int64?> entry_ids, bool starred) throws FeedbinError
+ requires (!entry_ids.contains(null))
+ {
+ set_entries_status("starred_entries", entry_ids, starred);
+ }
+
+ public Gee.Map<string, Bytes?> get_favicons() throws FeedbinError
+ {
+ // The favicon API isn't public right now; make sure to handle it
+ // suddenly changing or disappearing
+ try
+ {
+ var root = get_json("favicons.json");
+ if(root == null)
{
- continue;
+ return Gee.Map.empty<string, Bytes?>();
}
- var favicon_encoded = obj.get_string_member("favicon");
- if(favicon_encoded == null)
+
+ var array = root.get_array();
+ if(array == null)
{
- continue;
+ return Gee.Map.empty<string, Bytes?>();
}
- var favicon = new Bytes.take(Base64.decode(favicon_encoded));
- favicons.set(host, favicon);
+
+ var favicons = new Gee.HashMap<string, Bytes?>();
+ for(var i = 0; i < array.get_length(); ++i)
+ {
+ var obj = array.get_object_element(i);
+ string host = obj.get_string_member("host");
+ if(host == null)
+ {
+ continue;
+ }
+ var favicon_encoded = obj.get_string_member("favicon");
+ if(favicon_encoded == null)
+ {
+ continue;
+ }
+ var favicon = new Bytes.take(Base64.decode(favicon_encoded));
+ favicons.set(host, favicon);
+ }
+ return favicons;
+ }
+ catch(Error e)
+ {
+ return Gee.Map.empty<string, Bytes?>();
}
- return favicons;
- }
- catch(Error e)
- {
- return Gee.Map.empty<string, Bytes?>();
}
}
-}
diff --git a/plugins/backend/feedbin/feedbinInterface.vala b/plugins/backend/feedbin/feedbinInterface.vala
index 3c46de9a..86c3d5a3 100644
--- a/plugins/backend/feedbin/feedbinInterface.vala
+++ b/plugins/backend/feedbin/feedbinInterface.vala
@@ -14,745 +14,745 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedbinInterface : FeedServerInterface {
-
-private FeedbinAPI m_api;
-private FeedbinUtils m_utils;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new FeedbinUtils(settings_backend, secrets);
- m_api = new FeedbinAPI(m_utils.getUser(), m_utils.getPassword(), Constants.USER_AGENT);
-}
-
-public override string getWebsite()
-{
- return "https://feedbin.com/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.PAID);
-}
-
-public override string getID()
-{
- return "feedbin";
-}
-
-public override string iconName()
-{
- return "feed-service-feedbin";
-}
-
-public override string serviceName()
-{
- return "Feedbin";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-ensures (result != null)
-{
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
- var loginButton = new Gtk.Button.with_label(_("Login"));
-
- m_userEntry.activate.connect(() => {
+
+ private FeedbinAPI m_api;
+ private FeedbinUtils m_utils;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+ {
+ m_utils = new FeedbinUtils(settings_backend, secrets);
+ m_api = new FeedbinAPI(m_utils.getUser(), m_utils.getPassword(), Constants.USER_AGENT);
+ }
+
+ public override string getWebsite()
+ {
+ return "https://feedbin.com/";
+ }
+
+ public override BackendFlags getFlags()
+ {
+ return (BackendFlags.HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.PAID);
+ }
+
+ public override string getID()
+ {
+ return "feedbin";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-feedbin";
+ }
+
+ public override string serviceName()
+ {
+ return "Feedbin";
+ }
+
+ public override bool needWebLogin()
+ {
+ return false;
+ }
+
+ public override Gtk.Box? getWidget()
+ ensures (result != null)
+ {
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+
+ m_userEntry.activate.connect(() => {
loginButton.activate();
});
- m_passwordEntry.activate.connect(() => {
+ m_passwordEntry.activate.connect(() => {
loginButton.activate();
});
-
- m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(user_label, 0, 0, 1, 1);
- grid.attach(m_userEntry, 1, 0, 1, 1);
- grid.attach(password_label, 0, 1, 1, 1);
- grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
- var logo = new Gtk.Image.from_icon_name("feed-service-feedbin", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to Feedbin to enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => {
+
+ m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(user_label, 0, 0, 1, 1);
+ grid.attach(m_userEntry, 1, 0, 1, 1);
+ grid.attach(password_label, 0, 1, 1, 1);
+ grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-feedbin", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to Feedbin to enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => {
tryLogin();
});
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPassword());
-
- return box;
-}
-
-public override void writeData()
-{
- m_api.username = m_userEntry.get_text().strip();
- m_utils.setUser(m_api.username);
-
- m_api.password = m_passwordEntry.get_text().strip();
- m_utils.setPassword(m_api.password);
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-feedbin-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return "https://feedbin.com/";
-}
-
-public override string uncategorizedID()
-{
- return "0";
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return false;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- try
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPassword());
+
+ return box;
+ }
+
+ public override void writeData()
{
- if(m_api.login())
- {
- return LoginResponse.SUCCESS;
- }
- else
- {
- return LoginResponse.WRONG_LOGIN;
- }
+ m_api.username = m_userEntry.get_text().strip();
+ m_utils.setUser(m_api.username);
+
+ m_api.password = m_passwordEntry.get_text().strip();
+ m_utils.setPassword(m_api.password);
}
- catch(FeedbinError.NO_CONNECTION e)
+
+ public override bool supportTags()
{
- return LoginResponse.NO_CONNECTION;
+ return false;
}
- catch(Error e)
+
+ public override bool doInitSync()
{
- Logger.error("Feedbin login: " + e.message);
- return LoginResponse.UNKNOWN_ERROR;
+ return true;
}
-}
-
-public override bool serverAvailable()
-{
- return login() != LoginResponse.NO_CONNECTION;
-}
-
-public override void setArticleIsRead(string article_id, ArticleStatus status)
-{
- var entry_id = int64.parse(article_id);
- var entry_ids = ListUtils.single<int64?>(entry_id);
- try
+
+ public override string symbolicIcon()
{
- m_api.set_entries_read(entry_ids, status == ArticleStatus.READ);
+ return "feed-service-feedbin-symbolic";
}
- catch(Error e)
+
+ public override string accountName()
{
- Logger.error(@"FeedbinInterface.setArticleIsRead: " + e.message);
+ return m_utils.getUser();
}
-}
-
-public override void setArticleIsMarked(string article_id, ArticleStatus status)
-{
- var entry_id = int64.parse(article_id);
- var entry_ids = ListUtils.single<int64?>(entry_id);
- try
+
+ public override string getServerURL()
{
- m_api.set_entries_starred(entry_ids, status == ArticleStatus.MARKED);
+ return "https://feedbin.com/";
}
- catch(Error e)
+
+ public override string uncategorizedID()
{
- Logger.error(@"FeedbinInterface.setArticleIsMarked: " + e.message);
+ return "0";
}
-}
-
-private void setRead(string id, FeedListType type)
-{
- const int count = 1000;
- int num_articles = 1; // set to any value > 0
- var db = DataBase.readOnly();
- for(var offset = 0; num_articles > 0; offset += count)
- {
- var articles = db.read_articles(id, type, ArticleListState.ALL, "", count, offset);
- var entry_ids = new Gee.ArrayList<int64?>();
- foreach(var article in articles)
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return false;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ try
{
- entry_ids.add(int64.parse(article.getArticleID()));
+ if(m_api.login())
+ {
+ return LoginResponse.SUCCESS;
+ }
+ else
+ {
+ return LoginResponse.WRONG_LOGIN;
+ }
}
- try
+ catch(FeedbinError.NO_CONNECTION e)
{
- m_api.set_entries_read(entry_ids, true);
+ return LoginResponse.NO_CONNECTION;
}
catch(Error e)
{
- Logger.error(@"FeedbinInterface.setRead: " + e.message);
- break;
+ Logger.error("Feedbin login: " + e.message);
+ return LoginResponse.UNKNOWN_ERROR;
}
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feed_id)
-{
- setRead(feed_id, FeedListType.FEED);
-}
-
-public override void setCategoryRead(string category_id)
-{
- setRead(category_id, FeedListType.CATEGORY);
-}
-
-public override void markAllItemsRead()
-{
- setRead(FeedID.ALL.to_string(), FeedListType.FEED);
-}
-
-public override void tagArticle(string article_id, string tag_id)
-{
- return;
-}
-
-public override void removeArticleTag(string article_id, string tag_id)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- return "";
-}
-
-public override void deleteTag(string tag_id)
-{
- return;
-}
-
-public override void renameTag(string tagID, string title)
-{
- return;
-}
-
-public override bool addFeed(string feed_url, string? cat_id, string? category_name, out string feed_id, out string errmsg)
-{
- feed_id = "";
- try
+
+ public override bool serverAvailable()
+ {
+ return login() != LoginResponse.NO_CONNECTION;
+ }
+
+ public override void setArticleIsRead(string article_id, ArticleStatus status)
{
- var subscription = m_api.add_subscription(feed_url);
- if (subscription == null)
+ var entry_id = int64.parse(article_id);
+ var entry_ids = ListUtils.single<int64?>(entry_id);
+ try
{
- errmsg = @"Feedbin could not find a feed at $(feed_url)";
- return false;
+ m_api.set_entries_read(entry_ids, status == ArticleStatus.READ);
}
- feed_id = subscription.feed_id.to_string();
-
- if(category_name != null)
+ catch(Error e)
{
- m_api.add_tagging(subscription.feed_id, category_name);
+ Logger.error(@"FeedbinInterface.setArticleIsRead: " + e.message);
}
-
- errmsg = "";
- return true;
}
- catch(Error e)
+
+ public override void setArticleIsMarked(string article_id, ArticleStatus status)
{
- errmsg = e.message;
- Logger.error(@"FeedbinInterface.addFeed: $errmsg");
- return false;
+ var entry_id = int64.parse(article_id);
+ var entry_ids = ListUtils.single<int64?>(entry_id);
+ try
+ {
+ m_api.set_entries_starred(entry_ids, status == ArticleStatus.MARKED);
+ }
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.setArticleIsMarked: " + e.message);
+ }
}
-}
-
-private FeedbinAPI.Subscription subscription_for_feed(string feed_id_str) throws FeedbinError
-{
- var feed_id = int64.parse(feed_id_str);
- var subscriptions = m_api.get_subscriptions();
- foreach(var subscription in subscriptions)
+
+ private void setRead(string id, FeedListType type)
{
- if(subscription.feed_id == feed_id)
+ const int count = 1000;
+ int num_articles = 1; // set to any value > 0
+ var db = DataBase.readOnly();
+ for(var offset = 0; num_articles > 0; offset += count)
{
- return subscription;
+ var articles = db.read_articles(id, type, ArticleListState.ALL, "", count, offset);
+ var entry_ids = new Gee.ArrayList<int64?>();
+ foreach(var article in articles)
+ {
+ entry_ids.add(int64.parse(article.getArticleID()));
+ }
+ try
+ {
+ m_api.set_entries_read(entry_ids, true);
+ }
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.setRead: " + e.message);
+ break;
+ }
}
}
- throw new FeedbinError.NOT_FOUND("No subscription found for feed $feed_id");
-}
-
-public override void removeFeed(string feed_id_str)
-{
- try
+
+ public override bool alwaysSetReadByID()
{
- var subscription = subscription_for_feed(feed_id_str);
- m_api.delete_subscription(subscription.id);
+ return false;
}
- catch(Error e)
+
+ public override void setFeedRead(string feed_id)
{
- Logger.error(@"FeedbinInterface.removeFeed: " + e.message);
+ setRead(feed_id, FeedListType.FEED);
}
-}
-
-public override void renameFeed(string feed_id_str, string title)
-{
- try
+
+ public override void setCategoryRead(string category_id)
{
- var subscription = subscription_for_feed(feed_id_str);
- m_api.rename_subscription(subscription.id, title);
+ setRead(category_id, FeedListType.CATEGORY);
}
- catch(Error e)
+
+ public override void markAllItemsRead()
{
- Logger.error(@"FeedbinInterface.renameFeed: " + e.message);
+ setRead(FeedID.ALL.to_string(), FeedListType.FEED);
}
-}
-
-public override void moveFeed(string feed_id_str, string new_category, string? old_category)
-{
- Logger.debug(@"moveFeed: $feed_id_str from $old_category to $new_category");
- try
+
+ public override void tagArticle(string article_id, string tag_id)
{
- var subscription = subscription_for_feed(feed_id_str);
- var feed_id = subscription.feed_id;
- if(old_category != null)
- {
- var taggings = m_api.get_taggings();
- foreach(var tagging in taggings)
- {
- if(tagging.name != old_category || tagging.feed_id != feed_id)
- {
- continue;
- }
- Logger.debug(@"moveFeed: Deleting tag $old_category from $feed_id");
- m_api.delete_tagging(tagging.id);
- break;
- }
- }
- Logger.debug(@"moveFeed: Adding tag $new_category to $feed_id");
- m_api.add_tagging(feed_id, new_category);
+ return;
}
- catch(Error e)
+
+ public override void removeArticleTag(string article_id, string tag_id)
{
- Logger.error(@"FeedbinInterface.moveFeed: " + e.message);
+ return;
}
-}
-
-public override void renameCategory(string old_category, string new_category)
-{
- Logger.debug(@"renameCategory: From $old_category to $new_category");
- try
+
+ public override string createTag(string caption)
{
- var taggings = m_api.get_taggings();
- foreach(var tagging in taggings)
- {
- if(tagging.name != old_category)
- {
- continue;
- }
- var feed_id = tagging.feed_id;
- Logger.debug(@"renameCategory: Tagging $feed_id with $new_category");
- m_api.delete_tagging(tagging.id);
- m_api.add_tagging(feed_id, new_category);
- }
+ return "";
}
- catch(Error e)
+
+ public override void deleteTag(string tag_id)
{
- Logger.error(@"FeedbinInterface.renameCategory: " + e.message);
+ return;
}
-}
-
-public override void moveCategory(string category_id, string new_parent_id)
-{
- // Feedbin doesn't have multi-level categories
-}
-
-public override string createCategory(string title, string? parent_id)
-ensures (result == title)
-{
- // Categories are created and destroyed based on feeds having them.
- // There are no empty categories in Feedbin
- return title;
-}
-
-public override void deleteCategory(string category)
-{
- Logger.debug(@"deleteCategory: $category");
- try
+
+ public override void renameTag(string tagID, string title)
{
- var taggings = m_api.get_taggings();
- foreach(var tagging in taggings)
+ return;
+ }
+
+ public override bool addFeed(string feed_url, string? cat_id, string? category_name, out string feed_id, out string errmsg)
+ {
+ feed_id = "";
+ try
{
- if(tagging.name != category)
+ var subscription = m_api.add_subscription(feed_url);
+ if (subscription == null)
+ {
+ errmsg = @"Feedbin could not find a feed at $(feed_url)";
+ return false;
+ }
+ feed_id = subscription.feed_id.to_string();
+
+ if(category_name != null)
{
- continue;
+ m_api.add_tagging(subscription.feed_id, category_name);
}
- var feed_id = tagging.feed_id;
- Logger.debug(@"deleteCategory: Deleting category $category from feed $feed_id");
- m_api.delete_tagging(tagging.id);
+
+ errmsg = "";
+ return true;
+ }
+ catch(Error e)
+ {
+ errmsg = e.message;
+ Logger.error(@"FeedbinInterface.addFeed: $errmsg");
+ return false;
}
}
- catch(Error e)
- {
- Logger.error(@"FeedbinInterface.deleteCategory: " + e.message);
- }
-}
-
-public override void removeCatFromFeed(string feed_id_str, string category)
-{
- Logger.debug(@"removeCatFromFeed: Feed $feed_id_str, category $category");
- try
+
+ private FeedbinAPI.Subscription subscription_for_feed(string feed_id_str) throws FeedbinError
{
var feed_id = int64.parse(feed_id_str);
- var taggings = m_api.get_taggings();
- foreach(var tagging in taggings)
+ var subscriptions = m_api.get_subscriptions();
+ foreach(var subscription in subscriptions)
{
- if(tagging.feed_id != feed_id || tagging.name != category)
+ if(subscription.feed_id == feed_id)
{
- continue;
+ return subscription;
}
-
- Logger.debug(@"removeCatFromFeed: Deleting category $category from feed $feed_id");
- m_api.delete_tagging(tagging.id);
- break;
}
+ throw new FeedbinError.NOT_FOUND("No subscription found for feed $feed_id");
}
- catch(Error e)
- {
- Logger.error(@"FeedbinInterface.removeCatFromFeed: " + e.message);
- }
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- try
+
+ public override void removeFeed(string feed_id_str)
{
- var taggings = m_api.get_taggings();
- if(cancellable != null && cancellable.is_cancelled())
- {
- return false;
- }
-
- var favicons = m_api.get_favicons();
- if(cancellable != null && cancellable.is_cancelled())
+ try
{
- return false;
+ var subscription = subscription_for_feed(feed_id_str);
+ m_api.delete_subscription(subscription.id);
}
-
- // It's easier to rebuild the category list than to update it
- var category_names = new Gee.HashSet<string>();
- foreach(var tagging in taggings)
+ catch(Error e)
{
- category_names.add(tagging.name);
+ Logger.error(@"FeedbinInterface.removeFeed: " + e.message);
}
- Logger.debug("getFeedsAndCats: Got %d categories: %s".printf(category_names.size, StringUtils.join(category_names, ", ")));
-
- categories.clear();
- var top_category = CategoryID.MASTER.to_string();
- foreach(string name in category_names)
+ }
+
+ public override void renameFeed(string feed_id_str, string title)
+ {
+ try
{
- // Note: Feedbin categories *are* case sensitive, so we don't need
- // to change the case here. "articles" and "Articles" are different
- // tags.
- categories.add(
- new Category (
- name,
- name,
- 0,
- 0,
- top_category,
- 1
- )
- );
+ var subscription = subscription_for_feed(feed_id_str);
+ m_api.rename_subscription(subscription.id, title);
}
-
- var tag_map = new Gee.HashMultiMap<string, string>();
- foreach(var tagging in taggings)
+ catch(Error e)
{
- tag_map.set(tagging.feed_id.to_string(), tagging.name);
+ Logger.error(@"FeedbinInterface.renameFeed: " + e.message);
}
-
- var subscriptions = m_api.get_subscriptions();
- feeds.clear();
-
- foreach(var subscription in subscriptions)
+ }
+
+ public override void moveFeed(string feed_id_str, string new_category, string? old_category)
+ {
+ Logger.debug(@"moveFeed: $feed_id_str from $old_category to $new_category");
+ try
{
- var feed_id = subscription.feed_id.to_string();
- Gee.List<string> feed_categories = new Gee.ArrayList<string>();
-
- if(tag_map.contains(feed_id))
+ var subscription = subscription_for_feed(feed_id_str);
+ var feed_id = subscription.feed_id;
+ if(old_category != null)
{
- feed_categories.add_all(tag_map.get(feed_id));
- }
- else
- {
- feed_categories.add(uncategorizedID());
- }
-
- string? favicon_uri = null;
- if(subscription.site_url != null)
- {
- var uri = new Soup.URI(subscription.site_url);
- if(uri != null)
+ var taggings = m_api.get_taggings();
+ foreach(var tagging in taggings)
{
- var favicon = favicons.get(uri.host);
- if(favicon != null)
+ if(tagging.name != old_category || tagging.feed_id != feed_id)
{
- string base64 = Base64.encode(favicon.get_data());
- favicon_uri = @"data:application/octet-stream;base64,$base64";
+ continue;
}
+ Logger.debug(@"moveFeed: Deleting tag $old_category from $feed_id");
+ m_api.delete_tagging(tagging.id);
+ break;
}
}
-
- feeds.add(
- new Feed(
- feed_id,
- subscription.title,
- subscription.site_url,
- 0,
- feed_categories,
- favicon_uri,
- subscription.feed_url)
- );
+ Logger.debug(@"moveFeed: Adding tag $new_category to $feed_id");
+ m_api.add_tagging(feed_id, new_category);
+ }
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.moveFeed: " + e.message);
}
}
- catch(Error e)
+
+ public override void renameCategory(string old_category, string new_category)
{
- Logger.error(@"FeedbinInterface.getFeedsAndCats: " + e.message);
- return false;
+ Logger.debug(@"renameCategory: From $old_category to $new_category");
+ try
+ {
+ var taggings = m_api.get_taggings();
+ foreach(var tagging in taggings)
+ {
+ if(tagging.name != old_category)
+ {
+ continue;
+ }
+ var feed_id = tagging.feed_id;
+ Logger.debug(@"renameCategory: Tagging $feed_id with $new_category");
+ m_api.delete_tagging(tagging.id);
+ m_api.add_tagging(feed_id, new_category);
+ }
+ }
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.renameCategory: " + e.message);
+ }
}
- return true;
-}
-
-public override int getUnreadCount()
-ensures (result >= 0)
-{
- try
+
+ public override void moveCategory(string category_id, string new_parent_id)
{
- return m_api.get_unread_entries().size;
+ // Feedbin doesn't have multi-level categories
}
- catch(Error e)
+
+ public override string createCategory(string title, string? parent_id)
+ ensures (result == title)
{
- Logger.error(@"FeedbinInterface.getUnreadCount: " + e.message);
- return 0;
+ // Categories are created and destroyed based on feeds having them.
+ // There are no empty categories in Feedbin
+ return title;
}
-}
-
-public override void getArticles(int count, ArticleStatus what_to_get, DateTime? since, string? feed_id_str, bool is_tag_id, GLib.Cancellable? cancellable = null)
-requires (count >= 0)
-{
- try
+
+ public override void deleteCategory(string category)
{
- var db = DataBase.readOnly();
- int64? feed_id = null;
- if(!is_tag_id && feed_id_str != null)
+ Logger.debug(@"deleteCategory: $category");
+ try
{
- feed_id = int64.parse(feed_id_str);
+ var taggings = m_api.get_taggings();
+ foreach(var tagging in taggings)
+ {
+ if(tagging.name != category)
+ {
+ continue;
+ }
+ var feed_id = tagging.feed_id;
+ Logger.debug(@"deleteCategory: Deleting category $category from feed $feed_id");
+ m_api.delete_tagging(tagging.id);
+ }
}
- bool only_starred = what_to_get == ArticleStatus.MARKED;
-
- if(cancellable != null && cancellable.is_cancelled())
+ catch(Error e)
{
- return;
+ Logger.error(@"FeedbinInterface.deleteCategory: " + e.message);
}
-
- // The Feedbin API doesn't include read/unread/starred status in the entries.json
- // so look them up.
- var unread_ids = m_api.get_unread_entries();
- if(cancellable != null && cancellable.is_cancelled())
+ }
+
+ public override void removeCatFromFeed(string feed_id_str, string category)
+ {
+ Logger.debug(@"removeCatFromFeed: Feed $feed_id_str, category $category");
+ try
{
- return;
+ var feed_id = int64.parse(feed_id_str);
+ var taggings = m_api.get_taggings();
+ foreach(var tagging in taggings)
+ {
+ if(tagging.feed_id != feed_id || tagging.name != category)
+ {
+ continue;
+ }
+
+ Logger.debug(@"removeCatFromFeed: Deleting category $category from feed $feed_id");
+ m_api.delete_tagging(tagging.id);
+ break;
+ }
}
-
- var starred_ids = m_api.get_starred_entries();
-
+ catch(Error e)
{
- // Update read/unread status of existing entries
- string search_feed_id;
- FeedListType search_type;
- if(feed_id == null)
+ Logger.error(@"FeedbinInterface.removeCatFromFeed: " + e.message);
+ }
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ try
+ {
+ var taggings = m_api.get_taggings();
+ if(cancellable != null && cancellable.is_cancelled())
{
- search_feed_id = FeedID.ALL.to_string();
- search_type = FeedListType.ALL_FEEDS;
+ return false;
}
- else if(is_tag_id)
+
+ var favicons = m_api.get_favicons();
+ if(cancellable != null && cancellable.is_cancelled())
{
- search_feed_id = feed_id_str;
- search_type = FeedListType.TAG;
+ return false;
}
- else
+
+ // It's easier to rebuild the category list than to update it
+ var category_names = new Gee.HashSet<string>();
+ foreach(var tagging in taggings)
{
- search_feed_id = feed_id_str;
- search_type = FeedListType.FEED;
+ category_names.add(tagging.name);
}
-
- Logger.debug(@"Checking if any articles in $search_type $search_feed_id changed state");
- for(var offset = 0, c = 1000; ; offset += c)
+ Logger.debug("getFeedsAndCats: Got %d categories: %s".printf(category_names.size, StringUtils.join(category_names, ", ")));
+
+ categories.clear();
+ var top_category = CategoryID.MASTER.to_string();
+ foreach(string name in category_names)
{
- var articles = new Gee.ArrayList<Article>();
- var existing_articles = db.read_articles(search_feed_id, search_type, ArticleListState.ALL, "", c, offset);
- if(existing_articles.size == 0)
+ // Note: Feedbin categories *are* case sensitive, so we don't need
+ // to change the case here. "articles" and "Articles" are different
+ // tags.
+ categories.add(
+ new Category (
+ name,
+ name,
+ 0,
+ 0,
+ top_category,
+ 1
+ )
+ );
+ }
+
+ var tag_map = new Gee.HashMultiMap<string, string>();
+ foreach(var tagging in taggings)
+ {
+ tag_map.set(tagging.feed_id.to_string(), tagging.name);
+ }
+
+ var subscriptions = m_api.get_subscriptions();
+ feeds.clear();
+
+ foreach(var subscription in subscriptions)
+ {
+ var feed_id = subscription.feed_id.to_string();
+ Gee.List<string> feed_categories = new Gee.ArrayList<string>();
+
+ if(tag_map.contains(feed_id))
{
- break;
+ feed_categories.add_all(tag_map.get(feed_id));
}
-
- foreach(var article in existing_articles)
+ else
{
- var id = int64.parse(article.getArticleID());
- var marked = starred_ids.contains(id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
- var unread = unread_ids.contains(id) ? ArticleStatus.UNREAD : ArticleStatus.READ;
- var changed = false;
- if(article.getMarked() != marked)
- {
- article.setMarked(marked);
- changed = true;
- }
- if(article.getUnread() != unread)
+ feed_categories.add(uncategorizedID());
+ }
+
+ string? favicon_uri = null;
+ if(subscription.site_url != null)
+ {
+ var uri = new Soup.URI(subscription.site_url);
+ if(uri != null)
{
- article.setUnread(unread);
- changed = true;
+ var favicon = favicons.get(uri.host);
+ if(favicon != null)
+ {
+ string base64 = Base64.encode(favicon.get_data());
+ favicon_uri = @"data:application/octet-stream;base64,$base64";
+ }
}
- articles.add(article);
}
- writeArticles(articles);
+
+ feeds.add(
+ new Feed(
+ feed_id,
+ subscription.title,
+ subscription.site_url,
+ 0,
+ feed_categories,
+ favicon_uri,
+ subscription.feed_url)
+ );
}
}
-
- // Add new articles
- for(int page = 1; ; ++page)
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.getFeedsAndCats: " + e.message);
+ return false;
+ }
+ return true;
+ }
+
+ public override int getUnreadCount()
+ ensures (result >= 0)
+ {
+ try
+ {
+ return m_api.get_unread_entries().size;
+ }
+ catch(Error e)
{
+ Logger.error(@"FeedbinInterface.getUnreadCount: " + e.message);
+ return 0;
+ }
+ }
+
+ public override void getArticles(int count, ArticleStatus what_to_get, DateTime? since, string? feed_id_str, bool is_tag_id, GLib.Cancellable? cancellable = null)
+ requires (count >= 0)
+ {
+ try
+ {
+ var db = DataBase.readOnly();
+ int64? feed_id = null;
+ if(!is_tag_id && feed_id_str != null)
+ {
+ feed_id = int64.parse(feed_id_str);
+ }
+ bool only_starred = what_to_get == ArticleStatus.MARKED;
+
if(cancellable != null && cancellable.is_cancelled())
{
return;
}
-
- var entries = m_api.get_entries(page, only_starred, since, feed_id);
- if(entries.size == 0)
+
+ // The Feedbin API doesn't include read/unread/starred status in the entries.json
+ // so look them up.
+ var unread_ids = m_api.get_unread_entries();
+ if(cancellable != null && cancellable.is_cancelled())
{
- break;
+ return;
}
-
- var articles = new Gee.ArrayList<Article>();
- foreach(var entry in entries)
+
+ var starred_ids = m_api.get_starred_entries();
+
{
- articles.add(
- new Article(
- entry.id.to_string(),
- entry.title,
- entry.url,
- entry.feed_id.to_string(),
- unread_ids.contains(entry.id) ? ArticleStatus.UNREAD : ArticleStatus.READ,
- starred_ids.contains(entry.id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- entry.content,
- entry.summary,
- entry.author,
- entry.published != null ? entry.published : entry.created_at,
- -1,
- null,
+ // Update read/unread status of existing entries
+ string search_feed_id;
+ FeedListType search_type;
+ if(feed_id == null)
+ {
+ search_feed_id = FeedID.ALL.to_string();
+ search_type = FeedListType.ALL_FEEDS;
+ }
+ else if(is_tag_id)
+ {
+ search_feed_id = feed_id_str;
+ search_type = FeedListType.TAG;
+ }
+ else
+ {
+ search_feed_id = feed_id_str;
+ search_type = FeedListType.FEED;
+ }
+
+ Logger.debug(@"Checking if any articles in $search_type $search_feed_id changed state");
+ for(var offset = 0, c = 1000; ; offset += c)
+ {
+ var articles = new Gee.ArrayList<Article>();
+ var existing_articles = db.read_articles(search_feed_id, search_type, ArticleListState.ALL, "", c, offset);
+ if(existing_articles.size == 0)
+ {
+ break;
+ }
+
+ foreach(var article in existing_articles)
+ {
+ var id = int64.parse(article.getArticleID());
+ var marked = starred_ids.contains(id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+ var unread = unread_ids.contains(id) ? ArticleStatus.UNREAD : ArticleStatus.READ;
+ var changed = false;
+ if(article.getMarked() != marked)
+ {
+ article.setMarked(marked);
+ changed = true;
+ }
+ if(article.getUnread() != unread)
+ {
+ article.setUnread(unread);
+ changed = true;
+ }
+ articles.add(article);
+ }
+ writeArticles(articles);
+ }
+ }
+
+ // Add new articles
+ for(int page = 1; ; ++page)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ var entries = m_api.get_entries(page, only_starred, since, feed_id);
+ if(entries.size == 0)
+ {
+ break;
+ }
+
+ var articles = new Gee.ArrayList<Article>();
+ foreach(var entry in entries)
+ {
+ articles.add(
+ new Article(
+ entry.id.to_string(),
+ entry.title,
+ entry.url,
+ entry.feed_id.to_string(),
+ unread_ids.contains(entry.id) ? ArticleStatus.UNREAD : ArticleStatus.READ,
+ starred_ids.contains(entry.id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ entry.content,
+ entry.summary,
+ entry.author,
+ entry.published != null ? entry.published : entry.created_at,
+ -1,
+ null,
null)
);
+ }
+ writeArticles(articles);
}
- writeArticles(articles);
+ }
+ catch(Error e)
+ {
+ Logger.error(@"FeedbinInterface.getArticles: " + e.message);
}
}
- catch(Error e)
- {
- Logger.error(@"FeedbinInterface.getArticles: " + e.message);
- }
-}
}
[ModuleInit]
diff --git a/plugins/backend/feedbin/feedbinUtils.vala b/plugins/backend/feedbin/feedbinUtils.vala
index 599fe14d..3803e503 100644
--- a/plugins/backend/feedbin/feedbinUtils.vala
+++ b/plugins/backend/feedbin/feedbinUtils.vala
@@ -14,56 +14,56 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedbinUtils : GLib.Object {
-
-GLib.Settings m_settings;
-Password m_password;
-
-public FeedbinUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
- {
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedbin", settings_backend);
- }
- else
+
+ GLib.Settings m_settings;
+ Password m_password;
+
+ public FeedbinUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings("org.gnome.feedreader.feedbin");
- }
-
- var password_schema =
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedbin", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.feedbin");
+ }
+
+ var password_schema =
new Secret.Schema("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, password_schema, "FeedReader: feedbin login", () => {
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, password_schema, "FeedReader: feedbin login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = "feedbin.com";
attributes["Username"] = getUser();
return attributes;
});
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getPassword(Cancellable? cancellable = null)
-{
- return m_password.get_password(cancellable);
-}
-
-public void setPassword(string password, Cancellable? cancellable = null)
-{
- m_password.set_password(password, cancellable);
-}
-
-public void resetAccount(Cancellable? cancellable = null)
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password(cancellable);
-}
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getPassword(Cancellable? cancellable = null)
+ {
+ return m_password.get_password(cancellable);
+ }
+
+ public void setPassword(string password, Cancellable? cancellable = null)
+ {
+ m_password.set_password(password, cancellable);
+ }
+
+ public void resetAccount(Cancellable? cancellable = null)
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password(cancellable);
+ }
}
diff --git a/plugins/backend/feedhq/feedhqAPI.vala b/plugins/backend/feedhq/feedhqAPI.vala
index 6005a3e1..0ecb3ceb 100644
--- a/plugins/backend/feedhq/feedhqAPI.vala
+++ b/plugins/backend/feedhq/feedhqAPI.vala
@@ -14,412 +14,412 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedHQAPI : GLib.Object {
-
-public enum FeedHQSubscriptionAction {
- EDIT,
- SUBSCRIBE,
- UNSUBSCRIBE
-}
-
-private FeedHQConnection m_connection;
-private FeedHQUtils m_utils;
-private string m_userID;
-
-public FeedHQAPI (FeedHQUtils utils)
-{
- m_utils = utils;
- m_connection = new FeedHQConnection(m_utils);
-}
-
-
-public LoginResponse login()
-{
- Logger.debug("FeedHQ Login");
-
- if(m_utils.getAccessToken() == "")
- {
- var result = m_connection.getToken();
- if(m_connection.postToken() && getUserID())
+
+ public enum FeedHQSubscriptionAction {
+ EDIT,
+ SUBSCRIBE,
+ UNSUBSCRIBE
+ }
+
+ private FeedHQConnection m_connection;
+ private FeedHQUtils m_utils;
+ private string m_userID;
+
+ public FeedHQAPI (FeedHQUtils utils)
+ {
+ m_utils = utils;
+ m_connection = new FeedHQConnection(m_utils);
+ }
+
+
+ public LoginResponse login()
+ {
+ Logger.debug("FeedHQ Login");
+
+ if(m_utils.getAccessToken() == "")
{
- return result;
+ var result = m_connection.getToken();
+ if(m_connection.postToken() && getUserID())
+ {
+ return result;
+ }
}
- }
- else if(getUserID())
- {
- return LoginResponse.SUCCESS;
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-public bool ping()
-{
- return Utils.ping("https://feedhq.org");
-}
-
-private bool getUserID()
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("user-info?" + msg.get());
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getUserID: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
-
- if(root.has_member("userId"))
- {
- m_userID = root.get_string_member("userId");
- m_utils.setUserID(m_userID);
- Logger.info("FeedHQ: userID = " + m_userID);
-
- if(root.has_member("userName"))
+ else if(getUserID())
{
- m_utils.setUser(root.get_string_member("userName"));
+ return LoginResponse.SUCCESS;
}
- return true;
+
+ return LoginResponse.UNKNOWN_ERROR;
}
-
- return false;
-}
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("subscription/list?" + msg.get());
-
- if(response.status != 200)
+
+ public bool ping()
{
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
+ return Utils.ping("https://feedhq.org");
}
- catch(Error e)
+
+ private bool getUserID()
{
- Logger.error("getFeeds: Could not load message response");
- Logger.error(e.message);
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("user-info?" + msg.get());
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getUserID: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("userId"))
+ {
+ m_userID = root.get_string_member("userId");
+ m_utils.setUserID(m_userID);
+ Logger.info("FeedHQ: userID = " + m_userID);
+
+ if(root.has_member("userName"))
+ {
+ m_utils.setUser(root.get_string_member("userName"));
+ }
+ return true;
+ }
+
return false;
}
- var root = parser.get_root().get_object();
- var array = root.get_array_member("subscriptions");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- Json.Object object = array.get_object_element(i);
-
- string feedID = object.get_string_member("id");
- string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
- string? icon_url = object.has_member("iconUrl") ? "https:" + object.get_string_member("iconUrl") : null;
-
- uint catCount = object.get_array_member("categories").get_length();
-
- var categories = new Gee.ArrayList<string>();
- for(uint j = 0; j < catCount; ++j)
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("subscription/list?" + msg.get());
+
+ if(response.status != 200)
{
- categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ return false;
}
- feeds.add(
- new Feed(
- feedID,
- object.get_string_member("title"),
- url,
- 0,
- categories,
- icon_url,
- object.get_string_member("url")
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getFeeds: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("subscriptions");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ string feedID = object.get_string_member("id");
+ string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+ string? icon_url = object.has_member("iconUrl") ? "https:" + object.get_string_member("iconUrl") : null;
+
+ uint catCount = object.get_array_member("categories").get_length();
+
+ var categories = new Gee.ArrayList<string>();
+ for(uint j = 0; j < catCount; ++j)
+ {
+ categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ }
+ feeds.add(
+ new Feed(
+ feedID,
+ object.get_string_member("title"),
+ url,
+ 0,
+ categories,
+ icon_url,
+ object.get_string_member("url")
)
);
+ }
+ return true;
}
- return true;
-}
-
-public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("tag/list?" + msg.get());
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- var array = root.get_array_member("tags");
- uint length = array.get_length();
- int orderID = 0;
-
- for (uint i = 0; i < length; i++)
+
+ public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- int start = id.last_index_of_char('/') + 1;
- string title = id.substring(start);
-
- if(id.contains("/label/"))
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("tag/list?" + msg.get());
+
+ if(response.status != 200)
{
- categories.add(
- new Category(
- id,
- title,
- 0,
- orderID,
- CategoryID.MASTER.to_string(),
- 1
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("tags");
+ uint length = array.get_length();
+ int orderID = 0;
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ int start = id.last_index_of_char('/') + 1;
+ string title = id.substring(start);
+
+ if(id.contains("/label/"))
+ {
+ categories.add(
+ new Category(
+ id,
+ title,
+ 0,
+ orderID,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
- ++orderID;
+ ++orderID;
+ }
}
+ return true;
}
- return true;
-}
-
-
-public int getTotalUnread()
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- var response = m_connection.send_get_request("unread-count?" + msg.get());
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getTotalUnread: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("unreadcounts");
- uint length = array.get_length();
- int count = 0;
-
- for (uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- if(object.get_string_member("id").has_prefix("feed/"))
+
+
+ public int getTotalUnread()
+ {
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ var response = m_connection.send_get_request("unread-count?" + msg.get());
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getTotalUnread: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("unreadcounts");
+ uint length = array.get_length();
+ int count = 0;
+
+ for (uint i = 0; i < length; i++)
{
- count += (int)object.get_int_member("count");
+ Json.Object object = array.get_object_element(i);
+ if(object.get_string_member("id").has_prefix("feed/"))
+ {
+ count += (int)object.get_int_member("count");
+ }
+
}
-
- }
-
- Logger.debug("getTotalUnread %i".printf(count));
- return count;
-}
-
-
-public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- msg.add("n", count.to_string());
- msg.add("s", "user/-/state/com.google/read");
- if(continuation != null)
- {
- msg.add("c", continuation);
- }
-
- var response = m_connection.send_get_request("stream/items/ids?" + msg.get());
-
- if(response.status != 200)
- {
- return null;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("updateArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
-
- if(!root.has_member("itemRefs"))
- {
- Logger.error("updateArticles: wrong response?");
- return null;
- }
-
- var array = root.get_array_member("itemRefs");
- uint length = array.get_length();
-
- for(uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- ids.add(object.get_string_member("id"));
- }
-
- if(root.has_member("continuation") && root.get_string_member("continuation") != "")
- {
- return root.get_string_member("continuation");
+
+ Logger.debug("getTotalUnread %i".printf(count));
+ return count;
}
-
- return null;
-}
-
-public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
-{
- var msg = new feedhqMessage();
- msg.add("output", "json");
- msg.add("n", count.to_string());
-
- if(whatToGet == ArticleStatus.UNREAD)
- {
- msg.add("xt", "user/-/state/com.google/read");
- }
- if(whatToGet == ArticleStatus.READ)
+
+
+ public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
{
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ msg.add("n", count.to_string());
msg.add("s", "user/-/state/com.google/read");
- }
- else if(whatToGet == ArticleStatus.MARKED)
- {
- msg.add("s", "user/-/state/com.google/starred");
- }
-
- if(continuation != null)
- {
- msg.add("c", continuation);
- }
-
- string api_endpoint = "stream/contents";
- if(feed_id != null)
- {
- api_endpoint += "/" + feed_id;
- }
- else if(tagID != null)
- {
- api_endpoint += "/" + tagID;
- }
- var response = m_connection.send_get_request(api_endpoint + "?" + msg.get());
-
- if(response.status != 200)
- {
+ if(continuation != null)
+ {
+ msg.add("c", continuation);
+ }
+
+ var response = m_connection.send_get_request("stream/items/ids?" + msg.get());
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("updateArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+
+ if(!root.has_member("itemRefs"))
+ {
+ Logger.error("updateArticles: wrong response?");
+ return null;
+ }
+
+ var array = root.get_array_member("itemRefs");
+ uint length = array.get_length();
+
+ for(uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ ids.add(object.get_string_member("id"));
+ }
+
+ if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+ {
+ return root.get_string_member("continuation");
+ }
+
return null;
}
-
- Logger.debug(api_endpoint + "?" + msg.get());
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("items");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
+
+ public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
{
-
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- bool marked = false;
- bool read = false;
- var cats = object.get_array_member("categories");
- uint cat_length = cats.get_length();
-
- var tags = new Gee.ArrayList<string>();
- for (uint j = 0; j < cat_length; j++)
+ var msg = new feedhqMessage();
+ msg.add("output", "json");
+ msg.add("n", count.to_string());
+
+ if(whatToGet == ArticleStatus.UNREAD)
{
- string cat = cats.get_string_element(j);
- if(cat.has_suffix("com.google/starred"))
- {
- marked = true;
- }
- else if(cat.has_suffix("com.google/read"))
- {
- read = true;
- }
- else if(cat.contains("/label/"))
- {
- tags.add(cat);
- }
+ msg.add("xt", "user/-/state/com.google/read");
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+ if(whatToGet == ArticleStatus.READ)
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ msg.add("s", "user/-/state/com.google/read");
+ }
+ else if(whatToGet == ArticleStatus.MARKED)
+ {
+ msg.add("s", "user/-/state/com.google/starred");
+ }
+
+ if(continuation != null)
+ {
+ msg.add("c", continuation);
+ }
+
+ string api_endpoint = "stream/contents";
+ if(feed_id != null)
+ {
+ api_endpoint += "/" + feed_id;
+ }
+ else if(tagID != null)
+ {
+ api_endpoint += "/" + tagID;
+ }
+ var response = m_connection.send_get_request(api_endpoint + "?" + msg.get());
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ Logger.debug(api_endpoint + "?" + msg.get());
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("items");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ bool marked = false;
+ bool read = false;
+ var cats = object.get_array_member("categories");
+ uint cat_length = cats.get_length();
+
+ var tags = new Gee.ArrayList<string>();
+ for (uint j = 0; j < cat_length; j++)
{
- mediaCount = attachments.get_length();
+ string cat = cats.get_string_element(j);
+ if(cat.has_suffix("com.google/starred"))
+ {
+ marked = true;
+ }
+ else if(cat.has_suffix("com.google/read"))
+ {
+ read = true;
+ }
+ else if(cat.contains("/label/"))
+ {
+ tags.add(cat);
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
{
- var attachment = attachments.get_object_element(j);
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(attachment.get_string_member("type")))
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(attachment.get_string_member("type")))
);
+ }
}
- }
-
- articles.add(new Article(
- id,
- object.get_string_member("title"),
- object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
- object.get_object_member("origin").get_string_member("streamId"),
- read ? ArticleStatus.READ : ArticleStatus.UNREAD,
- marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- null,
- null,
- null,
- new DateTime.from_unix_local(object.get_int_member("published")),
- -1,
- tags,
- enclosures
- )
- );
- }
-
+
+ articles.add(new Article(
+ id,
+ object.get_string_member("title"),
+ object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+ object.get_object_member("origin").get_string_member("streamId"),
+ read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+ marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ null,
+ null,
+ null,
+ new DateTime.from_unix_local(object.get_int_member("published")),
+ -1,
+ tags,
+ enclosures
+ )
+ );
+ }
+
if(root.has_member("continuation") && root.get_string_member("continuation") != "")
{
return root.get_string_member("continuation");
}
-
+
return null;
}
@@ -428,7 +428,7 @@ public void edidTag(string articleID, string tagID, bool add = true)
{
var msg = new feedhqMessage();
msg.add("output", "json");
-
+
if(add)
{
msg.add("a", tagID);
@@ -437,7 +437,7 @@ public void edidTag(string articleID, string tagID, bool add = true)
{
msg.add("r", tagID);
}
-
+
msg.add("i", articleID);
m_connection.send_post_request("edit-tag", msg.get());
}
@@ -478,43 +478,43 @@ public bool editSubscription(FeedHQSubscriptionAction action, string[] feedID, s
{
var msg = new feedhqMessage();
msg.add("output", "json");
-
+
switch(action)
{
- case FeedHQSubscriptionAction.EDIT:
+ case FeedHQSubscriptionAction.EDIT:
msg.add("ac", "edit");
break;
- case FeedHQSubscriptionAction.SUBSCRIBE:
+ case FeedHQSubscriptionAction.SUBSCRIBE:
msg.add("ac", "subscribe");
break;
- case FeedHQSubscriptionAction.UNSUBSCRIBE:
+ case FeedHQSubscriptionAction.UNSUBSCRIBE:
msg.add("ac", "unsubscribe");
break;
}
-
+
foreach(string s in feedID) {
msg.add("s", s);
}
-
+
if(title != null)
{
msg.add("t", title);
}
-
+
if(add != null && add != "")
{
msg.add("a", add);
}
-
-
+
+
if(remove != null && remove != "")
{
msg.add("r", remove);
}
-
+
Logger.debug(msg.get());
var response = m_connection.send_post_request("subscription/edit", msg.get());
-
+
return response.status == 200;
}
diff --git a/plugins/backend/feedhq/feedhqConnection.vala b/plugins/backend/feedhq/feedhqConnection.vala
index 1f6fe043..9050f15c 100644
--- a/plugins/backend/feedhq/feedhqConnection.vala
+++ b/plugins/backend/feedhq/feedhqConnection.vala
@@ -14,162 +14,162 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedHQConnection {
-private string m_username;
-private string m_api_code;
-private string m_passwd;
-private FeedHQUtils m_utils;
-private Soup.Session m_session;
-
-public FeedHQConnection(FeedHQUtils utils)
-{
- m_utils = utils;
- m_username = m_utils.getUser();
- m_api_code = m_utils.getAccessToken();
- m_passwd = m_utils.getPasswd();
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
-}
-
-public LoginResponse getToken()
-{
- Logger.debug("FeedHQ Connection: getToken()");
-
- if(m_username == "" && m_passwd == "")
+ private string m_username;
+ private string m_api_code;
+ private string m_passwd;
+ private FeedHQUtils m_utils;
+ private Soup.Session m_session;
+
+ public FeedHQConnection(FeedHQUtils utils)
{
- return LoginResponse.ALL_EMPTY;
+ m_utils = utils;
+ m_username = m_utils.getUser();
+ m_api_code = m_utils.getAccessToken();
+ m_passwd = m_utils.getPasswd();
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
}
- if(m_username == "")
+
+ public LoginResponse getToken()
{
- return LoginResponse.MISSING_USER;
- }
- if(m_passwd == "")
- {
- return LoginResponse.MISSING_PASSWD;
- }
-
- var message = new Soup.Message("POST", "https://feedhq.org/accounts/ClientLogin");
- string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
- string response = (string)message.response_body.flatten().data;
- try{
-
- var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
- if(regex.match(response))
+ Logger.debug("FeedHQ Connection: getToken()");
+
+ if(m_username == "" && m_passwd == "")
+ {
+ return LoginResponse.ALL_EMPTY;
+ }
+ if(m_username == "")
+ {
+ return LoginResponse.MISSING_USER;
+ }
+ if(m_passwd == "")
{
- string split = regex.replace(response, -1,0,"");
- Logger.debug("FeedHQ Authcode : " + split);
- m_utils.setAccessToken(split.strip());
- return LoginResponse.SUCCESS;
+ return LoginResponse.MISSING_PASSWD;
+ }
+
+ var message = new Soup.Message("POST", "https://feedhq.org/accounts/ClientLogin");
+ string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+ string response = (string)message.response_body.flatten().data;
+ try{
+
+ var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+ if(regex.match(response))
+ {
+ string split = regex.replace(response, -1,0,"");
+ Logger.debug("FeedHQ Authcode : " + split);
+ m_utils.setAccessToken(split.strip());
+ return LoginResponse.SUCCESS;
+ }
+ else
+ {
+ Logger.debug(response);
+ return LoginResponse.WRONG_LOGIN;
+ }
}
- else
+ catch(Error e)
{
- Logger.debug(response);
- return LoginResponse.WRONG_LOGIN;
+ Logger.error("FeedHQConnection - getToken: Could not load message response");
+ Logger.error(e.message);
+ return LoginResponse.UNKNOWN_ERROR;
}
}
- catch(Error e)
+
+
+ public bool postToken()
{
- Logger.error("FeedHQConnection - getToken: Could not load message response");
- Logger.error(e.message);
- return LoginResponse.UNKNOWN_ERROR;
- }
-}
-
-
-public bool postToken()
-{
- Logger.debug("FeedHQ Connection: postToken()");
-
- var message = new Soup.Message("GET", FeedHQSecret.base_uri + "token?output=json");
-
- string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
- message.request_headers.append("Authorization", oldauth);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- Logger.debug("FeedHQ post token failed");
- return false;
+ Logger.debug("FeedHQ Connection: postToken()");
+
+ var message = new Soup.Message("GET", FeedHQSecret.base_uri + "token?output=json");
+
+ string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", oldauth);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.debug("FeedHQ post token failed");
+ return false;
+ }
+
+ string response = (string)message.response_body.data;
+ Logger.debug("FeedHQ post token : " + response);
+ m_utils.setPostToken(response);
+
+ return true;
+
}
-
- string response = (string)message.response_body.data;
- Logger.debug("FeedHQ post token : " + response);
- m_utils.setPostToken(response);
-
- return true;
-
-}
-public Response send_get_request(string path, string? message_string = null)
-{
- return send_request(path, "GET", message_string);
-}
-
-public Response send_post_request(string path, string? message_string = null)
-{
- return send_request(path, "POST", message_string);
-}
-
-
-
-private Response send_request(string path, string type, string? message_string = null)
-{
- var message = new Soup.Message(type, FeedHQSecret.base_uri + path);
-
- string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
- message.request_headers.append("Authorization", oldauth);
- var message_string_post = message_string + "&T=" + m_utils.getPostToken();
- if(message_string != null)
+ public Response send_get_request(string path, string? message_string = null)
{
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string_post.data);
+ return send_request(path, "GET", message_string);
}
-
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ public Response send_post_request(string path, string? message_string = null)
{
- Logger.warning(@"feedHQConnection: message unexpected response - $message_string");
+ return send_request(path, "POST", message_string);
}
-
- if((uint)message.status_code == 401)
+
+
+
+ private Response send_request(string path, string type, string? message_string = null)
{
- Logger.debug("FeedHQ Post Token Expired");
- postToken();
- return send_request(path, type, message_string);
+ var message = new Soup.Message(type, FeedHQSecret.base_uri + path);
+
+ string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", oldauth);
+ var message_string_post = message_string + "&T=" + m_utils.getPostToken();
+ if(message_string != null)
+ {
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string_post.data);
+ }
+
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning(@"feedHQConnection: message unexpected response - $message_string");
+ }
+
+ if((uint)message.status_code == 401)
+ {
+ Logger.debug("FeedHQ Post Token Expired");
+ postToken();
+ return send_request(path, type, message_string);
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
+
}
public class FeedReader.feedhqMessage {
-
-string request = "";
-
-public feedhqMessage()
-{
-
-}
-
-public void add(string parameter, string val)
-{
- if(request != "")
+
+ string request = "";
+
+ public feedhqMessage()
{
- request += "&";
+
+ }
+
+ public void add(string parameter, string val)
+ {
+ if(request != "")
+ {
+ request += "&";
+ }
+
+ request += parameter;
+ request += "=";
+ request += GLib.Uri.escape_string(val);
+ }
+
+ public string get()
+ {
+ return request;
}
-
- request += parameter;
- request += "=";
- request += GLib.Uri.escape_string(val);
-}
-
-public string get()
-{
- return request;
-}
}
diff --git a/plugins/backend/feedhq/feedhqInterface.vala b/plugins/backend/feedhq/feedhqInterface.vala
index 519a173d..e5866abe 100644
--- a/plugins/backend/feedhq/feedhqInterface.vala
+++ b/plugins/backend/feedhq/feedhqInterface.vala
@@ -14,421 +14,421 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedHQInterface : FeedServerInterface {
-
-private FeedHQAPI m_api;
-private FeedHQUtils m_utils;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new FeedHQUtils(settings_backend, secrets);
- m_api = new FeedHQAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://feedhq.org/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
-}
-
-public override string getID()
-{
- return "feedhq";
-}
-
-public override string iconName()
-{
- return "feed-service-feedhq";
-}
-
-public override string serviceName()
-{
- return "FeedHQ";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_userEntry.activate.connect(() => { tryLogin(); });
- m_passwordEntry.activate.connect(() => { tryLogin(); });
-
- m_passwordEntry.set_invisible_char('*');
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(user_label, 0, 0, 1, 1);
- grid.attach(m_userEntry, 1, 0, 1, 1);
- grid.attach(password_label, 0, 1, 1, 1);
- grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
- var logo = new Gtk.Image.from_icon_name("feed-service-feedhq", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override void writeData()
-{
- m_utils.setUser(m_userEntry.get_text());
- m_utils.setPassword(m_passwordEntry.get_text());
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-feedhq-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return "FeedHQ.org";
-}
-
-public override string uncategorizedID()
-{
- return "";
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool hideCategoryWhenEmpty(string cadID)
-{
- return false;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- if(read == ArticleStatus.READ)
+
+ private FeedHQAPI m_api;
+ private FeedHQUtils m_utils;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ m_utils = new FeedHQUtils(settings_backend, secrets);
+ m_api = new FeedHQAPI(m_utils);
}
- else
+
+ public override string getWebsite()
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+ return "https://feedhq.org/";
}
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override BackendFlags getFlags()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
}
- else
+
+ public override string getID()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ return "feedhq";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markAsRead(feedID);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markAsRead(catID);
-}
-
-public override void markAllItemsRead()
-{
- var db = DataBase.readOnly();
- var categories = db.read_categories();
- foreach(Category cat in categories)
+
+ public override string iconName()
{
- m_api.markAsRead(cat.getCatID());
+ return "feed-service-feedhq";
}
-
- var feeds = db.read_feeds_without_cat();
- foreach(Feed feed in feeds)
+
+ public override string serviceName()
{
- m_api.markAsRead(feed.getFeedID());
+ return "FeedHQ";
}
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- return;
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- return ":(";
-}
-
-public override void deleteTag(string tagID)
-{
- return;
-}
-
-public override void renameTag(string tagID, string title)
-{
- return;
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- feedID = "feed/" + feedURL;
- bool success = false;
-
- if(catID == null && newCatName != null)
+
+ public override bool needWebLogin()
{
- string newCatID = m_api.composeTagID(newCatName);
- Logger.debug(newCatID);
- success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
+ return false;
}
- else
+
+ public override Gtk.Box? getWidget()
{
- success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_userEntry.activate.connect(() => { tryLogin(); });
+ m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+ m_passwordEntry.set_invisible_char('*');
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(user_label, 0, 0, 1, 1);
+ grid.attach(m_userEntry, 1, 0, 1, 1);
+ grid.attach(password_label, 0, 1, 1, 1);
+ grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-feedhq", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
}
-
- if(!success)
+
+ public override void writeData()
{
- errmsg = @"feedHQ could not subscribe to $feedURL";
+ m_utils.setUser(m_userEntry.get_text());
+ m_utils.setPassword(m_passwordEntry.get_text());
}
- else
+
+ public override bool supportTags()
{
- errmsg = "";
+ return false;
}
-
- return success;
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.UNSUBSCRIBE, {feedID});
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, title);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.composeTagID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameTag(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.deleteTag(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override void importOPML(string opml)
-{
- m_api.import(opml);
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getFeeds(feeds))
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-feedhq-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return "FeedHQ.org";
+ }
+
+ public override string uncategorizedID()
+ {
+ return "";
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool hideCategoryWhenEmpty(string cadID)
+ {
+ return false;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
{
- if(cancellable != null && cancellable.is_cancelled())
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ if(read == ArticleStatus.READ)
{
- return false;
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read");
}
-
- if(m_api.getCategoriesAndTags(feeds, categories, tags))
+ else
{
- return true;
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
}
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getTotalUnread();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- if(whatToGet == ArticleStatus.READ)
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
+ {
+ if(marked == ArticleStatus.MARKED)
+ {
+ m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ }
+ else
+ {
+ m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ }
+ }
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.markAsRead(feedID);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markAsRead(catID);
+ }
+
+ public override void markAllItemsRead()
+ {
+ var db = DataBase.readOnly();
+ var categories = db.read_categories();
+ foreach(Category cat in categories)
+ {
+ m_api.markAsRead(cat.getCatID());
+ }
+
+ var feeds = db.read_feeds_without_cat();
+ foreach(Feed feed in feeds)
+ {
+ m_api.markAsRead(feed.getFeedID());
+ }
+ }
+
+ public override void tagArticle(string articleID, string tagID)
{
return;
}
- else if(whatToGet == ArticleStatus.ALL)
+
+ public override void removeArticleTag(string articleID, string tagID)
{
- var unreadIDs = new Gee.LinkedList<string>();
- string? continuation = null;
-
- do
+ return;
+ }
+
+ public override string createTag(string caption)
+ {
+ return ":(";
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ return;
+ }
+
+ public override void renameTag(string tagID, string title)
{
- if(cancellable != null && cancellable.is_cancelled())
+ return;
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ feedID = "feed/" + feedURL;
+ bool success = false;
+
+ if(catID == null && newCatName != null)
{
- return;
+ string newCatID = m_api.composeTagID(newCatName);
+ Logger.debug(newCatID);
+ success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
}
-
- continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
+ else
+ {
+ success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
+ }
+
+ if(!success)
+ {
+ errmsg = @"feedHQ could not subscribe to $feedURL";
+ }
+ else
+ {
+ errmsg = "";
+ }
+
+ return success;
}
- while(continuation != null);
- DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
- }
-
- var articles = new Gee.LinkedList<Article>();
- string? continuation = null;
- string? FeedHQ_feedID = (isTagID) ? null : feedID;
- string? FeedHQ_tagID = (isTagID) ? feedID : null;
-
- do
- {
- if(cancellable != null && cancellable.is_cancelled())
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.UNSUBSCRIBE, {feedID});
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, title);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.composeTagID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameTag(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
{
return;
}
-
- continuation = m_api.getArticles(articles, count, whatToGet, continuation, FeedHQ_tagID, FeedHQ_feedID);
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.deleteTag(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override void importOPML(string opml)
+ {
+ m_api.import(opml);
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getFeeds(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getCategoriesAndTags(feeds, categories, tags))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public override int getUnreadCount()
+ {
+ return m_api.getTotalUnread();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ if(whatToGet == ArticleStatus.READ)
+ {
+ return;
+ }
+ else if(whatToGet == ArticleStatus.ALL)
+ {
+ var unreadIDs = new Gee.LinkedList<string>();
+ string? continuation = null;
+
+ do
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
+ }
+ while(continuation != null);
+ DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+ }
+
+ var articles = new Gee.LinkedList<Article>();
+ string? continuation = null;
+ string? FeedHQ_feedID = (isTagID) ? null : feedID;
+ string? FeedHQ_tagID = (isTagID) ? feedID : null;
+
+ do
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ continuation = m_api.getArticles(articles, count, whatToGet, continuation, FeedHQ_tagID, FeedHQ_feedID);
+ }
+ while(continuation != null);
+
+ writeArticles(articles);
+ }
+
+ }
+
+ [ModuleInit]
+ public void peas_register_types(GLib.TypeModule module)
+ {
+ var objmodule = module as Peas.ObjectModule;
+ objmodule.register_extension_type(typeof(FeedReader.FeedServerInterface), typeof(FeedReader.FeedHQInterface));
}
- while(continuation != null);
-
- writeArticles(articles);
-}
-
-}
-
-[ModuleInit]
-public void peas_register_types(GLib.TypeModule module)
-{
- var objmodule = module as Peas.ObjectModule;
- objmodule.register_extension_type(typeof(FeedReader.FeedServerInterface), typeof(FeedReader.FeedHQInterface));
-}
diff --git a/plugins/backend/feedhq/feedhqUtils.vala b/plugins/backend/feedhq/feedhqUtils.vala
index 983204d3..f108a336 100644
--- a/plugins/backend/feedhq/feedhqUtils.vala
+++ b/plugins/backend/feedhq/feedhqUtils.vala
@@ -14,110 +14,110 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.FeedHQSecret {
-const string base_uri = "https://feedhq.org/reader/api/0/";
+ const string base_uri = "https://feedhq.org/reader/api/0/";
}
public class FeedReader.FeedHQUtils : GLib.Object {
-
-private GLib.Settings m_settings;
-private Password m_password;
-
-public FeedHQUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
+
+ private GLib.Settings m_settings;
+ private Password m_password;
+
+ public FeedHQUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedhq", settings_backend);
- }
- else
- {
- m_settings = new GLib.Settings("org.gnome.feedreader.feedhq");
- }
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.feedhq", Secret.SchemaFlags.NONE,
- "type", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, pwSchema, "Feedserver login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedhq", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.feedhq");
+ }
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.feedhq", Secret.SchemaFlags.NONE,
+ "type", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, pwSchema, "Feedserver login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["type"] = "FeedHQ";
attributes["Username"] = getUser();
return attributes;
});
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getAccessToken()
-{
- return Utils.gsettingReadString(m_settings, "access-token");
-}
-
-public void setAccessToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "access-token", token);
-}
-
-public string getPostToken()
-{
- return Utils.gsettingReadString(m_settings, "post-token");
-}
-
-public void setPostToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "post-token", token);
-}
-public string getUserID()
-{
- return Utils.gsettingReadString(m_settings, "user-id");
-}
-
-public void setUserID(string id)
-{
- Utils.gsettingWriteString(m_settings, "user-id", id);
-}
-
-public string getEmail()
-{
- return Utils.gsettingReadString(m_settings, "user-email");
-}
-
-public void setEmail(string email)
-{
- Utils.gsettingWriteString(m_settings, "user-email", email);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
-}
-
-public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
-{
- foreach(Feed feed in feeds)
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getAccessToken()
+ {
+ return Utils.gsettingReadString(m_settings, "access-token");
+ }
+
+ public void setAccessToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "access-token", token);
+ }
+
+ public string getPostToken()
+ {
+ return Utils.gsettingReadString(m_settings, "post-token");
+ }
+
+ public void setPostToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "post-token", token);
+ }
+ public string getUserID()
+ {
+ return Utils.gsettingReadString(m_settings, "user-id");
+ }
+
+ public void setUserID(string id)
+ {
+ Utils.gsettingWriteString(m_settings, "user-id", id);
+ }
+
+ public string getEmail()
+ {
+ return Utils.gsettingReadString(m_settings, "user-email");
+ }
+
+ public void setEmail(string email)
+ {
+ Utils.gsettingWriteString(m_settings, "user-email", email);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ }
+
+ public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
{
- if(feed.hasCat(tagID))
+ foreach(Feed feed in feeds)
{
- return true;
+ if(feed.hasCat(tagID))
+ {
+ return true;
+ }
}
+ return false;
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
}
- return false;
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
}
diff --git a/plugins/backend/feedly/feedlyAPI.vala b/plugins/backend/feedly/feedlyAPI.vala
index 8c5d3f46..57d151b0 100644
--- a/plugins/backend/feedly/feedlyAPI.vala
+++ b/plugins/backend/feedly/feedlyAPI.vala
@@ -14,747 +14,747 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedlyAPI : Object {
-
-private FeedlyConnection m_connection;
-private string m_userID;
-private Json.Array m_unreadcounts;
-private FeedlyUtils m_utils;
-
-public FeedlyAPI(FeedlyUtils utils) {
- m_utils = utils;
- m_connection = new FeedlyConnection(m_utils);
-}
-
-public string createCatID(string title)
-{
- return "user/%s/category/%s".printf(m_userID, title);
-}
-
-public string getMarkedID()
-{
- return "user/" + m_userID + "/tag/global.saved";
-}
-
-public LoginResponse login()
-{
- Logger.debug("feedly backend: login");
-
- if(!Utils.ping("http://feedly.com/"))
- {
- return LoginResponse.NO_CONNECTION;
- }
-
- if(m_utils.getRefreshToken() == "")
- {
- m_connection.getToken();
- }
-
- if(tokenStillValid() == ConnectionError.INVALID_SESSIONID)
- {
- Logger.debug("refresh token");
- m_connection.refreshToken();
- }
-
- if(getUserID())
- {
- Logger.debug("feedly: login success");
- return LoginResponse.SUCCESS;
+
+ private FeedlyConnection m_connection;
+ private string m_userID;
+ private Json.Array m_unreadcounts;
+ private FeedlyUtils m_utils;
+
+ public FeedlyAPI(FeedlyUtils utils) {
+ m_utils = utils;
+ m_connection = new FeedlyConnection(m_utils);
}
-
- m_utils.setAccessToken("");
- m_utils.setRefreshToken("");
- m_utils.setApiCode("");
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-private bool getUserID()
-{
- var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
-
- if(response.status != 200)
+
+ public string createCatID(string title)
{
- return false;
+ return "user/%s/category/%s".printf(m_userID, title);
}
-
- var parser = new Json.Parser();
- try
+
+ public string getMarkedID()
{
- parser.load_from_data(response.data, -1);
+ return "user/" + m_userID + "/tag/global.saved";
}
- catch(Error e)
+
+ public LoginResponse login()
{
- Logger.error("getUserID: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
-
- if(root.has_member("id"))
- {
- m_userID = root.get_string_member("id");
- Logger.info("feedly: userID = " + m_userID);
-
- if(root.has_member("email"))
+ Logger.debug("feedly backend: login");
+
+ if(!Utils.ping("http://feedly.com/"))
{
- m_utils.setEmail(root.get_string_member("email"));
+ return LoginResponse.NO_CONNECTION;
}
- else if(root.has_member("givenName"))
+
+ if(m_utils.getRefreshToken() == "")
{
- m_utils.setEmail(root.get_string_member("givenName"));
+ m_connection.getToken();
}
- else if(root.has_member("fullName"))
+
+ if(tokenStillValid() == ConnectionError.INVALID_SESSIONID)
{
- m_utils.setEmail(root.get_string_member("fullName"));
+ Logger.debug("refresh token");
+ m_connection.refreshToken();
}
- else if(root.has_member("google"))
+
+ if(getUserID())
{
- m_utils.setEmail(root.get_string_member("google"));
+ Logger.debug("feedly: login success");
+ return LoginResponse.SUCCESS;
}
- else if(root.has_member("reader"))
+
+ m_utils.setAccessToken("");
+ m_utils.setRefreshToken("");
+ m_utils.setApiCode("");
+
+ return LoginResponse.UNKNOWN_ERROR;
+ }
+
+ private bool getUserID()
+ {
+ var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
+
+ if(response.status != 200)
{
- m_utils.setEmail(root.get_string_member("reader"));
+ return false;
}
- else if(root.has_member("twitterUserId"))
+
+ var parser = new Json.Parser();
+ try
{
- m_utils.setEmail(root.get_string_member("twitterUserId"));
+ parser.load_from_data(response.data, -1);
}
- else if(root.has_member("facebookUserId"))
+ catch(Error e)
{
- m_utils.setEmail(root.get_string_member("facebookUserId"));
+ Logger.error("getUserID: Could not load message response");
+ Logger.error(e.message);
+ return false;
}
- else if(root.has_member("wordPressId"))
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("id"))
{
- m_utils.setEmail(root.get_string_member("wordPressId"));
- }
- else if(root.has_member("windowsLiveId"))
- {
- m_utils.setEmail(root.get_string_member("windowsLiveId"));
+ m_userID = root.get_string_member("id");
+ Logger.info("feedly: userID = " + m_userID);
+
+ if(root.has_member("email"))
+ {
+ m_utils.setEmail(root.get_string_member("email"));
+ }
+ else if(root.has_member("givenName"))
+ {
+ m_utils.setEmail(root.get_string_member("givenName"));
+ }
+ else if(root.has_member("fullName"))
+ {
+ m_utils.setEmail(root.get_string_member("fullName"));
+ }
+ else if(root.has_member("google"))
+ {
+ m_utils.setEmail(root.get_string_member("google"));
+ }
+ else if(root.has_member("reader"))
+ {
+ m_utils.setEmail(root.get_string_member("reader"));
+ }
+ else if(root.has_member("twitterUserId"))
+ {
+ m_utils.setEmail(root.get_string_member("twitterUserId"));
+ }
+ else if(root.has_member("facebookUserId"))
+ {
+ m_utils.setEmail(root.get_string_member("facebookUserId"));
+ }
+ else if(root.has_member("wordPressId"))
+ {
+ m_utils.setEmail(root.get_string_member("wordPressId"));
+ }
+ else if(root.has_member("windowsLiveId"))
+ {
+ m_utils.setEmail(root.get_string_member("windowsLiveId"));
+ }
+
+ return true;
}
-
- return true;
- }
-
- return false;
-}
-
-private ConnectionError tokenStillValid()
-{
- var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
-
- if(response.status != 200)
- {
- return ConnectionError.NO_RESPONSE;
- }
-
- var parser = new Json.Parser ();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("tokenStillValid: Could not load message response");
- Logger.error(e.message);
- return ConnectionError.NO_RESPONSE;
- }
-
- var root = parser.get_root().get_object();
-
- if(root.has_member("errorId"))
- {
- return ConnectionError.INVALID_SESSIONID;
- }
- return ConnectionError.SUCCESS;
-}
-
-
-public bool getCategories(Gee.List<Category> categories)
-{
- var response = m_connection.send_get_request_to_feedly ("/v3/categories/");
-
- if(response.status != 200)
- {
+
return false;
}
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch (Error e)
+
+ private ConnectionError tokenStillValid()
{
- Logger.error("getCategories: Could not load message response");
- Logger.error(e.message);
- return false;
+ var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
+
+ if(response.status != 200)
+ {
+ return ConnectionError.NO_RESPONSE;
+ }
+
+ var parser = new Json.Parser ();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("tokenStillValid: Could not load message response");
+ Logger.error(e.message);
+ return ConnectionError.NO_RESPONSE;
+ }
+
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("errorId"))
+ {
+ return ConnectionError.INVALID_SESSIONID;
+ }
+ return ConnectionError.SUCCESS;
}
- Json.Array array = parser.get_root().get_array();
-
- for (int i = 0; i < array.get_length(); i++)
+
+
+ public bool getCategories(Gee.List<Category> categories)
{
- Json.Object object = array.get_object_element(i);
- string categorieID = object.get_string_member("id");
-
- if(categorieID.has_suffix("global.all")
- || categorieID.has_suffix("global.uncategorized"))
+ var response = m_connection.send_get_request_to_feedly ("/v3/categories/");
+
+ if(response.status != 200)
{
- continue;
+ return false;
}
-
- categories.add(
- new Category (
- categorieID,
- object.get_string_member("label"),
- getUnreadCountforID(categorieID),
- i+1,
- CategoryID.MASTER.to_string(),
- 1
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e)
+ {
+ Logger.error("getCategories: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ Json.Array array = parser.get_root().get_array();
+
+ for (int i = 0; i < array.get_length(); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string categorieID = object.get_string_member("id");
+
+ if(categorieID.has_suffix("global.all")
+ || categorieID.has_suffix("global.uncategorized"))
+ {
+ continue;
+ }
+
+ categories.add(
+ new Category (
+ categorieID,
+ object.get_string_member("label"),
+ getUnreadCountforID(categorieID),
+ i+1,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
- var response = m_connection.send_get_request_to_feedly("/v3/subscriptions/");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
+
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- Logger.error("getFeeds: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- Json.Array array = parser.get_root().get_array();
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++) {
- Json.Object object = array.get_object_element(i);
-
- string feedID = object.get_string_member("id");
-
- string? icon_url = null;
- if(object.has_member("iconUrl"))
+ var response = m_connection.send_get_request_to_feedly("/v3/subscriptions/");
+
+ if(response.status != 200)
{
- icon_url = object.get_string_member("iconUrl");
+ return false;
}
- else if(object.has_member("visualUrl"))
+
+ var parser = new Json.Parser();
+ try
{
- icon_url = object.get_string_member("visualUrl");
+ parser.load_from_data(response.data, -1);
}
-
- uint catCount = object.get_array_member("categories").get_length();
-
- var categories = new Gee.ArrayList<string>();
- for(uint j = 0; j < catCount; ++j)
+ catch(Error e)
{
- string categoryID = object.get_array_member("categories").get_object_element(j).get_string_member("id");
-
- if(categoryID.has_suffix("global.all")
- || categoryID.has_suffix("global.uncategorized"))
+ Logger.error("getFeeds: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ Json.Array array = parser.get_root().get_array();
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++) {
+ Json.Object object = array.get_object_element(i);
+
+ string feedID = object.get_string_member("id");
+
+ string? icon_url = null;
+ if(object.has_member("iconUrl"))
{
- continue;
+ icon_url = object.get_string_member("iconUrl");
}
-
- categories.add(categoryID);
- }
-
- feeds.add(
- new Feed(
- feedID,
- object.get_string_member("title"),
- object.get_string_member("website"),
- getUnreadCountforID(object.get_string_member("id")),
- categories,
- icon_url
+ else if(object.has_member("visualUrl"))
+ {
+ icon_url = object.get_string_member("visualUrl");
+ }
+
+ uint catCount = object.get_array_member("categories").get_length();
+
+ var categories = new Gee.ArrayList<string>();
+ for(uint j = 0; j < catCount; ++j)
+ {
+ string categoryID = object.get_array_member("categories").get_object_element(j).get_string_member("id");
+
+ if(categoryID.has_suffix("global.all")
+ || categoryID.has_suffix("global.uncategorized"))
+ {
+ continue;
+ }
+
+ categories.add(categoryID);
+ }
+
+ feeds.add(
+ new Feed(
+ feedID,
+ object.get_string_member("title"),
+ object.get_string_member("website"),
+ getUnreadCountforID(object.get_string_member("id")),
+ categories,
+ icon_url
)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-
-public bool getTags(Gee.List<Tag> tags)
-{
- var response = m_connection.send_get_request_to_feedly("/v3/tags/");
-
- if(response.status != 200)
+
+
+ public bool getTags(Gee.List<Tag> tags)
{
- return false;
- }
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getTags: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- Json.Array array = parser.get_root().get_array ();
- uint length = array.get_length();
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++) {
- Json.Object object = array.get_object_element(i);
-
- tags.add(
- new Tag(
- object.get_string_member("id"),
- object.has_member("label") ? object.get_string_member("label") : "",
- db.getTagColor()
+ var response = m_connection.send_get_request_to_feedly("/v3/tags/");
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getTags: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ Json.Array array = parser.get_root().get_array ();
+ uint length = array.get_length();
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++) {
+ Json.Object object = array.get_object_element(i);
+
+ tags.add(
+ new Tag(
+ object.get_string_member("id"),
+ object.has_member("label") ? object.get_string_member("label") : "",
+ db.getTagColor()
)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-
-
-public string? getArticles(Gee.List<Article> articles, int count, string? continuation = null, ArticleStatus whatToGet = ArticleStatus.ALL, string tagID = "", string feed_id = "")
-{
- string steamID = "user/" + m_userID + "/category/global.all";
- string onlyUnread = "false";
- string marked_tag = "user/" + m_userID + "/tag/global.saved";
-
- if(whatToGet == ArticleStatus.MARKED)
- {
- steamID = marked_tag;
- }
- else if(whatToGet == ArticleStatus.UNREAD)
- {
- onlyUnread = "true";
- }
-
-
- if(tagID != "" && whatToGet == ArticleStatus.ALL)
- {
- steamID = tagID;
- }
-
- if(feed_id != "" && whatToGet == ArticleStatus.ALL)
- {
- steamID = feed_id;
- }
-
- var parser = new Json.Parser();
-
- string streamCall = "/v3/streams/ids?streamId=%s&unreadOnly=%s&count=%i&ranked=newest&continuation=%s".printf(steamID, onlyUnread, count, (continuation == null) ? "" : continuation);
- var entry_id_response = m_connection.send_get_request_to_feedly(streamCall);
-
- if(entry_id_response.status != 200)
- {
- return null;
- }
-
- try
- {
- parser.load_from_data(entry_id_response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- if(!root.has_member("continuation"))
- {
- return null;
- }
-
- string cont = root.get_string_member("continuation");
-
- var response = m_connection.send_post_string_request_to_feedly("/v3/entries/.mget", entry_id_response.data, "application/json");
-
- if(response.status != 200)
- {
- return null;
- }
-
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getArticles: Could not load message response");
- Logger.error(e.message);
- }
- var array = parser.get_root().get_array();
-
- for(int i = 0; i < array.get_length(); i++)
+
+
+
+ public string? getArticles(Gee.List<Article> articles, int count, string? continuation = null, ArticleStatus whatToGet = ArticleStatus.ALL, string tagID = "", string feed_id = "")
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- string title = object.get_string_member("title");
- string? author = object.get_string_member("author");
- string summaryContent = object.has_member("summary") ? object.get_object_member("summary").get_string_member("content") : null;
- string content = object.has_member("content") ? object.get_object_member("content").get_string_member("content") : summaryContent;
- bool unread = object.get_boolean_member("unread");
- string url = object.has_member("alternate") ? object.get_array_member("alternate").get_object_element(0).get_string_member("href") : null;
- string feedID = object.get_object_member("origin").get_string_member("streamId");
-
- DateTime date = new DateTime.now_local();
- if(object.has_member("updated") && object.get_int_member("updated") > 0)
+ string steamID = "user/" + m_userID + "/category/global.all";
+ string onlyUnread = "false";
+ string marked_tag = "user/" + m_userID + "/tag/global.saved";
+
+ if(whatToGet == ArticleStatus.MARKED)
{
- date = new DateTime.from_unix_local(object.get_int_member("updated")/1000);
+ steamID = marked_tag;
}
- else if(object.has_member("published") && object.get_int_member("published") > 0)
+ else if(whatToGet == ArticleStatus.UNREAD)
{
- date = new DateTime.from_unix_local(object.get_int_member("published")/1000);
+ onlyUnread = "true";
}
- else if(object.has_member("crawled") && object.get_int_member("crawled") > 0)
+
+
+ if(tagID != "" && whatToGet == ArticleStatus.ALL)
{
- date = new DateTime.from_unix_local(object.get_int_member("crawled")/1000);
+ steamID = tagID;
}
-
- var marked = ArticleStatus.UNMARKED;
-
- var tags = new Gee.ArrayList<string>();
- if(object.has_member("tags"))
+
+ if(feed_id != "" && whatToGet == ArticleStatus.ALL)
{
- var tag_array = object.get_array_member("tags");
- uint tagCount = tag_array.get_length();
-
- for(int j = 0; j < tagCount; ++j)
+ steamID = feed_id;
+ }
+
+ var parser = new Json.Parser();
+
+ string streamCall = "/v3/streams/ids?streamId=%s&unreadOnly=%s&count=%i&ranked=newest&continuation=%s".printf(steamID, onlyUnread, count, (continuation == null) ? "" : continuation);
+ var entry_id_response = m_connection.send_get_request_to_feedly(streamCall);
+
+ if(entry_id_response.status != 200)
+ {
+ return null;
+ }
+
+ try
+ {
+ parser.load_from_data(entry_id_response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ if(!root.has_member("continuation"))
+ {
+ return null;
+ }
+
+ string cont = root.get_string_member("continuation");
+
+ var response = m_connection.send_post_string_request_to_feedly("/v3/entries/.mget", entry_id_response.data, "application/json");
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+ var array = parser.get_root().get_array();
+
+ for(int i = 0; i < array.get_length(); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ string title = object.get_string_member("title");
+ string? author = object.get_string_member("author");
+ string summaryContent = object.has_member("summary") ? object.get_object_member("summary").get_string_member("content") : null;
+ string content = object.has_member("content") ? object.get_object_member("content").get_string_member("content") : summaryContent;
+ bool unread = object.get_boolean_member("unread");
+ string url = object.has_member("alternate") ? object.get_array_member("alternate").get_object_element(0).get_string_member("href") : null;
+ string feedID = object.get_object_member("origin").get_string_member("streamId");
+
+ DateTime date = new DateTime.now_local();
+ if(object.has_member("updated") && object.get_int_member("updated") > 0)
+ {
+ date = new DateTime.from_unix_local(object.get_int_member("updated")/1000);
+ }
+ else if(object.has_member("published") && object.get_int_member("published") > 0)
+ {
+ date = new DateTime.from_unix_local(object.get_int_member("published")/1000);
+ }
+ else if(object.has_member("crawled") && object.get_int_member("crawled") > 0)
+ {
+ date = new DateTime.from_unix_local(object.get_int_member("crawled")/1000);
+ }
+
+ var marked = ArticleStatus.UNMARKED;
+
+ var tags = new Gee.ArrayList<string>();
+ if(object.has_member("tags"))
{
- var tag = tag_array.get_object_element(j).get_string_member("id");
- if(tag == marked_tag)
+ var tag_array = object.get_array_member("tags");
+ uint tagCount = tag_array.get_length();
+
+ for(int j = 0; j < tagCount; ++j)
{
- marked = ArticleStatus.MARKED;
+ var tag = tag_array.get_object_element(j).get_string_member("id");
+ if(tag == marked_tag)
+ {
+ marked = ArticleStatus.MARKED;
+ }
+ else if(tag.contains("global."))
+ {
+ continue;
+ }
+ else
+ {
+ tags.add(tag);
+ }
}
- else if(tag.contains("global."))
+ }
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
+ {
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
{
- continue;
+ mediaCount = attachments.get_length();
}
- else
+
+ for(int j = 0; j < mediaCount; ++j)
{
- tags.add(tag);
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(attachment.get_string_member("type")))
+ );
}
}
+
+ var Article = new Article(
+ id,
+ title,
+ url,
+ feedID,
+ unread ? ArticleStatus.UNREAD : ArticleStatus.READ,
+ marked,
+ content,
+ //summaryContent,
+ null,
+ author,
+ date, // timestamp includes msecs so divide by 1000 to get rid of them
+ -1,
+ tags,
+ enclosures
+ );
+ articles.add(Article);
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+
+ return cont;
+ }
+
+ /** Returns the number of unread articles for an ID (may be a feed, subscription, category or tag */
+ public void getUnreadCounts()
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ var response = m_connection.send_get_request_to_feedly ("/v3/markers/counts");
+
+ if(response.status != 200)
{
- mediaCount = attachments.get_length();
+ return;
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var parser = new Json.Parser ();
+ try
{
- var attachment = attachments.get_object_element(j);
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(attachment.get_string_member("type")))
- );
+ parser.load_from_data(response.data, -1);
}
+ catch(Error e)
+ {
+ Logger.error("getUnreadCounts: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var object = parser.get_root ().get_object ();
+
+ m_unreadcounts = object.get_array_member("unreadcounts");
}
-
- var Article = new Article(
- id,
- title,
- url,
- feedID,
- unread ? ArticleStatus.UNREAD : ArticleStatus.READ,
- marked,
- content,
- //summaryContent,
- null,
- author,
- date, // timestamp includes msecs so divide by 1000 to get rid of them
- -1,
- tags,
- enclosures
- );
- articles.add(Article);
- }
-
- return cont;
-}
-
-/** Returns the number of unread articles for an ID (may be a feed, subscription, category or tag */
-public void getUnreadCounts()
-{
- var response = m_connection.send_get_request_to_feedly ("/v3/markers/counts");
-
- if(response.status != 200)
- {
- return;
- }
-
- var parser = new Json.Parser ();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getUnreadCounts: Could not load message response");
- Logger.error(e.message);
- }
-
- var object = parser.get_root ().get_object ();
-
- m_unreadcounts = object.get_array_member("unreadcounts");
-}
-
-private int getUnreadCountforID(string id)
-{
- int unread_count = -1;
-
- for(int i = 0; i < m_unreadcounts.get_length (); i++)
- {
- var unread = m_unreadcounts.get_object_element(i);
- string unread_id = unread.get_string_member("id");
-
- if(id == unread_id)
+
+ private int getUnreadCountforID(string id)
{
- unread_count = (int)unread.get_int_member("count");
- break;
+ int unread_count = -1;
+
+ for(int i = 0; i < m_unreadcounts.get_length (); i++)
+ {
+ var unread = m_unreadcounts.get_object_element(i);
+ string unread_id = unread.get_string_member("id");
+
+ if(id == unread_id)
+ {
+ unread_count = (int)unread.get_int_member("count");
+ break;
+ }
+ }
+
+ if(unread_count == -1)
+ {
+ Logger.error("Unknown id: %s".printf(id));
+ }
+
+ return unread_count;
}
- }
-
- if(unread_count == -1)
- {
- Logger.error("Unknown id: %s".printf(id));
- }
-
- return unread_count;
-}
-
-public int getTotalUnread()
-{
- return getUnreadCountforID("user/" + m_userID + "/category/global.all");
-}
-
-
-public void mark_as_read(string ids_string, string type, ArticleStatus read)
-{
- var id_array = ids_string.split(",");
- Json.Object object = new Json.Object();
-
- if(read == ArticleStatus.READ)
- {
- object.set_string_member ("action", "markAsRead");
- }
- else if(read == ArticleStatus.UNREAD)
- {
- object.set_string_member ("action", "keepUnread");
- }
- object.set_string_member ("type", type);
-
- Json.Array ids = new Json.Array();
- foreach(string id in id_array)
- {
- ids.add_string_element(id);
- }
-
- string* type_id_identificator = null;
-
- if(type == "entries")
- {
- type_id_identificator = "entryIds";
- }
- else if(type == "feeds")
- {
- type_id_identificator = "feedIds";
- }
- else if(type == "categories")
- {
- type_id_identificator = "categoryIds";
- }
- else
- {
- error ("Unknown type: " + type + " don't know what to do with this.");
- }
-
- object.set_array_member(type_id_identificator, ids);
-
- if(type == "feeds"
- || type == "categories")
- {
- var now = new DateTime.now_local();
- object.set_int_member("asOf", now.to_unix()*1000);
- }
-
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object (object);
-
- m_connection.send_post_request_to_feedly("/v3/markers", root);
-}
-
-public void addArticleTag(string ids_string, string tagID)
-{
- var id_array = ids_string.split(",");
- Json.Object object = new Json.Object();
-
- Json.Array ids = new Json.Array();
- foreach(string id in id_array)
- {
- ids.add_string_element(id);
- }
-
- object.set_array_member("entryIds", ids);
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
-}
-
-public void deleteArticleTag(string ids_string, string tagID)
-{
- string command = GLib.Uri.escape_string(tagID) + "/" + GLib.Uri.escape_string(ids_string);
- m_connection.send_delete_request_to_feedly("/v3/tags/" + command);
-}
-
-public string createTag(string caption)
-{
- string tagID = "user/" + m_userID + "/tag/" + caption;
- Json.Object object = new Json.Object();
- object.set_string_member("entryId", "");
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
- return tagID;
-}
-
-public void deleteTag(string tagID)
-{
- m_connection.send_delete_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID));
-}
-
-
-public bool addSubscription(string feedURL, string? title = null, string? catIDs = null)
-{
- Json.Object object = new Json.Object();
- object.set_string_member("id", "feed/" + feedURL);
-
- if(title != null)
- {
- object.set_string_member("title", title);
- }
-
- if(catIDs != null)
- {
- var catArray = catIDs.split(",");
- Json.Array cats = new Json.Array();
-
- var db = DataBase.readOnly();
- foreach(string catID in catArray)
+
+ public int getTotalUnread()
{
- string catName = db.getCategoryName(catID);
- Json.Object catObject = new Json.Object();
- catObject.set_string_member("id", catID);
- catObject.set_string_member("label", catName);
- cats.add_object_element(catObject);
+ return getUnreadCountforID("user/" + m_userID + "/category/global.all");
}
-
- object.set_array_member("categories", cats);
- }
-
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- var response = m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
-
- return response.status == 200;
-}
-
-public void moveSubscription(string feedID, string newCatID, string? oldCatID = null)
-{
- var db = DataBase.readOnly();
- var Feed = db.read_feed(feedID);
-
- Json.Object object = new Json.Object();
- object.set_string_member("id", feedID);
- object.set_string_member("title", Feed.getTitle());
-
-
- var catArray = Feed.getCatIDs();
- Json.Array cats = new Json.Array();
-
- foreach(string catID in catArray)
- {
- if(catID != oldCatID)
+
+
+ public void mark_as_read(string ids_string, string type, ArticleStatus read)
{
- string catName = db.getCategoryName(catID);
+ var id_array = ids_string.split(",");
+ Json.Object object = new Json.Object();
+
+ if(read == ArticleStatus.READ)
+ {
+ object.set_string_member ("action", "markAsRead");
+ }
+ else if(read == ArticleStatus.UNREAD)
+ {
+ object.set_string_member ("action", "keepUnread");
+ }
+ object.set_string_member ("type", type);
+
+ Json.Array ids = new Json.Array();
+ foreach(string id in id_array)
+ {
+ ids.add_string_element(id);
+ }
+
+ string* type_id_identificator = null;
+
+ if(type == "entries")
+ {
+ type_id_identificator = "entryIds";
+ }
+ else if(type == "feeds")
+ {
+ type_id_identificator = "feedIds";
+ }
+ else if(type == "categories")
+ {
+ type_id_identificator = "categoryIds";
+ }
+ else
+ {
+ error ("Unknown type: " + type + " don't know what to do with this.");
+ }
+
+ object.set_array_member(type_id_identificator, ids);
+
+ if(type == "feeds"
+ || type == "categories")
+ {
+ var now = new DateTime.now_local();
+ object.set_int_member("asOf", now.to_unix()*1000);
+ }
+
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object (object);
+
+ m_connection.send_post_request_to_feedly("/v3/markers", root);
+ }
+
+ public void addArticleTag(string ids_string, string tagID)
+ {
+ var id_array = ids_string.split(",");
+ Json.Object object = new Json.Object();
+
+ Json.Array ids = new Json.Array();
+ foreach(string id in id_array)
+ {
+ ids.add_string_element(id);
+ }
+
+ object.set_array_member("entryIds", ids);
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
+ }
+
+ public void deleteArticleTag(string ids_string, string tagID)
+ {
+ string command = GLib.Uri.escape_string(tagID) + "/" + GLib.Uri.escape_string(ids_string);
+ m_connection.send_delete_request_to_feedly("/v3/tags/" + command);
+ }
+
+ public string createTag(string caption)
+ {
+ string tagID = "user/" + m_userID + "/tag/" + caption;
+ Json.Object object = new Json.Object();
+ object.set_string_member("entryId", "");
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
+ return tagID;
+ }
+
+ public void deleteTag(string tagID)
+ {
+ m_connection.send_delete_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID));
+ }
+
+
+ public bool addSubscription(string feedURL, string? title = null, string? catIDs = null)
+ {
+ Json.Object object = new Json.Object();
+ object.set_string_member("id", "feed/" + feedURL);
+
+ if(title != null)
+ {
+ object.set_string_member("title", title);
+ }
+
+ if(catIDs != null)
+ {
+ var catArray = catIDs.split(",");
+ Json.Array cats = new Json.Array();
+
+ var db = DataBase.readOnly();
+ foreach(string catID in catArray)
+ {
+ string catName = db.getCategoryName(catID);
+ Json.Object catObject = new Json.Object();
+ catObject.set_string_member("id", catID);
+ catObject.set_string_member("label", catName);
+ cats.add_object_element(catObject);
+ }
+
+ object.set_array_member("categories", cats);
+ }
+
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ var response = m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
+
+ return response.status == 200;
+ }
+
+ public void moveSubscription(string feedID, string newCatID, string? oldCatID = null)
+ {
+ var db = DataBase.readOnly();
+ var Feed = db.read_feed(feedID);
+
+ Json.Object object = new Json.Object();
+ object.set_string_member("id", feedID);
+ object.set_string_member("title", Feed.getTitle());
+
+
+ var catArray = Feed.getCatIDs();
+ Json.Array cats = new Json.Array();
+
+ foreach(string catID in catArray)
+ {
+ if(catID != oldCatID)
+ {
+ string catName = db.getCategoryName(catID);
+ Json.Object catObject = new Json.Object();
+ catObject.set_string_member("id", catID);
+ catObject.set_string_member("label", catName);
+ cats.add_object_element(catObject);
+ }
+ }
+
+ string newCatName = db.getCategoryName(newCatID);
Json.Object catObject = new Json.Object();
- catObject.set_string_member("id", catID);
- catObject.set_string_member("label", catName);
+ catObject.set_string_member("id", newCatID);
+ catObject.set_string_member("label", newCatName);
cats.add_object_element(catObject);
+
+ object.set_array_member("categories", cats);
+
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
+ }
+
+ public void removeSubscription(string feedID)
+ {
+ Logger.info(@"Deleting $(feedID)");
+ m_connection.send_delete_request_to_feedly("/v3/subscriptions/" + Uri.escape_string(feedID));
+ }
+
+ public void renameCategory(string catID, string title)
+ {
+ Json.Object object = new Json.Object();
+ object.set_string_member("label", title);
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ m_connection.send_post_request_to_feedly("/v3/categories/" + Uri.escape_string(catID), root);
+ }
+
+ public void renameTag(string tagID, string title)
+ {
+ Json.Object object = new Json.Object();
+ object.set_string_member("label", title);
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(object);
+
+ m_connection.send_post_request_to_feedly("/v3/tags/" + Uri.escape_string(tagID), root);
+ }
+
+ public void removeCategory(string catID)
+ {
+ m_connection.send_delete_request_to_feedly("/v3/categories/" + Uri.escape_string(catID));
+ }
+
+ public void importOPML(string opml)
+ {
+ m_connection.send_post_string_request_to_feedly("/v3/opml", opml, "text/xml");
}
}
-
- string newCatName = db.getCategoryName(newCatID);
- Json.Object catObject = new Json.Object();
- catObject.set_string_member("id", newCatID);
- catObject.set_string_member("label", newCatName);
- cats.add_object_element(catObject);
-
- object.set_array_member("categories", cats);
-
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
-}
-
-public void removeSubscription(string feedID)
-{
- Logger.info(@"Deleting $(feedID)");
- m_connection.send_delete_request_to_feedly("/v3/subscriptions/" + Uri.escape_string(feedID));
-}
-
-public void renameCategory(string catID, string title)
-{
- Json.Object object = new Json.Object();
- object.set_string_member("label", title);
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- m_connection.send_post_request_to_feedly("/v3/categories/" + Uri.escape_string(catID), root);
-}
-
-public void renameTag(string tagID, string title)
-{
- Json.Object object = new Json.Object();
- object.set_string_member("label", title);
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(object);
-
- m_connection.send_post_request_to_feedly("/v3/tags/" + Uri.escape_string(tagID), root);
-}
-
-public void removeCategory(string catID)
-{
- m_connection.send_delete_request_to_feedly("/v3/categories/" + Uri.escape_string(catID));
-}
-
-public void importOPML(string opml)
-{
- m_connection.send_post_string_request_to_feedly("/v3/opml", opml, "text/xml");
-}
-}
diff --git a/plugins/backend/feedly/feedlyConnection.vala b/plugins/backend/feedly/feedlyConnection.vala
index 94c0581c..615bc8d0 100644
--- a/plugins/backend/feedly/feedlyConnection.vala
+++ b/plugins/backend/feedly/feedlyConnection.vala
@@ -14,273 +14,273 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.FeedlyConnection {
-
-private FeedlyUtils m_utils;
-private GLib.Settings m_settingsTweaks;
-private Soup.Session m_session;
-
-public FeedlyConnection(FeedlyUtils utils)
-{
- m_utils = utils;
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-}
-
-public LoginResponse getToken()
-{
- var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
- string message_string = "code=" + m_utils.getApiCode()
- + "&client_id=" + FeedlySecret.apiClientId
- + "&client_secret=" + FeedlySecret.apiClientSecret
- + "&redirect_uri=" + FeedlySecret.apiRedirectUri
- + "&grant_type=authorization_code"
- + "&state=getting_token";
-
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ private FeedlyUtils m_utils;
+ private GLib.Settings m_settingsTweaks;
+ private Soup.Session m_session;
+
+ public FeedlyConnection(FeedlyUtils utils)
{
- return LoginResponse.NO_CONNECTION;
+ m_utils = utils;
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
}
-
- try
+
+ public LoginResponse getToken()
{
- var parser = new Json.Parser();
- parser.load_from_data ((string)message.response_body.flatten().data);
- var root = parser.get_root().get_object();
-
- if(root.has_member("access_token"))
+ var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
+ string message_string = "code=" + m_utils.getApiCode()
+ + "&client_id=" + FeedlySecret.apiClientId
+ + "&client_secret=" + FeedlySecret.apiClientSecret
+ + "&redirect_uri=" + FeedlySecret.apiRedirectUri
+ + "&grant_type=authorization_code"
+ + "&state=getting_token";
+
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
{
- string accessToken = root.get_string_member("access_token");
- int64 expires = (int)root.get_int_member("expires_in");
- string refreshToken = root.get_string_member("refresh_token");
- int64 now = (new DateTime.now_local()).to_unix();
-
- Logger.debug("access-token: " + accessToken);
- Logger.debug("expires in: " + expires.to_string());
- Logger.debug("refresh-token: " + refreshToken);
- Logger.debug("now: " + now.to_string());
-
- m_utils.setAccessToken(accessToken);
- m_utils.setExpiration((int)(now + expires));
- m_utils.setRefreshToken(refreshToken);
- return LoginResponse.SUCCESS;
+ return LoginResponse.NO_CONNECTION;
}
- else if(root.has_member("errorCode"))
+
+ try
{
- Logger.error("Feedly: getToken response - " + root.get_string_member("errorMessage"));
- return LoginResponse.UNKNOWN_ERROR;
+ var parser = new Json.Parser();
+ parser.load_from_data ((string)message.response_body.flatten().data);
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("access_token"))
+ {
+ string accessToken = root.get_string_member("access_token");
+ int64 expires = (int)root.get_int_member("expires_in");
+ string refreshToken = root.get_string_member("refresh_token");
+ int64 now = (new DateTime.now_local()).to_unix();
+
+ Logger.debug("access-token: " + accessToken);
+ Logger.debug("expires in: " + expires.to_string());
+ Logger.debug("refresh-token: " + refreshToken);
+ Logger.debug("now: " + now.to_string());
+
+ m_utils.setAccessToken(accessToken);
+ m_utils.setExpiration((int)(now + expires));
+ m_utils.setRefreshToken(refreshToken);
+ return LoginResponse.SUCCESS;
+ }
+ else if(root.has_member("errorCode"))
+ {
+ Logger.error("Feedly: getToken response - " + root.get_string_member("errorMessage"));
+ return LoginResponse.UNKNOWN_ERROR;
+ }
}
+ catch(Error e)
+ {
+ Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
}
- catch(Error e)
- {
- Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-
-public LoginResponse refreshToken()
-{
- var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
- {
- message.request_headers.append("DNT", "1");
- }
-
- string message_string = "refresh_token=" + m_utils.getRefreshToken()
- + "&client_id=" + FeedlySecret.apiClientId
- + "&client_secret=" + FeedlySecret.apiClientSecret
- + "&grant_type=refresh_token";
-
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- return LoginResponse.NO_CONNECTION;
- }
-
- try
+
+
+ public LoginResponse refreshToken()
{
- var parser = new Json.Parser();
- parser.load_from_data ((string)message.response_body.flatten().data);
- var root = parser.get_root().get_object();
-
- if(root.has_member("access_token"))
+ var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
{
- string accessToken = root.get_string_member("access_token");
- int64 expires = (int)root.get_int_member("expires_in");
- string refreshToken = root.get_string_member("refresh_token");
- int64 now = (new DateTime.now_local()).to_unix();
-
- Logger.debug("access-token: " + accessToken);
- Logger.debug("expires in: " + expires.to_string());
- Logger.debug("refresh-token: " + refreshToken);
- Logger.debug("now: " + now.to_string());
-
- m_utils.setAccessToken(accessToken);
- m_utils.setExpiration((int)(now + expires));
- m_utils.setRefreshToken(refreshToken);
- return LoginResponse.SUCCESS;
+ message.request_headers.append("DNT", "1");
}
- else if(root.has_member("errorCode"))
+
+ string message_string = "refresh_token=" + m_utils.getRefreshToken()
+ + "&client_id=" + FeedlySecret.apiClientId
+ + "&client_secret=" + FeedlySecret.apiClientSecret
+ + "&grant_type=refresh_token";
+
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
{
- Logger.error("Feedly: refreshToken response - " + root.get_string_member("errorMessage"));
- return LoginResponse.UNKNOWN_ERROR;
+ return LoginResponse.NO_CONNECTION;
}
+
+ try
+ {
+ var parser = new Json.Parser();
+ parser.load_from_data ((string)message.response_body.flatten().data);
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("access_token"))
+ {
+ string accessToken = root.get_string_member("access_token");
+ int64 expires = (int)root.get_int_member("expires_in");
+ string refreshToken = root.get_string_member("refresh_token");
+ int64 now = (new DateTime.now_local()).to_unix();
+
+ Logger.debug("access-token: " + accessToken);
+ Logger.debug("expires in: " + expires.to_string());
+ Logger.debug("refresh-token: " + refreshToken);
+ Logger.debug("now: " + now.to_string());
+
+ m_utils.setAccessToken(accessToken);
+ m_utils.setExpiration((int)(now + expires));
+ m_utils.setRefreshToken(refreshToken);
+ return LoginResponse.SUCCESS;
+ }
+ else if(root.has_member("errorCode"))
+ {
+ Logger.error("Feedly: refreshToken response - " + root.get_string_member("errorMessage"));
+ return LoginResponse.UNKNOWN_ERROR;
+ }
+ }
+ catch(Error e)
+ {
+ Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
}
- catch(Error e)
- {
- Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-
-public Response send_get_request_to_feedly(string path)
-{
- return send_request(path, "GET");
-}
-
-public Response send_put_request_to_feedly(string path, Json.Node root)
-{
- if(!m_utils.accessTokenValid())
- {
- refreshToken();
- }
-
- var message = new Soup.Message("PUT", FeedlySecret.base_uri+path);
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
- {
- message.request_headers.append("DNT", "1");
- }
-
- var gen = new Json.Generator();
- gen.set_root(root);
- message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
-
- size_t length;
- string json;
- json = gen.to_data(out length);
- message.request_body.append_take(json.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- Logger.warning(@"FeedlyConnection: message unexpected response");
- }
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
-public Response send_post_request_to_feedly(string path, Json.Node root)
-{
- if(!m_utils.accessTokenValid())
- {
- refreshToken();
- }
-
- var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
- {
- message.request_headers.append("DNT", "1");
- }
-
- var gen = new Json.Generator();
- gen.set_root(root);
- message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
-
- size_t length;
- string json;
- json = gen.to_data(out length);
- Logger.debug(json);
- message.request_body.append_take(json.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- Logger.warning(@"FeedlyConnection: message unexpected response");
- Logger.debug("Status Code: " + message.status_code.to_string());
- }
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
-public Response send_post_string_request_to_feedly(string path, string input, string type)
-{
- if(!m_utils.accessTokenValid())
+
+
+ public Response send_get_request_to_feedly(string path)
{
- refreshToken();
+ return send_request(path, "GET");
}
-
- var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
+
+ public Response send_put_request_to_feedly(string path, Json.Node root)
{
- message.request_headers.append("DNT", "1");
+ if(!m_utils.accessTokenValid())
+ {
+ refreshToken();
+ }
+
+ var message = new Soup.Message("PUT", FeedlySecret.base_uri+path);
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ var gen = new Json.Generator();
+ gen.set_root(root);
+ message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+
+ size_t length;
+ string json;
+ json = gen.to_data(out length);
+ message.request_body.append_take(json.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning(@"FeedlyConnection: message unexpected response");
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
- message.request_headers.append("Content-Type", type);
-
- message.request_body.append_take(input.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ public Response send_post_request_to_feedly(string path, Json.Node root)
{
- Logger.warning(@"FeedlyConnection: message unexpected response - $input");
+ if(!m_utils.accessTokenValid())
+ {
+ refreshToken();
+ }
+
+ var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ var gen = new Json.Generator();
+ gen.set_root(root);
+ message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+
+ size_t length;
+ string json;
+ json = gen.to_data(out length);
+ Logger.debug(json);
+ message.request_body.append_take(json.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning(@"FeedlyConnection: message unexpected response");
+ Logger.debug("Status Code: " + message.status_code.to_string());
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
-public Response send_delete_request_to_feedly(string path)
-{
- return send_request(path, "DELETE");
-}
-
-private Response send_request(string path, string type)
-{
- if(!m_utils.accessTokenValid())
+
+ public Response send_post_string_request_to_feedly(string path, string input, string type)
{
- refreshToken();
+ if(!m_utils.accessTokenValid())
+ {
+ refreshToken();
+ }
+
+ var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+ message.request_headers.append("Content-Type", type);
+
+ message.request_body.append_take(input.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning(@"FeedlyConnection: message unexpected response - $input");
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- var message = new Soup.Message(type, FeedlySecret.base_uri+path);
- message.request_headers.append("Authorization", @"OAuth $(m_utils.getAccessToken())");
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
+
+ public Response send_delete_request_to_feedly(string path)
{
- message.request_headers.append("DNT", "1");
+ return send_request(path, "DELETE");
}
-
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ private Response send_request(string path, string type)
{
- Logger.warning(@"FeedlyConnection: message unexpected response");
+ if(!m_utils.accessTokenValid())
+ {
+ refreshToken();
+ }
+
+ var message = new Soup.Message(type, FeedlySecret.base_uri+path);
+ message.request_headers.append("Authorization", @"OAuth $(m_utils.getAccessToken())");
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning(@"FeedlyConnection: message unexpected response");
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
}
diff --git a/plugins/backend/feedly/feedlyInterface.vala b/plugins/backend/feedly/feedlyInterface.vala
index 2a2aeef3..f668b38e 100644
--- a/plugins/backend/feedly/feedlyInterface.vala
+++ b/plugins/backend/feedly/feedlyInterface.vala
@@ -14,385 +14,385 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.feedlyInterface : FeedServerInterface {
-
-private FeedlyAPI m_api;
-private FeedlyUtils m_utils;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new FeedlyUtils(settings_backend);
- m_api = new FeedlyAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "http://feedly.com/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-}
-
-public override string getID()
-{
- return "feedly";
-}
-
-public override string iconName()
-{
- return "feed-service-feedly";
-}
-
-public override string serviceName()
-{
- return "feedly";
-}
-
-public override bool needWebLogin()
-{
- return true;
-}
-
-public override bool extractCode(string redirectURL)
-{
- if(redirectURL.has_prefix(FeedlySecret.apiRedirectUri))
- {
- int start = redirectURL.index_of("=")+1;
- int end = redirectURL.index_of("&");
- string code = redirectURL.substring(start, end-start);
- m_utils.setApiCode(code);
- Logger.debug("feedlyLoginWidget: set feedly-api-code: " + code);
- GLib.Thread.usleep(500000);
+
+ private FeedlyAPI m_api;
+ private FeedlyUtils m_utils;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+ {
+ m_utils = new FeedlyUtils(settings_backend);
+ m_api = new FeedlyAPI(m_utils);
+ }
+
+ public override string getWebsite()
+ {
+ return "http://feedly.com/";
+ }
+
+ public override BackendFlags getFlags()
+ {
+ return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
+ }
+
+ public override string getID()
+ {
+ return "feedly";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-feedly";
+ }
+
+ public override string serviceName()
+ {
+ return "feedly";
+ }
+
+ public override bool needWebLogin()
+ {
return true;
}
-
- return false;
-}
-
-public override string buildLoginURL()
-{
- return FeedlySecret.base_uri + "/v3/auth/auth" + "?client_secret=" + FeedlySecret.apiClientSecret + "&client_id=" + FeedlySecret.apiClientId
- + "&redirect_uri=" + FeedlySecret.apiRedirectUri + "&scope=" + FeedlySecret.apiAuthScope + "&response_type=code&state=getting_code";
-}
-
-public override bool supportTags()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-feedly-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getEmail();
-}
-
-public override string getServerURL()
-{
- return "http://feedly.com/";
-}
-
-public override string uncategorizedID()
-{
- return "";
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return catID.has_suffix("global.must");
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return true;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return false;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- m_api.mark_as_read(articleIDs, "entries", read);
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override bool extractCode(string redirectURL)
{
- m_api.addArticleTag(articleID, m_api.getMarkedID());
+ if(redirectURL.has_prefix(FeedlySecret.apiRedirectUri))
+ {
+ int start = redirectURL.index_of("=")+1;
+ int end = redirectURL.index_of("&");
+ string code = redirectURL.substring(start, end-start);
+ m_utils.setApiCode(code);
+ Logger.debug("feedlyLoginWidget: set feedly-api-code: " + code);
+ GLib.Thread.usleep(500000);
+ return true;
+ }
+
+ return false;
}
- else if(marked == ArticleStatus.UNMARKED)
+
+ public override string buildLoginURL()
{
- m_api.deleteArticleTag(articleID, m_api.getMarkedID());
+ return FeedlySecret.base_uri + "/v3/auth/auth" + "?client_secret=" + FeedlySecret.apiClientSecret + "&client_id=" + FeedlySecret.apiClientId
+ + "&redirect_uri=" + FeedlySecret.apiRedirectUri + "&scope=" + FeedlySecret.apiAuthScope + "&response_type=code&state=getting_code";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.mark_as_read(feedID, "feeds", ArticleStatus.READ);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.mark_as_read(catID, "categories", ArticleStatus.READ);
-}
-
-public override void markAllItemsRead()
-{
- string catArray = "";
- string feedArray = "";
-
- var db = DataBase.readOnly();
- var categories = db.read_categories();
- var feeds = db.read_feeds_without_cat();
-
- foreach(Category cat in categories)
+
+ public override bool supportTags()
{
- catArray += cat.getCatID() + ",";
+ return true;
}
-
- foreach(Feed feed in feeds)
+
+ public override bool doInitSync()
{
- feedArray += feed.getFeedID() + ",";
+ return true;
}
-
- m_api.mark_as_read(catArray.substring(0, catArray.length-1), "categories", ArticleStatus.READ);
- m_api.mark_as_read(feedArray.substring(0, feedArray.length-1), "feeds", ArticleStatus.READ);
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- m_api.addArticleTag(articleID, tagID);
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- m_api.deleteArticleTag(articleID, tagID);
-}
-
-public override string createTag(string caption)
-{
- return m_api.createTag(caption);
-}
-
-public override void deleteTag(string tagID)
-{
- m_api.deleteTag(tagID);
-}
-
-public override void renameTag(string tagID, string title)
-{
- m_api.renameTag(tagID, title);
-}
-
-public override bool serverAvailable()
-{
- return Utils.ping("http://feedly.com/");
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- feedID = "feed/" + feedURL;
- bool success = false;
- errmsg = "";
-
- if(catID == null && newCatName != null)
+
+ public override string symbolicIcon()
{
- string newCatID = m_api.createCatID(newCatName);
- success = m_api.addSubscription(feedURL, null, newCatID);
+ return "feed-service-feedly-symbolic";
}
- else
+
+ public override string accountName()
{
- success = m_api.addSubscription(feedURL, null, catID);
+ return m_utils.getEmail();
}
-
- if(!success)
+
+ public override string getServerURL()
{
- errmsg = @"feedly could not add $feedURL";
+ return "http://feedly.com/";
}
-
- return success;
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.removeSubscription(feedID);
-}
-
-public override void renameFeed(string feedID, string title)
-{
- var feed = DataBase.readOnly().read_feed(feedID);
- m_api.addSubscription(feed.getFeedID(), title, feed.getCatString());
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID )
-{
- m_api.moveSubscription(feedID, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.createCatID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameCategory(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.removeCategory(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- var feed = DataBase.readOnly().read_feed(feedID);
- m_api.addSubscription(feed.getFeedID(), feed.getTitle(), feed.getCatString().replace(catID + ",", ""));
-}
-
-public override void importOPML(string opml)
-{
- m_api.importOPML(opml);
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- m_api.getUnreadCounts();
-
- if(m_api.getCategories(categories))
+
+ public override string uncategorizedID()
+ {
+ return "";
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return catID.has_suffix("global.must");
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return true;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return false;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ m_api.mark_as_read(articleIDs, "entries", read);
+ }
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(marked == ArticleStatus.MARKED)
{
- return false;
+ m_api.addArticleTag(articleID, m_api.getMarkedID());
}
-
- if(m_api.getFeeds(feeds))
+ else if(marked == ArticleStatus.UNMARKED)
{
- if(cancellable != null && cancellable.is_cancelled())
- {
- return false;
- }
-
- if(m_api.getTags(tags))
- {
- return true;
- }
+ m_api.deleteArticleTag(articleID, m_api.getMarkedID());
}
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getTotalUnread();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- string continuation = null;
- string feedly_tagID = "";
- string feedly_feedID = "";
- if(feedID != null)
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.mark_as_read(feedID, "feeds", ArticleStatus.READ);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.mark_as_read(catID, "categories", ArticleStatus.READ);
+ }
+
+ public override void markAllItemsRead()
{
- if(isTagID)
+ string catArray = "";
+ string feedArray = "";
+
+ var db = DataBase.readOnly();
+ var categories = db.read_categories();
+ var feeds = db.read_feeds_without_cat();
+
+ foreach(Category cat in categories)
{
- feedly_tagID = feedID;
+ catArray += cat.getCatID() + ",";
}
- else
+
+ foreach(Feed feed in feeds)
{
- feedly_feedID = feedID;
+ feedArray += feed.getFeedID() + ",";
}
+
+ m_api.mark_as_read(catArray.substring(0, catArray.length-1), "categories", ArticleStatus.READ);
+ m_api.mark_as_read(feedArray.substring(0, feedArray.length-1), "feeds", ArticleStatus.READ);
}
-
- int skip = count;
- int amount = 200;
- var articles = new Gee.LinkedList<Article>();
-
- while(skip > 0)
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ m_api.addArticleTag(articleID, tagID);
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ m_api.deleteArticleTag(articleID, tagID);
+ }
+
+ public override string createTag(string caption)
+ {
+ return m_api.createTag(caption);
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ m_api.deleteTag(tagID);
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ m_api.renameTag(tagID, title);
+ }
+
+ public override bool serverAvailable()
+ {
+ return Utils.ping("http://feedly.com/");
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
{
- if(cancellable != null && cancellable.is_cancelled())
+ feedID = "feed/" + feedURL;
+ bool success = false;
+ errmsg = "";
+
+ if(catID == null && newCatName != null)
{
- return;
+ string newCatID = m_api.createCatID(newCatName);
+ success = m_api.addSubscription(feedURL, null, newCatID);
}
-
- if(skip >= amount)
+ else
{
- skip -= amount;
+ success = m_api.addSubscription(feedURL, null, catID);
}
- else
+
+ if(!success)
{
- amount = skip;
- skip = 0;
+ errmsg = @"feedly could not add $feedURL";
}
-
- continuation = m_api.getArticles(articles, amount, continuation, whatToGet, feedly_tagID, feedly_feedID);
-
- if(continuation == null)
+
+ return success;
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.removeSubscription(feedID);
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ var feed = DataBase.readOnly().read_feed(feedID);
+ m_api.addSubscription(feed.getFeedID(), title, feed.getCatString());
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID )
+ {
+ m_api.moveSubscription(feedID, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.createCatID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameCategory(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ return;
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.removeCategory(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ var feed = DataBase.readOnly().read_feed(feedID);
+ m_api.addSubscription(feed.getFeedID(), feed.getTitle(), feed.getCatString().replace(catID + ",", ""));
+ }
+
+ public override void importOPML(string opml)
+ {
+ m_api.importOPML(opml);
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ m_api.getUnreadCounts();
+
+ if(m_api.getCategories(categories))
{
- break;
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getFeeds(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getTags(tags))
+ {
+ return true;
+ }
+ }
}
+
+ return false;
+ }
+
+ public override int getUnreadCount()
+ {
+ return m_api.getTotalUnread();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ string continuation = null;
+ string feedly_tagID = "";
+ string feedly_feedID = "";
+ if(feedID != null)
+ {
+ if(isTagID)
+ {
+ feedly_tagID = feedID;
+ }
+ else
+ {
+ feedly_feedID = feedID;
+ }
+ }
+
+ int skip = count;
+ int amount = 200;
+ var articles = new Gee.LinkedList<Article>();
+
+ while(skip > 0)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(skip >= amount)
+ {
+ skip -= amount;
+ }
+ else
+ {
+ amount = skip;
+ skip = 0;
+ }
+
+ continuation = m_api.getArticles(articles, amount, continuation, whatToGet, feedly_tagID, feedly_feedID);
+
+ if(continuation == null)
+ {
+ break;
+ }
+ }
+
+ writeArticles(articles);
}
-
- writeArticles(articles);
-}
}
[ModuleInit]
diff --git a/plugins/backend/feedly/feedlyUtils.vala b/plugins/backend/feedly/feedlyUtils.vala
index 1626eaee..5dc0825d 100644
--- a/plugins/backend/feedly/feedlyUtils.vala
+++ b/plugins/backend/feedly/feedlyUtils.vala
@@ -14,94 +14,94 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.FeedlySecret {
-const string base_uri = "http://cloud.feedly.com";
-const string apiClientId = "boutroue";
-const string apiClientSecret = "FE012EGICU4ZOBDRBEOVAJA1JZYH";
-const string apiRedirectUri = "http://localhost";
-const string apiAuthScope = "https://cloud.feedly.com/subscriptions";
+ const string base_uri = "http://cloud.feedly.com";
+ const string apiClientId = "boutroue";
+ const string apiClientSecret = "FE012EGICU4ZOBDRBEOVAJA1JZYH";
+ const string apiRedirectUri = "http://localhost";
+ const string apiAuthScope = "https://cloud.feedly.com/subscriptions";
}
public class FeedReader.FeedlyUtils : Object {
-
-private GLib.Settings m_settings;
-
-public FeedlyUtils(GLib.SettingsBackend? settings_backend)
-{
- if(settings_backend != null)
+
+ private GLib.Settings m_settings;
+
+ public FeedlyUtils(GLib.SettingsBackend? settings_backend)
{
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedly", settings_backend);
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedly", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.feedly");
+ }
}
- else
+
+ public string getRefreshToken()
{
- m_settings = new GLib.Settings("org.gnome.feedreader.feedly");
+ return Utils.gsettingReadString(m_settings, "refresh-token");
}
-}
-
-public string getRefreshToken()
-{
- return Utils.gsettingReadString(m_settings, "refresh-token");
-}
-
-public void setRefreshToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "refresh-token", token);
-}
-
-public string getAccessToken()
-{
- return Utils.gsettingReadString(m_settings, "access-token");
-}
-
-public void setAccessToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "access-token", token);
-}
-
-public string getApiCode()
-{
- return Utils.gsettingReadString(m_settings, "api-code");
-}
-
-public void setApiCode(string code)
-{
- Utils.gsettingWriteString(m_settings, "api-code", code);
-}
-
-public string getEmail()
-{
- return Utils.gsettingReadString(m_settings, "email");
-}
-
-public void setEmail(string email)
-{
- Utils.gsettingWriteString(m_settings, "email", email);
-}
-
-public int getExpiration()
-{
- return m_settings.get_int("access-token-expires");
-}
-
-public void setExpiration(int seconds)
-{
- m_settings.set_int("access-token-expires", seconds);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
-}
-
-public bool accessTokenValid()
-{
- var now = new DateTime.now_local();
-
- if((int)now.to_unix() > getExpiration())
+
+ public void setRefreshToken(string token)
{
- Logger.warning("FeedlyUtils: access token expired");
- return false;
+ Utils.gsettingWriteString(m_settings, "refresh-token", token);
+ }
+
+ public string getAccessToken()
+ {
+ return Utils.gsettingReadString(m_settings, "access-token");
+ }
+
+ public void setAccessToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "access-token", token);
+ }
+
+ public string getApiCode()
+ {
+ return Utils.gsettingReadString(m_settings, "api-code");
+ }
+
+ public void setApiCode(string code)
+ {
+ Utils.gsettingWriteString(m_settings, "api-code", code);
+ }
+
+ public string getEmail()
+ {
+ return Utils.gsettingReadString(m_settings, "email");
+ }
+
+ public void setEmail(string email)
+ {
+ Utils.gsettingWriteString(m_settings, "email", email);
+ }
+
+ public int getExpiration()
+ {
+ return m_settings.get_int("access-token-expires");
+ }
+
+ public void setExpiration(int seconds)
+ {
+ m_settings.set_int("access-token-expires", seconds);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ }
+
+ public bool accessTokenValid()
+ {
+ var now = new DateTime.now_local();
+
+ if((int)now.to_unix() > getExpiration())
+ {
+ Logger.warning("FeedlyUtils: access token expired");
+ return false;
+ }
+
+ return true;
}
-
- return true;
-}
}
diff --git a/plugins/backend/fresh/freshAPI.vala b/plugins/backend/fresh/freshAPI.vala
index bbe154b8..a0086982 100644
--- a/plugins/backend/fresh/freshAPI.vala
+++ b/plugins/backend/fresh/freshAPI.vala
@@ -14,291 +14,291 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.freshAPI : Object {
-
-private freshConnection m_connection;
-private freshUtils m_utils;
-
-public freshAPI(freshUtils utils)
-{
- m_utils = utils;
- m_connection = new freshConnection(m_utils);
-}
-
-public LoginResponse login()
-{
- Logger.debug("fresh backend: login");
-
- if(!Utils.ping(m_utils.getUnmodifiedURL()))
+
+ private freshConnection m_connection;
+ private freshUtils m_utils;
+
+ public freshAPI(freshUtils utils)
{
- return LoginResponse.NO_CONNECTION;
+ m_utils = utils;
+ m_connection = new freshConnection(m_utils);
}
-
- return m_connection.getSID();
-}
-
-public bool getSubscriptionList(Gee.List<Feed> feeds)
-{
- var response = m_connection.getRequest("reader/api/0/subscription/list?output=json");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
+
+ public LoginResponse login()
{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e)
- {
- Logger.error("getTagList: Could not load message response");
- Logger.error(e.message);
- return false;
+ Logger.debug("fresh backend: login");
+
+ if(!Utils.ping(m_utils.getUnmodifiedURL()))
+ {
+ return LoginResponse.NO_CONNECTION;
+ }
+
+ return m_connection.getSID();
}
- Json.Array array = parser.get_root().get_object().get_array_member("subscriptions");
-
- for (int i = 0; i < array.get_length (); i++)
+
+ public bool getSubscriptionList(Gee.List<Feed> feeds)
{
- Json.Object object = array.get_object_element(i);
-
- string url = object.get_string_member("htmlUrl");
- string id = object.get_string_member("id");
- string catID = object.get_array_member("categories").get_object_element(0).get_string_member("id");
- string xmlURL = object.get_string_member("url");
-
- feeds.add(
- new Feed(
- id,
- object.get_string_member("title"),
- url,
- 0,
- ListUtils.single(catID),
- object.get_string_member("iconUrl"),
+ var response = m_connection.getRequest("reader/api/0/subscription/list?output=json");
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e)
+ {
+ Logger.error("getTagList: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ Json.Array array = parser.get_root().get_object().get_array_member("subscriptions");
+
+ for (int i = 0; i < array.get_length (); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ string url = object.get_string_member("htmlUrl");
+ string id = object.get_string_member("id");
+ string catID = object.get_array_member("categories").get_object_element(0).get_string_member("id");
+ string xmlURL = object.get_string_member("url");
+
+ feeds.add(
+ new Feed(
+ id,
+ object.get_string_member("title"),
+ url,
+ 0,
+ ListUtils.single(catID),
+ object.get_string_member("iconUrl"),
xmlURL)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-public bool getTagList(Gee.List<Category> categories)
-{
- var response = m_connection.getRequest("reader/api/0/tag/list?output=json");
- string prefix = "user/-/label/";
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch (Error e)
- {
- Logger.error("getTagList: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- Json.Array array = parser.get_root().get_object().get_array_member("tags");
-
- for (int i = 0; i < array.get_length (); i++)
+
+ public bool getTagList(Gee.List<Category> categories)
{
- Json.Object object = array.get_object_element(i);
- string categorieID = object.get_string_member("id");
-
-
- if(!categorieID.has_prefix(prefix))
+ var response = m_connection.getRequest("reader/api/0/tag/list?output=json");
+ string prefix = "user/-/label/";
+
+ if(response.status != 200)
{
- continue;
+ return false;
}
-
- categories.add(
- new Category (
- categorieID,
- categorieID.substring(prefix.length),
- 0,
- i+1,
- CategoryID.MASTER.to_string(),
- 1
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e)
+ {
+ Logger.error("getTagList: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ Json.Array array = parser.get_root().get_object().get_array_member("tags");
+
+ for (int i = 0; i < array.get_length (); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string categorieID = object.get_string_member("id");
+
+
+ if(!categorieID.has_prefix(prefix))
+ {
+ continue;
+ }
+
+ categories.add(
+ new Category (
+ categorieID,
+ categorieID.substring(prefix.length),
+ 0,
+ i+1,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-public int getUnreadCounts()
-{
- var response = m_connection.getRequest("reader/api/0/unread-count?output=json");
-
- if(response.status != 200)
- {
- return 0;
- }
-
- int count = 0;
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch (Error e)
+
+ public int getUnreadCounts()
{
- Logger.error("getTagList: Could not load message response");
- Logger.error(e.message);
- }
- Json.Array array = parser.get_root().get_object().get_array_member("unreadcounts");
-
- for (int i = 0; i < array.get_length (); i++)
- {
- Json.Object object = array.get_object_element(i);
- if(object.get_string_member("id") == "user/-/state/com.google/reading-list")
+ var response = m_connection.getRequest("reader/api/0/unread-count?output=json");
+
+ if(response.status != 200)
{
- count = (int)object.get_int_member("count");
+ return 0;
}
- }
-
- return count;
-}
-
-public string? getStreamContents(
- Gee.List<Article> articles,
- string? feedID = null,
- string? labelID = null,
- string? exclude = null,
- int count = 400,
- string order = "d",
- string? checkpoint = null
- )
-{
- var now = new DateTime.now_local();
- string path = "reader/api/0/stream/contents";
-
- if(feedID != null)
- {
- path += "/" + feedID;
- }
- else if(labelID != null)
- {
- path += "/" + labelID;
- }
-
-
- var msg = new freshMessage();
- msg.add("output", "json");
- msg.add("r", order);
- msg.add("n", count.to_string());
- msg.add("client", "FeedReader");
- msg.add("ck", now.to_unix().to_string());
-
- if(exclude != null)
- {
- msg.add("xt", exclude);
- }
-
- if(checkpoint != null)
- {
- msg.add("c", checkpoint);
- }
-
- Logger.debug("getStreamContents: %s".printf(msg.get()));
-
- var response = m_connection.getRequest(path + "?" + msg.get());
-
- if(response.status != 200)
- {
- return null;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getStreamContents: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("items");
- uint length = array.get_length();
-
- for(uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- bool marked = false;
- bool read = false;
- var cats = object.get_array_member("categories");
- uint cat_length = cats.get_length();
-
- for(uint j = 0; j < cat_length; j++)
+
+ int count = 0;
+
+ var parser = new Json.Parser();
+ try
{
- string cat = cats.get_string_element(j);
- if(cat.has_suffix("com.google/starred"))
- {
- marked = true;
- }
- else if(cat.has_suffix("com.google/read"))
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e)
+ {
+ Logger.error("getTagList: Could not load message response");
+ Logger.error(e.message);
+ }
+ Json.Array array = parser.get_root().get_object().get_array_member("unreadcounts");
+
+ for (int i = 0; i < array.get_length (); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ if(object.get_string_member("id") == "user/-/state/com.google/reading-list")
{
- read = true;
+ count = (int)object.get_int_member("count");
}
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+
+ return count;
+ }
+
+ public string? getStreamContents(
+ Gee.List<Article> articles,
+ string? feedID = null,
+ string? labelID = null,
+ string? exclude = null,
+ int count = 400,
+ string order = "d",
+ string? checkpoint = null
+ )
+ {
+ var now = new DateTime.now_local();
+ string path = "reader/api/0/stream/contents";
+
+ if(feedID != null)
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ path += "/" + feedID;
+ }
+ else if(labelID != null)
+ {
+ path += "/" + labelID;
+ }
+
+
+ var msg = new freshMessage();
+ msg.add("output", "json");
+ msg.add("r", order);
+ msg.add("n", count.to_string());
+ msg.add("client", "FeedReader");
+ msg.add("ck", now.to_unix().to_string());
+
+ if(exclude != null)
+ {
+ msg.add("xt", exclude);
+ }
+
+ if(checkpoint != null)
+ {
+ msg.add("c", checkpoint);
+ }
+
+ Logger.debug("getStreamContents: %s".printf(msg.get()));
+
+ var response = m_connection.getRequest(path + "?" + msg.get());
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getStreamContents: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("items");
+ uint length = array.get_length();
+
+ for(uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ bool marked = false;
+ bool read = false;
+ var cats = object.get_array_member("categories");
+ uint cat_length = cats.get_length();
+
+ for(uint j = 0; j < cat_length; j++)
{
- mediaCount = attachments.get_length();
+ string cat = cats.get_string_element(j);
+ if(cat.has_suffix("com.google/starred"))
+ {
+ marked = true;
+ }
+ else if(cat.has_suffix("com.google/read"))
+ {
+ read = true;
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
{
- var attachment = attachments.get_object_element(j);
- string type = attachment.has_member("type") ? attachment.get_string_member("type") : "";
-
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(type))
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ string type = attachment.has_member("type") ? attachment.get_string_member("type") : "";
+
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(type))
);
+ }
}
- }
-
- articles.add(new Article(
- id,
- object.get_string_member("title"),
- object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
- object.get_object_member("origin").get_string_member("streamId"),
- read ? ArticleStatus.READ : ArticleStatus.UNREAD,
- marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- object.get_object_member("summary").get_string_member("content"),
- null,
- object.get_string_member("author"),
- new DateTime.from_unix_local(object.get_int_member("published")),
- -1,
- null,
- enclosures
- )
- );
- }
-
-
+
+ articles.add(new Article(
+ id,
+ object.get_string_member("title"),
+ object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+ object.get_object_member("origin").get_string_member("streamId"),
+ read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+ marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ object.get_object_member("summary").get_string_member("content"),
+ null,
+ object.get_string_member("author"),
+ new DateTime.from_unix_local(object.get_int_member("published")),
+ -1,
+ null,
+ enclosures
+ )
+ );
+ }
+
+
if(root.has_member("continuation") && root.get_string_member("continuation") != "")
{
return root.get_string_member("continuation");
}
-
+
return null;
}
@@ -306,27 +306,27 @@ public void editTags(string articleIDs, string? addTag = null, string? removeTag
{
string path = "reader/api/0/edit-tag";
string[] arrayID = articleIDs.split(",");
-
+
var msg = new freshMessage();
msg.add("T", m_connection.getToken());
-
+
if(addTag != null)
{
msg.add("a", addTag);
}
-
+
if(removeTag != null)
{
msg.add("r", removeTag);
}
-
+
foreach(string id in arrayID)
{
msg.add("i", "-/" + id);
}
-
+
var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
-
+
if(response.status != 200)
{
Logger.debug(path + " " + msg.get());
@@ -337,14 +337,14 @@ public void editTags(string articleIDs, string? addTag = null, string? removeTag
public void markAllAsRead(string streamID)
{
string path = "reader/api/0/mark-all-as-read";
-
+
var msg = new freshMessage();
msg.add("T", m_connection.getToken());
msg.add("s", streamID);
msg.add("ts", DataBase.readOnly().getNewestArticle());
-
+
var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
-
+
if(response.status != 200)
{
Logger.debug(path + " " + msg.get());
@@ -358,44 +358,44 @@ public Response editStream(
string? title = null,
string? add = null,
string? remove = null
- )
+)
{
string path = "reader/api/0/subscription/edit";
-
+
var msg = new freshMessage();
msg.add("T", m_connection.getToken());
msg.add("ac", action);
-
+
if(streamID != null)
{
foreach(string s in streamID) {
msg.add("s", s);
}
}
-
+
if(title != null)
{
msg.add("t", title);
}
-
+
if(add != null)
{
msg.add("a", add);
}
-
+
if(remove != null)
{
msg.add("r", remove);
}
-
+
var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
-
+
if(response.status != 200)
{
Logger.debug(path + " " + msg.get());
Logger.debug(response.status.to_string());
}
-
+
return response;
}
@@ -407,15 +407,15 @@ public string composeTagID(string title)
public void renameTag(string tagID, string title)
{
string path = "reader/api/0/rename-tag";
-
+
var msg = new freshMessage();
msg.add("T", m_connection.getToken());
msg.add("s", tagID);
msg.add("dest", composeTagID(title));
-
+
var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
-
-
+
+
if(response.status != 200)
{
Logger.debug(path + " " + msg.get());
@@ -426,13 +426,13 @@ public void renameTag(string tagID, string title)
public void deleteTag(string tagID)
{
string path = "reader/api/0/disable-tag";
-
+
var msg = new freshMessage();
msg.add("T", m_connection.getToken());
msg.add("s", tagID);
-
+
var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
-
+
if(response.status != 200)
{
Logger.debug(path + " " + msg.get());
diff --git a/plugins/backend/fresh/freshConnection.vala b/plugins/backend/fresh/freshConnection.vala
index e9e8e692..eaf0c7f7 100644
--- a/plugins/backend/fresh/freshConnection.vala
+++ b/plugins/backend/fresh/freshConnection.vala
@@ -14,145 +14,145 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.freshConnection {
-
-private freshUtils m_utils;
-private GLib.Settings m_settingsTweaks;
-private Soup.Session m_session;
-
-public freshConnection(freshUtils utils)
-{
- m_utils = utils;
- m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_session.authenticate.connect((msg, auth, retrying) => {
+
+ private freshUtils m_utils;
+ private GLib.Settings m_settingsTweaks;
+ private Soup.Session m_session;
+
+ public freshConnection(freshUtils utils)
+ {
+ m_utils = utils;
+ m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_session.authenticate.connect((msg, auth, retrying) => {
if(m_utils.getHtaccessUser() == "")
{
- Logger.error("fresh Session: need Authentication");
+ Logger.error("fresh Session: need Authentication");
}
else if(!retrying)
{
- auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+ auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
}
});
-}
-
-public LoginResponse getSID()
-{
- var message = new Soup.Message("POST", m_utils.getURL()+"accounts/ClientLogin");
-
- var msg = new freshMessage();
- msg.add("Email", m_utils.getUser());
- msg.add("Passwd", m_utils.getPasswd());
-
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, msg.get().data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- Logger.error("No response from freshRSS to message getSID()");
- return LoginResponse.NO_CONNECTION;
}
-
- string response = (string)message.response_body.flatten().data;
-
- if(!response.has_prefix("SID="))
+
+ public LoginResponse getSID()
{
- m_utils.setToken("");
- m_utils.setUser("");
- m_utils.setURL("");
- return LoginResponse.WRONG_LOGIN;
+ var message = new Soup.Message("POST", m_utils.getURL()+"accounts/ClientLogin");
+
+ var msg = new freshMessage();
+ msg.add("Email", m_utils.getUser());
+ msg.add("Passwd", m_utils.getPasswd());
+
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, msg.get().data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.error("No response from freshRSS to message getSID()");
+ return LoginResponse.NO_CONNECTION;
+ }
+
+ string response = (string)message.response_body.flatten().data;
+
+ if(!response.has_prefix("SID="))
+ {
+ m_utils.setToken("");
+ m_utils.setUser("");
+ m_utils.setURL("");
+ return LoginResponse.WRONG_LOGIN;
+ }
+ else
+ {
+ int start = response.index_of("=")+1;
+ int end = response.index_of("\n");
+ string token = response.substring(start, end-start);
+ Logger.debug("Token: " + token);
+ m_utils.setToken(token);
+ return LoginResponse.SUCCESS;
+ }
}
- else
+
+ public string getToken()
{
- int start = response.index_of("=")+1;
- int end = response.index_of("\n");
- string token = response.substring(start, end-start);
- Logger.debug("Token: " + token);
- m_utils.setToken(token);
- return LoginResponse.SUCCESS;
+ return getRequest("reader/api/0/token").data.replace("\n", "");
}
-}
-
-public string getToken()
-{
- return getRequest("reader/api/0/token").data.replace("\n", "");
-}
-
-public Response postRequest(string path, string input, string type)
-{
- var message = new Soup.Message("POST", m_utils.getURL()+path);
-
- if(m_settingsTweaks.get_boolean("do-not-track"))
+
+ public Response postRequest(string path, string input, string type)
{
- message.request_headers.append("DNT", "1");
+ var message = new Soup.Message("POST", m_utils.getURL()+path);
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
+ message.request_headers.append("Content-Type", type);
+
+ message.request_body.append_take(input.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
- message.request_headers.append("Content-Type", type);
-
- message.request_body.append_take(input.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ public Response getRequest(string path)
{
- Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
+ var message = new Soup.Message("GET", m_utils.getURL()+path);
+ message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
+
+ if(m_settingsTweaks.get_boolean("do-not-track"))
+ {
+ message.request_headers.append("DNT", "1");
+ }
+
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
}
-public Response getRequest(string path)
-{
- var message = new Soup.Message("GET", m_utils.getURL()+path);
- message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
- if(m_settingsTweaks.get_boolean("do-not-track"))
+public class FeedReader.freshMessage {
+
+ string request = "";
+
+ public freshMessage()
{
- message.request_headers.append("DNT", "1");
+
}
-
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ public void add(string parameter, string val)
{
- Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
+ if(request != "")
+ {
+ request += "&";
+ }
+
+ request += parameter;
+ request += "=";
+ request += GLib.Uri.escape_string(val, "/");
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-}
-
-
-public class FeedReader.freshMessage {
-
-string request = "";
-
-public freshMessage()
-{
-
-}
-
-public void add(string parameter, string val)
-{
- if(request != "")
+
+ public string get()
{
- request += "&";
+ return request;
}
-
- request += parameter;
- request += "=";
- request += GLib.Uri.escape_string(val, "/");
-}
-
-public string get()
-{
- return request;
-}
}
diff --git a/plugins/backend/fresh/freshInterface.vala b/plugins/backend/fresh/freshInterface.vala
index 47375901..3461a500 100644
--- a/plugins/backend/fresh/freshInterface.vala
+++ b/plugins/backend/fresh/freshInterface.vala
@@ -14,487 +14,487 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.freshInterface : FeedServerInterface {
-
-private freshAPI m_api;
-private freshUtils m_utils;
-private Gtk.Entry m_urlEntry;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-private Gtk.Entry m_authPasswordEntry;
-private Gtk.Entry m_authUserEntry;
-private Gtk.Revealer m_revealer;
-private bool m_need_htaccess = false;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new freshUtils(settings_backend, secrets);
- m_api = new freshAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://freshrss.org/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-}
-
-public override string getID()
-{
- return "fresh";
-}
-
-public override string iconName()
-{
- return "feed-service-fresh";
-}
-
-public override string serviceName()
-{
- return "freshRSS";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var url_label = new Gtk.Label(_("freshRSS URL:"));
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- url_label.set_alignment(1.0f, 0.5f);
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- url_label.set_hexpand(true);
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_urlEntry = new Gtk.Entry();
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_urlEntry.activate.connect(() => { tryLogin(); });
- m_userEntry.activate.connect(() => { tryLogin(); });
- m_passwordEntry.activate.connect(() => { tryLogin(); });
-
- m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(url_label, 0, 0, 1, 1);
- grid.attach(m_urlEntry, 1, 0, 1, 1);
- grid.attach(user_label, 0, 1, 1, 1);
- grid.attach(m_userEntry, 1, 1, 1, 1);
- grid.attach(password_label, 0, 2, 1, 1);
- grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
-
- // http auth stuff ----------------------------------------------------
- var auth_user_label = new Gtk.Label(_("Username:"));
- var auth_password_label = new Gtk.Label(_("Password:"));
-
- auth_user_label.set_alignment(1.0f, 0.5f);
- auth_password_label.set_alignment(1.0f, 0.5f);
-
- auth_user_label.set_hexpand(true);
- auth_password_label.set_hexpand(true);
-
- m_authUserEntry = new Gtk.Entry();
- m_authPasswordEntry = new Gtk.Entry();
- m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_authPasswordEntry.set_visibility(false);
-
- m_authUserEntry.activate.connect(() => { tryLogin(); });
- m_authPasswordEntry.activate.connect(() => { tryLogin(); });
-
- var authGrid = new Gtk.Grid();
- authGrid.margin = 10;
- authGrid.set_column_spacing(10);
- authGrid.set_row_spacing(10);
- authGrid.set_valign(Gtk.Align.CENTER);
- authGrid.set_halign(Gtk.Align.CENTER);
-
- authGrid.attach(auth_user_label, 0, 0, 1, 1);
- authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
- authGrid.attach(auth_password_label, 0, 1, 1, 1);
- authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
-
- var frame = new Gtk.Frame(_("HTTP Authorization"));
- frame.set_halign(Gtk.Align.CENTER);
- frame.add(authGrid);
- m_revealer = new Gtk.Revealer();
- m_revealer.add(frame);
- //---------------------------------------------------------------------
-
- var logo = new Gtk.Image.from_icon_name("feed-service-fresh", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to your freshRSS server and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_start(m_revealer, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_urlEntry.set_text(m_utils.getUnmodifiedURL());
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override void showHtAccess()
-{
- m_revealer.set_reveal_child(true);
-}
-
-public override void writeData()
-{
- m_utils.setURL(m_urlEntry.get_text());
- m_utils.setUser(m_userEntry.get_text().strip());
- m_utils.setPassword(m_passwordEntry.get_text().strip());
- if(m_need_htaccess)
+
+ private freshAPI m_api;
+ private freshUtils m_utils;
+ private Gtk.Entry m_urlEntry;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+ private Gtk.Entry m_authPasswordEntry;
+ private Gtk.Entry m_authUserEntry;
+ private Gtk.Revealer m_revealer;
+ private bool m_need_htaccess = false;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
- m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
+ m_utils = new freshUtils(settings_backend, secrets);
+ m_api = new freshAPI(m_utils);
}
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-fresh-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return m_utils.getUnmodifiedURL();
-}
-
-public override string uncategorizedID()
-{
- return "1";
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override bool serverAvailable()
-{
- return Utils.ping(m_utils.getUnmodifiedURL());
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- if(read == ArticleStatus.READ)
+
+ public override string getWebsite()
{
- m_api.editTags(articleIDs, "user/-/state/com.google/read", null);
+ return "https://freshrss.org/";
}
- else
+
+ public override BackendFlags getFlags()
{
- m_api.editTags(articleIDs, null, "user/-/state/com.google/read");
+ return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
}
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override string getID()
{
- m_api.editTags(articleID, "user/-/state/com.google/starred", null);
+ return "fresh";
}
- else
+
+ public override string iconName()
{
- m_api.editTags(articleID, null, "user/-/state/com.google/starred");
+ return "feed-service-fresh";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markAllAsRead(feedID);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markAllAsRead(catID);
-}
-
-public override void markAllItemsRead()
-{
- m_api.markAllAsRead("user/-/state/com.google/reading-list");
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- return;
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- return "";
-}
-
-public override void deleteTag(string tagID)
-{
-
-}
-
-public override void renameTag(string tagID, string title)
-{
-
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- string? cat = null;
- if(catID != null)
+
+ public override string serviceName()
{
- cat = catID;
+ return "freshRSS";
}
- else if(newCatName != null)
+
+ public override bool needWebLogin()
{
- cat = newCatName;
+ return false;
}
-
- cat = m_api.composeTagID(cat);
-
- var response = m_api.editStream("subscribe", {"feed/" + feedURL}, null, cat, null);
- if(response.status != 200)
+
+ public override Gtk.Box? getWidget()
+ {
+ var url_label = new Gtk.Label(_("freshRSS URL:"));
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ url_label.set_alignment(1.0f, 0.5f);
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ url_label.set_hexpand(true);
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_urlEntry = new Gtk.Entry();
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_urlEntry.activate.connect(() => { tryLogin(); });
+ m_userEntry.activate.connect(() => { tryLogin(); });
+ m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+ m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(url_label, 0, 0, 1, 1);
+ grid.attach(m_urlEntry, 1, 0, 1, 1);
+ grid.attach(user_label, 0, 1, 1, 1);
+ grid.attach(m_userEntry, 1, 1, 1, 1);
+ grid.attach(password_label, 0, 2, 1, 1);
+ grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+
+ // http auth stuff ----------------------------------------------------
+ var auth_user_label = new Gtk.Label(_("Username:"));
+ var auth_password_label = new Gtk.Label(_("Password:"));
+
+ auth_user_label.set_alignment(1.0f, 0.5f);
+ auth_password_label.set_alignment(1.0f, 0.5f);
+
+ auth_user_label.set_hexpand(true);
+ auth_password_label.set_hexpand(true);
+
+ m_authUserEntry = new Gtk.Entry();
+ m_authPasswordEntry = new Gtk.Entry();
+ m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_authPasswordEntry.set_visibility(false);
+
+ m_authUserEntry.activate.connect(() => { tryLogin(); });
+ m_authPasswordEntry.activate.connect(() => { tryLogin(); });
+
+ var authGrid = new Gtk.Grid();
+ authGrid.margin = 10;
+ authGrid.set_column_spacing(10);
+ authGrid.set_row_spacing(10);
+ authGrid.set_valign(Gtk.Align.CENTER);
+ authGrid.set_halign(Gtk.Align.CENTER);
+
+ authGrid.attach(auth_user_label, 0, 0, 1, 1);
+ authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
+ authGrid.attach(auth_password_label, 0, 1, 1, 1);
+ authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
+
+ var frame = new Gtk.Frame(_("HTTP Authorization"));
+ frame.set_halign(Gtk.Align.CENTER);
+ frame.add(authGrid);
+ m_revealer = new Gtk.Revealer();
+ m_revealer.add(frame);
+ //---------------------------------------------------------------------
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-fresh", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to your freshRSS server and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_start(m_revealer, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
+ }
+
+ public override void showHtAccess()
+ {
+ m_revealer.set_reveal_child(true);
+ }
+
+ public override void writeData()
+ {
+ m_utils.setURL(m_urlEntry.get_text());
+ m_utils.setUser(m_userEntry.get_text().strip());
+ m_utils.setPassword(m_passwordEntry.get_text().strip());
+ if(m_need_htaccess)
+ {
+ m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
+ m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
+ }
+ }
+
+ public override bool supportTags()
{
- feedID = "";
- errmsg = response.data;
return false;
}
-
- errmsg = "";
- feedID = response.data;
- return true;
-}
-
-public override void addFeeds(Gee.List<Feed> feeds)
-{
- string cat = "";
- string[] urls = {};
-
- foreach(Feed f in feeds)
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-fresh-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return m_utils.getUnmodifiedURL();
+ }
+
+ public override string uncategorizedID()
+ {
+ return "1";
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return false;
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
{
- if(f.getCatIDs()[0] != cat)
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override bool serverAvailable()
+ {
+ return Utils.ping(m_utils.getUnmodifiedURL());
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ if(read == ArticleStatus.READ)
{
- m_api.editStream("subscribe", urls, null, cat, null);
- urls = {};
- cat = f.getCatIDs()[0];
+ m_api.editTags(articleIDs, "user/-/state/com.google/read", null);
+ }
+ else
+ {
+ m_api.editTags(articleIDs, null, "user/-/state/com.google/read");
}
-
- urls += "feed/" + f.getXmlUrl();
}
-
- m_api.editStream("subscribe", urls, null, cat, null);
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.editStream("unsubscribe", {feedID}, null, null, null);
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.editStream("edit", {feedID}, title, null, null);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.editStream("edit", {feedID}, null, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.composeTagID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameTag(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.deleteTag(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getSubscriptionList(feeds))
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(marked == ArticleStatus.MARKED)
+ {
+ m_api.editTags(articleID, "user/-/state/com.google/starred", null);
+ }
+ else
{
+ m_api.editTags(articleID, null, "user/-/state/com.google/starred");
+ }
+ }
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.markAllAsRead(feedID);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markAllAsRead(catID);
+ }
+
+ public override void markAllItemsRead()
+ {
+ m_api.markAllAsRead("user/-/state/com.google/reading-list");
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override string createTag(string caption)
+ {
+ return "";
+ }
+
+ public override void deleteTag(string tagID)
+ {
+
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ string? cat = null;
+ if(catID != null)
+ {
+ cat = catID;
+ }
+ else if(newCatName != null)
+ {
+ cat = newCatName;
+ }
+
+ cat = m_api.composeTagID(cat);
+
+ var response = m_api.editStream("subscribe", {"feed/" + feedURL}, null, cat, null);
+ if(response.status != 200)
+ {
+ feedID = "";
+ errmsg = response.data;
return false;
}
-
- if(m_api.getTagList(categories))
+
+ errmsg = "";
+ feedID = response.data;
+ return true;
+ }
+
+ public override void addFeeds(Gee.List<Feed> feeds)
+ {
+ string cat = "";
+ string[] urls = {};
+
+ foreach(Feed f in feeds)
{
- return true;
+ if(f.getCatIDs()[0] != cat)
+ {
+ m_api.editStream("subscribe", urls, null, cat, null);
+ urls = {};
+ cat = f.getCatIDs()[0];
+ }
+
+ urls += "feed/" + f.getXmlUrl();
}
+
+ m_api.editStream("subscribe", urls, null, cat, null);
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getUnreadCounts();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- if(whatToGet == ArticleStatus.READ)
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.editStream("unsubscribe", {feedID}, null, null, null);
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.editStream("edit", {feedID}, title, null, null);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.editStream("edit", {feedID}, null, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.composeTagID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameTag(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
{
return;
}
-
- var articles = new Gee.LinkedList<Article>();
- string? continuation = null;
- string? exclude = null;
- string? labelID = null;
- int left = count;
- if(whatToGet == ArticleStatus.ALL)
+
+ public override void deleteCategory(string catID)
{
- labelID = "user/-/state/com.google/reading-list";
+ m_api.deleteTag(catID);
}
- else if(whatToGet == ArticleStatus.MARKED)
+
+ public override void removeCatFromFeed(string feedID, string catID)
{
- labelID = "user/-/state/com.google/starred";
+ return;
}
- else if(whatToGet == ArticleStatus.UNREAD)
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
{
- labelID = "user/-/state/com.google/reading-list";
- exclude = "user/-/state/com.google/read";
+ if(m_api.getSubscriptionList(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getTagList(categories))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
-
-
- while(left > 0)
+
+ public override int getUnreadCount()
+ {
+ return m_api.getUnreadCounts();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(whatToGet == ArticleStatus.READ)
{
return;
}
-
- if(left > 1000)
+
+ var articles = new Gee.LinkedList<Article>();
+ string? continuation = null;
+ string? exclude = null;
+ string? labelID = null;
+ int left = count;
+ if(whatToGet == ArticleStatus.ALL)
{
- continuation = m_api.getStreamContents(articles, null, labelID, exclude, 1000, "d");
- left -= 1000;
+ labelID = "user/-/state/com.google/reading-list";
}
- else
+ else if(whatToGet == ArticleStatus.MARKED)
+ {
+ labelID = "user/-/state/com.google/starred";
+ }
+ else if(whatToGet == ArticleStatus.UNREAD)
{
- continuation = m_api.getStreamContents(articles, null, labelID, exclude, left, "d");
- left = 0;
+ labelID = "user/-/state/com.google/reading-list";
+ exclude = "user/-/state/com.google/read";
}
+
+
+ while(left > 0)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.getStreamContents(articles, null, labelID, exclude, 1000, "d");
+ left -= 1000;
+ }
+ else
+ {
+ continuation = m_api.getStreamContents(articles, null, labelID, exclude, left, "d");
+ left = 0;
+ }
+ }
+ writeArticles(articles);
}
- writeArticles(articles);
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/fresh/freshUtils.vala b/plugins/backend/fresh/freshUtils.vala
index caca081c..92aa2316 100644
--- a/plugins/backend/fresh/freshUtils.vala
+++ b/plugins/backend/fresh/freshUtils.vala
@@ -14,133 +14,133 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.freshUtils : GLib.Object {
-
-GLib.Settings m_settings;
-Password m_password;
-Password m_htaccess_password;
-
-public freshUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
+
+ GLib.Settings m_settings;
+ Password m_password;
+ Password m_htaccess_password;
+
+ public freshUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.fresh", settings_backend);
- }
- else
- {
- m_settings = new GLib.Settings("org.gnome.feedreader.fresh");
- }
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, pwSchema, "FeedReader: freshRSS login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.fresh", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.fresh");
+ }
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, pwSchema, "FeedReader: freshRSS login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getUser();
return attributes;
});
-
- var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING,
- "htaccess", Secret.SchemaAttributeType.BOOLEAN);
- m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: freshRSS htaccess Authentication", () => {
+
+ var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING,
+ "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+ m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: freshRSS htaccess Authentication", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getHtaccessUser();
attributes["htaccess"] = "true";
return attributes;
});
-}
-
-public string getURL()
-{
- string tmp_url = Utils.gsettingReadString(m_settings, "url");
- if(tmp_url != "")
+ }
+
+ public string getURL()
{
- if(!tmp_url.has_suffix("/"))
+ string tmp_url = Utils.gsettingReadString(m_settings, "url");
+ if(tmp_url != "")
{
- tmp_url = tmp_url + "/";
- }
-
- if(!tmp_url.has_suffix("/api/greader.php/"))
- {
- tmp_url = tmp_url + "api/greader.php/";
- }
-
- if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
- {
- tmp_url = "https://" + tmp_url;
+ if(!tmp_url.has_suffix("/"))
+ {
+ tmp_url = tmp_url + "/";
+ }
+
+ if(!tmp_url.has_suffix("/api/greader.php/"))
+ {
+ tmp_url = tmp_url + "api/greader.php/";
+ }
+
+ if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+ {
+ tmp_url = "https://" + tmp_url;
+ }
}
+
+ return tmp_url;
+ }
+
+ public void setURL(string url)
+ {
+ Utils.gsettingWriteString(m_settings, "url", url);
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "token", token);
+ }
+
+ public string getToken()
+ {
+ return Utils.gsettingReadString(m_settings, "token");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getHtaccessUser()
+ {
+ return Utils.gsettingReadString(m_settings, "htaccess-username");
+ }
+
+ public void setHtaccessUser(string ht_user)
+ {
+ Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+ }
+
+ public string getUnmodifiedURL()
+ {
+ return Utils.gsettingReadString(m_settings, "url");
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ m_htaccess_password.delete_password();
+ }
+
+ public string getHtaccessPasswd()
+ {
+ return m_htaccess_password.get_password();
+ }
+
+ public void setHtAccessPassword(string passwd)
+ {
+ m_htaccess_password.set_password(passwd);
}
-
- return tmp_url;
-}
-
-public void setURL(string url)
-{
- Utils.gsettingWriteString(m_settings, "url", url);
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "token", token);
-}
-
-public string getToken()
-{
- return Utils.gsettingReadString(m_settings, "token");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getHtaccessUser()
-{
- return Utils.gsettingReadString(m_settings, "htaccess-username");
-}
-
-public void setHtaccessUser(string ht_user)
-{
- Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-}
-
-public string getUnmodifiedURL()
-{
- return Utils.gsettingReadString(m_settings, "url");
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
- m_htaccess_password.delete_password();
-}
-
-public string getHtaccessPasswd()
-{
- return m_htaccess_password.get_password();
-}
-
-public void setHtAccessPassword(string passwd)
-{
- m_htaccess_password.set_password(passwd);
-}
}
diff --git a/plugins/backend/inoreader/InoReaderAPI.vala b/plugins/backend/inoreader/InoReaderAPI.vala
index c40c2102..3c4eadf2 100644
--- a/plugins/backend/inoreader/InoReaderAPI.vala
+++ b/plugins/backend/inoreader/InoReaderAPI.vala
@@ -14,419 +14,419 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.InoReaderAPI : GLib.Object {
-
-public enum InoSubscriptionAction {
- EDIT,
- SUBSCRIBE,
- UNSUBSCRIBE
-}
-
-private InoReaderConnection m_connection;
-private InoReaderUtils m_utils;
-private string m_userID;
-
-public InoReaderAPI (InoReaderUtils utils)
-{
- m_utils = utils;
- m_connection = new InoReaderConnection(m_utils);
-}
-
-
-public LoginResponse login()
-{
- if(m_utils.getAccessToken() == "")
- {
- m_connection.getToken();
- }
-
- if(getUserID())
- {
- return LoginResponse.SUCCESS;
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-public bool ping() {
- return Utils.ping("http://www.inoreader.com/");
-}
-
-private bool getUserID()
-{
- var response = m_connection.send_request("user-info");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getUserID: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
-
- if(root.has_member("userId"))
- {
- m_userID = root.get_string_member("userId");
- m_utils.setUserID(m_userID);
- Logger.info("Inoreader: userID = " + m_userID);
-
- if(root.has_member("userEmail"))
+
+ public enum InoSubscriptionAction {
+ EDIT,
+ SUBSCRIBE,
+ UNSUBSCRIBE
+ }
+
+ private InoReaderConnection m_connection;
+ private InoReaderUtils m_utils;
+ private string m_userID;
+
+ public InoReaderAPI (InoReaderUtils utils)
+ {
+ m_utils = utils;
+ m_connection = new InoReaderConnection(m_utils);
+ }
+
+
+ public LoginResponse login()
+ {
+ if(m_utils.getAccessToken() == "")
{
- m_utils.setEmail(root.get_string_member("userEmail"));
+ m_connection.getToken();
}
-
- if(root.has_member("userName"))
+
+ if(getUserID())
{
- m_utils.setUser(root.get_string_member("userName"));
+ return LoginResponse.SUCCESS;
}
-
- return true;
- }
-
- return false;
-}
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
- var response = m_connection.send_request("subscription/list");
-
- if(response.status != 200)
- {
- return false;
+
+ return LoginResponse.UNKNOWN_ERROR;
}
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
+
+ public bool ping() {
+ return Utils.ping("http://www.inoreader.com/");
}
- catch(Error e)
+
+ private bool getUserID()
{
- Logger.error("getFeeds: Could not load message response");
- Logger.error(e.message);
+ var response = m_connection.send_request("user-info");
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getUserID: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+
+ if(root.has_member("userId"))
+ {
+ m_userID = root.get_string_member("userId");
+ m_utils.setUserID(m_userID);
+ Logger.info("Inoreader: userID = " + m_userID);
+
+ if(root.has_member("userEmail"))
+ {
+ m_utils.setEmail(root.get_string_member("userEmail"));
+ }
+
+ if(root.has_member("userName"))
+ {
+ m_utils.setUser(root.get_string_member("userName"));
+ }
+
+ return true;
+ }
+
return false;
}
- var root = parser.get_root().get_object();
- var array = root.get_array_member("subscriptions");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- Json.Object object = array.get_object_element(i);
-
- string feedID = object.get_string_member("id");
- string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
-
- uint catCount = object.get_array_member("categories").get_length();
- var categories = new Gee.ArrayList<string>();
-
- for(uint j = 0; j < catCount; ++j)
+ var response = m_connection.send_request("subscription/list");
+
+ if(response.status != 200)
{
- categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ return false;
}
-
- feeds.add(
- new Feed(
- feedID,
- object.get_string_member("title"),
- url,
- 0,
- categories,
- object.get_string_member("iconUrl"),
- object.get_string_member("url")
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getFeeds: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("subscriptions");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ string feedID = object.get_string_member("id");
+ string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+
+ uint catCount = object.get_array_member("categories").get_length();
+ var categories = new Gee.ArrayList<string>();
+
+ for(uint j = 0; j < catCount; ++j)
+ {
+ categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ }
+
+ feeds.add(
+ new Feed(
+ feedID,
+ object.get_string_member("title"),
+ url,
+ 0,
+ categories,
+ object.get_string_member("iconUrl"),
+ object.get_string_member("url")
)
);
+ }
+
+ return true;
}
-
- return true;
-}
-
-public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-{
- var response = m_connection.send_request("tag/list");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- var array = root.get_array_member("tags");
- uint length = array.get_length();
- int orderID = 0;
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++)
+
+ public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- int start = id.last_index_of_char('/') + 1;
- string title = id.substring(start);
-
- if(id.contains("/label/"))
+ var response = m_connection.send_request("tag/list");
+
+ if(response.status != 200)
{
- if(m_utils.tagIsCat(id, feeds))
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("tags");
+ uint length = array.get_length();
+ int orderID = 0;
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ int start = id.last_index_of_char('/') + 1;
+ string title = id.substring(start);
+
+ if(id.contains("/label/"))
{
- categories.add(
- new Category(
- id,
- title,
- 0,
- orderID,
- CategoryID.MASTER.to_string(),
- 1
+ if(m_utils.tagIsCat(id, feeds))
+ {
+ categories.add(
+ new Category(
+ id,
+ title,
+ 0,
+ orderID,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
- }
- else
- {
- tags.add(
- new Tag(
- id,
- title,
- db.getTagColor()
+ }
+ else
+ {
+ tags.add(
+ new Tag(
+ id,
+ title,
+ db.getTagColor()
)
);
+ }
+
+ ++orderID;
}
-
- ++orderID;
}
+ return true;
}
- return true;
-}
-
-
-public int getTotalUnread()
-{
- var response = m_connection.send_request("unread-count");
-
- if(response.status != 200)
- {
- return 0;
- }
-
- var parser = new Json.Parser();
- try{
- parser.load_from_data(response.data, -1);
- }
- catch (Error e) {
- Logger.error("getTotalUnread: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("unreadcounts");
- uint length = array.get_length();
- int count = 0;
-
- for (uint i = 0; i < length; i++)
+
+
+ public int getTotalUnread()
{
- Json.Object object = array.get_object_element(i);
- if(object.get_string_member("id").has_prefix("feed/"))
+ var response = m_connection.send_request("unread-count");
+
+ if(response.status != 200)
{
- count += (int)object.get_int_member("count");
+ return 0;
}
-
- }
-
- Logger.debug("getTotalUnread %i".printf(count));
- return count;
-}
-
-
-public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
-{
- var message_string = "n=" + count.to_string();
- message_string += "&xt=user/-/state/com.google/read";
- if(continuation != null)
- {
- message_string += "&c=" + continuation;
- }
- var response = m_connection.send_request("stream/items/ids", message_string);
-
- if(response.status != 200)
- {
- return null;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("updateArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- if(!root.has_member("itemRefs"))
- {
- return null;
- }
- var array = root.get_array_member("itemRefs");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- ids.add(object.get_string_member("id"));
+
+ var parser = new Json.Parser();
+ try{
+ parser.load_from_data(response.data, -1);
+ }
+ catch (Error e) {
+ Logger.error("getTotalUnread: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("unreadcounts");
+ uint length = array.get_length();
+ int count = 0;
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ if(object.get_string_member("id").has_prefix("feed/"))
+ {
+ count += (int)object.get_int_member("count");
+ }
+
+ }
+
+ Logger.debug("getTotalUnread %i".printf(count));
+ return count;
}
-
- if(root.has_member("continuation") && root.get_string_member("continuation") != "")
- {
- return root.get_string_member("continuation");
- }
-
- return null;
-}
-
-public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
-{
- var message_string = "n=" + count.to_string();
-
- if(whatToGet == ArticleStatus.UNREAD)
+
+
+ public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
{
+ var message_string = "n=" + count.to_string();
message_string += "&xt=user/-/state/com.google/read";
- }
- if(whatToGet == ArticleStatus.READ)
- {
- message_string += "&it=user/-/state/com.google/read";
- }
- else if(whatToGet == ArticleStatus.MARKED)
- {
- message_string += "&it=user/-/state/com.google/starred";
- }
-
- if(continuation != null)
- {
- message_string += "&c=" + continuation;
- }
-
-
- string api_endpoint = "stream/contents";
- if(feed_id != null)
- {
- api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
- }
- else if(tagID != null)
- {
- api_endpoint += "/" + GLib.Uri.escape_string(tagID);
- }
- var response = m_connection.send_request(api_endpoint, message_string);
-
- if(response.status != 200)
- {
+ if(continuation != null)
+ {
+ message_string += "&c=" + continuation;
+ }
+ var response = m_connection.send_request("stream/items/ids", message_string);
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("updateArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ if(!root.has_member("itemRefs"))
+ {
+ return null;
+ }
+ var array = root.get_array_member("itemRefs");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ ids.add(object.get_string_member("id"));
+ }
+
+ if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+ {
+ return root.get_string_member("continuation");
+ }
+
return null;
}
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getArticles: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("items");
- uint length = array.get_length();
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++)
+
+ public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- id = id.substring(id.last_index_of_char('/')+1);
- var tags = new Gee.ArrayList<string>();
- bool marked = false;
- bool read = false;
- var cats = object.get_array_member("categories");
- uint cat_length = cats.get_length();
-
- for (uint j = 0; j < cat_length; j++)
+ var message_string = "n=" + count.to_string();
+
+ if(whatToGet == ArticleStatus.UNREAD)
{
- string cat = cats.get_string_element(j);
- if(cat.has_suffix("com.google/starred"))
- {
- marked = true;
- }
- else if(cat.has_suffix("com.google/read"))
- {
- read = true;
- }
- else if(cat.contains("/label/") && db.getTagName(cat) != null)
- {
- tags.add(cat);
- }
+ message_string += "&xt=user/-/state/com.google/read";
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+ if(whatToGet == ArticleStatus.READ)
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ message_string += "&it=user/-/state/com.google/read";
+ }
+ else if(whatToGet == ArticleStatus.MARKED)
+ {
+ message_string += "&it=user/-/state/com.google/starred";
+ }
+
+ if(continuation != null)
+ {
+ message_string += "&c=" + continuation;
+ }
+
+
+ string api_endpoint = "stream/contents";
+ if(feed_id != null)
+ {
+ api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
+ }
+ else if(tagID != null)
+ {
+ api_endpoint += "/" + GLib.Uri.escape_string(tagID);
+ }
+ var response = m_connection.send_request(api_endpoint, message_string);
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getArticles: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("items");
+ uint length = array.get_length();
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ id = id.substring(id.last_index_of_char('/')+1);
+ var tags = new Gee.ArrayList<string>();
+ bool marked = false;
+ bool read = false;
+ var cats = object.get_array_member("categories");
+ uint cat_length = cats.get_length();
+
+ for (uint j = 0; j < cat_length; j++)
{
- mediaCount = attachments.get_length();
+ string cat = cats.get_string_element(j);
+ if(cat.has_suffix("com.google/starred"))
+ {
+ marked = true;
+ }
+ else if(cat.has_suffix("com.google/read"))
+ {
+ read = true;
+ }
+ else if(cat.contains("/label/") && db.getTagName(cat) != null)
+ {
+ tags.add(cat);
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
{
- var attachment = attachments.get_object_element(j);
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(attachment.get_string_member("type")))
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(attachment.get_string_member("type")))
);
+ }
}
- }
-
- articles.add(new Article(
- id,
- object.get_string_member("title"),
- object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
- object.get_object_member("origin").get_string_member("streamId"),
- read ? ArticleStatus.READ : ArticleStatus.UNREAD,
- marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- object.get_object_member("summary").get_string_member("content"),
- null,
- object.get_string_member("author"),
- new DateTime.from_unix_local(object.get_int_member("published")),
- -1,
- tags,
- enclosures
- )
- );
- }
-
+
+ articles.add(new Article(
+ id,
+ object.get_string_member("title"),
+ object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+ object.get_object_member("origin").get_string_member("streamId"),
+ read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+ marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ object.get_object_member("summary").get_string_member("content"),
+ null,
+ object.get_string_member("author"),
+ new DateTime.from_unix_local(object.get_int_member("published")),
+ -1,
+ tags,
+ enclosures
+ )
+ );
+ }
+
if(root.has_member("continuation") && root.get_string_member("continuation") != "")
{
return root.get_string_member("continuation");
}
-
+
return null;
}
@@ -442,9 +442,9 @@ public void edidTag(string articleIDs, string tagID, bool add = true)
{
message_string += "r=";
}
-
+
message_string += tagID;
-
+
var id_array = articleIDs.split(",");
foreach(string id in id_array)
{
@@ -482,40 +482,40 @@ public void renameTag(string tagID, string title)
public bool editSubscription(InoSubscriptionAction action, string[] feedID, string? title, string? add, string? remove)
{
var message_string = "ac=";
-
+
switch(action)
{
- case InoSubscriptionAction.EDIT:
+ case InoSubscriptionAction.EDIT:
message_string += "edit";
break;
- case InoSubscriptionAction.SUBSCRIBE:
+ case InoSubscriptionAction.SUBSCRIBE:
message_string += "subscribe";
break;
- case InoSubscriptionAction.UNSUBSCRIBE:
+ case InoSubscriptionAction.UNSUBSCRIBE:
message_string += "unsubscribe";
break;
}
-
+
foreach(string s in feedID) {
message_string += "&s=" + GLib.Uri.escape_string(s);
}
-
+
if(title != null)
{
message_string += "&t=" + title;
}
-
+
if(add != null)
{
message_string += "&a=" + add;
}
-
+
if(remove != null)
{
message_string += "&r=" + remove;
}
-
-
+
+
return m_connection.send_request("subscription/edit", message_string).status == 200;
}
}
diff --git a/plugins/backend/inoreader/InoReaderConnection.vala b/plugins/backend/inoreader/InoReaderConnection.vala
index b2c3f93f..ff321e93 100644
--- a/plugins/backend/inoreader/InoReaderConnection.vala
+++ b/plugins/backend/inoreader/InoReaderConnection.vala
@@ -14,160 +14,160 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.InoReaderConnection {
-private string m_api_username;
-private string m_api_code;
-private InoReaderUtils m_utils;
-private Soup.Session m_session;
-
-public InoReaderConnection(InoReaderUtils utils)
-{
- m_utils = utils;
- m_api_username = m_utils.getUser();
- m_api_code = m_utils.getAccessToken();
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
-}
-
-public LoginResponse getToken()
-{
- Logger.debug("InoReaderConnection: getToken()");
-
- var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
- string message_string = "code=" + m_utils.getApiCode()
- + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
- + "&client_id=" + InoReaderSecret.apiClientId
- + "&client_secret=" + InoReaderSecret.apiClientSecret
- + "&scope="
- + "&grant_type=authorization_code";
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- return LoginResponse.NO_CONNECTION;
- }
-
- string response = (string)message.response_body.flatten().data;
-
- try
+ private string m_api_username;
+ private string m_api_code;
+ private InoReaderUtils m_utils;
+ private Soup.Session m_session;
+
+ public InoReaderConnection(InoReaderUtils utils)
{
- var parser = new Json.Parser();
- parser.load_from_data(response, -1);
- var root = parser.get_root().get_object();
-
- string accessToken = root.get_string_member("access_token");
- int64 expires = (int)root.get_int_member("expires_in");
- string refreshToken = root.get_string_member("refresh_token");
- int64 now = (new DateTime.now_local()).to_unix();
-
- Logger.debug("access-token: " + accessToken);
- Logger.debug("expires in: " + expires.to_string());
- Logger.debug("refresh-token: " + refreshToken);
- Logger.debug("now: " + now.to_string());
-
- m_utils.setAccessToken(accessToken);
- m_utils.setExpiration((int)(now + expires));
- m_utils.setRefreshToken(refreshToken);
+ m_utils = utils;
+ m_api_username = m_utils.getUser();
+ m_api_code = m_utils.getAccessToken();
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
}
- catch(Error e)
+
+ public LoginResponse getToken()
{
- Logger.error("InoReaderConnection - getToken: Could not load message response");
- Logger.error(e.message);
- return LoginResponse.UNKNOWN_ERROR;
- }
-
- return LoginResponse.SUCCESS;
-}
-
-public LoginResponse refreshToken()
-{
- Logger.debug("InoReaderConnection: refreshToken()");
-
- var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
- string message_string = "client_id=" + InoReaderSecret.apiClientId
- + "&client_secret=" + InoReaderSecret.apiClientSecret
- + "&grant_type=refresh_token"
- + "&refresh_token=" + m_utils.getRefreshToken();
-
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
- {
- return LoginResponse.NO_CONNECTION;
- }
-
- string response = (string)message.response_body.flatten().data;
-
- try
- {
- var parser = new Json.Parser();
- parser.load_from_data(response, -1);
- var root = parser.get_root().get_object();
-
- if(!root.has_member("access_token"))
+ Logger.debug("InoReaderConnection: getToken()");
+
+ var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
+ string message_string = "code=" + m_utils.getApiCode()
+ + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
+ + "&client_id=" + InoReaderSecret.apiClientId
+ + "&client_secret=" + InoReaderSecret.apiClientSecret
+ + "&scope="
+ + "&grant_type=authorization_code";
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
{
- return getToken();
+ return LoginResponse.NO_CONNECTION;
}
-
- string accessToken = root.get_string_member("access_token");
- int64 expires = (int)root.get_int_member("expires_in");
- string refreshToken = root.get_string_member("refresh_token");
- int64 now = (new DateTime.now_local()).to_unix();
-
- Logger.debug("access-token: " + accessToken);
- Logger.debug("expires in: " + expires.to_string());
- Logger.debug("refresh-token: " + refreshToken);
- Logger.debug("now: " + now.to_string());
-
- m_utils.setAccessToken(accessToken);
- m_utils.setExpiration((int)(now + expires));
- m_utils.setRefreshToken(refreshToken);
- }
- catch(Error e)
- {
- Logger.error("InoReaderConnection - getToken: Could not load message response");
- Logger.error(e.message);
- return LoginResponse.UNKNOWN_ERROR;
+
+ string response = (string)message.response_body.flatten().data;
+
+ try
+ {
+ var parser = new Json.Parser();
+ parser.load_from_data(response, -1);
+ var root = parser.get_root().get_object();
+
+ string accessToken = root.get_string_member("access_token");
+ int64 expires = (int)root.get_int_member("expires_in");
+ string refreshToken = root.get_string_member("refresh_token");
+ int64 now = (new DateTime.now_local()).to_unix();
+
+ Logger.debug("access-token: " + accessToken);
+ Logger.debug("expires in: " + expires.to_string());
+ Logger.debug("refresh-token: " + refreshToken);
+ Logger.debug("now: " + now.to_string());
+
+ m_utils.setAccessToken(accessToken);
+ m_utils.setExpiration((int)(now + expires));
+ m_utils.setRefreshToken(refreshToken);
+ }
+ catch(Error e)
+ {
+ Logger.error("InoReaderConnection - getToken: Could not load message response");
+ Logger.error(e.message);
+ return LoginResponse.UNKNOWN_ERROR;
+ }
+
+ return LoginResponse.SUCCESS;
}
-
- return LoginResponse.SUCCESS;
-}
-
-public Response send_request(string path, string? message_string = null)
-{
- return send_post_request(path, "POST", message_string);
-}
-
-private Response send_post_request(string path, string type, string? message_string = null)
-{
- if(!m_utils.accessTokenValid())
+
+ public LoginResponse refreshToken()
{
- refreshToken();
+ Logger.debug("InoReaderConnection: refreshToken()");
+
+ var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
+ string message_string = "client_id=" + InoReaderSecret.apiClientId
+ + "&client_secret=" + InoReaderSecret.apiClientSecret
+ + "&grant_type=refresh_token"
+ + "&refresh_token=" + m_utils.getRefreshToken();
+
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ return LoginResponse.NO_CONNECTION;
+ }
+
+ string response = (string)message.response_body.flatten().data;
+
+ try
+ {
+ var parser = new Json.Parser();
+ parser.load_from_data(response, -1);
+ var root = parser.get_root().get_object();
+
+ if(!root.has_member("access_token"))
+ {
+ return getToken();
+ }
+
+ string accessToken = root.get_string_member("access_token");
+ int64 expires = (int)root.get_int_member("expires_in");
+ string refreshToken = root.get_string_member("refresh_token");
+ int64 now = (new DateTime.now_local()).to_unix();
+
+ Logger.debug("access-token: " + accessToken);
+ Logger.debug("expires in: " + expires.to_string());
+ Logger.debug("refresh-token: " + refreshToken);
+ Logger.debug("now: " + now.to_string());
+
+ m_utils.setAccessToken(accessToken);
+ m_utils.setExpiration((int)(now + expires));
+ m_utils.setRefreshToken(refreshToken);
+ }
+ catch(Error e)
+ {
+ Logger.error("InoReaderConnection - getToken: Could not load message response");
+ Logger.error(e.message);
+ return LoginResponse.UNKNOWN_ERROR;
+ }
+
+ return LoginResponse.SUCCESS;
}
-
- var message = new Soup.Message(type, InoReaderSecret.base_uri + path);
-
- string inoauth = "Bearer " + m_utils.getAccessToken();
- message.request_headers.append("Authorization", inoauth);
-
- if(message_string != null)
+
+ public Response send_request(string path, string? message_string = null)
{
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ return send_post_request(path, "POST", message_string);
}
-
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ private Response send_post_request(string path, string type, string? message_string = null)
{
- Logger.warning("InoReaderConnection: unexpected response");
- Logger.debug(message.status_code.to_string());
+ if(!m_utils.accessTokenValid())
+ {
+ refreshToken();
+ }
+
+ var message = new Soup.Message(type, InoReaderSecret.base_uri + path);
+
+ string inoauth = "Bearer " + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", inoauth);
+
+ if(message_string != null)
+ {
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ }
+
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning("InoReaderConnection: unexpected response");
+ Logger.debug(message.status_code.to_string());
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
+
}
diff --git a/plugins/backend/inoreader/InoReaderInterface.vala b/plugins/backend/inoreader/InoReaderInterface.vala
index 60b383e5..5dfa2c18 100644
--- a/plugins/backend/inoreader/InoReaderInterface.vala
+++ b/plugins/backend/inoreader/InoReaderInterface.vala
@@ -14,420 +14,420 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.InoReaderInterface : FeedServerInterface {
-
-private InoReaderAPI m_api;
-private InoReaderUtils m_utils;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new InoReaderUtils(settings_backend);
- m_api = new InoReaderAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "http://www.inoreader.com/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-}
-
-public override string getID()
-{
- return "inoreader";
-}
-
-public override string iconName()
-{
- return "feed-service-inoreader";
-}
-
-public override string serviceName()
-{
- return "InoReader";
-}
-
-public override bool extractCode(string redirectURL)
-{
- if(redirectURL.has_prefix(InoReaderSecret.apiRedirectUri))
+
+ private InoReaderAPI m_api;
+ private InoReaderUtils m_utils;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- Logger.debug(redirectURL);
- int csrf_start = redirectURL.index_of("state=")+6;
- string csrf_code = redirectURL.substring(csrf_start);
- Logger.debug("InoReaderLoginWidget: csrf_code: " + csrf_code);
-
- if(csrf_code == InoReaderSecret.csrf_protection)
+ m_utils = new InoReaderUtils(settings_backend);
+ m_api = new InoReaderAPI(m_utils);
+ }
+
+ public override string getWebsite()
+ {
+ return "http://www.inoreader.com/";
+ }
+
+ public override BackendFlags getFlags()
+ {
+ return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
+ }
+
+ public override string getID()
+ {
+ return "inoreader";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-inoreader";
+ }
+
+ public override string serviceName()
+ {
+ return "InoReader";
+ }
+
+ public override bool extractCode(string redirectURL)
+ {
+ if(redirectURL.has_prefix(InoReaderSecret.apiRedirectUri))
+ {
+ Logger.debug(redirectURL);
+ int csrf_start = redirectURL.index_of("state=")+6;
+ string csrf_code = redirectURL.substring(csrf_start);
+ Logger.debug("InoReaderLoginWidget: csrf_code: " + csrf_code);
+
+ if(csrf_code == InoReaderSecret.csrf_protection)
+ {
+ int start = redirectURL.index_of("code=")+5;
+ int end = redirectURL.index_of("&", start);
+ string code = redirectURL.substring(start, end-start);
+ m_utils.setApiCode(code);
+ Logger.debug("InoReaderLoginWidget: set inoreader-api-code: " + code);
+ GLib.Thread.usleep(500000);
+ return true;
+ }
+
+ Logger.error("InoReaderLoginWidget: csrf_code mismatch");
+ }
+ else
{
- int start = redirectURL.index_of("code=")+5;
- int end = redirectURL.index_of("&", start);
- string code = redirectURL.substring(start, end-start);
- m_utils.setApiCode(code);
- Logger.debug("InoReaderLoginWidget: set inoreader-api-code: " + code);
- GLib.Thread.usleep(500000);
- return true;
+ Logger.warning("InoReaderLoginWidget: wrong redirect_uri");
}
-
- Logger.error("InoReaderLoginWidget: csrf_code mismatch");
+
+ return false;
}
- else
+
+ public override string buildLoginURL()
{
- Logger.warning("InoReaderLoginWidget: wrong redirect_uri");
+ return "https://www.inoreader.com/oauth2/auth"
+ + "?client_id=" + InoReaderSecret.apiClientId
+ + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
+ + "&response_type=code"
+ + "&scope=read+write"
+ + "&state=" + InoReaderSecret.csrf_protection;
}
-
- return false;
-}
-
-public override string buildLoginURL()
-{
- return "https://www.inoreader.com/oauth2/auth"
- + "?client_id=" + InoReaderSecret.apiClientId
- + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
- + "&response_type=code"
- + "&scope=read+write"
- + "&state=" + InoReaderSecret.csrf_protection;
-}
-
-public override bool needWebLogin()
-{
- return true;
-}
-
-public override bool supportTags()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-inoreader-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return "http://www.inoreader.com/";
-}
-
-public override string uncategorizedID()
-{
- return "";
-}
-
-public override bool hideCategoryWhenEmpty(string cadID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return true;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- if(read == ArticleStatus.READ)
+
+ public override bool needWebLogin()
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ return true;
}
- else
+
+ public override bool supportTags()
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+ return true;
}
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override bool doInitSync()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ return true;
}
- else
+
+ public override string symbolicIcon()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ return "feed-service-inoreader-symbolic";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markAsRead(feedID);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markAsRead(catID);
-}
-
-public override void markAllItemsRead()
-{
- var db = DataBase.readOnly();
- var categories = db.read_categories();
- foreach(Category cat in categories)
+
+ public override string accountName()
{
- m_api.markAsRead(cat.getCatID());
+ return m_utils.getUser();
}
-
- var feeds = db.read_feeds_without_cat();
- foreach(Feed feed in feeds)
+
+ public override string getServerURL()
{
- m_api.markAsRead(feed.getFeedID());
+ return "http://www.inoreader.com/";
}
- m_api.markAsRead();
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, true);
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, false);
-}
-
-public override string createTag(string caption)
-{
- return m_api.composeTagID(caption);
-}
-
-public override void deleteTag(string tagID)
-{
- m_api.deleteTag(tagID);
-}
-
-public override void renameTag(string tagID, string title)
-{
- m_api.renameTag(tagID, title);
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- bool success = false;
- feedID = "feed/" + feedURL;
- errmsg = "";
-
- if(catID == null && newCatName != null)
+
+ public override string uncategorizedID()
{
- string newCatID = m_api.composeTagID(newCatName);
- success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID, null);
+ return "";
}
- else
+
+ public override bool hideCategoryWhenEmpty(string cadID)
{
- success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID, null);
+ return false;
}
-
- if(!success)
+
+ public override bool supportCategories()
{
- errmsg = "Inoreader could not add %s";
+ return true;
}
-
- return success;
-}
-
-public override void addFeeds(Gee.List<Feed> feeds)
-{
- string cat = "";
- string[] urls = {};
-
- foreach(Feed f in feeds)
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
{
- if(f.getCatIDs()[0] != cat)
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return true;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ if(read == ArticleStatus.READ)
{
- m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
- urls = {};
- cat = f.getCatIDs()[0];
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ }
+ else
+ {
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
}
-
- urls += "feed/" + f.getXmlUrl();
}
-
- m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.UNSUBSCRIBE, {feedID}, null, null, null);
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, title, null, null);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.composeTagID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameTag(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.deleteTag(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getFeeds(feeds))
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(marked == ArticleStatus.MARKED)
{
- return false;
+ m_api.edidTag(articleID, "user/-/state/com.google/starred");
}
-
- if(m_api.getCategoriesAndTags(feeds, categories, tags))
+ else
{
- return true;
+ m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
}
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getTotalUnread();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- if(whatToGet == ArticleStatus.READ)
+
+ public override bool alwaysSetReadByID()
{
- return;
+ return false;
}
- else if(whatToGet == ArticleStatus.ALL)
+
+ public override void setFeedRead(string feedID)
{
- var unreadIDs = new Gee.LinkedList<string>();
- string? continuation = null;
- int left = 4*count;
-
- while(left > 0)
+ m_api.markAsRead(feedID);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markAsRead(catID);
+ }
+
+ public override void markAllItemsRead()
+ {
+ var db = DataBase.readOnly();
+ var categories = db.read_categories();
+ foreach(Category cat in categories)
{
- if(cancellable != null && cancellable.is_cancelled())
+ m_api.markAsRead(cat.getCatID());
+ }
+
+ var feeds = db.read_feeds_without_cat();
+ foreach(Feed feed in feeds)
+ {
+ m_api.markAsRead(feed.getFeedID());
+ }
+ m_api.markAsRead();
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, true);
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, false);
+ }
+
+ public override string createTag(string caption)
+ {
+ return m_api.composeTagID(caption);
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ m_api.deleteTag(tagID);
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ m_api.renameTag(tagID, title);
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ bool success = false;
+ feedID = "feed/" + feedURL;
+ errmsg = "";
+
+ if(catID == null && newCatName != null)
+ {
+ string newCatID = m_api.composeTagID(newCatName);
+ success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID, null);
+ }
+ else
+ {
+ success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID, null);
+ }
+
+ if(!success)
+ {
+ errmsg = "Inoreader could not add %s";
+ }
+
+ return success;
+ }
+
+ public override void addFeeds(Gee.List<Feed> feeds)
+ {
+ string cat = "";
+ string[] urls = {};
+
+ foreach(Feed f in feeds)
+ {
+ if(f.getCatIDs()[0] != cat)
{
- return;
+ m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
+ urls = {};
+ cat = f.getCatIDs()[0];
}
-
- if(left > 1000)
+
+ urls += "feed/" + f.getXmlUrl();
+ }
+
+ m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.UNSUBSCRIBE, {feedID}, null, null, null);
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, title, null, null);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.composeTagID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameTag(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ return;
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.deleteTag(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getFeeds(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
{
- continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
- left -= 1000;
+ return false;
}
- else
+
+ if(m_api.getCategoriesAndTags(feeds, categories, tags))
{
- m_api.updateArticles(unreadIDs, left, continuation);
- left = 0;
+ return true;
}
}
- DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
- updateArticleList();
+
+ return false;
}
-
- var articles = new Gee.LinkedList<Article>();
- string? continuation = null;
- int left = count;
- string? inoreader_feedID = (isTagID) ? null : feedID;
- string? inoreader_tagID = (isTagID) ? feedID : null;
-
- while(left > 0)
+
+ public override int getUnreadCount()
{
- if(cancellable != null && cancellable.is_cancelled())
+ return m_api.getTotalUnread();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ if(whatToGet == ArticleStatus.READ)
{
return;
}
-
- if(left > 1000)
+ else if(whatToGet == ArticleStatus.ALL)
{
- continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
- left -= 1000;
+ var unreadIDs = new Gee.LinkedList<string>();
+ string? continuation = null;
+ int left = 4*count;
+
+ while(left > 0)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
+ left -= 1000;
+ }
+ else
+ {
+ m_api.updateArticles(unreadIDs, left, continuation);
+ left = 0;
+ }
+ }
+ DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+ updateArticleList();
}
- else
+
+ var articles = new Gee.LinkedList<Article>();
+ string? continuation = null;
+ int left = count;
+ string? inoreader_feedID = (isTagID) ? null : feedID;
+ string? inoreader_tagID = (isTagID) ? feedID : null;
+
+ while(left > 0)
{
- continuation = m_api.getArticles(articles, left, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
- left = 0;
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+ left -= 1000;
+ }
+ else
+ {
+ continuation = m_api.getArticles(articles, left, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+ left = 0;
+ }
}
+ writeArticles(articles);
}
- writeArticles(articles);
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/inoreader/InoReaderUtils.vala b/plugins/backend/inoreader/InoReaderUtils.vala
index 9ab65306..fa7c789d 100644
--- a/plugins/backend/inoreader/InoReaderUtils.vala
+++ b/plugins/backend/inoreader/InoReaderUtils.vala
@@ -14,126 +14,126 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.InoReaderSecret {
-const string base_uri = "https://www.inoreader.com/reader/api/0/";
-const string apiClientId = "1000001384";
-const string apiClientSecret = "3AA9IyNTFL_Mgu77WPpWbawx9loERRdf";
-const string apiRedirectUri = "http://localhost";
-const string csrf_protection = "123456";
+ const string base_uri = "https://www.inoreader.com/reader/api/0/";
+ const string apiClientId = "1000001384";
+ const string apiClientSecret = "3AA9IyNTFL_Mgu77WPpWbawx9loERRdf";
+ const string apiRedirectUri = "http://localhost";
+ const string csrf_protection = "123456";
}
public class FeedReader.InoReaderUtils : GLib.Object {
-
-private GLib.Settings m_settings;
-
-public InoReaderUtils(GLib.SettingsBackend? settings_backend)
-{
- if(settings_backend != null)
+
+ private GLib.Settings m_settings;
+
+ public InoReaderUtils(GLib.SettingsBackend? settings_backend)
{
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.inoreader", settings_backend);
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.inoreader", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.inoreader");
+ }
}
- else
+
+ public string getUser()
{
- m_settings = new GLib.Settings("org.gnome.feedreader.inoreader");
+ return Utils.gsettingReadString(m_settings, "username");
}
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getRefreshToken()
-{
- return Utils.gsettingReadString(m_settings, "refresh-token");
-}
-
-public void setRefreshToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "refresh-token", token);
-}
-
-public string getAccessToken()
-{
- return Utils.gsettingReadString(m_settings, "access-token");
-}
-
-public void setAccessToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "access-token", token);
-}
-
-public string getApiCode()
-{
- return Utils.gsettingReadString(m_settings, "api-code");
-}
-
-public void setApiCode(string code)
-{
- Utils.gsettingWriteString(m_settings, "api-code", code);
-}
-
-public int getExpiration()
-{
- return m_settings.get_int("access-token-expires");
-}
-
-public void setExpiration(int seconds)
-{
- m_settings.set_int("access-token-expires", seconds);
-}
-
-public string getUserID()
-{
- return Utils.gsettingReadString(m_settings, "user-id");
-}
-
-public void setUserID(string id)
-{
- Utils.gsettingWriteString(m_settings, "user-id", id);
-}
-
-public string getEmail()
-{
- return Utils.gsettingReadString(m_settings, "user-email");
-}
-
-public void setEmail(string email)
-{
- Utils.gsettingWriteString(m_settings, "user-email", email);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
-}
-
-public bool accessTokenValid()
-{
- var now = new DateTime.now_local();
-
- if((int)now.to_unix() > getExpiration())
+
+ public void setUser(string user)
{
- Logger.warning("InoReaderUtils: access token expired");
- return false;
+ Utils.gsettingWriteString(m_settings, "username", user);
}
-
- return true;
-}
-
-public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
-{
- foreach(Feed feed in feeds)
+
+ public string getRefreshToken()
+ {
+ return Utils.gsettingReadString(m_settings, "refresh-token");
+ }
+
+ public void setRefreshToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "refresh-token", token);
+ }
+
+ public string getAccessToken()
+ {
+ return Utils.gsettingReadString(m_settings, "access-token");
+ }
+
+ public void setAccessToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "access-token", token);
+ }
+
+ public string getApiCode()
+ {
+ return Utils.gsettingReadString(m_settings, "api-code");
+ }
+
+ public void setApiCode(string code)
+ {
+ Utils.gsettingWriteString(m_settings, "api-code", code);
+ }
+
+ public int getExpiration()
+ {
+ return m_settings.get_int("access-token-expires");
+ }
+
+ public void setExpiration(int seconds)
{
- if(feed.hasCat(tagID))
+ m_settings.set_int("access-token-expires", seconds);
+ }
+
+ public string getUserID()
+ {
+ return Utils.gsettingReadString(m_settings, "user-id");
+ }
+
+ public void setUserID(string id)
+ {
+ Utils.gsettingWriteString(m_settings, "user-id", id);
+ }
+
+ public string getEmail()
+ {
+ return Utils.gsettingReadString(m_settings, "user-email");
+ }
+
+ public void setEmail(string email)
+ {
+ Utils.gsettingWriteString(m_settings, "user-email", email);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ }
+
+ public bool accessTokenValid()
+ {
+ var now = new DateTime.now_local();
+
+ if((int)now.to_unix() > getExpiration())
{
- return true;
+ Logger.warning("InoReaderUtils: access token expired");
+ return false;
}
+
+ return true;
+ }
+
+ public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+ {
+ foreach(Feed feed in feeds)
+ {
+ if(feed.hasCat(tagID))
+ {
+ return true;
+ }
+ }
+ return false;
}
- return false;
-}
}
diff --git a/plugins/backend/local/SuggestedFeedRow.vala b/plugins/backend/local/SuggestedFeedRow.vala
index 9a97e7fc..f1ac26b7 100644
--- a/plugins/backend/local/SuggestedFeedRow.vala
+++ b/plugins/backend/local/SuggestedFeedRow.vala
@@ -14,95 +14,95 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.SuggestedFeedRow : Gtk.ListBoxRow {
-
-private string m_name;
-private string m_url;
-private string m_category;
-private string m_desc;
-private Gtk.CheckButton m_check;
-
-public SuggestedFeedRow(string url, string iconURL, string category, string name, string desc, string lang)
-{
- m_name = name;
- m_url = url;
- m_category = category;
- m_desc = desc;
-
- var iconStack = new Gtk.Stack();
- iconStack.set_size_request(24, 24);
- iconStack.set_transition_duration(100);
- iconStack.set_transition_type(Gtk.StackTransitionType.CROSSFADE);
-
- var spinner = new Gtk.Spinner();
- iconStack.add_named(spinner, "spinner");
- spinner.start();
-
- m_check = new Gtk.CheckButton();
- var label = new Gtk.Label(name);
- label.get_style_context().add_class("h3");
- label.set_alignment(0.0f, 0.5f);
-
- var langLabel = new Gtk.Label(lang);
- langLabel.opacity = 0.7;
- langLabel.set_alignment(1.0f, 0.5f);
- langLabel.get_style_context().add_class("preview");
-
- var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box.margin_top = 5;
- box.margin_bottom = 5;
- box.pack_start(m_check, false, false, 10);
- box.pack_start(iconStack, false, false, 10);
- box.pack_start(label, true, true, 10);
- box.pack_end(langLabel, false, false, 10);
- var box2 = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
- box2.pack_start(box);
- box2.pack_start(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
- this.add(box2);
- this.set_tooltip_text(m_desc);
- show_all();
-
- var uri = new Soup.URI(url);
- var fakeFeed = new Feed(uri.get_host(), null, null, 0);
- load_favicon.begin(iconStack, fakeFeed, iconURL, (obj, res) => {
+
+ private string m_name;
+ private string m_url;
+ private string m_category;
+ private string m_desc;
+ private Gtk.CheckButton m_check;
+
+ public SuggestedFeedRow(string url, string iconURL, string category, string name, string desc, string lang)
+ {
+ m_name = name;
+ m_url = url;
+ m_category = category;
+ m_desc = desc;
+
+ var iconStack = new Gtk.Stack();
+ iconStack.set_size_request(24, 24);
+ iconStack.set_transition_duration(100);
+ iconStack.set_transition_type(Gtk.StackTransitionType.CROSSFADE);
+
+ var spinner = new Gtk.Spinner();
+ iconStack.add_named(spinner, "spinner");
+ spinner.start();
+
+ m_check = new Gtk.CheckButton();
+ var label = new Gtk.Label(name);
+ label.get_style_context().add_class("h3");
+ label.set_alignment(0.0f, 0.5f);
+
+ var langLabel = new Gtk.Label(lang);
+ langLabel.opacity = 0.7;
+ langLabel.set_alignment(1.0f, 0.5f);
+ langLabel.get_style_context().add_class("preview");
+
+ var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box.margin_top = 5;
+ box.margin_bottom = 5;
+ box.pack_start(m_check, false, false, 10);
+ box.pack_start(iconStack, false, false, 10);
+ box.pack_start(label, true, true, 10);
+ box.pack_end(langLabel, false, false, 10);
+ var box2 = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+ box2.pack_start(box);
+ box2.pack_start(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
+ this.add(box2);
+ this.set_tooltip_text(m_desc);
+ show_all();
+
+ var uri = new Soup.URI(url);
+ var fakeFeed = new Feed(uri.get_host(), null, null, 0);
+ load_favicon.begin(iconStack, fakeFeed, iconURL, (obj, res) => {
load_favicon.end(res);
});
-}
-
-private async void load_favicon(Gtk.Stack iconStack, Feed feed, string iconURL)
-{
- Gtk.Image? icon = null;
- var surface = yield FavIcon.for_feed(feed).get_surface();
- if(surface != null)
+ }
+
+ private async void load_favicon(Gtk.Stack iconStack, Feed feed, string iconURL)
{
- icon = new Gtk.Image.from_surface(surface);
+ Gtk.Image? icon = null;
+ var surface = yield FavIcon.for_feed(feed).get_surface();
+ if(surface != null)
+ {
+ icon = new Gtk.Image.from_surface(surface);
+ }
+ else
+ {
+ icon = new Gtk.Image.from_icon_name("feed-rss-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
+ }
+
+ iconStack.add_named(icon, "icon");
+ show_all();
+ iconStack.set_visible_child_name("icon");
}
- else
+
+ public bool checked()
{
- icon = new Gtk.Image.from_icon_name("feed-rss-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
+ return m_check.active;
+ }
+
+ public string getName()
+ {
+ return m_name;
+ }
+
+ public string getURL()
+ {
+ return m_url;
+ }
+
+ public string getCategory()
+ {
+ return m_category;
}
-
- iconStack.add_named(icon, "icon");
- show_all();
- iconStack.set_visible_child_name("icon");
-}
-
-public bool checked()
-{
- return m_check.active;
-}
-
-public string getName()
-{
- return m_name;
-}
-
-public string getURL()
-{
- return m_url;
-}
-
-public string getCategory()
-{
- return m_category;
-}
}
diff --git a/plugins/backend/local/TestLocalRSS.vala b/plugins/backend/local/TestLocalRSS.vala
index 60a9d419..4b7dc673 100644
--- a/plugins/backend/local/TestLocalRSS.vala
+++ b/plugins/backend/local/TestLocalRSS.vala
@@ -3,107 +3,107 @@ using FeedReader;
void main(string[] args)
{
Test.init(ref args);
-
+
Test.add_data_func ("/Rfc822/parseDate/Basic", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 2006 23:59:45 +0000");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/LowerCase", () => {
var date = Rfc822.parseDate("thu, 09 feb 2006 16:59:45 mst");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/UpperCase", () => {
var date = Rfc822.parseDate("THU, 09 FEB 2006 16:59:45 MST");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/LotsOfWhiteSpace", () => {
var date = Rfc822.parseDate(" \t\n Thu, \t\n 09 \t\n Feb \t\n 2006 \t\n 23:59:45 \t\n +0000 \t\n");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2000", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 00 23:59:45 +0000");
assert(new DateTime.utc(2000, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2006", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 06 23:59:45 +0000");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2049", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 49 23:59:45 +0000");
assert(new DateTime.utc(2049, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1950", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 50 23:59:45 +0000");
assert(new DateTime.utc(1950, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1956", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 56 23:59:45 +0000");
assert(new DateTime.utc(1956, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1999", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 99 23:59:45 +0000");
assert(new DateTime.utc(1999, 2, 9, 23, 59, 45).equal(date));
});
-
+
// Just in case we get RSS feeds made by Romans
Test.add_data_func ("/Rfc822/parseDate/ThreeDigitYear", () => {
var date = Rfc822.parseDate("Thu, 09 Feb 156 23:59:45 +0000");
assert(new DateTime.utc(156, 2, 9, 23, 59, 45).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/OnlyRequired", () => {
var date = Rfc822.parseDate("09 Feb 2006 23:59 +0000");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/OneDigitDay", () => {
var date = Rfc822.parseDate("9 Feb 2006 23:59 +0000");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/UnsupportedZone", () => {
var date = Rfc822.parseDate("09 Feb 2006 23:59 X");
assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingDay", () => {
var date = Rfc822.parseDate("Feb 2006 23:59 +0000");
assert(date == null);
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingMonth", () => {
var date = Rfc822.parseDate("09 2006 23:59 +0000");
assert(date == null);
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingYear", () => {
var date = Rfc822.parseDate("09 Feb 23:59 +0000");
assert(date == null);
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingHour", () => {
var date = Rfc822.parseDate("09 Feb 2006 59 +0000");
assert(date == null);
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingMinute", () => {
var date = Rfc822.parseDate("09 Feb 2006 23 +0000");
assert(date == null);
});
-
+
Test.add_data_func ("/Rfc822/parseDate/MissingZone", () => {
var date = Rfc822.parseDate("09 Feb 2006 23:59");
assert(date == null);
});
-
+
Test.run ();
}
diff --git a/plugins/backend/local/localInterface.vala b/plugins/backend/local/localInterface.vala
index c9aabad0..6a2d46d1 100644
--- a/plugins/backend/local/localInterface.vala
+++ b/plugins/backend/local/localInterface.vala
@@ -14,597 +14,597 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.localInterface : FeedServerInterface {
-
-private localUtils m_utils;
-private Soup.Session m_session;
-private Gtk.ListBox m_feedlist;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new localUtils();
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_session.timeout = 5;
-}
-
-public override string getWebsite()
-{
- return "http://jangernert.github.io/FeedReader/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-}
-
-public override string getID()
-{
- return "local";
-}
-
-public override string iconName()
-{
- return "feed-service-local";
-}
-
-public override string serviceName()
-{
- return "Local RSS";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var doneLabel = new Gtk.Label(_("Done"));
- var waitingLabel = new Gtk.Label(_("Adding Feeds"));
- var waitingSpinner = new Gtk.Spinner();
- var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
- waitingBox.pack_start(waitingSpinner, false, false, 0);
- waitingBox.pack_start(waitingLabel, true, false, 0);
- var loginStack = new Gtk.Stack();
- loginStack.add_named(doneLabel, "label");
- loginStack.add_named(waitingBox, "waiting");
- var loginButton = new Gtk.Button();
- loginButton.add(loginStack);
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => {
+
+ private localUtils m_utils;
+ private Soup.Session m_session;
+ private Gtk.ListBox m_feedlist;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+ {
+ m_utils = new localUtils();
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_session.timeout = 5;
+ }
+
+ public override string getWebsite()
+ {
+ return "http://jangernert.github.io/FeedReader/";
+ }
+
+ public override BackendFlags getFlags()
+ {
+ return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+ }
+
+ public override string getID()
+ {
+ return "local";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-local";
+ }
+
+ public override string serviceName()
+ {
+ return "Local RSS";
+ }
+
+ public override bool needWebLogin()
+ {
+ return false;
+ }
+
+ public override Gtk.Box? getWidget()
+ {
+ var doneLabel = new Gtk.Label(_("Done"));
+ var waitingLabel = new Gtk.Label(_("Adding Feeds"));
+ var waitingSpinner = new Gtk.Spinner();
+ var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+ waitingBox.pack_start(waitingSpinner, false, false, 0);
+ waitingBox.pack_start(waitingLabel, true, false, 0);
+ var loginStack = new Gtk.Stack();
+ loginStack.add_named(doneLabel, "label");
+ loginStack.add_named(waitingBox, "waiting");
+ var loginButton = new Gtk.Button();
+ loginButton.add(loginStack);
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => {
tryLogin();
loginButton.set_sensitive(false);
waitingSpinner.start();
loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
loginStack.set_visible_child_name("waiting");
});
- loginButton.show_all();
-
- var headlineLabel = new Gtk.Label("Recommended Feeds:");
- headlineLabel.get_style_context().add_class("h1");
- headlineLabel.set_justify(Gtk.Justification.CENTER);
-
- var loginLabel = new Gtk.Label("Fill your library with feeds. Here are some recommendations.");
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- m_feedlist = new Gtk.ListBox();
- m_feedlist.set_selection_mode(Gtk.SelectionMode.NONE);
- m_feedlist.set_sort_func(sortFunc);
- m_feedlist.set_header_func(headerFunc);
-
- try
- {
- uint8[] contents;
- var file = File.new_for_uri("resource:///org/gnome/FeedReader/recommendedFeeds.json");
- file.load_contents(null, out contents, null);
-
- var parser = new Json.Parser();
- parser.load_from_data((string)contents);
-
- Json.Array array = parser.get_root().get_array();
-
- for (int i = 0; i < array.get_length (); i++)
+ loginButton.show_all();
+
+ var headlineLabel = new Gtk.Label("Recommended Feeds:");
+ headlineLabel.get_style_context().add_class("h1");
+ headlineLabel.set_justify(Gtk.Justification.CENTER);
+
+ var loginLabel = new Gtk.Label("Fill your library with feeds. Here are some recommendations.");
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ m_feedlist = new Gtk.ListBox();
+ m_feedlist.set_selection_mode(Gtk.SelectionMode.NONE);
+ m_feedlist.set_sort_func(sortFunc);
+ m_feedlist.set_header_func(headerFunc);
+
+ try
{
- Json.Object object = array.get_object_element(i);
-
- m_feedlist.add(
- new SuggestedFeedRow(
- object.get_string_member("url"),
- object.get_string_member("icon"),
- object.get_string_member("category"),
- object.get_string_member("name"),
- object.get_string_member("description"),
- object.get_string_member("language")
+ uint8[] contents;
+ var file = File.new_for_uri("resource:///org/gnome/FeedReader/recommendedFeeds.json");
+ file.load_contents(null, out contents, null);
+
+ var parser = new Json.Parser();
+ parser.load_from_data((string)contents);
+
+ Json.Array array = parser.get_root().get_array();
+
+ for (int i = 0; i < array.get_length (); i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ m_feedlist.add(
+ new SuggestedFeedRow(
+ object.get_string_member("url"),
+ object.get_string_member("icon"),
+ object.get_string_member("category"),
+ object.get_string_member("name"),
+ object.get_string_member("description"),
+ object.get_string_member("language")
)
);
+ }
}
+ catch(GLib.Error e)
+ {
+ Logger.error("localLoginWidget: loading json filed");
+ Logger.error(e.message);
+ }
+
+ var scroll = new Gtk.ScrolledWindow(null, null);
+ scroll.set_size_request(450, 0);
+ scroll.set_halign(Gtk.Align.CENTER);
+ scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+ scroll.add(m_feedlist);
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+ box.margin = 50;
+ box.valign = Gtk.Align.FILL;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(headlineLabel, false, false, 0);
+ box.pack_start(loginLabel, false, false, 2);
+ box.pack_start(scroll, true, true, 20);
+ box.pack_end(loginButton, false, false, 0);
+ return box;
}
- catch(GLib.Error e)
+
+ public override async void postLoginAction()
{
- Logger.error("localLoginWidget: loading json filed");
- Logger.error(e.message);
- }
-
- var scroll = new Gtk.ScrolledWindow(null, null);
- scroll.set_size_request(450, 0);
- scroll.set_halign(Gtk.Align.CENTER);
- scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
- scroll.add(m_feedlist);
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
- box.margin = 50;
- box.valign = Gtk.Align.FILL;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(headlineLabel, false, false, 0);
- box.pack_start(loginLabel, false, false, 2);
- box.pack_start(scroll, true, true, 20);
- box.pack_end(loginButton, false, false, 0);
- return box;
-}
-
-public override async void postLoginAction()
-{
- SourceFunc callback = postLoginAction.callback;
- new GLib.Thread<void*>(null, () => {
+ SourceFunc callback = postLoginAction.callback;
+ new GLib.Thread<void*>(null, () => {
var children = m_feedlist.get_children();
foreach(var r in children)
{
- var row = r as SuggestedFeedRow;
- if(row.checked())
- {
- FeedReaderBackend.get_default().addFeed(row.getURL(), row.getCategory(), false);
+ var row = r as SuggestedFeedRow;
+ if(row.checked())
+ {
+ FeedReaderBackend.get_default().addFeed(row.getURL(), row.getCategory(), false);
}
}
Idle.add((owned) callback);
return null;
});
- yield;
-}
-
-private int sortFunc(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
-{
- var r1 = row1 as SuggestedFeedRow;
- var r2 = row2 as SuggestedFeedRow;
-
- string cat1 = r1.getCategory();
- string cat2 = r2.getCategory();
-
- string name1 = r1.getName();
- string name2 = r2.getName();
-
- if(cat1 != cat2)
+ yield;
+ }
+
+ private int sortFunc(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
+ {
+ var r1 = row1 as SuggestedFeedRow;
+ var r2 = row2 as SuggestedFeedRow;
+
+ string cat1 = r1.getCategory();
+ string cat2 = r2.getCategory();
+
+ string name1 = r1.getName();
+ string name2 = r2.getName();
+
+ if(cat1 != cat2)
+ {
+ return cat1.collate(cat2);
+ }
+
+ return name1.collate(name2);
+ }
+
+ private void headerFunc(Gtk.ListBoxRow row, Gtk.ListBoxRow? before)
{
- return cat1.collate(cat2);
+ var r1 = row as SuggestedFeedRow;
+ string cat1 = r1.getCategory();
+
+ var label = new Gtk.Label(cat1);
+ label.get_style_context().add_class("bold");
+ label.margin_top = 20;
+ label.margin_bottom = 5;
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+ box.pack_start(label, true, true, 0);
+ box.pack_end(new Gtk.Separator(Gtk.Orientation.HORIZONTAL), false, false, 0);
+ box.show_all();
+
+ if(before == null)
+ {
+ row.set_header(box);
+ return;
+ }
+
+ var r2 = before as SuggestedFeedRow;
+ string cat2 = r2.getCategory();
+
+ if(cat1 != cat2)
+ {
+ row.set_header(box);
+ }
}
-
- return name1.collate(name2);
-}
-
-private void headerFunc(Gtk.ListBoxRow row, Gtk.ListBoxRow? before)
-{
- var r1 = row as SuggestedFeedRow;
- string cat1 = r1.getCategory();
-
- var label = new Gtk.Label(cat1);
- label.get_style_context().add_class("bold");
- label.margin_top = 20;
- label.margin_bottom = 5;
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
- box.pack_start(label, true, true, 0);
- box.pack_end(new Gtk.Separator(Gtk.Orientation.HORIZONTAL), false, false, 0);
- box.show_all();
-
- if(before == null)
+
+
+ public override bool supportTags()
+ {
+ return true;
+ }
+
+ public override bool doInitSync()
+ {
+ return false;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-local-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return "Local RSS";
+ }
+
+ public override string getServerURL()
+ {
+ return "http://localhost/";
+ }
+
+ public override string uncategorizedID()
+ {
+ return "0";
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return false;
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return true;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return false;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return false;
+ }
+
+ public override void resetAccount()
{
- row.set_header(box);
return;
}
-
- var r2 = before as SuggestedFeedRow;
- string cat2 = r2.getCategory();
-
- if(cat1 != cat2)
+
+ public override bool useMaxArticles()
{
- row.set_header(box);
+ return true;
}
-}
-
-
-public override bool supportTags()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return false;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-local-symbolic";
-}
-
-public override string accountName()
-{
- return "Local RSS";
-}
-
-public override string getServerURL()
-{
- return "http://localhost/";
-}
-
-public override string uncategorizedID()
-{
- return "0";
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return true;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return false;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return false;
-}
-
-public override void resetAccount()
-{
- return;
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return LoginResponse.SUCCESS;
-}
-
-public override bool serverAvailable()
-{
- return Utils.ping("https://duckduckgo.com/");
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- return;
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- return;
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- return;
-}
-
-public override void setCategoryRead(string catID)
-{
- return;
-}
-
-public override void markAllItemsRead()
-{
- return;
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- return;
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- string tagID = "1";
-
- var db = DataBase.readOnly();
- if(!db.isTableEmpty("tags"))
+
+ public override LoginResponse login()
{
- tagID = (int.parse(db.getMaxID("tags", "tagID")) + 1).to_string();
+ return LoginResponse.SUCCESS;
}
-
- Logger.info("createTag: ID = " + tagID);
- return tagID;
-}
-
-public override void deleteTag(string tagID)
-{
- return;
-}
-
-public override void renameTag(string tagID, string title)
-{
- return;
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- var catIDs = new Gee.ArrayList<string>();
- var db = DataBase.writeAccess();
- if(catID == null && newCatName != null)
+
+ public override bool serverAvailable()
{
- string cID = createCategory(newCatName, null);
- var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
- db.write_categories(ListUtils.single(cat));
- catIDs.add(cID);
+ return Utils.ping("https://duckduckgo.com/");
}
- else if(catID != null && newCatName == null)
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
{
- catIDs.add(catID);
+ return;
}
- else
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
{
- catIDs.add("0");
+ return;
}
-
- feedID = Uuid.string_random();
-
- Logger.info(@"addFeed: ID = $feedID");
- Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
-
- if(feed != null)
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ return;
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ return;
+ }
+
+ public override void markAllItemsRead()
{
- if(!db.feed_exists(feed.getURL()))
+ return;
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override string createTag(string caption)
+ {
+ string tagID = "1";
+
+ var db = DataBase.readOnly();
+ if(!db.isTableEmpty("tags"))
{
- db.write_feeds(ListUtils.single(feed));
- return true;
+ tagID = (int.parse(db.getMaxID("tags", "tagID")) + 1).to_string();
}
+
+ Logger.info("createTag: ID = " + tagID);
+ return tagID;
}
-
- return false;
-}
-
-public override void addFeeds(Gee.List<Feed> feeds)
-{
- var finishedFeeds = new Gee.ArrayList<Feed>();
-
- foreach(Feed f in feeds)
+
+ public override void deleteTag(string tagID)
{
- string feedID = Uuid.string_random();
-
- string url = f.getXmlUrl();
- Logger.info(@"addFeed: url = $url, ID = $feedID");
- string errmsg = "";
- Feed? feed = m_utils.downloadFeed(m_session, url, feedID, f.getCatIDs(), out errmsg);
-
+ return;
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ return;
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ var catIDs = new Gee.ArrayList<string>();
+ var db = DataBase.writeAccess();
+ if(catID == null && newCatName != null)
+ {
+ string cID = createCategory(newCatName, null);
+ var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
+ db.write_categories(ListUtils.single(cat));
+ catIDs.add(cID);
+ }
+ else if(catID != null && newCatName == null)
+ {
+ catIDs.add(catID);
+ }
+ else
+ {
+ catIDs.add("0");
+ }
+
+ feedID = Uuid.string_random();
+
+ Logger.info(@"addFeed: ID = $feedID");
+ Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
+
if(feed != null)
{
- if(feed.getTitle() != "No Title")
+ if(!db.feed_exists(feed.getURL()))
{
- feed.setTitle(f.getTitle());
+ db.write_feeds(ListUtils.single(feed));
+ return true;
}
-
- finishedFeeds.add(feed);
+ }
+
+ return false;
+ }
+
+ public override void addFeeds(Gee.List<Feed> feeds)
+ {
+ var finishedFeeds = new Gee.ArrayList<Feed>();
+
+ foreach(Feed f in feeds)
+ {
+ string feedID = Uuid.string_random();
+
+ string url = f.getXmlUrl();
+ Logger.info(@"addFeed: url = $url, ID = $feedID");
+ string errmsg = "";
+ Feed? feed = m_utils.downloadFeed(m_session, url, feedID, f.getCatIDs(), out errmsg);
+
+ if(feed != null)
+ {
+ if(feed.getTitle() != "No Title")
+ {
+ feed.setTitle(f.getTitle());
+ }
+
+ finishedFeeds.add(feed);
+ }
+ else
+ {
+ Logger.error("Couldn't add Feed: " + f.getXmlUrl());
+ }
+ }
+
+ foreach(var feed in finishedFeeds)
+ {
+ Logger.debug("finishedFeed: " + feed.getTitle());
+ }
+
+ DataBase.writeAccess().write_feeds(finishedFeeds);
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ return;
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ return;
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ return;
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ string catID;
+
+ string? id = DataBase.readOnly().getCategoryID(title);
+ if(id == null)
+ {
+ catID = Uuid.string_random();
}
else
{
- Logger.error("Couldn't add Feed: " + f.getXmlUrl());
+ catID = id;
}
+
+ Logger.info(@"createCategory: title= $title ID = $catID");
+ return catID;
}
-
- foreach(var feed in finishedFeeds)
+
+ public override void renameCategory(string catID, string title)
{
- Logger.debug("finishedFeed: " + feed.getTitle());
+ return;
}
-
- DataBase.writeAccess().write_feeds(finishedFeeds);
-}
-
-public override void removeFeed(string feedID)
-{
- return;
-}
-
-public override void renameFeed(string feedID, string title)
-{
- return;
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- return;
-}
-
-public override string createCategory(string title, string? parentID)
-{
- string catID;
-
- string? id = DataBase.readOnly().getCategoryID(title);
- if(id == null)
+
+ public override void moveCategory(string catID, string newParentID)
{
- catID = Uuid.string_random();
+ return;
}
- else
+
+ public override void deleteCategory(string catID)
{
- catID = id;
+ return;
}
-
- Logger.info(@"createCategory: title= $title ID = $catID");
- return catID;
-}
-
-public override void renameCategory(string catID, string title)
-{
- return;
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- return;
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- return true;
-}
-
-public override int getUnreadCount()
-{
- return 0;
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- var db = DataBase.writeAccess();
- var feeds = db.read_feeds();
- var articles = new Gee.ArrayList<Article>();
- GLib.Mutex mutex = GLib.Mutex();
-
- try
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
{
- var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
+ return true;
+ }
+
+ public override int getUnreadCount()
+ {
+ return 0;
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ var db = DataBase.writeAccess();
+ var feeds = db.read_feeds();
+ var articles = new Gee.ArrayList<Article>();
+ GLib.Mutex mutex = GLib.Mutex();
+
+ try
+ {
+ var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
if(cancellable != null && cancellable.is_cancelled())
{
- return;
+ return;
}
-
+
Logger.debug("getArticles for feed: " + feed.getTitle());
string url = feed.getXmlUrl().escape("");
-
+
if(url == null || url == "" || GLib.Uri.parse_scheme(url) == null)
{
- Logger.error("no valid URL");
- return;
+ Logger.error("no valid URL");
+ return;
}
-
+
var msg = new Soup.Message("GET", url);
var session = new Soup.Session();
session.user_agent = Constants.USER_AGENT;
session.timeout = 5;
session.send_message(msg);
string xml = (string)msg.response_body.flatten().data;
-
+
// parse
Rss.Parser parser = new Rss.Parser();
try
{
- parser.load_from_data(xml, xml.length);
+ parser.load_from_data(xml, xml.length);
}
catch(GLib.Error e)
{
- Logger.error("localInterface.getArticles: %s".printf(e.message));
- return;
+ Logger.error("localInterface.getArticles: %s".printf(e.message));
+ return;
}
var doc = parser.get_document();
-
+
string? locale = null;
if(doc.encoding != null
- && doc.encoding != "")
+ && doc.encoding != "")
{
- locale = doc.encoding;
+ locale = doc.encoding;
}
-
+
Logger.debug("Got %u articles".printf(doc.get_items().length()));
var newArticles = new Gee.ArrayList<Article>();
foreach(Rss.Item item in doc.get_items())
{
- string? articleID = item.guid;
-
- if(articleID == null)
- {
- if(item.link == null)
- {
- Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
- continue;
+ string? articleID = item.guid;
+
+ if(articleID == null)
+ {
+ if(item.link == null)
+ {
+ Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
+ continue;
}
-
- articleID = item.link;
+
+ articleID = item.link;
}
-
- var date = Rfc822.parseDate(item.pub_date);
- if (date != null)
- {
- Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
+
+ var date = Rfc822.parseDate(item.pub_date);
+ if (date != null)
+ {
+ Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
}
- else
- {
- if (item.pub_date != null)
- {
- Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
+ else
+ {
+ if (item.pub_date != null)
+ {
+ Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
}
- date = new DateTime.now_local();
+ date = new DateTime.now_local();
}
-
- //Logger.info("Got content: " + item.description);
- string? content = m_utils.convert(item.description, locale);
- //Logger.info("Converted to: " + item.description);
- if(content == null)
- {
- content = _("Nothing to read here.");
+
+ //Logger.info("Got content: " + item.description);
+ string? content = m_utils.convert(item.description, locale);
+ //Logger.info("Converted to: " + item.description);
+ if(content == null)
+ {
+ content = _("Nothing to read here.");
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
-
- if(item.enclosure_url != null)
- {
- // FIXME: check what type of media we actually got
- enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+
+ if(item.enclosure_url != null)
+ {
+ // FIXME: check what type of media we actually got
+ enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
}
-
- string articleURL = item.link;
- if(articleURL.has_prefix("/"))
- {
- articleURL = feed.getURL() + articleURL.substring(1);
+
+ string articleURL = item.link;
+ if(articleURL.has_prefix("/"))
+ {
+ articleURL = feed.getURL() + articleURL.substring(1);
}
-
- var article = new Article(
+
+ var article = new Article(
articleID,
(item.title != null) ? m_utils.convert(item.title, locale) : null,
articleURL,
@@ -618,51 +618,51 @@ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? s
0,
null,
enclosures
- );
-
- Logger.debug("Got new article: " + article.getTitle());
-
- newArticles.add(article);
+ );
+
+ Logger.debug("Got new article: " + article.getTitle());
+
+ newArticles.add(article);
}
mutex.lock();
articles.add_all(newArticles);
mutex.unlock();
}, (int)GLib.get_num_processors(), true);
-
- foreach(Feed feed in feeds)
- {
- try
- {
- threads.add(feed);
- }
- catch(GLib.Error e)
+
+ foreach(Feed feed in feeds)
{
- Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
+ try
+ {
+ threads.add(feed);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
+ }
}
+
+ bool immediate = false; // allow to queue up additional tasks
+ bool wait = true; // function will block until all tasks are done
+ ThreadPool.free((owned)threads, immediate, wait);
}
-
- bool immediate = false; // allow to queue up additional tasks
- bool wait = true; // function will block until all tasks are done
- ThreadPool.free((owned)threads, immediate, wait);
- }
- catch(Error e)
- {
- Logger.error("Error creating threads to download Feeds: " + e.message);
- }
-
- articles.sort((a, b) => {
+ catch(Error e)
+ {
+ Logger.error("Error creating threads to download Feeds: " + e.message);
+ }
+
+ articles.sort((a, b) => {
return strcmp(a.getArticleID(), b.getArticleID());
});
-
- if(articles.size > 0)
- {
- db.write_articles(articles);
- Logger.debug("localInterface: %i articles written".printf(articles.size));
- refreshFeedListCounter();
- updateArticleList();
+
+ if(articles.size > 0)
+ {
+ db.write_articles(articles);
+ Logger.debug("localInterface: %i articles written".printf(articles.size));
+ refreshFeedListCounter();
+ updateArticleList();
+ }
}
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/local/localUtils.vala b/plugins/backend/local/localUtils.vala
index b97e6c44..27a5b688 100644
--- a/plugins/backend/local/localUtils.vala
+++ b/plugins/backend/local/localUtils.vala
@@ -14,100 +14,100 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.localUtils : GLib.Object {
-
-public localUtils()
-{
-
-}
-
-public Feed? downloadFeed(Soup.Session session, string feed_url, string feedID, Gee.List<string> catIDs, out string errmsg)
-{
- var error = new StringBuilder(_("Failed to add feed"));
- error.append_printf(" %s\n", feed_url);
-
- var msg = new Soup.Message("GET", feed_url);
- if (msg == null)
+
+ public localUtils()
{
- error.append(_("Failed to parse URL."));
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
+
}
-
- uint status = session.send_message(msg);
- if(status < 100 || status >= 400)
+
+ public Feed? downloadFeed(Soup.Session session, string feed_url, string feedID, Gee.List<string> catIDs, out string errmsg)
{
- if(status < 100)
+ var error = new StringBuilder(_("Failed to add feed"));
+ error.append_printf(" %s\n", feed_url);
+
+ var msg = new Soup.Message("GET", feed_url);
+ if (msg == null)
{
- error.append(_("Network error connecting to the server."));
+ error.append(_("Failed to parse URL."));
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
}
- else
+
+ uint status = session.send_message(msg);
+ if(status < 100 || status >= 400)
{
- error.append(_("Got HTTP error code"));
- error.append_printf(" %u %s", status, Soup.Status.get_phrase(status));
+ if(status < 100)
+ {
+ error.append(_("Network error connecting to the server."));
+ }
+ else
+ {
+ error.append(_("Got HTTP error code"));
+ error.append_printf(" %u %s", status, Soup.Status.get_phrase(status));
+ }
+
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
}
-
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
- }
- string xml = (string)msg.response_body.flatten().data;
- string? url = null;
-
- // parse
- Rss.Parser parser = new Rss.Parser();
- try
- {
- parser.load_from_data(xml, xml.length);
- }
- catch(Error e)
- {
- error.append(_("Could not parse feed as RSS or ATOM."));
- errmsg = error.str;
- Logger.warning(errmsg);
- return null;
- }
-
- var doc = parser.get_document();
-
- if(doc.link != null
- && doc.link != "")
- {
- url = doc.link;
- }
-
- errmsg = "";
- return new Feed(
- feedID,
- doc.title,
- url,
- 0,
- catIDs,
- doc.image_url,
+ string xml = (string)msg.response_body.flatten().data;
+ string? url = null;
+
+ // parse
+ Rss.Parser parser = new Rss.Parser();
+ try
+ {
+ parser.load_from_data(xml, xml.length);
+ }
+ catch(Error e)
+ {
+ error.append(_("Could not parse feed as RSS or ATOM."));
+ errmsg = error.str;
+ Logger.warning(errmsg);
+ return null;
+ }
+
+ var doc = parser.get_document();
+
+ if(doc.link != null
+ && doc.link != "")
+ {
+ url = doc.link;
+ }
+
+ errmsg = "";
+ return new Feed(
+ feedID,
+ doc.title,
+ url,
+ 0,
+ catIDs,
+ doc.image_url,
feed_url);
-}
-
-public string? convert(string? text, string? locale)
-{
- if(text == null)
- {
- return null;
- }
-
- if(locale == null)
- {
- return text;
- }
-
- try
- {
- return GLib.convert(text, -1, "utf-8", locale);
}
- catch(ConvertError e)
+
+ public string? convert(string? text, string? locale)
{
- Logger.error(e.message);
+ if(text == null)
+ {
+ return null;
+ }
+
+ if(locale == null)
+ {
+ return text;
+ }
+
+ try
+ {
+ return GLib.convert(text, -1, "utf-8", locale);
+ }
+ catch(ConvertError e)
+ {
+ Logger.error(e.message);
+ }
+
+ return "";
}
-
- return "";
-}
}
diff --git a/plugins/backend/oldreader/oldreaderAPI.vala b/plugins/backend/oldreader/oldreaderAPI.vala
index d672f2e8..476caff0 100644
--- a/plugins/backend/oldreader/oldreaderAPI.vala
+++ b/plugins/backend/oldreader/oldreaderAPI.vala
@@ -14,393 +14,393 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OldReaderAPI : GLib.Object {
-
-public enum OldreaderSubscriptionAction {
- EDIT,
- SUBSCRIBE,
- UNSUBSCRIBE
-}
-
-private OldReaderConnection m_connection;
-private OldReaderUtils m_utils;
-private string m_userID;
-
-public OldReaderAPI(OldReaderUtils utils)
-{
- m_utils = utils;
- m_connection = new OldReaderConnection(m_utils);
-}
-
-public LoginResponse login()
-{
- if(m_utils.getAccessToken() == "")
- {
- var response = m_connection.getToken();
- if(response != LoginResponse.SUCCESS)
+
+ public enum OldreaderSubscriptionAction {
+ EDIT,
+ SUBSCRIBE,
+ UNSUBSCRIBE
+ }
+
+ private OldReaderConnection m_connection;
+ private OldReaderUtils m_utils;
+ private string m_userID;
+
+ public OldReaderAPI(OldReaderUtils utils)
+ {
+ m_utils = utils;
+ m_connection = new OldReaderConnection(m_utils);
+ }
+
+ public LoginResponse login()
+ {
+ if(m_utils.getAccessToken() == "")
{
- return response;
+ var response = m_connection.getToken();
+ if(response != LoginResponse.SUCCESS)
+ {
+ return response;
+ }
}
+ if(getUserID())
+ {
+ return LoginResponse.SUCCESS;
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
}
- if(getUserID())
- {
- return LoginResponse.SUCCESS;
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-public bool ping() {
- return Utils.ping("https://theoldreader.com/");
-}
-
-private bool getUserID()
-{
- Logger.debug("getUserID: getting user info");
- var response = m_connection.send_get_request("user-info?output=json");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getUserID: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- if(root.has_member("userId"))
- {
- m_userID = root.get_string_member("userId");
- m_utils.setUserID(m_userID);
- Logger.info("Oldreader: userID = " + m_userID);
-
- return true;
- }
-
- return false;
-}
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
-
- var response = m_connection.send_get_request("subscription/list?output=json");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
+
+ public bool ping() {
+ return Utils.ping("https://theoldreader.com/");
}
- catch(Error e)
+
+ private bool getUserID()
{
- Logger.error("getFeeds: Could not load message response");
- Logger.error(e.message);
+ Logger.debug("getUserID: getting user info");
+ var response = m_connection.send_get_request("user-info?output=json");
+
+ if(response.status != 200)
+ {
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getUserID: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ if(root.has_member("userId"))
+ {
+ m_userID = root.get_string_member("userId");
+ m_utils.setUserID(m_userID);
+ Logger.info("Oldreader: userID = " + m_userID);
+
+ return true;
+ }
+
return false;
}
- var root = parser.get_root().get_object();
- var array = root.get_array_member("subscriptions");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- Json.Object object = array.get_object_element(i);
-
- string feedID = object.get_string_member("id");
- string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
-
- uint catCount = object.get_array_member("categories").get_length();
- var categories = new Gee.ArrayList<string>();
- for(uint j = 0; j < catCount; ++j)
+
+ var response = m_connection.send_get_request("subscription/list?output=json");
+
+ if(response.status != 200)
{
- categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ return false;
}
-
- feeds.add(
- new Feed(
- feedID,
- object.get_string_member("title"),
- url,
- 0,
- categories,
- object.get_string_member("iconUrl")
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getFeeds: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("subscriptions");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+
+ string feedID = object.get_string_member("id");
+ string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+
+ uint catCount = object.get_array_member("categories").get_length();
+ var categories = new Gee.ArrayList<string>();
+ for(uint j = 0; j < catCount; ++j)
+ {
+ categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+ }
+
+ feeds.add(
+ new Feed(
+ feedID,
+ object.get_string_member("title"),
+ url,
+ 0,
+ categories,
+ object.get_string_member("iconUrl")
)
);
+ }
+ return true;
}
- return true;
-}
-
-public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-{
- var response = m_connection.send_get_request("tag/list?output=json");
-
- if(response.status != 200)
- {
- return false;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- return false;
- }
- var root = parser.get_root().get_object();
- var array = root.get_array_member("tags");
- uint length = array.get_length();
- int orderID = 0;
-
- for (uint i = 0; i < length; i++)
+
+ public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- int start = id.last_index_of_char('/') + 1;
- string title = id.substring(start);
-
- if(id.contains("/label/"))
+ var response = m_connection.send_get_request("tag/list?output=json");
+
+ if(response.status != 200)
{
- categories.add(
- new Category(
- id,
- title,
- 0,
- orderID,
- CategoryID.MASTER.to_string(),
- 1
+ return false;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ return false;
+ }
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("tags");
+ uint length = array.get_length();
+ int orderID = 0;
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ int start = id.last_index_of_char('/') + 1;
+ string title = id.substring(start);
+
+ if(id.contains("/label/"))
+ {
+ categories.add(
+ new Category(
+ id,
+ title,
+ 0,
+ orderID,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
- ++orderID;
+ ++orderID;
+ }
}
+ return true;
}
- return true;
-}
-
-
-public int getTotalUnread()
-{
- var response = m_connection.send_get_request("unread-count?output=json");
-
- if(response.status != 200)
- {
- return 0;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getTotalUnread: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("unreadcounts");
- uint length = array.get_length();
- int count = 0;
-
- for (uint i = 0; i < length; i++)
+
+
+ public int getTotalUnread()
{
- Json.Object object = array.get_object_element(i);
- if(object.get_string_member("id").has_prefix("feed/"))
+ var response = m_connection.send_get_request("unread-count?output=json");
+
+ if(response.status != 200)
{
- count += (int)object.get_int_member("count");
+ return 0;
}
-
- }
-
- Logger.debug("getTotalUnread %i".printf(count));
- return count;
-}
-
-
-public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
-{
- var message_string = "n=" + count.to_string();
- message_string += "&xt=user/-/state/com.google/read";
- if(continuation != null)
- {
- message_string += "&c=" + continuation;
- }
-
- var response = m_connection.send_get_request("stream/items/ids?output=json&"+message_string);
-
- if(response.status != 200)
- {
- return null;
- }
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("updateArticles: Could not load message response");
- Logger.error(e.message);
- return null;
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("itemRefs");
- uint length = array.get_length();
-
- for (uint i = 0; i < length; i++)
- {
- Json.Object object = array.get_object_element(i);
- ids.add(object.get_string_member("id"));
- }
-
- if(root.has_member("continuation") && root.get_string_member("continuation") != "")
- {
- return root.get_string_member("continuation");
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getTotalUnread: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("unreadcounts");
+ uint length = array.get_length();
+ int count = 0;
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ if(object.get_string_member("id").has_prefix("feed/"))
+ {
+ count += (int)object.get_int_member("count");
+ }
+
+ }
+
+ Logger.debug("getTotalUnread %i".printf(count));
+ return count;
}
-
- return null;
-}
-
-public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
-{
- var message_string = "n=" + count.to_string();
-
- if(whatToGet == ArticleStatus.UNREAD)
+
+
+ public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
{
+ var message_string = "n=" + count.to_string();
message_string += "&xt=user/-/state/com.google/read";
- }
- if(whatToGet == ArticleStatus.READ)
- {
- message_string += "&s=user/-/state/com.google/read";
- }
- else if(whatToGet == ArticleStatus.MARKED)
- {
- message_string += "&s=user/-/state/com.google/starred";
- }
-
- message_string += "&c=" + continuation;
-
-
- string api_endpoint = "stream/contents";
- if(feed_id != null)
- {
- api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
- }
- else if(tagID != null)
- {
- api_endpoint += "/" + GLib.Uri.escape_string(tagID);
- }
- var response = m_connection.send_get_request(api_endpoint+"?output=json&"+message_string);
-
- if(response.status != 200)
- {
+ if(continuation != null)
+ {
+ message_string += "&c=" + continuation;
+ }
+
+ var response = m_connection.send_get_request("stream/items/ids?output=json&"+message_string);
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("updateArticles: Could not load message response");
+ Logger.error(e.message);
+ return null;
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("itemRefs");
+ uint length = array.get_length();
+
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ ids.add(object.get_string_member("id"));
+ }
+
+ if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+ {
+ return root.get_string_member("continuation");
+ }
+
return null;
}
-
- var parser = new Json.Parser();
- try
- {
- parser.load_from_data(response.data, -1);
- }
- catch(Error e)
- {
- Logger.error("getCategoriesAndTags: Could not load message response");
- Logger.error(e.message);
- }
-
- var root = parser.get_root().get_object();
- var array = root.get_array_member("items");
- uint length = array.get_length();
-
- var db = DataBase.readOnly();
- for (uint i = 0; i < length; i++)
+
+ public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
{
- Json.Object object = array.get_object_element(i);
- string id = object.get_string_member("id");
- id = id.substring(id.last_index_of_char('/') + 1);
- bool marked = false;
- bool read = false;
- var cats = object.get_array_member("categories");
- uint cat_length = cats.get_length();
-
- var tags = new Gee.ArrayList<string>();
- for (uint j = 0; j < cat_length; j++)
+ var message_string = "n=" + count.to_string();
+
+ if(whatToGet == ArticleStatus.UNREAD)
{
- string cat = cats.get_string_element(j);
- if(cat.has_suffix("com.google/starred"))
- {
- marked = true;
- }
- else if(cat.has_suffix("com.google/read"))
- {
- read = true;
- }
- else if(cat.contains("/label/") && db.getTagName(cat) != null)
- {
- tags.add(cat);
- }
+ message_string += "&xt=user/-/state/com.google/read";
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(object.has_member("enclosure"))
+ if(whatToGet == ArticleStatus.READ)
{
- var attachments = object.get_array_member("enclosure");
-
- uint mediaCount = 0;
- if(attachments != null)
+ message_string += "&s=user/-/state/com.google/read";
+ }
+ else if(whatToGet == ArticleStatus.MARKED)
+ {
+ message_string += "&s=user/-/state/com.google/starred";
+ }
+
+ message_string += "&c=" + continuation;
+
+
+ string api_endpoint = "stream/contents";
+ if(feed_id != null)
+ {
+ api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
+ }
+ else if(tagID != null)
+ {
+ api_endpoint += "/" + GLib.Uri.escape_string(tagID);
+ }
+ var response = m_connection.send_get_request(api_endpoint+"?output=json&"+message_string);
+
+ if(response.status != 200)
+ {
+ return null;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response.data, -1);
+ }
+ catch(Error e)
+ {
+ Logger.error("getCategoriesAndTags: Could not load message response");
+ Logger.error(e.message);
+ }
+
+ var root = parser.get_root().get_object();
+ var array = root.get_array_member("items");
+ uint length = array.get_length();
+
+ var db = DataBase.readOnly();
+ for (uint i = 0; i < length; i++)
+ {
+ Json.Object object = array.get_object_element(i);
+ string id = object.get_string_member("id");
+ id = id.substring(id.last_index_of_char('/') + 1);
+ bool marked = false;
+ bool read = false;
+ var cats = object.get_array_member("categories");
+ uint cat_length = cats.get_length();
+
+ var tags = new Gee.ArrayList<string>();
+ for (uint j = 0; j < cat_length; j++)
{
- mediaCount = attachments.get_length();
+ string cat = cats.get_string_element(j);
+ if(cat.has_suffix("com.google/starred"))
+ {
+ marked = true;
+ }
+ else if(cat.has_suffix("com.google/read"))
+ {
+ read = true;
+ }
+ else if(cat.contains("/label/") && db.getTagName(cat) != null)
+ {
+ tags.add(cat);
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(object.has_member("enclosure"))
{
- var attachment = attachments.get_object_element(j);
- enclosures.add(
- new Enclosure(id, attachment.get_string_member("href"),
- EnclosureType.from_string(attachment.get_string_member("type")))
+ var attachments = object.get_array_member("enclosure");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(
+ new Enclosure(id, attachment.get_string_member("href"),
+ EnclosureType.from_string(attachment.get_string_member("type")))
);
+ }
}
- }
-
- articles.add(new Article(
- id,
- object.get_string_member("title"),
- object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
- object.get_object_member("origin").get_string_member("streamId"),
- read ? ArticleStatus.READ : ArticleStatus.UNREAD,
- marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- object.get_object_member("summary").get_string_member("content"),
- null,
- object.get_string_member("author"),
- new DateTime.from_unix_local(object.get_int_member("published")),
- -1,
- tags,
- enclosures
- )
- );
- }
-
+
+ articles.add(new Article(
+ id,
+ object.get_string_member("title"),
+ object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+ object.get_object_member("origin").get_string_member("streamId"),
+ read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+ marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ object.get_object_member("summary").get_string_member("content"),
+ null,
+ object.get_string_member("author"),
+ new DateTime.from_unix_local(object.get_int_member("published")),
+ -1,
+ tags,
+ enclosures
+ )
+ );
+ }
+
if(root.has_member("continuation") && root.get_string_member("continuation") != "")
{
return root.get_string_member("continuation");
}
-
+
return null;
}
@@ -416,7 +416,7 @@ public void edidTag(string articleID, string tagID, bool add = true)
{
message_string += "r=";
}
-
+
message_string += tagID;
message_string += "&i=" + articleID;
m_connection.send_post_request("edit-tag?output=json", message_string);
@@ -450,42 +450,42 @@ public void renameTag(string tagID, string title)
public bool editSubscription(OldreaderSubscriptionAction action, string[] feedID, string? title = null, string? add = null, string? remove = null)
{
var message_string = "ac=";
-
+
switch(action)
{
- case OldreaderSubscriptionAction.EDIT:
+ case OldreaderSubscriptionAction.EDIT:
message_string += "edit";
break;
- case OldreaderSubscriptionAction.SUBSCRIBE:
+ case OldreaderSubscriptionAction.SUBSCRIBE:
message_string += "subscribe";
break;
- case OldreaderSubscriptionAction.UNSUBSCRIBE:
+ case OldreaderSubscriptionAction.UNSUBSCRIBE:
message_string += "unsubscribe";
break;
}
-
+
foreach(string s in feedID) {
message_string += "&s=" + s;
}
-
+
if(title != null)
{
message_string += "&t=" + title;
}
-
+
if(add != null)
{
message_string += "&a=" + add;
}
-
+
if(remove != null)
{
message_string += "&r=" + remove;
}
-
-
+
+
var response = m_connection.send_post_request("subscription/edit?output=json", message_string);
-
+
return response.status == 200;
}
}
diff --git a/plugins/backend/oldreader/oldreaderConnection.vala b/plugins/backend/oldreader/oldreaderConnection.vala
index 5f039f18..ee203a02 100644
--- a/plugins/backend/oldreader/oldreaderConnection.vala
+++ b/plugins/backend/oldreader/oldreaderConnection.vala
@@ -14,100 +14,100 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OldReaderConnection {
-private string m_api_username;
-private string m_api_code;
-private string m_passwd;
-private OldReaderUtils m_utils;
-private Soup.Session m_session;
-
-public OldReaderConnection(OldReaderUtils utils)
-{
- m_utils = utils;
- m_api_username = m_utils.getUser();
- m_api_code = m_utils.getAccessToken();
- m_passwd = m_utils.getPasswd();
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
-}
-
-public LoginResponse getToken()
-{
- Logger.debug("OldReader Connection: getToken()");
-
- var message = new Soup.Message("POST", "https://theoldreader.com/accounts/ClientLogin/");
- string message_string = "Email=" + m_api_username
- + "&Passwd=" + m_passwd
- + "&service=reader"
- + "&accountType=HOSTED_OR_GOOGLE"
- + "&client=FeedReader";
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
- m_session.send_message(message);
-
- if(message.status_code != 200)
+ private string m_api_username;
+ private string m_api_code;
+ private string m_passwd;
+ private OldReaderUtils m_utils;
+ private Soup.Session m_session;
+
+ public OldReaderConnection(OldReaderUtils utils)
{
- return LoginResponse.NO_CONNECTION;
+ m_utils = utils;
+ m_api_username = m_utils.getUser();
+ m_api_code = m_utils.getAccessToken();
+ m_passwd = m_utils.getPasswd();
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
}
-
- string response = (string)message.response_body.flatten().data;
- try
+
+ public LoginResponse getToken()
{
- var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
- if(regex.match(response))
+ Logger.debug("OldReader Connection: getToken()");
+
+ var message = new Soup.Message("POST", "https://theoldreader.com/accounts/ClientLogin/");
+ string message_string = "Email=" + m_api_username
+ + "&Passwd=" + m_passwd
+ + "&service=reader"
+ + "&accountType=HOSTED_OR_GOOGLE"
+ + "&client=FeedReader";
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
{
- Logger.debug(@"Regex oldreader - $response");
- string split = regex.replace( response, -1,0,"");
- Logger.debug(@"authcode: $split");
- m_utils.setAccessToken(split.strip());
- return LoginResponse.SUCCESS;
+ return LoginResponse.NO_CONNECTION;
}
- else
+
+ string response = (string)message.response_body.flatten().data;
+ try
{
- Logger.debug(message_string);
- Logger.error(response);
- return LoginResponse.WRONG_LOGIN;
+ var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+ if(regex.match(response))
+ {
+ Logger.debug(@"Regex oldreader - $response");
+ string split = regex.replace( response, -1,0,"");
+ Logger.debug(@"authcode: $split");
+ m_utils.setAccessToken(split.strip());
+ return LoginResponse.SUCCESS;
+ }
+ else
+ {
+ Logger.debug(message_string);
+ Logger.error(response);
+ return LoginResponse.WRONG_LOGIN;
+ }
+ }
+ catch(Error e)
+ {
+ Logger.error("OldReaderConnection - getToken: Could not load message response");
+ Logger.error(e.message);
+ return LoginResponse.UNKNOWN_ERROR;
}
}
- catch(Error e)
+
+ public Response send_get_request(string path, string? message_string = null)
{
- Logger.error("OldReaderConnection - getToken: Could not load message response");
- Logger.error(e.message);
- return LoginResponse.UNKNOWN_ERROR;
+ return send_request(path, "GET", message_string);
}
-}
-
-public Response send_get_request(string path, string? message_string = null)
-{
- return send_request(path, "GET", message_string);
-}
-
-public Response send_post_request(string path, string? message_string = null)
-{
- return send_request(path, "POST", message_string);
-}
-
-private Response send_request(string path, string type, string? message_string = null)
-{
- var message = new Soup.Message(type, OldReaderSecret.base_uri + path);
-
- string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
- message.request_headers.append("Authorization", oldauth);
-
- if(message_string != null)
+
+ public Response send_post_request(string path, string? message_string = null)
{
- message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ return send_request(path, "POST", message_string);
}
-
- m_session.send_message(message);
-
- if(message.status_code != 200)
+
+ private Response send_request(string path, string type, string? message_string = null)
{
- Logger.warning("OldReaderConnection: unexpected response %u".printf(message.status_code));
+ var message = new Soup.Message(type, OldReaderSecret.base_uri + path);
+
+ string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+ message.request_headers.append("Authorization", oldauth);
+
+ if(message_string != null)
+ {
+ message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+ }
+
+ m_session.send_message(message);
+
+ if(message.status_code != 200)
+ {
+ Logger.warning("OldReaderConnection: unexpected response %u".printf(message.status_code));
+ }
+
+ return Response() {
+ status = message.status_code,
+ data = (string)message.response_body.flatten().data
+ };
}
-
- return Response() {
- status = message.status_code,
- data = (string)message.response_body.flatten().data
- };
-}
-
+
}
diff --git a/plugins/backend/oldreader/oldreaderInterface.vala b/plugins/backend/oldreader/oldreaderInterface.vala
index 22f725b9..9bcfbc0f 100644
--- a/plugins/backend/oldreader/oldreaderInterface.vala
+++ b/plugins/backend/oldreader/oldreaderInterface.vala
@@ -14,456 +14,456 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OldReaderInterface : FeedServerInterface {
-
-private OldReaderAPI m_api;
-private OldReaderUtils m_utils;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new OldReaderUtils(settings_backend, secrets);
- m_api = new OldReaderAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://theoldreader.com/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-}
-
-public override string getID()
-{
- return "oldreader";
-}
-
-public override string iconName()
-{
- return "feed-service-oldreader";
-}
-
-public override string serviceName()
-{
- return "The Old Reader";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_userEntry.activate.connect(() => { tryLogin(); });
- m_passwordEntry.activate.connect(() => { tryLogin(); });
-
- m_passwordEntry.set_invisible_char('*');
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(user_label, 0, 0, 1, 1);
- grid.attach(m_userEntry, 1, 0, 1, 1);
- grid.attach(password_label, 0, 1, 1, 1);
- grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
- var logo = new Gtk.Image.from_icon_name("feed-service-oldreader", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to the Old Reader and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override void writeData()
-{
- m_utils.setUser(m_userEntry.get_text().strip());
- m_utils.setPassword(m_passwordEntry.get_text().strip());
-}
-
-public override string buildLoginURL()
-{
- return "";
-}
-
-public override bool extractCode(string redirectURL)
-{
- return false;
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-oldreader-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return "https://theoldreader.com/";
-}
-
-public override string uncategorizedID()
-{
- return "";
-}
-
-public override bool hideCategoryWhenEmpty(string cadID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return true;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- if(read == ArticleStatus.READ)
+
+ private OldReaderAPI m_api;
+ private OldReaderUtils m_utils;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ m_utils = new OldReaderUtils(settings_backend, secrets);
+ m_api = new OldReaderAPI(m_utils);
}
- else
+
+ public override string getWebsite()
{
- m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+ return "https://theoldreader.com/";
}
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- if(marked == ArticleStatus.MARKED)
+
+ public override BackendFlags getFlags()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred");
+ return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
}
- else
+
+ public override string getID()
{
- m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+ return "oldreader";
}
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markAsRead(feedID);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markAsRead(catID);
-}
-
-public override void markAllItemsRead()
-{
- var db = DataBase.readOnly();
- var categories = db.read_categories();
- foreach(Category cat in categories)
+
+ public override string iconName()
{
- m_api.markAsRead(cat.getCatID());
+ return "feed-service-oldreader";
}
-
- var feeds = db.read_feeds_without_cat();
- foreach(Feed feed in feeds)
+
+ public override string serviceName()
{
- m_api.markAsRead(feed.getFeedID());
+ return "The Old Reader";
}
- m_api.markAsRead();
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, true);
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- m_api.edidTag(articleID, tagID, false);
-}
-
-public override string createTag(string caption)
-{
- return m_api.composeTagID(caption);
-}
-
-public override void deleteTag(string tagID)
-{
- m_api.deleteTag(tagID);
-}
-
-public override void renameTag(string tagID, string title)
-{
- m_api.renameTag(tagID, title);
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- feedID = "feed/" + feedURL;
- errmsg = "";
- bool success = false;
-
- if(catID == null && newCatName != null)
+
+ public override bool needWebLogin()
{
- string newCatID = m_api.composeTagID(newCatName);
- success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
+ return false;
}
- else
+
+ public override Gtk.Box? getWidget()
{
- success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_userEntry.activate.connect(() => { tryLogin(); });
+ m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+ m_passwordEntry.set_invisible_char('*');
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(user_label, 0, 0, 1, 1);
+ grid.attach(m_userEntry, 1, 0, 1, 1);
+ grid.attach(password_label, 0, 1, 1, 1);
+ grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-oldreader", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to the Old Reader and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
}
-
- if(!success)
+
+ public override void writeData()
{
- errmsg = @"The old reader could not add $feedURL";
+ m_utils.setUser(m_userEntry.get_text().strip());
+ m_utils.setPassword(m_passwordEntry.get_text().strip());
}
-
- return success;
-}
-
-public override void addFeeds(Gee.List<Feed> feeds)
-{
- string cat = "";
- string[] urls = {};
-
- foreach(Feed f in feeds)
+
+ public override string buildLoginURL()
+ {
+ return "";
+ }
+
+ public override bool extractCode(string redirectURL)
+ {
+ return false;
+ }
+
+ public override bool supportTags()
{
- if(f.getCatIDs()[0] != cat)
+ return false;
+ }
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-oldreader-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return "https://theoldreader.com/";
+ }
+
+ public override string uncategorizedID()
+ {
+ return "";
+ }
+
+ public override bool hideCategoryWhenEmpty(string cadID)
+ {
+ return false;
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return true;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ if(read == ArticleStatus.READ)
{
- m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
- urls = {};
- cat = f.getCatIDs()[0];
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+ }
+ else
+ {
+ m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
}
-
- urls += "feed/" + f.getXmlUrl();
}
-
- m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.UNSUBSCRIBE, {feedID});
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, title);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.composeTagID(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameTag(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.deleteTag(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getFeeds(feeds))
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(marked == ArticleStatus.MARKED)
{
- return false;
+ m_api.edidTag(articleID, "user/-/state/com.google/starred");
}
-
- if(m_api.getCategoriesAndTags(feeds, categories, tags))
+ else
{
- return true;
+ m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
}
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getTotalUnread();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- if(whatToGet == ArticleStatus.READ)
+
+ public override bool alwaysSetReadByID()
{
- return;
+ return false;
}
- else if(whatToGet == ArticleStatus.ALL)
+
+ public override void setFeedRead(string feedID)
{
- var unreadIDs = new Gee.LinkedList<string>();
- string? continuation = null;
- int left = 4*count;
-
- while(left > 0)
+ m_api.markAsRead(feedID);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markAsRead(catID);
+ }
+
+ public override void markAllItemsRead()
+ {
+ var db = DataBase.readOnly();
+ var categories = db.read_categories();
+ foreach(Category cat in categories)
{
- if(cancellable != null && cancellable.is_cancelled())
+ m_api.markAsRead(cat.getCatID());
+ }
+
+ var feeds = db.read_feeds_without_cat();
+ foreach(Feed feed in feeds)
+ {
+ m_api.markAsRead(feed.getFeedID());
+ }
+ m_api.markAsRead();
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, true);
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ m_api.edidTag(articleID, tagID, false);
+ }
+
+ public override string createTag(string caption)
+ {
+ return m_api.composeTagID(caption);
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ m_api.deleteTag(tagID);
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ m_api.renameTag(tagID, title);
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ feedID = "feed/" + feedURL;
+ errmsg = "";
+ bool success = false;
+
+ if(catID == null && newCatName != null)
+ {
+ string newCatID = m_api.composeTagID(newCatName);
+ success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
+ }
+ else
+ {
+ success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
+ }
+
+ if(!success)
+ {
+ errmsg = @"The old reader could not add $feedURL";
+ }
+
+ return success;
+ }
+
+ public override void addFeeds(Gee.List<Feed> feeds)
+ {
+ string cat = "";
+ string[] urls = {};
+
+ foreach(Feed f in feeds)
+ {
+ if(f.getCatIDs()[0] != cat)
{
- return;
+ m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
+ urls = {};
+ cat = f.getCatIDs()[0];
}
-
- if(left > 1000)
+
+ urls += "feed/" + f.getXmlUrl();
+ }
+
+ m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.UNSUBSCRIBE, {feedID});
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, title);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.composeTagID(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameTag(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ return;
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.deleteTag(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getFeeds(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
{
- continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
- left -= 1000;
+ return false;
}
- else
+
+ if(m_api.getCategoriesAndTags(feeds, categories, tags))
{
- m_api.updateArticles(unreadIDs, left, continuation);
- left = 0;
+ return true;
}
}
- DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
- updateArticleList();
+
+ return false;
}
-
- var articles = new Gee.LinkedList<Article>();
- string? continuation = null;
- int left = count;
- string? OldReader_feedID = (isTagID) ? null : feedID;
- string? OldReader_tagID = (isTagID) ? feedID : null;
-
- while(left > 0)
+
+ public override int getUnreadCount()
+ {
+ return m_api.getTotalUnread();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
{
- if(cancellable != null && cancellable.is_cancelled())
+ if(whatToGet == ArticleStatus.READ)
{
return;
}
-
- if(left > 1000)
+ else if(whatToGet == ArticleStatus.ALL)
{
- continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
- left -= 1000;
+ var unreadIDs = new Gee.LinkedList<string>();
+ string? continuation = null;
+ int left = 4*count;
+
+ while(left > 0)
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
+ left -= 1000;
+ }
+ else
+ {
+ m_api.updateArticles(unreadIDs, left, continuation);
+ left = 0;
+ }
+ }
+ DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+ updateArticleList();
}
- else
+
+ var articles = new Gee.LinkedList<Article>();
+ string? continuation = null;
+ int left = count;
+ string? OldReader_feedID = (isTagID) ? null : feedID;
+ string? OldReader_tagID = (isTagID) ? feedID : null;
+
+ while(left > 0)
{
- continuation = m_api.getArticles(articles, left, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
- left = 0;
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(left > 1000)
+ {
+ continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+ left -= 1000;
+ }
+ else
+ {
+ continuation = m_api.getArticles(articles, left, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+ left = 0;
+ }
}
+ writeArticles(articles);
}
- writeArticles(articles);
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/oldreader/oldreaderUtils.vala b/plugins/backend/oldreader/oldreaderUtils.vala
index 1d58863f..1ae850ec 100644
--- a/plugins/backend/oldreader/oldreaderUtils.vala
+++ b/plugins/backend/oldreader/oldreaderUtils.vala
@@ -14,78 +14,78 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.OldReaderSecret {
-const string base_uri = "https://theoldreader.com/reader/api/0/";
+ const string base_uri = "https://theoldreader.com/reader/api/0/";
}
public class FeedReader.OldReaderUtils : GLib.Object {
-
-private GLib.Settings m_settings;
-private Password m_password;
-
-public OldReaderUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
- {
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.oldreader", settings_backend);
- }
- else
+
+ private GLib.Settings m_settings;
+ private Password m_password;
+
+ public OldReaderUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings("org.gnome.feedreader.oldreader");
- }
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.oldreader", Secret.SchemaFlags.NONE,
- "type", "oldreader",
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, pwSchema, "FeedReader: oldreader login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.oldreader", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.oldreader");
+ }
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.oldreader", Secret.SchemaFlags.NONE,
+ "type", "oldreader",
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, pwSchema, "FeedReader: oldreader login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["Username"] = getUser();
return attributes;
});
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getAccessToken()
-{
- return Utils.gsettingReadString(m_settings, "access-token");
-}
-
-public void setAccessToken(string token)
-{
- Utils.gsettingWriteString(m_settings, "access-token", token);
-}
-
-public string getUserID()
-{
- return Utils.gsettingReadString(m_settings, "user-id");
-}
-
-public void setUserID(string id)
-{
- Utils.gsettingWriteString(m_settings, "user-id", id);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getAccessToken()
+ {
+ return Utils.gsettingReadString(m_settings, "access-token");
+ }
+
+ public void setAccessToken(string token)
+ {
+ Utils.gsettingWriteString(m_settings, "access-token", token);
+ }
+
+ public string getUserID()
+ {
+ return Utils.gsettingReadString(m_settings, "user-id");
+ }
+
+ public void setUserID(string id)
+ {
+ Utils.gsettingWriteString(m_settings, "user-id", id);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
+ }
}
diff --git a/plugins/backend/owncloud/OwncloudNewsAPI.vala b/plugins/backend/owncloud/OwncloudNewsAPI.vala
index 7993d5f4..fe3fc81e 100644
--- a/plugins/backend/owncloud/OwncloudNewsAPI.vala
+++ b/plugins/backend/owncloud/OwncloudNewsAPI.vala
@@ -14,578 +14,578 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OwncloudNewsAPI : GLib.Object {
-
-public enum OwnCloudType {
- FEED,
- FOLDER,
- STARRED,
- ALL
-}
-
-private string m_OwnCloudURL;
-private string m_OwnCloudVersion;
-private Json.Parser m_parser;
-private string m_username;
-private string m_password;
-private OwncloudNewsUtils m_utils;
-private Soup.Session m_session;
-
-public OwncloudNewsAPI(OwncloudNewsUtils utils)
-{
- m_parser = new Json.Parser ();
- m_utils = utils;
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_session.ssl_strict = false;
- m_session.authenticate.connect((msg, auth, retrying) => {
+
+ public enum OwnCloudType {
+ FEED,
+ FOLDER,
+ STARRED,
+ ALL
+ }
+
+ private string m_OwnCloudURL;
+ private string m_OwnCloudVersion;
+ private Json.Parser m_parser;
+ private string m_username;
+ private string m_password;
+ private OwncloudNewsUtils m_utils;
+ private Soup.Session m_session;
+
+ public OwncloudNewsAPI(OwncloudNewsUtils utils)
+ {
+ m_parser = new Json.Parser ();
+ m_utils = utils;
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_session.ssl_strict = false;
+ m_session.authenticate.connect((msg, auth, retrying) => {
if(m_utils.getHtaccessUser() == "")
{
- Logger.error("Nextcloud Session: need Authentication");
+ Logger.error("Nextcloud Session: need Authentication");
}
else if(!retrying)
{
- auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+ auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
}
});
-}
-
-public LoginResponse login()
-{
- Logger.debug("Nextcloud: login");
- m_username = m_utils.getUser();
- m_password = m_utils.getPasswd();
- m_OwnCloudURL = m_utils.getURL();
-
- if(m_OwnCloudURL == "" && m_username == "" && m_password == "")
- {
- m_OwnCloudURL = "example-host/nextcloud";
- return LoginResponse.ALL_EMPTY;
- }
- if(m_OwnCloudURL == "")
- {
- return LoginResponse.MISSING_URL;
- }
- if(GLib.Uri.parse_scheme(m_OwnCloudURL) == null)
- {
- return LoginResponse.INVALID_URL;
- }
- if(m_username == "")
- {
- return LoginResponse.MISSING_USER;
- }
- if(m_password == "")
- {
- return LoginResponse.MISSING_PASSWD;
- }
-
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "status", m_username, m_password, "GET");
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- m_OwnCloudVersion = response.get_string_member("version");
- Logger.info("Nextcloud version: %s".printf(m_OwnCloudVersion));
- return LoginResponse.SUCCESS;
}
- else if(error == ConnectionError.API_ERROR)
+
+ public LoginResponse login()
{
- return LoginResponse.WRONG_LOGIN;
- }
- else if(error == ConnectionError.NO_RESPONSE)
- {
- return LoginResponse.NO_CONNECTION;
- }
- else if(error == ConnectionError.CA_ERROR)
- {
- return LoginResponse.CA_ERROR;
- }
- else if(error == ConnectionError.UNAUTHORIZED)
- {
- return LoginResponse.UNAUTHORIZED;
+ Logger.debug("Nextcloud: login");
+ m_username = m_utils.getUser();
+ m_password = m_utils.getPasswd();
+ m_OwnCloudURL = m_utils.getURL();
+
+ if(m_OwnCloudURL == "" && m_username == "" && m_password == "")
+ {
+ m_OwnCloudURL = "example-host/nextcloud";
+ return LoginResponse.ALL_EMPTY;
+ }
+ if(m_OwnCloudURL == "")
+ {
+ return LoginResponse.MISSING_URL;
+ }
+ if(GLib.Uri.parse_scheme(m_OwnCloudURL) == null)
+ {
+ return LoginResponse.INVALID_URL;
+ }
+ if(m_username == "")
+ {
+ return LoginResponse.MISSING_USER;
+ }
+ if(m_password == "")
+ {
+ return LoginResponse.MISSING_PASSWD;
+ }
+
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "status", m_username, m_password, "GET");
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ m_OwnCloudVersion = response.get_string_member("version");
+ Logger.info("Nextcloud version: %s".printf(m_OwnCloudVersion));
+ return LoginResponse.SUCCESS;
+ }
+ else if(error == ConnectionError.API_ERROR)
+ {
+ return LoginResponse.WRONG_LOGIN;
+ }
+ else if(error == ConnectionError.NO_RESPONSE)
+ {
+ return LoginResponse.NO_CONNECTION;
+ }
+ else if(error == ConnectionError.CA_ERROR)
+ {
+ return LoginResponse.CA_ERROR;
+ }
+ else if(error == ConnectionError.UNAUTHORIZED)
+ {
+ return LoginResponse.UNAUTHORIZED;
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
}
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-
-public bool isloggedin()
-{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
-
- if(message.send() == ConnectionError.SUCCESS)
+
+
+ public bool isloggedin()
{
- return true;
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
+
+ if(message.send() == ConnectionError.SUCCESS)
+ {
+ return true;
+ }
+
+ Logger.error("OwncloudNewsAPI.isloggedin: not logged in");
+ return false;
}
-
- Logger.error("OwncloudNewsAPI.isloggedin: not logged in");
- return false;
-}
-
-public bool getFeeds(Gee.List<Feed> feeds)
-{
- if(isloggedin())
+
+ public bool getFeeds(Gee.List<Feed> feeds)
{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "feeds", m_username, m_password, "GET");
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
+ if(isloggedin())
{
- var response = message.get_response_object();
- if(response.has_member("feeds"))
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "feeds", m_username, m_password, "GET");
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
{
- var feed_array = response.get_array_member("feeds");
- var feed_count = feed_array.get_length();
-
- for(uint i = 0; i < feed_count; i++)
+ var response = message.get_response_object();
+ if(response.has_member("feeds"))
{
- var feed_node = feed_array.get_object_element(i);
-
- feeds.add(
- new Feed(
- feed_node.get_int_member("id").to_string(),
- feed_node.get_string_member("title"),
- feed_node.get_string_member("link"),
- (int)feed_node.get_int_member("unreadCount"),
- ListUtils.single(feed_node.get_int_member("folderId").to_string()),
- feed_node.get_string_member("faviconLink")
+ var feed_array = response.get_array_member("feeds");
+ var feed_count = feed_array.get_length();
+
+ for(uint i = 0; i < feed_count; i++)
+ {
+ var feed_node = feed_array.get_object_element(i);
+
+ feeds.add(
+ new Feed(
+ feed_node.get_int_member("id").to_string(),
+ feed_node.get_string_member("title"),
+ feed_node.get_string_member("link"),
+ (int)feed_node.get_int_member("unreadCount"),
+ ListUtils.single(feed_node.get_int_member("folderId").to_string()),
+ feed_node.get_string_member("faviconLink")
)
);
+ }
+
+ return true;
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.getFeeds: no member \"feeds\"");
}
-
- return true;
}
else
{
- Logger.error("OwncloudNewsAPI.getFeeds: no member \"feeds\"");
+ Logger.error("OwncloudNewsAPI.getFeeds");
}
}
- else
- {
- Logger.error("OwncloudNewsAPI.getFeeds");
- }
+
+ return false;
}
-
- return false;
-}
-
-
-public bool getCategories(Gee.List<Category> categories, Gee.List<Feed> feeds)
-{
- if(isloggedin())
+
+
+ public bool getCategories(Gee.List<Category> categories, Gee.List<Feed> feeds)
{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "folders", m_username, m_password, "GET");
- int error = message.send();
- int orderID = 0;
-
- if(error == ConnectionError.SUCCESS)
+ if(isloggedin())
{
- var response = message.get_response_object();
-
- if(response.has_member("folders"))
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "folders", m_username, m_password, "GET");
+ int error = message.send();
+ int orderID = 0;
+
+ if(error == ConnectionError.SUCCESS)
{
- var folder_array = response.get_array_member("folders");
- var folder_count = folder_array.get_length();
-
- for(uint i = 0; i < folder_count; i++)
+ var response = message.get_response_object();
+
+ if(response.has_member("folders"))
{
- ++orderID;
- var folder_node = folder_array.get_object_element(i);
- string id = folder_node.get_int_member("id").to_string();
-
- categories.add(
- new Category (
- id,
- folder_node.get_string_member("name"),
- m_utils.countUnread(feeds, id),
- orderID,
- CategoryID.MASTER.to_string(),
- 1
+ var folder_array = response.get_array_member("folders");
+ var folder_count = folder_array.get_length();
+
+ for(uint i = 0; i < folder_count; i++)
+ {
+ ++orderID;
+ var folder_node = folder_array.get_object_element(i);
+ string id = folder_node.get_int_member("id").to_string();
+
+ categories.add(
+ new Category (
+ id,
+ folder_node.get_string_member("name"),
+ m_utils.countUnread(feeds, id),
+ orderID,
+ CategoryID.MASTER.to_string(),
+ 1
)
);
+ }
+ return true;
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.getCategories: no member \"folders\"");
}
- return true;
}
else
{
- Logger.error("OwncloudNewsAPI.getCategories: no member \"folders\"");
+ Logger.error("OwncloudNewsAPI.getCategories");
}
}
- else
- {
- Logger.error("OwncloudNewsAPI.getCategories");
- }
+ return false;
}
- return false;
-}
-
-
-public void getNewArticles(Gee.List<Article> articles, int lastModified, OwnCloudType type, int id)
-{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items/updated", m_username, m_password, "GET");
- message.add_int("lastModified", lastModified);
- message.add_int("type", type);
- message.add_int("id", id);
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
+
+
+ public void getNewArticles(Gee.List<Article> articles, int lastModified, OwnCloudType type, int id)
{
- var response = message.get_response_object();
- if(response.has_member("items"))
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items/updated", m_username, m_password, "GET");
+ message.add_int("lastModified", lastModified);
+ message.add_int("type", type);
+ message.add_int("id", id);
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
{
- var article_array = response.get_array_member("items");
- var article_count = article_array.get_length();
- Logger.debug("getNewArticles: %u articles returned".printf(article_count));
-
- for(uint i = 0; i < article_count; i++)
+ var response = message.get_response_object();
+ if(response.has_member("items"))
{
- var article_node = article_array.get_object_element(i);
- //Logger.debug(article_node.get_int_member("id").to_string());
-
- ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
- ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+ var article_array = response.get_array_member("items");
+ var article_count = article_array.get_length();
+ Logger.debug("getNewArticles: %u articles returned".printf(article_count));
+
+ for(uint i = 0; i < article_count; i++)
{
- if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
+ var article_node = article_array.get_object_element(i);
+ //Logger.debug(article_node.get_int_member("id").to_string());
+
+ ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
+ ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
{
- enclosures.add(new Enclosure(
- article_node.get_int_member("id").to_string(),
- article_node.get_string_member("enclosureLink"),
- EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
+ if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
+ {
+ enclosures.add(new Enclosure(
+ article_node.get_int_member("id").to_string(),
+ article_node.get_string_member("enclosureLink"),
+ EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
+ }
}
+
+ var Article = new Article( article_node.get_int_member("id").to_string(),
+ article_node.get_string_member("title"),
+ article_node.get_string_member("url"),
+ article_node.get_int_member("feedId").to_string(),
+ unread,
+ marked,
+ article_node.get_string_member("body"),
+ null,
+ article_node.get_string_member("author"),
+ new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
+ -1,
+ null, // tags
+ enclosures,
+ article_node.get_string_member("guidHash"),
+ (int)article_node.get_int_member("lastModified"));
+
+ articles.add(Article);
}
-
- var Article = new Article( article_node.get_int_member("id").to_string(),
- article_node.get_string_member("title"),
- article_node.get_string_member("url"),
- article_node.get_int_member("feedId").to_string(),
- unread,
- marked,
- article_node.get_string_member("body"),
- null,
- article_node.get_string_member("author"),
- new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
- -1,
- null, // tags
- enclosures,
- article_node.get_string_member("guidHash"),
- (int)article_node.get_int_member("lastModified"));
-
- articles.add(Article);
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.getNewArticles: no member \"items\"");
}
}
else
{
- Logger.error("OwncloudNewsAPI.getNewArticles: no member \"items\"");
+ Logger.error("OwncloudNewsAPI.getNewArticles");
}
}
- else
- {
- Logger.error("OwncloudNewsAPI.getNewArticles");
- }
-}
-
-
-
-public void getArticles(Gee.List<Article> articles, int skip, int count, bool read, OwnCloudType type, int id)
-{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items", m_username, m_password, "GET");
- message.add_bool("oldestFirst", false);
- message.add_int("type", type);
- message.add_bool("getRead", read);
- message.add_int("id", id);
- message.add_int("offset", skip);
- message.add_int("batchSize", count);
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.has_member("items"))
+
+
+
+ public void getArticles(Gee.List<Article> articles, int skip, int count, bool read, OwnCloudType type, int id)
+ {
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items", m_username, m_password, "GET");
+ message.add_bool("oldestFirst", false);
+ message.add_int("type", type);
+ message.add_bool("getRead", read);
+ message.add_int("id", id);
+ message.add_int("offset", skip);
+ message.add_int("batchSize", count);
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
{
- var article_array = response.get_array_member("items");
- var article_count = article_array.get_length();
- Logger.debug("getArticles: %u articles returned".printf(article_count));
-
- for(uint i = 0; i < article_count; i++)
+ var response = message.get_response_object();
+ if(response.has_member("items"))
{
- var article_node = article_array.get_object_element(i);
-
- ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
- ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+ var article_array = response.get_array_member("items");
+ var article_count = article_array.get_length();
+ Logger.debug("getArticles: %u articles returned".printf(article_count));
+
+ for(uint i = 0; i < article_count; i++)
{
- if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
+ var article_node = article_array.get_object_element(i);
+
+ ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
+ ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
{
- enclosures.add(new Enclosure(
- article_node.get_int_member("id").to_string(),
- article_node.get_string_member("enclosureLink"),
- EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
+ if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
+ {
+ enclosures.add(new Enclosure(
+ article_node.get_int_member("id").to_string(),
+ article_node.get_string_member("enclosureLink"),
+ EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
+ }
}
+
+ var Article = new Article( article_node.get_int_member("id").to_string(),
+ article_node.get_string_member("title"),
+ article_node.get_string_member("url"),
+ article_node.get_int_member("feedId").to_string(),
+ unread,
+ marked,
+ article_node.get_string_member("body"),
+ null,
+ article_node.get_string_member("author"),
+ new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
+ -1,
+ null, // tags
+ enclosures,
+ article_node.get_string_member("guidHash"),
+ (int)article_node.get_int_member("lastModified"));
+
+ articles.add(Article);
}
-
- var Article = new Article( article_node.get_int_member("id").to_string(),
- article_node.get_string_member("title"),
- article_node.get_string_member("url"),
- article_node.get_int_member("feedId").to_string(),
- unread,
- marked,
- article_node.get_string_member("body"),
- null,
- article_node.get_string_member("author"),
- new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
- -1,
- null, // tags
- enclosures,
- article_node.get_string_member("guidHash"),
- (int)article_node.get_int_member("lastModified"));
-
- articles.add(Article);
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.getArticles: no member \"items\"");
}
}
else
{
- Logger.error("OwncloudNewsAPI.getArticles: no member \"items\"");
+ Logger.error("OwncloudNewsAPI.getArticles");
}
}
- else
+
+
+ public bool markFeedRead(string feedID, bool isCatID)
{
- Logger.error("OwncloudNewsAPI.getArticles");
- }
-}
-
-
-public bool markFeedRead(string feedID, bool isCatID)
-{
- string url = "%s/%s/read".printf((isCatID) ? "folders" : "feeds", feedID);
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
- {
- return true;
- }
-
- Logger.error("OwncloudNewsAPI.markFeedRead");
- return false;
-}
-
-public bool markAllItemsRead()
-{
- string url = "items/read";
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
- {
- return true;
- }
-
- Logger.error("OwncloudNewsAPI.markAllItemsRead");
- return false;
-}
-
-
-public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
-{
- string url = "";
-
- if(unread == ArticleStatus.UNREAD)
- {
- url = "items/unread/multiple";
- }
- else if(unread == ArticleStatus.READ)
- {
- url = "items/read/multiple";
- }
-
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_int_array("items", articleIDs);
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
- {
- return true;
- }
-
- Logger.error("OwncloudNewsAPI.updateArticleUnread");
- return false;
-}
-
-
-public bool updateArticleMarked(string articleID, ArticleStatus marked)
-{
- var article = DataBase.readOnly().read_article(articleID);
- string url = "items/%s/%s/".printf(article.getFeedID(), article.getHash());
-
- if(marked == ArticleStatus.MARKED)
- {
- url += "star";
+ string url = "%s/%s/read".printf((isCatID) ? "folders" : "feeds", feedID);
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
+ {
+ return true;
+ }
+
+ Logger.error("OwncloudNewsAPI.markFeedRead");
+ return false;
}
- else if(marked == ArticleStatus.UNMARKED)
+
+ public bool markAllItemsRead()
{
- url += "unstar";
+ string url = "items/read";
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
+ {
+ return true;
+ }
+
+ Logger.error("OwncloudNewsAPI.markAllItemsRead");
+ return false;
}
-
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
+
+
+ public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
{
- return true;
+ string url = "";
+
+ if(unread == ArticleStatus.UNREAD)
+ {
+ url = "items/unread/multiple";
+ }
+ else if(unread == ArticleStatus.READ)
+ {
+ url = "items/read/multiple";
+ }
+
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_int_array("items", articleIDs);
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
+ {
+ return true;
+ }
+
+ Logger.error("OwncloudNewsAPI.updateArticleUnread");
+ return false;
}
-
- Logger.error("OwncloudNewsAPI.updateArticleMarked");
- return false;
-}
-
-public bool addFeed(string feedURL, string? catID, out int64 feedID, out string errmsg)
-{
- string url = "feeds";
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
- message.add_string("url", feedURL);
- message.add_int("folderId", (catID != null) ? int.parse(catID) : 0);
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
+
+
+ public bool updateArticleMarked(string articleID, ArticleStatus marked)
{
- var response = message.get_response_object();
- if(response.has_member("feeds"))
+ var article = DataBase.readOnly().read_article(articleID);
+ string url = "items/%s/%s/".printf(article.getFeedID(), article.getHash());
+
+ if(marked == ArticleStatus.MARKED)
+ {
+ url += "star";
+ }
+ else if(marked == ArticleStatus.UNMARKED)
+ {
+ url += "unstar";
+ }
+
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
{
- errmsg = "";
- feedID = response.get_array_member("feeds").get_object_element(0).get_int_member("id");
return true;
}
+
+ Logger.error("OwncloudNewsAPI.updateArticleMarked");
+ return false;
}
- else
+
+ public bool addFeed(string feedURL, string? catID, out int64 feedID, out string errmsg)
{
- Logger.error("OwncloudNewsAPI.addFeed");
+ string url = "feeds";
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
+ message.add_string("url", feedURL);
+ message.add_int("folderId", (catID != null) ? int.parse(catID) : 0);
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.has_member("feeds"))
+ {
+ errmsg = "";
+ feedID = response.get_array_member("feeds").get_object_element(0).get_int_member("id");
+ return true;
+ }
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.addFeed");
+ }
+
+
+ errmsg = "Nextcloud could not add the feed";
+ feedID = 0;
+
+ switch(message.getStatusCode())
+ {
+ case 409:
+ errmsg = "Feed already added (409)";
+ return true;
+ case 422:
+ errmsg = "Nextcloud can't read the feed (422)";
+ break;
+ }
+
+ return false;
}
-
-
- errmsg = "Nextcloud could not add the feed";
- feedID = 0;
-
- switch(message.getStatusCode())
+
+ public void removeFeed(string feedID)
{
- case 409:
- errmsg = "Feed already added (409)";
- return true;
- case 422:
- errmsg = "Nextcloud can't read the feed (422)";
- break;
+ string url = "feeds/%s".printf(feedID);
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
+ int error = message.send();
+
+ if(error != ConnectionError.SUCCESS)
+ {
+ Logger.error("OwncloudNewsAPI.removeFeed");
+ }
}
-
- return false;
-}
-
-public void removeFeed(string feedID)
-{
- string url = "feeds/%s".printf(feedID);
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
- int error = message.send();
-
- if(error != ConnectionError.SUCCESS)
+
+ public void renameFeed(string feedID, string title)
{
- Logger.error("OwncloudNewsAPI.removeFeed");
+ string url = "feeds/%s/rename".printf(feedID);
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_string("feedTitle", title);
+ int error = message.send();
+
+ if(error != ConnectionError.SUCCESS)
+ {
+ Logger.error("OwncloudNewsAPI.renameFeed");
+ }
}
-}
-
-public void renameFeed(string feedID, string title)
-{
- string url = "feeds/%s/rename".printf(feedID);
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_string("feedTitle", title);
- int error = message.send();
-
- if(error != ConnectionError.SUCCESS)
+
+ public void moveFeed(string feedID, string? newCatID = null)
{
- Logger.error("OwncloudNewsAPI.renameFeed");
+ string url = "feeds/%s/move".printf(feedID);
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_int("folderId", (newCatID != null) ? int.parse(newCatID) : 0);
+ int error = message.send();
+
+ if(error != ConnectionError.SUCCESS)
+ {
+ Logger.error("OwncloudNewsAPI.moveFeed");
+ }
}
-}
-
-public void moveFeed(string feedID, string? newCatID = null)
-{
- string url = "feeds/%s/move".printf(feedID);
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_int("folderId", (newCatID != null) ? int.parse(newCatID) : 0);
- int error = message.send();
-
- if(error != ConnectionError.SUCCESS)
+
+ public int64 addFolder(string title)
{
- Logger.error("OwncloudNewsAPI.moveFeed");
+ string url = "folders";
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
+ message.add_string("name", title);
+ int error = message.send();
+
+ if(error != ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.has_member("folders"))
+ {
+ return response.get_array_member("folders").get_object_element(0).get_int_member("id");
+ }
+ }
+ else
+ {
+ Logger.error("OwncloudNewsAPI.addFolder");
+ }
+
+ return 0;
}
-}
-
-public int64 addFolder(string title)
-{
- string url = "folders";
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
- message.add_string("name", title);
- int error = message.send();
-
- if(error != ConnectionError.SUCCESS)
+
+ public bool removeFolder(string catID)
{
- var response = message.get_response_object();
- if(response.has_member("folders"))
+ string url = "folders/%s".printf(catID);
+
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
+ int error = message.send();
+
+ if(error == ConnectionError.SUCCESS)
{
- return response.get_array_member("folders").get_object_element(0).get_int_member("id");
+ return true;
}
+
+ Logger.error("OwncloudNewsAPI.removeFolder");
+ return false;
}
- else
+
+ public void renameCategory(string catID, string title)
{
- Logger.error("OwncloudNewsAPI.addFolder");
+ string url = "folders/%s".printf(catID);
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+ message.add_string("name", title);
+ int error = message.send();
+
+ if(error != ConnectionError.SUCCESS)
+ {
+ Logger.error("OwncloudNewsAPI.renameCategory");
+ }
}
-
- return 0;
-}
-
-public bool removeFolder(string catID)
-{
- string url = "folders/%s".printf(catID);
-
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
- int error = message.send();
-
- if(error == ConnectionError.SUCCESS)
+
+ public bool ping()
{
+ var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
+ int error = message.send(true);
+
+ if(error == ConnectionError.NO_RESPONSE)
+ {
+ Logger.error("OwncloudNewsAPI.ping: failed");
+ return false;
+ }
+
return true;
}
-
- Logger.error("OwncloudNewsAPI.removeFolder");
- return false;
-}
-
-public void renameCategory(string catID, string title)
-{
- string url = "folders/%s".printf(catID);
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
- message.add_string("name", title);
- int error = message.send();
-
- if(error != ConnectionError.SUCCESS)
- {
- Logger.error("OwncloudNewsAPI.renameCategory");
- }
-}
-
-public bool ping()
-{
- var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
- int error = message.send(true);
-
- if(error == ConnectionError.NO_RESPONSE)
- {
- Logger.error("OwncloudNewsAPI.ping: failed");
- return false;
- }
-
- return true;
-}
}
diff --git a/plugins/backend/owncloud/OwncloudNewsInterface.vala b/plugins/backend/owncloud/OwncloudNewsInterface.vala
index a75f35cd..6a9df88d 100644
--- a/plugins/backend/owncloud/OwncloudNewsInterface.vala
+++ b/plugins/backend/owncloud/OwncloudNewsInterface.vala
@@ -14,444 +14,444 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OwncloudNewsInterface : FeedServerInterface {
-
-private OwncloudNewsAPI m_api;
-private OwncloudNewsUtils m_utils;
-private Gtk.Entry m_urlEntry;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-private Gtk.Entry m_AuthUserEntry;
-private Gtk.Entry m_AuthPasswordEntry;
-private Gtk.Revealer m_revealer;
-private bool m_need_htaccess = false;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new OwncloudNewsUtils(settings_backend, secrets);
- m_api = new OwncloudNewsAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://github.com/nextcloud/news";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-}
-
-public override string getID()
-{
- return "owncloud";
-}
-
-public override string iconName()
-{
- return "feed-service-nextcloud";
-}
-
-public override string serviceName()
-{
- return "Nextcloud News";
-}
-
-public override void writeData()
-{
- m_utils.setURL(m_urlEntry.get_text());
- m_utils.setUser(m_userEntry.get_text().strip());
- m_utils.setPassword(m_passwordEntry.get_text().strip());
- if(m_need_htaccess)
+
+ private OwncloudNewsAPI m_api;
+ private OwncloudNewsUtils m_utils;
+ private Gtk.Entry m_urlEntry;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+ private Gtk.Entry m_AuthUserEntry;
+ private Gtk.Entry m_AuthPasswordEntry;
+ private Gtk.Revealer m_revealer;
+ private bool m_need_htaccess = false;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_utils.setHtaccessUser(m_AuthUserEntry.get_text().strip());
- m_utils.setHtAccessPassword(m_AuthPasswordEntry.get_text().strip());
+ m_utils = new OwncloudNewsUtils(settings_backend, secrets);
+ m_api = new OwncloudNewsAPI(m_utils);
}
-}
-
-public override void showHtAccess()
-{
- m_revealer.set_reveal_child(true);
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var urlLabel = new Gtk.Label(_("Nextcloud URL:"));
- var userLabel = new Gtk.Label(_("Username:"));
- var passwordLabel = new Gtk.Label(_("Password:"));
-
- urlLabel.set_alignment(1.0f, 0.5f);
- userLabel.set_alignment(1.0f, 0.5f);
- passwordLabel.set_alignment(1.0f, 0.5f);
-
- urlLabel.set_hexpand(true);
- userLabel.set_hexpand(true);
- passwordLabel.set_hexpand(true);
-
- m_urlEntry = new Gtk.Entry();
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_urlEntry.activate.connect(writeData);
- m_userEntry.activate.connect(writeData);
- m_passwordEntry.activate.connect(writeData);
-
- m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- var logo = new Gtk.Image.from_icon_name("feed-service-nextcloud", Gtk.IconSize.MENU);
-
- grid.attach(urlLabel, 0, 0, 1, 1);
- grid.attach(m_urlEntry, 1, 0, 1, 1);
- grid.attach(userLabel, 0, 1, 1, 1);
- grid.attach(m_userEntry, 1, 1, 1, 1);
- grid.attach(passwordLabel, 0, 2, 1, 1);
- grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
- // http auth stuff ----------------------------------------------------
- var authUserLabel = new Gtk.Label(_("Username:"));
- var authPasswordLabel = new Gtk.Label(_("Password:"));
-
- authUserLabel.set_alignment(1.0f, 0.5f);
- authPasswordLabel.set_alignment(1.0f, 0.5f);
-
- authUserLabel.set_hexpand(true);
- authPasswordLabel.set_hexpand(true);
-
- m_AuthUserEntry = new Gtk.Entry();
- m_AuthPasswordEntry = new Gtk.Entry();
- m_AuthPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_AuthPasswordEntry.set_visibility(false);
-
- m_AuthUserEntry.activate.connect(writeData);
- m_AuthPasswordEntry.activate.connect(writeData);
-
- var authGrid = new Gtk.Grid();
- authGrid.margin = 10;
- authGrid.set_column_spacing(10);
- authGrid.set_row_spacing(10);
- authGrid.set_valign(Gtk.Align.CENTER);
- authGrid.set_halign(Gtk.Align.CENTER);
-
- authGrid.attach(authUserLabel, 0, 0, 1, 1);
- authGrid.attach(m_AuthUserEntry, 1, 0, 1, 1);
- authGrid.attach(authPasswordLabel, 0, 1, 1, 1);
- authGrid.attach(m_AuthPasswordEntry, 1, 1, 1, 1);
-
- var frame = new Gtk.Frame(_("HTTP Authorization"));
- frame.set_halign(Gtk.Align.CENTER);
- frame.add(authGrid);
- m_revealer = new Gtk.Revealer();
- m_revealer.add(frame);
- //---------------------------------------------------------------------
-
- var loginLabel = new Gtk.Label(_("Please log in to your Nextcloud News instance and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_start(m_revealer, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
-
- m_urlEntry.set_text(m_utils.getUnmodifiedURL());
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override bool supportTags()
-{
- return false;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-nextcloud-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return m_utils.getURL();
-}
-
-public override string uncategorizedID()
-{
- return "0";
-}
-
-public override bool hideCategoryWhenEmpty(string cadID)
-{
- return false;
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return false;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return false;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return false;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- m_api.updateArticleUnread(articleIDs, read);
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- m_api.updateArticleMarked(articleID, marked);
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.markFeedRead(feedID, false);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.markFeedRead(catID, true);
-}
-
-public override void markAllItemsRead()
-{
- m_api.markAllItemsRead();
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- return;
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- return;
-}
-
-public override string createTag(string caption)
-{
- return ":(";
-}
-
-public override void deleteTag(string tagID)
-{
- return;
-}
-
-public override void renameTag(string tagID, string title)
-{
- return;
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- bool success = false;
- int64 id = 0;
- if(catID == null && newCatName != null)
+
+ public override string getWebsite()
{
- string newCatID = m_api.addFolder(newCatName).to_string();
- success = m_api.addFeed(feedURL, newCatID, out id, out errmsg);
+ return "https://github.com/nextcloud/news";
}
- else
+
+ public override BackendFlags getFlags()
{
- success = m_api.addFeed(feedURL, catID, out id, out errmsg);
+ return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
}
-
-
- feedID = id.to_string();
- return success;
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.removeFeed(feedID);
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.renameFeed(feedID, title);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.moveFeed(feedID, newCatID);
-}
-
-public override string createCategory(string title, string? parentID)
-{
- return m_api.addFolder(title).to_string();
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameCategory(catID, title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- return;
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.removeFolder(catID);
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getFeeds(feeds))
+
+ public override string getID()
{
- if(cancellable != null && cancellable.is_cancelled())
- {
- return false;
- }
-
- if(m_api.getCategories(categories, feeds))
+ return "owncloud";
+ }
+
+ public override string iconName()
+ {
+ return "feed-service-nextcloud";
+ }
+
+ public override string serviceName()
+ {
+ return "Nextcloud News";
+ }
+
+ public override void writeData()
+ {
+ m_utils.setURL(m_urlEntry.get_text());
+ m_utils.setUser(m_userEntry.get_text().strip());
+ m_utils.setPassword(m_passwordEntry.get_text().strip());
+ if(m_need_htaccess)
{
- return true;
+ m_utils.setHtaccessUser(m_AuthUserEntry.get_text().strip());
+ m_utils.setHtAccessPassword(m_AuthPasswordEntry.get_text().strip());
}
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return (int)DataBase.readOnly().get_unread_total();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- var type = OwncloudNewsAPI.OwnCloudType.ALL;
- bool read = true;
- int id = 0;
-
- switch(whatToGet)
+
+ public override void showHtAccess()
{
- case ArticleStatus.ALL:
- break;
- case ArticleStatus.UNREAD:
- read = false;
- break;
- case ArticleStatus.MARKED:
- type = OwncloudNewsAPI.OwnCloudType.STARRED;
- break;
+ m_revealer.set_reveal_child(true);
}
-
- if(feedID != null)
+
+ public override bool needWebLogin()
+ {
+ return false;
+ }
+
+ public override Gtk.Box? getWidget()
{
- if(isTagID == true)
+ var urlLabel = new Gtk.Label(_("Nextcloud URL:"));
+ var userLabel = new Gtk.Label(_("Username:"));
+ var passwordLabel = new Gtk.Label(_("Password:"));
+
+ urlLabel.set_alignment(1.0f, 0.5f);
+ userLabel.set_alignment(1.0f, 0.5f);
+ passwordLabel.set_alignment(1.0f, 0.5f);
+
+ urlLabel.set_hexpand(true);
+ userLabel.set_hexpand(true);
+ passwordLabel.set_hexpand(true);
+
+ m_urlEntry = new Gtk.Entry();
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_urlEntry.activate.connect(writeData);
+ m_userEntry.activate.connect(writeData);
+ m_passwordEntry.activate.connect(writeData);
+
+ m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-nextcloud", Gtk.IconSize.MENU);
+
+ grid.attach(urlLabel, 0, 0, 1, 1);
+ grid.attach(m_urlEntry, 1, 0, 1, 1);
+ grid.attach(userLabel, 0, 1, 1, 1);
+ grid.attach(m_userEntry, 1, 1, 1, 1);
+ grid.attach(passwordLabel, 0, 2, 1, 1);
+ grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+ // http auth stuff ----------------------------------------------------
+ var authUserLabel = new Gtk.Label(_("Username:"));
+ var authPasswordLabel = new Gtk.Label(_("Password:"));
+
+ authUserLabel.set_alignment(1.0f, 0.5f);
+ authPasswordLabel.set_alignment(1.0f, 0.5f);
+
+ authUserLabel.set_hexpand(true);
+ authPasswordLabel.set_hexpand(true);
+
+ m_AuthUserEntry = new Gtk.Entry();
+ m_AuthPasswordEntry = new Gtk.Entry();
+ m_AuthPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_AuthPasswordEntry.set_visibility(false);
+
+ m_AuthUserEntry.activate.connect(writeData);
+ m_AuthPasswordEntry.activate.connect(writeData);
+
+ var authGrid = new Gtk.Grid();
+ authGrid.margin = 10;
+ authGrid.set_column_spacing(10);
+ authGrid.set_row_spacing(10);
+ authGrid.set_valign(Gtk.Align.CENTER);
+ authGrid.set_halign(Gtk.Align.CENTER);
+
+ authGrid.attach(authUserLabel, 0, 0, 1, 1);
+ authGrid.attach(m_AuthUserEntry, 1, 0, 1, 1);
+ authGrid.attach(authPasswordLabel, 0, 1, 1, 1);
+ authGrid.attach(m_AuthPasswordEntry, 1, 1, 1, 1);
+
+ var frame = new Gtk.Frame(_("HTTP Authorization"));
+ frame.set_halign(Gtk.Align.CENTER);
+ frame.add(authGrid);
+ m_revealer = new Gtk.Revealer();
+ m_revealer.add(frame);
+ //---------------------------------------------------------------------
+
+ var loginLabel = new Gtk.Label(_("Please log in to your Nextcloud News instance and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_start(m_revealer, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+
+ m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
+ }
+
+ public override bool supportTags()
+ {
+ return false;
+ }
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-nextcloud-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return m_utils.getURL();
+ }
+
+ public override string uncategorizedID()
+ {
+ return "0";
+ }
+
+ public override bool hideCategoryWhenEmpty(string cadID)
+ {
+ return false;
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return false;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return false;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return false;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ m_api.updateArticleUnread(articleIDs, read);
+ }
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
+ {
+ m_api.updateArticleMarked(articleID, marked);
+ }
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.markFeedRead(feedID, false);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.markFeedRead(catID, true);
+ }
+
+ public override void markAllItemsRead()
+ {
+ m_api.markAllItemsRead();
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ return;
+ }
+
+ public override string createTag(string caption)
+ {
+ return ":(";
+ }
+
+ public override void deleteTag(string tagID)
{
return;
}
-
- id = int.parse(feedID);
- type = OwncloudNewsAPI.OwnCloudType.FEED;
- }
-
- var articles = new Gee.LinkedList<Article>();
-
- if(count == -1)
- {
- m_api.getNewArticles(articles, DataBase.readOnly().getLastModified(), type, id);
+
+ public override void renameTag(string tagID, string title)
+ {
+ return;
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ bool success = false;
+ int64 id = 0;
+ if(catID == null && newCatName != null)
+ {
+ string newCatID = m_api.addFolder(newCatName).to_string();
+ success = m_api.addFeed(feedURL, newCatID, out id, out errmsg);
+ }
+ else
+ {
+ success = m_api.addFeed(feedURL, catID, out id, out errmsg);
+ }
+
+
+ feedID = id.to_string();
+ return success;
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.removeFeed(feedID);
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.renameFeed(feedID, title);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.moveFeed(feedID, newCatID);
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ return m_api.addFolder(title).to_string();
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameCategory(catID, title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ return;
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.removeFolder(catID);
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getFeeds(feeds))
+ {
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getCategories(categories, feeds))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public override int getUnreadCount()
+ {
+ return (int)DataBase.readOnly().get_unread_total();
+ }
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+ {
+ var type = OwncloudNewsAPI.OwnCloudType.ALL;
+ bool read = true;
+ int id = 0;
+
+ switch(whatToGet)
+ {
+ case ArticleStatus.ALL:
+ break;
+ case ArticleStatus.UNREAD:
+ read = false;
+ break;
+ case ArticleStatus.MARKED:
+ type = OwncloudNewsAPI.OwnCloudType.STARRED;
+ break;
+ }
+
+ if(feedID != null)
+ {
+ if(isTagID == true)
+ {
+ return;
+ }
+
+ id = int.parse(feedID);
+ type = OwncloudNewsAPI.OwnCloudType.FEED;
+ }
+
+ var articles = new Gee.LinkedList<Article>();
+
+ if(count == -1)
+ {
+ m_api.getNewArticles(articles, DataBase.readOnly().getLastModified(), type, id);
+ }
+ else
+ {
+ m_api.getArticles(articles, 0, -1, read, type, id);
+ }
+
+ writeArticles(articles);
+ }
}
- else
+
+ [ModuleInit]
+ public void peas_register_types(GLib.TypeModule module)
{
- m_api.getArticles(articles, 0, -1, read, type, id);
+ var objmodule = module as Peas.ObjectModule;
+ objmodule.register_extension_type(typeof(FeedReader.FeedServerInterface), typeof(FeedReader.OwncloudNewsInterface));
}
-
- writeArticles(articles);
-}
-}
-
-[ModuleInit]
-public void peas_register_types(GLib.TypeModule module)
-{
- var objmodule = module as Peas.ObjectModule;
- objmodule.register_extension_type(typeof(FeedReader.FeedServerInterface), typeof(FeedReader.OwncloudNewsInterface));
-}
diff --git a/plugins/backend/owncloud/OwncloudNewsMessage.vala b/plugins/backend/owncloud/OwncloudNewsMessage.vala
index ff81aab4..8691d392 100644
--- a/plugins/backend/owncloud/OwncloudNewsMessage.vala
+++ b/plugins/backend/owncloud/OwncloudNewsMessage.vala
@@ -14,192 +14,192 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OwnCloudNewsMessage : GLib.Object {
-
-private Soup.Session m_session;
-private Soup.Message m_message_soup;
-private GLib.StringBuilder m_message_string;
-private string m_contenttype;
-private Json.Parser m_parser;
-private Json.Object m_root_object;
-private string m_method;
-private string m_destination;
-
-public OwnCloudNewsMessage(Soup.Session session, string destination, string username, string password, string method)
-{
- m_message_string = new GLib.StringBuilder();
- m_method = method;
- m_session = session;
- m_destination = destination;
-
- if(method == "GET")
- {
- m_contenttype = "application/x-www-form-urlencoded";
- }
- else
- {
- m_contenttype = "application/json";
- }
-
- m_parser = new Json.Parser();
- m_message_soup = new Soup.Message(m_method, m_destination);
-
- string credentials = username + ":" + password;
- string base64 = GLib.Base64.encode(credentials.data);
- m_message_soup.request_headers.append("Authorization","Basic %s".printf(base64));
-}
-
-public void add_int(string type, int val)
-{
- if(m_method == "GET")
- {
- if(m_message_string.len > 0)
+
+ private Soup.Session m_session;
+ private Soup.Message m_message_soup;
+ private GLib.StringBuilder m_message_string;
+ private string m_contenttype;
+ private Json.Parser m_parser;
+ private Json.Object m_root_object;
+ private string m_method;
+ private string m_destination;
+
+ public OwnCloudNewsMessage(Soup.Session session, string destination, string username, string password, string method)
+ {
+ m_message_string = new GLib.StringBuilder();
+ m_method = method;
+ m_session = session;
+ m_destination = destination;
+
+ if(method == "GET")
{
- m_message_string.append("&");
+ m_contenttype = "application/x-www-form-urlencoded";
}
-
- m_message_string.append(type + "=" + val.to_string());
- }
- else
- {
- m_message_string.append(",\"" + type + "\":" + val.to_string());
- }
-}
-
-public void add_int_array(string type, string values)
-{
- if(m_method == "GET")
- {
- Logger.warning("OwnCloudNewsMessage.add_int_array: this should not happen");
- }
- else
- {
- m_message_string.append(",\"" + type + "\":[" + values + "]");
- }
-}
-
-public void add_bool(string type, bool val)
-{
- if(m_method == "GET")
- {
- if(m_message_string.len > 0)
+ else
{
- m_message_string.append("&");
+ m_contenttype = "application/json";
}
-
- m_message_string.append(type + "=" + (val ? "true" : "false"));
- }
- else
- {
- m_message_string.append(",\"" + type + "\":" + (val ? "true" : "false"));
- }
-}
-
-public void add_string(string type, string val)
-{
- if(m_method == "GET")
- {
- if(m_message_string.len > 0)
+
+ m_parser = new Json.Parser();
+ m_message_soup = new Soup.Message(m_method, m_destination);
+
+ string credentials = username + ":" + password;
+ string base64 = GLib.Base64.encode(credentials.data);
+ m_message_soup.request_headers.append("Authorization","Basic %s".printf(base64));
+ }
+
+ public void add_int(string type, int val)
+ {
+ if(m_method == "GET")
{
- m_message_string.append("&");
+ if(m_message_string.len > 0)
+ {
+ m_message_string.append("&");
+ }
+
+ m_message_string.append(type + "=" + val.to_string());
+ }
+ else
+ {
+ m_message_string.append(",\"" + type + "\":" + val.to_string());
}
-
- m_message_string.append(type + "=" + val);
- }
- else
- {
- m_message_string.append(",\"" + type + "\":\"" + val + "\"");
}
-}
-
-public ConnectionError send(bool ping = false)
-{
- var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-
- if(m_method == "GET")
+
+ public void add_int_array(string type, string values)
{
- string destination = m_destination;
- if(m_message_string.len > 0)
+ if(m_method == "GET")
{
- destination += "?" + m_message_string.str;
+ Logger.warning("OwnCloudNewsMessage.add_int_array: this should not happen");
+ }
+ else
+ {
+ m_message_string.append(",\"" + type + "\":[" + values + "]");
}
- m_message_soup.set_uri(new Soup.URI(destination));
- Logger.debug(destination);
}
- else
+
+ public void add_bool(string type, bool val)
{
- m_message_string.overwrite(0, "{").append("}");
- m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
+ if(m_method == "GET")
+ {
+ if(m_message_string.len > 0)
+ {
+ m_message_string.append("&");
+ }
+
+ m_message_string.append(type + "=" + (val ? "true" : "false"));
+ }
+ else
+ {
+ m_message_string.append(",\"" + type + "\":" + (val ? "true" : "false"));
+ }
}
-
- if(settingsTweaks.get_boolean("do-not-track"))
+
+ public void add_string(string type, string val)
{
- m_message_soup.request_headers.append("DNT", "1");
+ if(m_method == "GET")
+ {
+ if(m_message_string.len > 0)
+ {
+ m_message_string.append("&");
+ }
+
+ m_message_string.append(type + "=" + val);
+ }
+ else
+ {
+ m_message_string.append(",\"" + type + "\":\"" + val + "\"");
+ }
}
-
- var status = m_session.send_message(m_message_soup);
-
- if(status == 401) // unauthorized
-
+
+ public ConnectionError send(bool ping = false)
{
- return ConnectionError.UNAUTHORIZED;
+ var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+
+ if(m_method == "GET")
+ {
+ string destination = m_destination;
+ if(m_message_string.len > 0)
+ {
+ destination += "?" + m_message_string.str;
+ }
+ m_message_soup.set_uri(new Soup.URI(destination));
+ Logger.debug(destination);
+ }
+ else
+ {
+ m_message_string.overwrite(0, "{").append("}");
+ m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
+ }
+
+ if(settingsTweaks.get_boolean("do-not-track"))
+ {
+ m_message_soup.request_headers.append("DNT", "1");
+ }
+
+ var status = m_session.send_message(m_message_soup);
+
+ if(status == 401) // unauthorized
+
+ {
+ return ConnectionError.UNAUTHORIZED;
+ }
+
+ if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
+ {
+ Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
+ return ConnectionError.CA_ERROR;
+ }
+
+ if(m_message_soup.status_code != 200)
+ {
+ Logger.error("Nextcloud Message: No response - status code: %u %s".printf(m_message_soup.status_code, Soup.Status.get_phrase(m_message_soup.status_code)));
+ return ConnectionError.NO_RESPONSE;
+ }
+
+ if(ping)
+ {
+ Logger.debug("Nextcloud Message: ping successful");
+ return ConnectionError.SUCCESS;
+ }
+
+ try
+ {
+ m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+ }
+ catch(Error e)
+ {
+ Logger.error("Could not load response from Message to Nextcloud");
+ printMessage();
+ Logger.error(e.message);
+ return ConnectionError.UNKNOWN;
+ }
+
+ m_root_object = m_parser.get_root().get_object();
+ return ConnectionError.SUCCESS;
}
-
- if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
+
+ public uint getStatusCode()
{
- Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
- return ConnectionError.CA_ERROR;
+ return m_message_soup.status_code;
}
-
- if(m_message_soup.status_code != 200)
+
+ public Json.Object? get_response_object()
{
- Logger.error("Nextcloud Message: No response - status code: %u %s".printf(m_message_soup.status_code, Soup.Status.get_phrase(m_message_soup.status_code)));
- return ConnectionError.NO_RESPONSE;
+ return m_root_object;
}
-
- if(ping)
+
+ public string getMessage()
{
- Logger.debug("Nextcloud Message: ping successful");
- return ConnectionError.SUCCESS;
+ return m_message_string.str;
}
-
- try
+
+ public void printMessage()
{
- m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+ Logger.debug(m_message_string.str);
}
- catch(Error e)
+
+ public void printResponse()
{
- Logger.error("Could not load response from Message to Nextcloud");
- printMessage();
- Logger.error(e.message);
- return ConnectionError.UNKNOWN;
+ Logger.debug((string)m_message_soup.response_body.flatten().data);
}
-
- m_root_object = m_parser.get_root().get_object();
- return ConnectionError.SUCCESS;
-}
-
-public uint getStatusCode()
-{
- return m_message_soup.status_code;
-}
-
-public Json.Object? get_response_object()
-{
- return m_root_object;
-}
-
-public string getMessage()
-{
- return m_message_string.str;
-}
-
-public void printMessage()
-{
- Logger.debug(m_message_string.str);
-}
-
-public void printResponse()
-{
- Logger.debug((string)m_message_soup.response_body.flatten().data);
-}
}
diff --git a/plugins/backend/owncloud/OwncloudNewsUtils.vala b/plugins/backend/owncloud/OwncloudNewsUtils.vala
index f1795455..2d2d213b 100644
--- a/plugins/backend/owncloud/OwncloudNewsUtils.vala
+++ b/plugins/backend/owncloud/OwncloudNewsUtils.vala
@@ -14,145 +14,145 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.OwncloudNewsUtils : GLib.Object {
-
-GLib.Settings m_settings;
-Password m_password;
-Password m_htaccess_password;
-
-public OwncloudNewsUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
+
+ GLib.Settings m_settings;
+ Password m_password;
+ Password m_htaccess_password;
+
+ public OwncloudNewsUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.owncloud", settings_backend);
- }
- else
- {
- m_settings = new GLib.Settings("org.gnome.feedreader.owncloud");
- }
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, pwSchema, "FeedReader: Nextcloud login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.owncloud", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.owncloud");
+ }
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, pwSchema, "FeedReader: Nextcloud login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getUser();
return attributes;
});
-
- var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING,
- "htaccess", Secret.SchemaAttributeType.BOOLEAN);
- m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: Nextcloud login", () => {
+
+ var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING,
+ "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+ m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: Nextcloud login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getHtaccessUser();
attributes["htaccess"] = "true";
return attributes;
});
-}
-
-public string getURL()
-{
- string tmp_url = Utils.gsettingReadString(m_settings, "url");
- if(tmp_url != "")
+ }
+
+ public string getURL()
{
- if(!tmp_url.has_suffix("/"))
- {
- tmp_url = tmp_url + "/";
- }
-
- if(!tmp_url.has_suffix("/index.php/apps/news/api/v1-2/"))
- {
- tmp_url = tmp_url + "index.php/apps/news/api/v1-2/";
- }
-
- if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+ string tmp_url = Utils.gsettingReadString(m_settings, "url");
+ if(tmp_url != "")
{
- tmp_url = "https://" + tmp_url;
+ if(!tmp_url.has_suffix("/"))
+ {
+ tmp_url = tmp_url + "/";
+ }
+
+ if(!tmp_url.has_suffix("/index.php/apps/news/api/v1-2/"))
+ {
+ tmp_url = tmp_url + "index.php/apps/news/api/v1-2/";
+ }
+
+ if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+ {
+ tmp_url = "https://" + tmp_url;
+ }
}
+
+ Logger.debug("Nextcloud URL: " + tmp_url);
+
+ return tmp_url;
}
-
- Logger.debug("Nextcloud URL: " + tmp_url);
-
- return tmp_url;
-}
-
-public void setURL(string url)
-{
- Utils.gsettingWriteString(m_settings, "url", url);
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getHtaccessUser()
-{
- return Utils.gsettingReadString(m_settings, "htaccess-username");
-}
-
-public void setHtaccessUser(string ht_user)
-{
- Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-}
-
-public string getUnmodifiedURL()
-{
- return Utils.gsettingReadString(m_settings, "url");
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
- m_htaccess_password.delete_password();
-}
-
-public string getHtaccessPasswd()
-{
- return m_htaccess_password.get_password();
-}
-
-public void setHtAccessPassword(string passwd)
-{
- m_htaccess_password.set_password(passwd);
-}
-
-public int countUnread(Gee.List<Feed> feeds, string id)
-{
- int unread = 0;
-
- foreach(Feed feed in feeds)
+
+ public void setURL(string url)
+ {
+ Utils.gsettingWriteString(m_settings, "url", url);
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getHtaccessUser()
+ {
+ return Utils.gsettingReadString(m_settings, "htaccess-username");
+ }
+
+ public void setHtaccessUser(string ht_user)
+ {
+ Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+ }
+
+ public string getUnmodifiedURL()
{
- var ids = feed.getCatIDs();
- foreach(string ID in ids)
+ return Utils.gsettingReadString(m_settings, "url");
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ m_htaccess_password.delete_password();
+ }
+
+ public string getHtaccessPasswd()
+ {
+ return m_htaccess_password.get_password();
+ }
+
+ public void setHtAccessPassword(string passwd)
+ {
+ m_htaccess_password.set_password(passwd);
+ }
+
+ public int countUnread(Gee.List<Feed> feeds, string id)
+ {
+ int unread = 0;
+
+ foreach(Feed feed in feeds)
{
- if(ID == id)
+ var ids = feed.getCatIDs();
+ foreach(string ID in ids)
{
- unread += (int)feed.getUnread();
- break;
+ if(ID == id)
+ {
+ unread += (int)feed.getUnread();
+ break;
+ }
}
}
+
+ return unread;
}
-
- return unread;
-}
}
diff --git a/plugins/backend/ttrss/UntypedJson.vala b/plugins/backend/ttrss/UntypedJson.vala
index 66f5088c..c2e7cd1f 100644
--- a/plugins/backend/ttrss/UntypedJson.vala
+++ b/plugins/backend/ttrss/UntypedJson.vala
@@ -2,46 +2,46 @@
// dynamically cast everything to the type we expect
namespace FeedReader.UntypedJson
{
-
-namespace Object
-{
-
-public Value? get_value_member(Json.Object obj, string key)
-{
- var member = obj.get_member(key);
- if(member == null)
- {
- return null;
- }
-
- return member.get_value();
-}
-
-public int? get_int_member(Json.Object obj, string key)
-{
- var value = get_value_member(obj, key);
- if (value == null)
+
+ namespace Object
{
- return null;
+
+ public Value? get_value_member(Json.Object obj, string key)
+ {
+ var member = obj.get_member(key);
+ if(member == null)
+ {
+ return null;
+ }
+
+ return member.get_value();
+ }
+
+ public int? get_int_member(Json.Object obj, string key)
+ {
+ var value = get_value_member(obj, key);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var result = new Value(Type.INT);
+ value.transform(ref result);
+ return result.get_int();
+ }
+
+ public string? get_string_member(Json.Object obj, string key)
+ {
+ var value = get_value_member(obj, key);
+ if (value == null)
+ {
+ return null;
+ }
+
+ var result = new Value(Type.STRING);
+ value.transform(ref result);
+ return result.get_string();
+ }
+
}
-
- var result = new Value(Type.INT);
- value.transform(ref result);
- return result.get_int();
-}
-
-public string? get_string_member(Json.Object obj, string key)
-{
- var value = get_value_member(obj, key);
- if (value == null)
- {
- return null;
- }
-
- var result = new Value(Type.STRING);
- value.transform(ref result);
- return result.get_string();
-}
-
-}
}
diff --git a/plugins/backend/ttrss/ttrssAPI.vala b/plugins/backend/ttrss/ttrssAPI.vala
index 98c9e356..92ad7420 100644
--- a/plugins/backend/ttrss/ttrssAPI.vala
+++ b/plugins/backend/ttrss/ttrssAPI.vala
@@ -14,961 +14,961 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.ttrssAPI : GLib.Object {
-
-public string m_ttrss_url { get; private set; }
-private ttrssUtils m_utils;
-private string m_ttrss_sessionid;
-private string? m_iconDir = null;
-private Soup.Session m_session;
-
-public ttrssAPI (ttrssUtils utils)
-{
- m_utils = utils;
- m_session = new Soup.Session();
- m_session.user_agent = Constants.USER_AGENT;
- m_session.ssl_strict = false;
- m_session.authenticate.connect((msg, auth, retrying) => {
+
+ public string m_ttrss_url { get; private set; }
+ private ttrssUtils m_utils;
+ private string m_ttrss_sessionid;
+ private string? m_iconDir = null;
+ private Soup.Session m_session;
+
+ public ttrssAPI (ttrssUtils utils)
+ {
+ m_utils = utils;
+ m_session = new Soup.Session();
+ m_session.user_agent = Constants.USER_AGENT;
+ m_session.ssl_strict = false;
+ m_session.authenticate.connect((msg, auth, retrying) => {
if(m_utils.getHtaccessUser() == "")
{
- Logger.error("TTRSS Session: need Authentication");
+ Logger.error("TTRSS Session: need Authentication");
}
else if(!retrying)
{
- auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+ auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
}
});
-}
-
-
-public LoginResponse login()
-{
- Logger.debug("TTRSS: login");
- string username = m_utils.getUser();
- string passwd = m_utils.getPasswd();
- m_ttrss_url = m_utils.getURL();
-
- if(m_ttrss_url == "" && username == "" && passwd == "")
- {
- m_ttrss_url = "example-host/tt-rss";
- return LoginResponse.ALL_EMPTY;
- }
- if(m_ttrss_url == "")
- {
- return LoginResponse.MISSING_URL;
- }
- if(GLib.Uri.parse_scheme(m_ttrss_url) == null)
- {
- return LoginResponse.INVALID_URL;
- }
- if(passwd == "")
- {
- return LoginResponse.MISSING_PASSWD;
}
-
-
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("op", "login");
- if(username != "")
+
+
+ public LoginResponse login()
{
- message.add_string("user", username);
- }
- message.add_string("password", passwd);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- m_ttrss_sessionid = UntypedJson.Object.get_string_member(response, "session_id");
- var api_level = UntypedJson.Object.get_int_member(response, "api_level");
- Logger.info("TTRSS Session ID: %s".printf(m_ttrss_sessionid));
- Logger.info("TTRSS API Level: %lld".printf(api_level));
-
- m_iconDir = m_ttrss_url.replace("api/", getIconDir());
-
- if(haveAPIplugin())
+ Logger.debug("TTRSS: login");
+ string username = m_utils.getUser();
+ string passwd = m_utils.getPasswd();
+ m_ttrss_url = m_utils.getURL();
+
+ if(m_ttrss_url == "" && username == "" && passwd == "")
{
- return LoginResponse.SUCCESS;
+ m_ttrss_url = "example-host/tt-rss";
+ return LoginResponse.ALL_EMPTY;
}
-
- return LoginResponse.PLUGIN_NEEDED;
- }
-
- if(status == ConnectionError.API_ERROR)
- {
- return LoginResponse.API_ERROR;
- }
- else if(status == ConnectionError.NO_RESPONSE)
- {
- return LoginResponse.NO_CONNECTION;
- }
- else if(status == ConnectionError.API_DISABLED)
- {
- return LoginResponse.NO_API_ACCESS;
- }
- else if(status == ConnectionError.CA_ERROR)
- {
- return LoginResponse.CA_ERROR;
- }
- else if(status == ConnectionError.UNAUTHORIZED)
- {
- return LoginResponse.UNAUTHORIZED;
- }
-
- return LoginResponse.UNKNOWN_ERROR;
-}
-
-public bool logout()
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "logout");
- int status = message.send();
- Logger.warning("TTRSS: logout");
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- m_ttrss_sessionid = "";
- return response.get_boolean_member("status");
- }
-
- return false;
-}
-
-
-public bool isloggedin()
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "isLoggedIn");
- int status = message.send();
- Logger.debug("TTRSS: isloggedin?");
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- return response.get_boolean_member("status");
- }
-
- return false;
-}
-
-private bool haveAPIplugin()
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "removeLabel");
- int status = message.send();
-
- if(status == ConnectionError.API_ERROR)
- {
- var response = message.get_response_object();
- if(response.has_member("error"))
+ if(m_ttrss_url == "")
{
- if(response.get_string_member("error") == "INCORRECT_USAGE")
+ return LoginResponse.MISSING_URL;
+ }
+ if(GLib.Uri.parse_scheme(m_ttrss_url) == null)
+ {
+ return LoginResponse.INVALID_URL;
+ }
+ if(passwd == "")
+ {
+ return LoginResponse.MISSING_PASSWD;
+ }
+
+
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("op", "login");
+ if(username != "")
+ {
+ message.add_string("user", username);
+ }
+ message.add_string("password", passwd);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ m_ttrss_sessionid = UntypedJson.Object.get_string_member(response, "session_id");
+ var api_level = UntypedJson.Object.get_int_member(response, "api_level");
+ Logger.info("TTRSS Session ID: %s".printf(m_ttrss_sessionid));
+ Logger.info("TTRSS API Level: %lld".printf(api_level));
+
+ m_iconDir = m_ttrss_url.replace("api/", getIconDir());
+
+ if(haveAPIplugin())
{
- return true;
+ return LoginResponse.SUCCESS;
}
+
+ return LoginResponse.PLUGIN_NEEDED;
}
- }
-
- return false;
-}
-
-
-public int getUnreadCount()
-{
- int unread = 0;
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getUnread");
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- int? maybe_unread = UntypedJson.Object.get_int_member(response, "unread");
- if(maybe_unread != null)
+
+ if(status == ConnectionError.API_ERROR)
{
- unread = maybe_unread;
+ return LoginResponse.API_ERROR;
}
- else
+ else if(status == ConnectionError.NO_RESPONSE)
{
- Logger.warning("Could not parse unread articles");
+ return LoginResponse.NO_CONNECTION;
}
- }
- Logger.info("There are %i unread articles".printf(unread));
-
- return unread;
-}
-
-
-public bool getFeeds(Gee.List<Feed> feeds, Gee.List<Category> categories)
-{
- foreach(var item in categories)
- {
- if(int.parse(item.getCatID()) > 0)
+ else if(status == ConnectionError.API_DISABLED)
{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getFeeds");
- message.add_int("cat_id", int.parse(item.getCatID()));
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
+ return LoginResponse.NO_API_ACCESS;
+ }
+ else if(status == ConnectionError.CA_ERROR)
+ {
+ return LoginResponse.CA_ERROR;
+ }
+ else if(status == ConnectionError.UNAUTHORIZED)
+ {
+ return LoginResponse.UNAUTHORIZED;
+ }
+
+ return LoginResponse.UNKNOWN_ERROR;
+ }
+
+ public bool logout()
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "logout");
+ int status = message.send();
+ Logger.warning("TTRSS: logout");
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ m_ttrss_sessionid = "";
+ return response.get_boolean_member("status");
+ }
+
+ return false;
+ }
+
+
+ public bool isloggedin()
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "isLoggedIn");
+ int status = message.send();
+ Logger.debug("TTRSS: isloggedin?");
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ return response.get_boolean_member("status");
+ }
+
+ return false;
+ }
+
+ private bool haveAPIplugin()
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "removeLabel");
+ int status = message.send();
+
+ if(status == ConnectionError.API_ERROR)
+ {
+ var response = message.get_response_object();
+ if(response.has_member("error"))
{
- var response = message.get_response_array();
- var feed_count = response.get_length();
-
- for(uint i = 0; i < feed_count; i++)
+ if(response.get_string_member("error") == "INCORRECT_USAGE")
{
- var feed_node = response.get_object_element(i);
- string feed_id = UntypedJson.Object.get_string_member(feed_node, "id");
- string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
-
- feeds.add(
- new Feed(
- feed_id,
- feed_node.get_string_member("title"),
- feed_node.get_string_member("feed_url"),
- UntypedJson.Object.get_int_member(feed_node, "unread"),
- ListUtils.single(UntypedJson.Object.get_string_member(feed_node, "cat_id")),
- icon_url,
- feed_node.get_string_member("feed_url")
- )
- );
+ return true;
}
}
+ }
+
+ return false;
+ }
+
+
+ public int getUnreadCount()
+ {
+ int unread = 0;
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getUnread");
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ int? maybe_unread = UntypedJson.Object.get_int_member(response, "unread");
+ if(maybe_unread != null)
+ {
+ unread = maybe_unread;
+ }
else
{
- return false;
+ Logger.warning("Could not parse unread articles");
}
}
+ Logger.info("There are %i unread articles".printf(unread));
+
+ return unread;
}
- return true;
-}
-
-
-public bool getUncategorizedFeeds(Gee.List<Feed> feeds)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getFeeds");
- message.add_int("cat_id", 0);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
+
+
+ public bool getFeeds(Gee.List<Feed> feeds, Gee.List<Category> categories)
{
- var response = message.get_response_array();
- var feed_count = response.get_length();
-
- for(uint i = 0; i < feed_count; i++)
+ foreach(var item in categories)
{
- var feed_node = response.get_object_element(i);
- string feed_id = UntypedJson.Object.get_string_member(feed_node, "id");
- string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
-
- feeds.add(
- new Feed(
- feed_id,
- feed_node.get_string_member("title"),
- feed_node.get_string_member("feed_url"),
- UntypedJson.Object.get_int_member(feed_node, "unread"),
- ListUtils.single(UntypedJson.Object.get_string_member(feed_node, "cat_id")),
- icon_url,
- feed_node.get_string_member("feed_url")
- )
- );
+ if(int.parse(item.getCatID()) > 0)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getFeeds");
+ message.add_int("cat_id", int.parse(item.getCatID()));
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_array();
+ var feed_count = response.get_length();
+
+ for(uint i = 0; i < feed_count; i++)
+ {
+ var feed_node = response.get_object_element(i);
+ string feed_id = UntypedJson.Object.get_string_member(feed_node, "id");
+ string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
+
+ feeds.add(
+ new Feed(
+ feed_id,
+ feed_node.get_string_member("title"),
+ feed_node.get_string_member("feed_url"),
+ UntypedJson.Object.get_int_member(feed_node, "unread"),
+ ListUtils.single(UntypedJson.Object.get_string_member(feed_node, "cat_id")),
+ icon_url,
+ feed_node.get_string_member("feed_url")
+ )
+ );
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
}
return true;
}
-
- return false;
-}
-
-public bool getTags(Gee.List<Tag> tags)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getLabels");
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_array();
- var tag_count = response.get_length();
-
- var db = DataBase.readOnly();
- for(uint i = 0; i < tag_count; ++i)
- {
- var tag_node = response.get_object_element(i);
- tags.add(
- new Tag(
- UntypedJson.Object.get_string_member(tag_node, "id"),
- tag_node.get_string_member("caption"),
- db.getTagColor()
+
+
+ public bool getUncategorizedFeeds(Gee.List<Feed> feeds)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getFeeds");
+ message.add_int("cat_id", 0);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_array();
+ var feed_count = response.get_length();
+
+ for(uint i = 0; i < feed_count; i++)
+ {
+ var feed_node = response.get_object_element(i);
+ string feed_id = UntypedJson.Object.get_string_member(feed_node, "id");
+ string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
+
+ feeds.add(
+ new Feed(
+ feed_id,
+ feed_node.get_string_member("title"),
+ feed_node.get_string_member("feed_url"),
+ UntypedJson.Object.get_int_member(feed_node, "unread"),
+ ListUtils.single(UntypedJson.Object.get_string_member(feed_node, "cat_id")),
+ icon_url,
+ feed_node.get_string_member("feed_url")
)
);
+ }
+ return true;
}
-
- return true;
- }
-
- return false;
-}
-
-
-public string? getIconDir()
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getConfig");
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- return response.get_string_member("icons_url") + "/";
- }
-
- return null;
-}
-
-
-public bool getCategories(Gee.List<Category> categories)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getFeedTree");
- message.add_bool("include_empty", true);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.has_member("categories"))
+
+ return false;
+ }
+
+ public bool getTags(Gee.List<Tag> tags)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getLabels");
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
{
- var category_object = response.get_object_member("categories");
- getSubCategories(categories, category_object, 0, CategoryID.MASTER.to_string());
+ var response = message.get_response_array();
+ var tag_count = response.get_length();
+
+ var db = DataBase.readOnly();
+ for(uint i = 0; i < tag_count; ++i)
+ {
+ var tag_node = response.get_object_element(i);
+ tags.add(
+ new Tag(
+ UntypedJson.Object.get_string_member(tag_node, "id"),
+ tag_node.get_string_member("caption"),
+ db.getTagColor()
+ )
+ );
+ }
+
return true;
}
+
+ return false;
+ }
+
+
+ public string? getIconDir()
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getConfig");
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ return response.get_string_member("icons_url") + "/";
+ }
+
+ return null;
}
-
- return false;
-}
-
-
-private void getSubCategories(Gee.List<Category> categories, Json.Object categorie, int level, string parent)
-{
- level++;
- int orderID = 0;
- var subcategorie = categorie.get_array_member("items");
- var items_count = subcategorie.get_length();
- for(uint i = 0; i < items_count; i++)
- {
- var categorie_node = subcategorie.get_object_element(i);
- string catID = UntypedJson.Object.get_string_member(categorie_node, "id");
- if(catID.has_prefix("CAT:"))
- {
- orderID++;
- string categorieID = catID.slice(4, catID.length);
-
- if(int.parse(categorieID) > 0)
+
+
+ public bool getCategories(Gee.List<Category> categories)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getFeedTree");
+ message.add_bool("include_empty", true);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.has_member("categories"))
{
- string title = categorie_node.get_string_member("name");
- int unread_count = UntypedJson.Object.get_int_member(categorie_node, "unread");
-
- if(title == "Uncategorized")
- {
- unread_count = getUncategorizedUnread();
- }
-
- categories.add(
- new Category (
- categorieID,
- title,
- unread_count,
- orderID,
- parent,
- level
- )
- );
+ var category_object = response.get_object_member("categories");
+ getSubCategories(categories, category_object, 0, CategoryID.MASTER.to_string());
+ return true;
}
-
- getSubCategories(categories, categorie_node, level, categorieID);
}
- }
-}
-
-
-private int getUncategorizedUnread()
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getCounters");
- message.add_string("output_mode", "c");
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_array();
- var categorie_count = response.get_length();
-
- for(int i = 0; i < categorie_count; i++)
+
+ return false;
+ }
+
+
+ private void getSubCategories(Gee.List<Category> categories, Json.Object categorie, int level, string parent)
+ {
+ level++;
+ int orderID = 0;
+ var subcategorie = categorie.get_array_member("items");
+ var items_count = subcategorie.get_length();
+ for(uint i = 0; i < items_count; i++)
{
- var categorie_node = response.get_object_element(i);
- if(UntypedJson.Object.get_int_member(categorie_node, "id") == 0)
+ var categorie_node = subcategorie.get_object_element(i);
+ string catID = UntypedJson.Object.get_string_member(categorie_node, "id");
+ if(catID.has_prefix("CAT:"))
{
- if(categorie_node.has_member("kind"))
+ orderID++;
+ string categorieID = catID.slice(4, catID.length);
+
+ if(int.parse(categorieID) > 0)
{
- if(categorie_node.get_string_member("kind") == "cat")
+ string title = categorie_node.get_string_member("name");
+ int unread_count = UntypedJson.Object.get_int_member(categorie_node, "unread");
+
+ if(title == "Uncategorized")
{
- return UntypedJson.Object.get_int_member(categorie_node, "counter");
+ unread_count = getUncategorizedUnread();
}
+
+ categories.add(
+ new Category (
+ categorieID,
+ title,
+ unread_count,
+ orderID,
+ parent,
+ level
+ )
+ );
}
+
+ getSubCategories(categories, categorie_node, level, categorieID);
}
}
}
-
- return 0;
-}
-
-
-public void getHeadlines(Gee.List<Article> articles, int skip, int limit, ArticleStatus whatToGet, int feedID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getHeadlines");
- message.add_int("feed_id", feedID);
- message.add_int("limit", limit);
- message.add_int("skip", skip);
-
- switch(whatToGet)
- {
- case ArticleStatus.ALL:
- message.add_string("view_mode", "all_articles");
- break;
-
- case ArticleStatus.UNREAD:
- message.add_string("view_mode", "unread");
- break;
-
- case ArticleStatus.MARKED:
- message.add_string("view_mode", "marked");
- break;
- }
-
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_array();
- var headline_count = response.get_length();
-
- for(uint i = 0; i < headline_count; i++)
+
+
+ private int getUncategorizedUnread()
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getCounters");
+ message.add_string("output_mode", "c");
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
{
- var headline_node = response.get_object_element(i);
-
- Gee.List<string>? tags = null;
- if(headline_node.has_member("labels"))
+ var response = message.get_response_array();
+ var categorie_count = response.get_length();
+
+ for(int i = 0; i < categorie_count; i++)
{
- var labels = headline_node.get_array_member("labels");
-
- uint tag_count = 0;
- if(labels != null)
- {
- tag_count = labels.get_length();
- }
-
- if(tag_count > 0)
+ var categorie_node = response.get_object_element(i);
+ if(UntypedJson.Object.get_int_member(categorie_node, "id") == 0)
{
- tags = new Gee.ArrayList<string>();
- for(int j = 0; j < tag_count; ++j)
+ if(categorie_node.has_member("kind"))
{
- tags.add(labels.get_array_element(j).get_int_element(0).to_string());
+ if(categorie_node.get_string_member("kind") == "cat")
+ {
+ return UntypedJson.Object.get_int_member(categorie_node, "counter");
+ }
}
}
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(headline_node.has_member("attachments"))
+ }
+
+ return 0;
+ }
+
+
+ public void getHeadlines(Gee.List<Article> articles, int skip, int limit, ArticleStatus whatToGet, int feedID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getHeadlines");
+ message.add_int("feed_id", feedID);
+ message.add_int("limit", limit);
+ message.add_int("skip", skip);
+
+ switch(whatToGet)
+ {
+ case ArticleStatus.ALL:
+ message.add_string("view_mode", "all_articles");
+ break;
+
+ case ArticleStatus.UNREAD:
+ message.add_string("view_mode", "unread");
+ break;
+
+ case ArticleStatus.MARKED:
+ message.add_string("view_mode", "marked");
+ break;
+ }
+
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_array();
+ var headline_count = response.get_length();
+
+ for(uint i = 0; i < headline_count; i++)
{
- var attachments = headline_node.get_array_member("attachments");
-
- uint mediaCount = 0;
- if(attachments != null)
+ var headline_node = response.get_object_element(i);
+
+ Gee.List<string>? tags = null;
+ if(headline_node.has_member("labels"))
{
- mediaCount = attachments.get_length();
+ var labels = headline_node.get_array_member("labels");
+
+ uint tag_count = 0;
+ if(labels != null)
+ {
+ tag_count = labels.get_length();
+ }
+
+ if(tag_count > 0)
+ {
+ tags = new Gee.ArrayList<string>();
+ for(int j = 0; j < tag_count; ++j)
+ {
+ tags.add(labels.get_array_element(j).get_int_element(0).to_string());
+ }
+ }
}
-
- for(int j = 0; j < mediaCount; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(headline_node.has_member("attachments"))
{
- var attachment = attachments.get_object_element(j);
- enclosures.add(new Enclosure(
- UntypedJson.Object.get_string_member(headline_node, "id"),
- attachment.get_string_member("content_url"),
- EnclosureType.from_string(attachment.get_string_member("content_type"))));
+ var attachments = headline_node.get_array_member("attachments");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(new Enclosure(
+ UntypedJson.Object.get_string_member(headline_node, "id"),
+ attachment.get_string_member("content_url"),
+ EnclosureType.from_string(attachment.get_string_member("content_type"))));
+ }
}
- }
-
- var Article = new Article(
- UntypedJson.Object.get_string_member(headline_node, "id"),
- headline_node.get_string_member("title"),
- headline_node.get_string_member("link"),
- UntypedJson.Object.get_string_member(headline_node, "feed_id"),
- headline_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
- headline_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- null,
- null,
- headline_node.get_string_member("author"),
- new DateTime.from_unix_local(UntypedJson.Object.get_int_member(headline_node, "updated")),
- -1,
- tags,
- enclosures
+
+ var Article = new Article(
+ UntypedJson.Object.get_string_member(headline_node, "id"),
+ headline_node.get_string_member("title"),
+ headline_node.get_string_member("link"),
+ UntypedJson.Object.get_string_member(headline_node, "feed_id"),
+ headline_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
+ headline_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ null,
+ null,
+ headline_node.get_string_member("author"),
+ new DateTime.from_unix_local(UntypedJson.Object.get_int_member(headline_node, "updated")),
+ -1,
+ tags,
+ enclosures
);
-
- articles.add(Article);
+
+ articles.add(Article);
+ }
}
}
-}
-
-// tt-rss server needs newsplusplus extention
-public Gee.List<string>? NewsPlus(ArticleStatus type, int limit)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getCompactHeadlines");
- message.add_int("feed_id", ttrssUtils.TTRSSSpecialID.ALL);
- message.add_int("limit", limit);
- if(type == ArticleStatus.UNREAD)
- {
- message.add_string("view_mode", "unread");
- }
- else if(type == ArticleStatus.MARKED)
- {
- message.add_string("view_mode", "marked");
- }
- else
+
+ // tt-rss server needs newsplusplus extention
+ public Gee.List<string>? NewsPlus(ArticleStatus type, int limit)
{
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getCompactHeadlines");
+ message.add_int("feed_id", ttrssUtils.TTRSSSpecialID.ALL);
+ message.add_int("limit", limit);
+ if(type == ArticleStatus.UNREAD)
+ {
+ message.add_string("view_mode", "unread");
+ }
+ else if(type == ArticleStatus.MARKED)
+ {
+ message.add_string("view_mode", "marked");
+ }
+ else
+ {
+ return null;
+ }
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_array();
+ var headline_count = response.get_length();
+
+ var ids = new Gee.LinkedList<string>();
+
+ for(uint i = 0; i < headline_count; i++)
+ {
+ var headline_node = response.get_object_element(i);
+ ids.add(UntypedJson.Object.get_string_member(headline_node, "id"));
+ }
+ return ids;
+ }
return null;
}
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
+
+
+ public Gee.List<Article> getArticles(Gee.List<int> articleIDs)
{
- var response = message.get_response_array();
- var headline_count = response.get_length();
-
- var ids = new Gee.LinkedList<string>();
-
- for(uint i = 0; i < headline_count; i++)
+ var articles = new Gee.ArrayList<Article>();
+ if(articleIDs.is_empty)
{
- var headline_node = response.get_object_element(i);
- ids.add(UntypedJson.Object.get_string_member(headline_node, "id"));
+ return articles;
}
- return ids;
- }
- return null;
-}
-
-
-public Gee.List<Article> getArticles(Gee.List<int> articleIDs)
-{
- var articles = new Gee.ArrayList<Article>();
- if(articleIDs.is_empty)
- {
- return articles;
- }
-
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "getArticle");
- message.add_comma_separated_int_array("article_id", articleIDs);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_array();
- var article_count = response.get_length();
- Logger.debug(@"Got $article_count new articles");
-
- for(uint i = 0; i < article_count; i++)
+
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "getArticle");
+ message.add_comma_separated_int_array("article_id", articleIDs);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
{
- var article_node = response.get_object_element(i);
-
- Gee.List<string>? tags = null;
- if(article_node.has_member("labels"))
+ var response = message.get_response_array();
+ var article_count = response.get_length();
+ Logger.debug(@"Got $article_count new articles");
+
+ for(uint i = 0; i < article_count; i++)
{
- var labels = article_node.get_array_member("labels");
-
- uint tag_count = 0;
- if(labels != null)
- {
- tag_count = labels.get_length();
- }
-
- if(tag_count > 0)
+ var article_node = response.get_object_element(i);
+
+ Gee.List<string>? tags = null;
+ if(article_node.has_member("labels"))
{
- tags = new Gee.ArrayList<string>();
+ var labels = article_node.get_array_member("labels");
+
+ uint tag_count = 0;
+ if(labels != null)
+ {
+ tag_count = labels.get_length();
+ }
+
+ if(tag_count > 0)
+ {
+ tags = new Gee.ArrayList<string>();
+ }
+
+ for(int j = 0; j < tag_count; ++j)
+ {
+ tags.add(labels.get_array_element(j).get_int_element(0).to_string());
+ }
}
-
- for(int j = 0; j < tag_count; ++j)
+
+ var enclosures = new Gee.ArrayList<Enclosure>();
+ if(article_node.has_member("attachments"))
{
- tags.add(labels.get_array_element(j).get_int_element(0).to_string());
+ var attachments = article_node.get_array_member("attachments");
+
+ uint mediaCount = 0;
+ if(attachments != null)
+ {
+ mediaCount = attachments.get_length();
+ }
+
+ for(int j = 0; j < mediaCount; ++j)
+ {
+ var attachment = attachments.get_object_element(j);
+ enclosures.add(new Enclosure(
+ UntypedJson.Object.get_string_member(article_node, "id"),
+ attachment.get_string_member("content_url"),
+ EnclosureType.from_string(attachment.get_string_member("content_type"))));
+ }
}
+
+ var Article = new Article(
+ UntypedJson.Object.get_string_member(article_node, "id"),
+ article_node.get_string_member("title"),
+ article_node.get_string_member("link"),
+ UntypedJson.Object.get_string_member(article_node, "feed_id"),
+ article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
+ article_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+ article_node.get_string_member("content"),
+ null,
+ article_node.get_string_member("author"),
+ new DateTime.from_unix_local(UntypedJson.Object.get_int_member(article_node, "updated")),
+ -1,
+ tags,
+ enclosures
+ );
+
+ articles.add(Article);
}
-
- var enclosures = new Gee.ArrayList<Enclosure>();
- if(article_node.has_member("attachments"))
+ }
+ return articles;
+ }
+
+ public bool catchupFeed(int feedID, bool isCatID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "catchupFeed");
+ message.add_int("feed_id", feedID);
+ message.add_bool("is_cat", isCatID);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.get_string_member("status") == "OK")
{
- var attachments = article_node.get_array_member("attachments");
-
- uint mediaCount = 0;
- if(attachments != null)
- {
- mediaCount = attachments.get_length();
- }
-
- for(int j = 0; j < mediaCount; ++j)
- {
- var attachment = attachments.get_object_element(j);
- enclosures.add(new Enclosure(
- UntypedJson.Object.get_string_member(article_node, "id"),
- attachment.get_string_member("content_url"),
- EnclosureType.from_string(attachment.get_string_member("content_type"))));
- }
+ return true;
}
-
- var Article = new Article(
- UntypedJson.Object.get_string_member(article_node, "id"),
- article_node.get_string_member("title"),
- article_node.get_string_member("link"),
- UntypedJson.Object.get_string_member(article_node, "feed_id"),
- article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
- article_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
- article_node.get_string_member("content"),
- null,
- article_node.get_string_member("author"),
- new DateTime.from_unix_local(UntypedJson.Object.get_int_member(article_node, "updated")),
- -1,
- tags,
- enclosures
- );
-
- articles.add(Article);
}
+
+ return false;
}
- return articles;
-}
-
-public bool catchupFeed(int feedID, bool isCatID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "catchupFeed");
- message.add_int("feed_id", feedID);
- message.add_bool("is_cat", isCatID);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
+
+ public bool updateArticleUnread(Gee.List<int> articleIDs, ArticleStatus unread)
{
- var response = message.get_response_object();
- if(response.get_string_member("status") == "OK")
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "updateArticle");
+ message.add_comma_separated_int_array("article_ids", articleIDs);
+ if(unread == ArticleStatus.UNREAD)
{
- return true;
+ message.add_int("mode", 1);
}
- }
-
- return false;
-}
-
-public bool updateArticleUnread(Gee.List<int> articleIDs, ArticleStatus unread)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "updateArticle");
- message.add_comma_separated_int_array("article_ids", articleIDs);
- if(unread == ArticleStatus.UNREAD)
- {
- message.add_int("mode", 1);
- }
- else if(unread == ArticleStatus.READ)
- {
- message.add_int("mode", 0);
- }
- message.add_int("field", 2);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.get_string_member("status") == "OK")
+ else if(unread == ArticleStatus.READ)
{
- return true;
+ message.add_int("mode", 0);
}
- }
-
- return false;
-}
-
-
-public bool updateArticleMarked(int articleID, ArticleStatus marked)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "updateArticle");
- message.add_int("article_ids", articleID);
- if(marked == ArticleStatus.MARKED)
- {
- message.add_int("mode", 1);
- }
- else if(marked == ArticleStatus.UNMARKED)
- {
- message.add_int("mode", 0);
- }
- message.add_int("field", 0);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.get_string_member("status") == "OK")
+ message.add_int("field", 2);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
{
- return true;
+ var response = message.get_response_object();
+ if(response.get_string_member("status") == "OK")
+ {
+ return true;
+ }
}
- }
-
- return false;
-}
-
-public bool setArticleLabel(int articleID, int tagID, bool add)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "setArticleLabel");
- message.add_int("article_ids", articleID);
- message.add_int("label_id", tagID);
- message.add_bool("assign", add);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.get_string_member("status") == "OK")
+
+ return false;
+ }
+
+
+ public bool updateArticleMarked(int articleID, ArticleStatus marked)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "updateArticle");
+ message.add_int("article_ids", articleID);
+ if(marked == ArticleStatus.MARKED)
{
- return true;
+ message.add_int("mode", 1);
}
- }
-
- return false;
-}
-
-public int64 addLabel(string caption)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "addLabel");
- message.add_string("caption", caption);
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- return message.get_response_int();
- }
-
- return 0;
-}
-
-public bool removeLabel(int tagID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "removeLabel");
- message.add_int("label_id", tagID);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool renameLabel(int tagID, string newName)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "renameLabel");
- message.add_int("label_id", tagID);
- message.add_string("caption", newName);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-
-public bool subscribeToFeed(string feedURL, string? catID, string? username, string? password, out string errmsg)
-{
- errmsg = "";
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "subscribeToFeed");
- message.add_string("feed_url", feedURL);
-
- if(catID != null)
- {
- message.add_int("category_id", int.parse(catID));
- }
- if(username != null && password != null)
- {
- message.add_string("login", username);
- message.add_string("password", password);
- }
-
- int msg_status = message.send();
-
- if(msg_status == ConnectionError.SUCCESS)
- {
- var response = message.get_response_object();
- if(response.has_member("status"))
+ else if(marked == ArticleStatus.UNMARKED)
+ {
+ message.add_int("mode", 0);
+ }
+ message.add_int("field", 0);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.get_string_member("status") == "OK")
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool setArticleLabel(int articleID, int tagID, bool add)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "setArticleLabel");
+ message.add_int("article_ids", articleID);
+ message.add_int("label_id", tagID);
+ message.add_bool("assign", add);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.get_string_member("status") == "OK")
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public int64 addLabel(string caption)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "addLabel");
+ message.add_string("caption", caption);
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ return message.get_response_int();
+ }
+
+ return 0;
+ }
+
+ public bool removeLabel(int tagID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "removeLabel");
+ message.add_int("label_id", tagID);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool renameLabel(int tagID, string newName)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "renameLabel");
+ message.add_int("label_id", tagID);
+ message.add_string("caption", newName);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+
+ public bool subscribeToFeed(string feedURL, string? catID, string? username, string? password, out string errmsg)
+ {
+ errmsg = "";
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "subscribeToFeed");
+ message.add_string("feed_url", feedURL);
+
+ if(catID != null)
+ {
+ message.add_int("category_id", int.parse(catID));
+ }
+ if(username != null && password != null)
{
- var status = response.get_object_member("status");
- if(status.has_member("code"))
+ message.add_string("login", username);
+ message.add_string("password", password);
+ }
+
+ int msg_status = message.send();
+
+ if(msg_status == ConnectionError.SUCCESS)
+ {
+ var response = message.get_response_object();
+ if(response.has_member("status"))
{
- switch(UntypedJson.Object.get_int_member(status, "code"))
+ var status = response.get_object_member("status");
+ if(status.has_member("code"))
{
- case 0:
- case 1:
- return true;
- case 2:
- errmsg = _("Invalid URL");
- return false;
- case 3:
- errmsg = _("URL content is HTML, no feeds available");
- return false;
- case 4:
- errmsg = _("URL content is HTML which contains multiple feeds.");
- return false;
- case 5:
- errmsg = _("Couldn't download the URL content.");
- return false;
- case 6:
- errmsg = _("The content is invalid XML.");
- return false;
- default:
- if(status.has_member("message"))
- {
- errmsg = status.get_string_member("message");
- }
- else
+ switch(UntypedJson.Object.get_int_member(status, "code"))
{
- errmsg = "ttrss error";
+ case 0:
+ case 1:
+ return true;
+ case 2:
+ errmsg = _("Invalid URL");
+ return false;
+ case 3:
+ errmsg = _("URL content is HTML, no feeds available");
+ return false;
+ case 4:
+ errmsg = _("URL content is HTML which contains multiple feeds.");
+ return false;
+ case 5:
+ errmsg = _("Couldn't download the URL content.");
+ return false;
+ case 6:
+ errmsg = _("The content is invalid XML.");
+ return false;
+ default:
+ if(status.has_member("message"))
+ {
+ errmsg = status.get_string_member("message");
+ }
+ else
+ {
+ errmsg = "ttrss error";
+ }
+ return false;
}
- return false;
}
}
}
+
+ errmsg = _("Error reaching tt-rss");
+ return false;
+ }
+
+ public bool unsubscribeFeed(int feedID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "unsubscribeFeed");
+ message.add_int("feed_id", feedID);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public string? createCategory(string title, int? parentID = null)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "addCategory");
+ message.add_string("caption", title);
+ if(parentID != null)
+ {
+ message.add_int("parent_id", parentID);
+ }
+ int status = message.send();
+
+ if(status == ConnectionError.SUCCESS)
+ {
+ return message.get_response_string();
+ }
+
+ return null;
}
-
- errmsg = _("Error reaching tt-rss");
- return false;
-}
-
-public bool unsubscribeFeed(int feedID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "unsubscribeFeed");
- message.add_int("feed_id", feedID);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public string? createCategory(string title, int? parentID = null)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "addCategory");
- message.add_string("caption", title);
- if(parentID != null)
- {
- message.add_int("parent_id", parentID);
- }
- int status = message.send();
-
- if(status == ConnectionError.SUCCESS)
- {
- return message.get_response_string();
- }
-
- return null;
-}
-
-public bool removeCategory(int catID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "removeCategory");
- message.add_int("category_id", catID);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool moveCategory(int catID, int parentID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "moveCategory");
- message.add_int("category_id", catID);
- if(parentID != int.parse(CategoryID.MASTER.to_string()))
- {
- message.add_int("parent_id", parentID);
+
+ public bool removeCategory(int catID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "removeCategory");
+ message.add_int("category_id", catID);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool moveCategory(int catID, int parentID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "moveCategory");
+ message.add_int("category_id", catID);
+ if(parentID != int.parse(CategoryID.MASTER.to_string()))
+ {
+ message.add_int("parent_id", parentID);
+ }
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool renameCategory(int catID, string title)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "renameCategory");
+ message.add_int("category_id", catID);
+ message.add_string("caption", title);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool renameFeed(int feedID, string title)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "renameFeed");
+ message.add_int("feed_id", feedID);
+ message.add_string("caption", title);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool moveFeed(int feedID, int catID)
+ {
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ message.add_string("sid", m_ttrss_sessionid);
+ message.add_string("op", "moveFeed");
+ message.add_int("feed_id", feedID);
+ message.add_int("category_id", catID);
+ int status = message.send();
+
+ return status == ConnectionError.SUCCESS;
+ }
+
+ public bool ping()
+ {
+ Logger.debug("TTRSS: ping");
+ var message = new ttrssMessage(m_session, m_ttrss_url);
+ int status = message.send(true);
+
+ return status == ConnectionError.SUCCESS;
}
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool renameCategory(int catID, string title)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "renameCategory");
- message.add_int("category_id", catID);
- message.add_string("caption", title);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool renameFeed(int feedID, string title)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "renameFeed");
- message.add_int("feed_id", feedID);
- message.add_string("caption", title);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool moveFeed(int feedID, int catID)
-{
- var message = new ttrssMessage(m_session, m_ttrss_url);
- message.add_string("sid", m_ttrss_sessionid);
- message.add_string("op", "moveFeed");
- message.add_int("feed_id", feedID);
- message.add_int("category_id", catID);
- int status = message.send();
-
- return status == ConnectionError.SUCCESS;
-}
-
-public bool ping()
-{
- Logger.debug("TTRSS: ping");
- var message = new ttrssMessage(m_session, m_ttrss_url);
- int status = message.send(true);
-
- return status == ConnectionError.SUCCESS;
-}
}
diff --git a/plugins/backend/ttrss/ttrssInterface.vala b/plugins/backend/ttrss/ttrssInterface.vala
index 2b507ab2..0b8a505a 100644
--- a/plugins/backend/ttrss/ttrssInterface.vala
+++ b/plugins/backend/ttrss/ttrssInterface.vala
@@ -14,531 +14,531 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.ttrssInterface : FeedServerInterface {
-
-private ttrssAPI m_api;
-private ttrssUtils m_utils;
-private Gtk.Entry m_urlEntry;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passwordEntry;
-private Gtk.Entry m_authPasswordEntry;
-private Gtk.Entry m_authUserEntry;
-private Gtk.Revealer m_revealer;
-
-public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- m_utils = new ttrssUtils(settings_backend, secrets);
- m_api = new ttrssAPI(m_utils);
-}
-
-public override string getWebsite()
-{
- return "https://tt-rss.org/";
-}
-
-public override BackendFlags getFlags()
-{
- return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-}
-
-public override string getID()
-{
- return "ttrss";
-}
-
-public override string iconName()
-{
- return "feed-service-ttrss";
-}
-
-public override string serviceName()
-{
- return "Tiny Tiny RSS";
-}
-
-public override bool needWebLogin()
-{
- return false;
-}
-
-public override Gtk.Box? getWidget()
-{
- var url_label = new Gtk.Label(_("Tiny Tiny RSS URL:"));
- var user_label = new Gtk.Label(_("Username:"));
- var password_label = new Gtk.Label(_("Password:"));
-
- url_label.set_alignment(1.0f, 0.5f);
- user_label.set_alignment(1.0f, 0.5f);
- password_label.set_alignment(1.0f, 0.5f);
-
- url_label.set_hexpand(true);
- user_label.set_hexpand(true);
- password_label.set_hexpand(true);
-
- m_urlEntry = new Gtk.Entry();
- m_userEntry = new Gtk.Entry();
- m_passwordEntry = new Gtk.Entry();
-
- m_urlEntry.activate.connect(() => { tryLogin(); });
- m_userEntry.activate.connect(() => { tryLogin(); });
- m_passwordEntry.activate.connect(() => { tryLogin(); });
-
- m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passwordEntry.set_visibility(false);
-
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
-
- grid.attach(url_label, 0, 0, 1, 1);
- grid.attach(m_urlEntry, 1, 0, 1, 1);
- grid.attach(user_label, 0, 1, 1, 1);
- grid.attach(m_userEntry, 1, 1, 1, 1);
- grid.attach(password_label, 0, 2, 1, 1);
- grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
-
- // http auth stuff ----------------------------------------------------
- var auth_user_label = new Gtk.Label(_("Username:"));
- var auth_password_label = new Gtk.Label(_("Password:"));
-
- auth_user_label.set_alignment(1.0f, 0.5f);
- auth_password_label.set_alignment(1.0f, 0.5f);
-
- auth_user_label.set_hexpand(true);
- auth_password_label.set_hexpand(true);
-
- m_authUserEntry = new Gtk.Entry();
- m_authPasswordEntry = new Gtk.Entry();
- m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_authPasswordEntry.set_visibility(false);
-
- m_authUserEntry.activate.connect(() => { tryLogin(); });
- m_authPasswordEntry.activate.connect(() => { tryLogin(); });
-
- var authGrid = new Gtk.Grid();
- authGrid.margin = 10;
- authGrid.set_column_spacing(10);
- authGrid.set_row_spacing(10);
- authGrid.set_valign(Gtk.Align.CENTER);
- authGrid.set_halign(Gtk.Align.CENTER);
-
- authGrid.attach(auth_user_label, 0, 0, 1, 1);
- authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
- authGrid.attach(auth_password_label, 0, 1, 1, 1);
- authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
-
- var frame = new Gtk.Frame(_("HTTP Authorization"));
- frame.set_halign(Gtk.Align.CENTER);
- frame.add(authGrid);
- m_revealer = new Gtk.Revealer();
- m_revealer.add(frame);
- //---------------------------------------------------------------------
-
- var logo = new Gtk.Image.from_icon_name("feed-service-ttrss", Gtk.IconSize.MENU);
-
- var loginLabel = new Gtk.Label(_("Please log in to your Tiny Tiny RSS server and enjoy using FeedReader"));
- loginLabel.get_style_context().add_class("h2");
- loginLabel.set_justify(Gtk.Justification.CENTER);
- loginLabel.set_lines(3);
-
- var loginButton = new Gtk.Button.with_label(_("Login"));
- loginButton.halign = Gtk.Align.END;
- loginButton.set_size_request(80, 30);
- loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- loginButton.clicked.connect(() => { tryLogin(); });
-
- var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
- box.valign = Gtk.Align.CENTER;
- box.halign = Gtk.Align.CENTER;
- box.pack_start(loginLabel, false, false, 10);
- box.pack_start(logo, false, false, 10);
- box.pack_start(grid, true, true, 10);
- box.pack_start(m_revealer, true, true, 10);
- box.pack_end(loginButton, false, false, 20);
-
- m_urlEntry.set_text(m_utils.getUnmodifiedURL());
- m_userEntry.set_text(m_utils.getUser());
- m_passwordEntry.set_text(m_utils.getPasswd());
-
- return box;
-}
-
-public override void showHtAccess()
-{
- m_revealer.set_reveal_child(true);
-}
-
-public override void writeData()
-{
- string url = m_urlEntry.get_text();
- if (GLib.Uri.parse_scheme(url) == null)
+
+ private ttrssAPI m_api;
+ private ttrssUtils m_utils;
+ private Gtk.Entry m_urlEntry;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passwordEntry;
+ private Gtk.Entry m_authPasswordEntry;
+ private Gtk.Entry m_authUserEntry;
+ private Gtk.Revealer m_revealer;
+
+ public override void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- url = "https://" + url;
- m_urlEntry.set_text(url);
+ m_utils = new ttrssUtils(settings_backend, secrets);
+ m_api = new ttrssAPI(m_utils);
}
- m_utils.setURL(url);
- m_utils.setUser(m_userEntry.get_text().strip());
- m_utils.setPassword(m_passwordEntry.get_text().strip());
-}
-
-public override bool supportTags()
-{
- return true;
-}
-
-public override bool doInitSync()
-{
- return true;
-}
-
-public override string symbolicIcon()
-{
- return "feed-service-ttrss-symbolic";
-}
-
-public override string accountName()
-{
- return m_utils.getUser();
-}
-
-public override string getServerURL()
-{
- return m_utils.getURL();
-}
-
-public override string uncategorizedID()
-{
- return "0";
-}
-
-public override bool hideCategoryWhenEmpty(string catID)
-{
- return catID == "0";
-}
-
-public override bool supportCategories()
-{
- return true;
-}
-
-public override bool supportFeedManipulation()
-{
- return true;
-}
-
-public override bool supportMultiLevelCategories()
-{
- return true;
-}
-
-public override bool supportMultiCategoriesPerFeed()
-{
- return false;
-}
-
-public override bool syncFeedsAndCategories()
-{
- return true;
-}
-
-public override bool tagIDaffectedByNameChange()
-{
- return false;
-}
-
-public override void resetAccount()
-{
- m_utils.resetAccount();
-}
-
-public override bool useMaxArticles()
-{
- return true;
-}
-
-public override LoginResponse login()
-{
- return m_api.login();
-}
-
-public override bool logout()
-{
- return m_api.logout();
-}
-
-public override bool serverAvailable()
-{
- return m_api.ping();
-}
-
-public override void setArticleIsRead(string articleIDs, ArticleStatus read)
-{
- var ids = new Gee.ArrayList<int>();
- foreach(var id in StringUtils.split(articleIDs, ","))
+
+ public override string getWebsite()
{
- ids.add(int.parse(id));
+ return "https://tt-rss.org/";
}
- m_api.updateArticleUnread(ids, read);
-}
-
-public override void setArticleIsMarked(string articleID, ArticleStatus marked)
-{
- m_api.updateArticleMarked(int.parse(articleID), marked);
-}
-
-public override bool alwaysSetReadByID()
-{
- return false;
-}
-
-public override void setFeedRead(string feedID)
-{
- m_api.catchupFeed(int.parse(feedID), false);
-}
-
-public override void setCategoryRead(string catID)
-{
- m_api.catchupFeed(int.parse(catID), true);
-}
-
-public override void markAllItemsRead()
-{
- var categories = DataBase.readOnly().read_categories();
- foreach(Category cat in categories)
+
+ public override BackendFlags getFlags()
{
- m_api.catchupFeed(int.parse(cat.getCatID()), true);
+ return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
}
-}
-
-public override void tagArticle(string articleID, string tagID)
-{
- m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), true);
-}
-
-public override void removeArticleTag(string articleID, string tagID)
-{
- m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), false);
-}
-
-public override string createTag(string caption)
-{
- return m_api.addLabel(caption).to_string();
-}
-
-public override void deleteTag(string tagID)
-{
- m_api.removeLabel(int.parse(tagID));
-}
-
-public override void renameTag(string tagID, string title)
-{
- m_api.renameLabel(int.parse(tagID), title);
-}
-
-public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-{
- bool success = false;
- if(catID == null && newCatName != null)
+
+ public override string getID()
{
- var newCatID = m_api.createCategory(newCatName);
- success = m_api.subscribeToFeed(feedURL, newCatID, null, null, out errmsg);
+ return "ttrss";
}
- else
+
+ public override string iconName()
{
- success = m_api.subscribeToFeed(feedURL, catID, null, null, out errmsg);
+ return "feed-service-ttrss";
}
-
- if(success)
+
+ public override string serviceName()
{
- feedID = (int.parse(DataBase.readOnly().getMaxID("feeds", "feed_id")) + 1).to_string();
+ return "Tiny Tiny RSS";
}
- else
+
+ public override bool needWebLogin()
{
- feedID = "-98";
+ return false;
}
-
-
- return success;
-}
-
-public override void removeFeed(string feedID)
-{
- m_api.unsubscribeFeed(int.parse(feedID));
-}
-
-public override void renameFeed(string feedID, string title)
-{
- m_api.renameFeed(int.parse(feedID), title);
-}
-
-public override void moveFeed(string feedID, string newCatID, string? currentCatID)
-{
- m_api.moveFeed(int.parse(feedID), int.parse(newCatID));
-}
-
-public override string createCategory(string title, string? parentID)
-{
- if(parentID != null)
+
+ public override Gtk.Box? getWidget()
{
- return m_api.createCategory(title, int.parse(parentID));
+ var url_label = new Gtk.Label(_("Tiny Tiny RSS URL:"));
+ var user_label = new Gtk.Label(_("Username:"));
+ var password_label = new Gtk.Label(_("Password:"));
+
+ url_label.set_alignment(1.0f, 0.5f);
+ user_label.set_alignment(1.0f, 0.5f);
+ password_label.set_alignment(1.0f, 0.5f);
+
+ url_label.set_hexpand(true);
+ user_label.set_hexpand(true);
+ password_label.set_hexpand(true);
+
+ m_urlEntry = new Gtk.Entry();
+ m_userEntry = new Gtk.Entry();
+ m_passwordEntry = new Gtk.Entry();
+
+ m_urlEntry.activate.connect(() => { tryLogin(); });
+ m_userEntry.activate.connect(() => { tryLogin(); });
+ m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+ m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passwordEntry.set_visibility(false);
+
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+
+ grid.attach(url_label, 0, 0, 1, 1);
+ grid.attach(m_urlEntry, 1, 0, 1, 1);
+ grid.attach(user_label, 0, 1, 1, 1);
+ grid.attach(m_userEntry, 1, 1, 1, 1);
+ grid.attach(password_label, 0, 2, 1, 1);
+ grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+
+ // http auth stuff ----------------------------------------------------
+ var auth_user_label = new Gtk.Label(_("Username:"));
+ var auth_password_label = new Gtk.Label(_("Password:"));
+
+ auth_user_label.set_alignment(1.0f, 0.5f);
+ auth_password_label.set_alignment(1.0f, 0.5f);
+
+ auth_user_label.set_hexpand(true);
+ auth_password_label.set_hexpand(true);
+
+ m_authUserEntry = new Gtk.Entry();
+ m_authPasswordEntry = new Gtk.Entry();
+ m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_authPasswordEntry.set_visibility(false);
+
+ m_authUserEntry.activate.connect(() => { tryLogin(); });
+ m_authPasswordEntry.activate.connect(() => { tryLogin(); });
+
+ var authGrid = new Gtk.Grid();
+ authGrid.margin = 10;
+ authGrid.set_column_spacing(10);
+ authGrid.set_row_spacing(10);
+ authGrid.set_valign(Gtk.Align.CENTER);
+ authGrid.set_halign(Gtk.Align.CENTER);
+
+ authGrid.attach(auth_user_label, 0, 0, 1, 1);
+ authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
+ authGrid.attach(auth_password_label, 0, 1, 1, 1);
+ authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
+
+ var frame = new Gtk.Frame(_("HTTP Authorization"));
+ frame.set_halign(Gtk.Align.CENTER);
+ frame.add(authGrid);
+ m_revealer = new Gtk.Revealer();
+ m_revealer.add(frame);
+ //---------------------------------------------------------------------
+
+ var logo = new Gtk.Image.from_icon_name("feed-service-ttrss", Gtk.IconSize.MENU);
+
+ var loginLabel = new Gtk.Label(_("Please log in to your Tiny Tiny RSS server and enjoy using FeedReader"));
+ loginLabel.get_style_context().add_class("h2");
+ loginLabel.set_justify(Gtk.Justification.CENTER);
+ loginLabel.set_lines(3);
+
+ var loginButton = new Gtk.Button.with_label(_("Login"));
+ loginButton.halign = Gtk.Align.END;
+ loginButton.set_size_request(80, 30);
+ loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ loginButton.clicked.connect(() => { tryLogin(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+ box.valign = Gtk.Align.CENTER;
+ box.halign = Gtk.Align.CENTER;
+ box.pack_start(loginLabel, false, false, 10);
+ box.pack_start(logo, false, false, 10);
+ box.pack_start(grid, true, true, 10);
+ box.pack_start(m_revealer, true, true, 10);
+ box.pack_end(loginButton, false, false, 20);
+
+ m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+ m_userEntry.set_text(m_utils.getUser());
+ m_passwordEntry.set_text(m_utils.getPasswd());
+
+ return box;
}
-
- return m_api.createCategory(title);
-}
-
-public override void renameCategory(string catID, string title)
-{
- m_api.renameCategory(int.parse(catID), title);
-}
-
-public override void moveCategory(string catID, string newParentID)
-{
- m_api.moveCategory(int.parse(catID), int.parse(newParentID));
-}
-
-public override void deleteCategory(string catID)
-{
- m_api.removeCategory(int.parse(catID));
-}
-
-public override void removeCatFromFeed(string feedID, string catID)
-{
- return;
-}
-
-public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-{
- if(m_api.getCategories(categories))
+
+ public override void showHtAccess()
{
- if(cancellable != null && cancellable.is_cancelled())
+ m_revealer.set_reveal_child(true);
+ }
+
+ public override void writeData()
+ {
+ string url = m_urlEntry.get_text();
+ if (GLib.Uri.parse_scheme(url) == null)
{
- return false;
+ url = "https://" + url;
+ m_urlEntry.set_text(url);
}
-
- if(m_api.getFeeds(feeds, categories))
+ m_utils.setURL(url);
+ m_utils.setUser(m_userEntry.get_text().strip());
+ m_utils.setPassword(m_passwordEntry.get_text().strip());
+ }
+
+ public override bool supportTags()
+ {
+ return true;
+ }
+
+ public override bool doInitSync()
+ {
+ return true;
+ }
+
+ public override string symbolicIcon()
+ {
+ return "feed-service-ttrss-symbolic";
+ }
+
+ public override string accountName()
+ {
+ return m_utils.getUser();
+ }
+
+ public override string getServerURL()
+ {
+ return m_utils.getURL();
+ }
+
+ public override string uncategorizedID()
+ {
+ return "0";
+ }
+
+ public override bool hideCategoryWhenEmpty(string catID)
+ {
+ return catID == "0";
+ }
+
+ public override bool supportCategories()
+ {
+ return true;
+ }
+
+ public override bool supportFeedManipulation()
+ {
+ return true;
+ }
+
+ public override bool supportMultiLevelCategories()
+ {
+ return true;
+ }
+
+ public override bool supportMultiCategoriesPerFeed()
+ {
+ return false;
+ }
+
+ public override bool syncFeedsAndCategories()
+ {
+ return true;
+ }
+
+ public override bool tagIDaffectedByNameChange()
+ {
+ return false;
+ }
+
+ public override void resetAccount()
+ {
+ m_utils.resetAccount();
+ }
+
+ public override bool useMaxArticles()
+ {
+ return true;
+ }
+
+ public override LoginResponse login()
+ {
+ return m_api.login();
+ }
+
+ public override bool logout()
+ {
+ return m_api.logout();
+ }
+
+ public override bool serverAvailable()
+ {
+ return m_api.ping();
+ }
+
+ public override void setArticleIsRead(string articleIDs, ArticleStatus read)
+ {
+ var ids = new Gee.ArrayList<int>();
+ foreach(var id in StringUtils.split(articleIDs, ","))
+ {
+ ids.add(int.parse(id));
+ }
+ m_api.updateArticleUnread(ids, read);
+ }
+
+ public override void setArticleIsMarked(string articleID, ArticleStatus marked)
+ {
+ m_api.updateArticleMarked(int.parse(articleID), marked);
+ }
+
+ public override bool alwaysSetReadByID()
+ {
+ return false;
+ }
+
+ public override void setFeedRead(string feedID)
+ {
+ m_api.catchupFeed(int.parse(feedID), false);
+ }
+
+ public override void setCategoryRead(string catID)
+ {
+ m_api.catchupFeed(int.parse(catID), true);
+ }
+
+ public override void markAllItemsRead()
+ {
+ var categories = DataBase.readOnly().read_categories();
+ foreach(Category cat in categories)
+ {
+ m_api.catchupFeed(int.parse(cat.getCatID()), true);
+ }
+ }
+
+ public override void tagArticle(string articleID, string tagID)
+ {
+ m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), true);
+ }
+
+ public override void removeArticleTag(string articleID, string tagID)
+ {
+ m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), false);
+ }
+
+ public override string createTag(string caption)
+ {
+ return m_api.addLabel(caption).to_string();
+ }
+
+ public override void deleteTag(string tagID)
+ {
+ m_api.removeLabel(int.parse(tagID));
+ }
+
+ public override void renameTag(string tagID, string title)
+ {
+ m_api.renameLabel(int.parse(tagID), title);
+ }
+
+ public override bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+ {
+ bool success = false;
+ if(catID == null && newCatName != null)
+ {
+ var newCatID = m_api.createCategory(newCatName);
+ success = m_api.subscribeToFeed(feedURL, newCatID, null, null, out errmsg);
+ }
+ else
+ {
+ success = m_api.subscribeToFeed(feedURL, catID, null, null, out errmsg);
+ }
+
+ if(success)
+ {
+ feedID = (int.parse(DataBase.readOnly().getMaxID("feeds", "feed_id")) + 1).to_string();
+ }
+ else
+ {
+ feedID = "-98";
+ }
+
+
+ return success;
+ }
+
+ public override void removeFeed(string feedID)
+ {
+ m_api.unsubscribeFeed(int.parse(feedID));
+ }
+
+ public override void renameFeed(string feedID, string title)
+ {
+ m_api.renameFeed(int.parse(feedID), title);
+ }
+
+ public override void moveFeed(string feedID, string newCatID, string? currentCatID)
+ {
+ m_api.moveFeed(int.parse(feedID), int.parse(newCatID));
+ }
+
+ public override string createCategory(string title, string? parentID)
+ {
+ if(parentID != null)
+ {
+ return m_api.createCategory(title, int.parse(parentID));
+ }
+
+ return m_api.createCategory(title);
+ }
+
+ public override void renameCategory(string catID, string title)
+ {
+ m_api.renameCategory(int.parse(catID), title);
+ }
+
+ public override void moveCategory(string catID, string newParentID)
+ {
+ m_api.moveCategory(int.parse(catID), int.parse(newParentID));
+ }
+
+ public override void deleteCategory(string catID)
+ {
+ m_api.removeCategory(int.parse(catID));
+ }
+
+ public override void removeCatFromFeed(string feedID, string catID)
+ {
+ return;
+ }
+
+ public override bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+ {
+ if(m_api.getCategories(categories))
{
if(cancellable != null && cancellable.is_cancelled())
{
return false;
}
-
- if(m_api.getUncategorizedFeeds(feeds))
+
+ if(m_api.getFeeds(feeds, categories))
{
if(cancellable != null && cancellable.is_cancelled())
{
return false;
}
-
- if(m_api.getTags(tags))
+
+ if(m_api.getUncategorizedFeeds(feeds))
{
- return true;
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return false;
+ }
+
+ if(m_api.getTags(tags))
+ {
+ return true;
+ }
}
}
}
+
+ return false;
}
-
- return false;
-}
-
-public override int getUnreadCount()
-{
- return m_api.getUnreadCount();
-}
-
-public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-{
- var settings_general = new GLib.Settings("org.gnome.feedreader");
-
- // first use newsPlus plugin to update states of 10x as much articles as we would normaly do
- var unreadIDs = m_api.NewsPlus(ArticleStatus.UNREAD, 10*settings_general.get_int("max-articles"));
-
- if(cancellable != null && cancellable.is_cancelled())
+
+ public override int getUnreadCount()
{
- return;
+ return m_api.getUnreadCount();
}
-
- var db = DataBase.writeAccess();
- if(unreadIDs != null && whatToGet == ArticleStatus.ALL)
- {
- Logger.debug("getArticles: newsplus plugin active");
- var markedIDs = m_api.NewsPlus(ArticleStatus.MARKED, settings_general.get_int("max-articles"));
- db.updateArticlesByID(unreadIDs, "unread");
- db.updateArticlesByID(markedIDs, "marked");
- //updateArticleList();
- }
-
- if(cancellable != null && cancellable.is_cancelled())
- {
- return;
- }
-
- var articleIDs = new Gee.ArrayList<int>();
- int skip = count;
- int amount = 200;
-
- while(skip > 0)
+
+ public override void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
{
+ var settings_general = new GLib.Settings("org.gnome.feedreader");
+
+ // first use newsPlus plugin to update states of 10x as much articles as we would normaly do
+ var unreadIDs = m_api.NewsPlus(ArticleStatus.UNREAD, 10*settings_general.get_int("max-articles"));
+
if(cancellable != null && cancellable.is_cancelled())
{
return;
}
-
- if(skip >= amount)
+
+ var db = DataBase.writeAccess();
+ if(unreadIDs != null && whatToGet == ArticleStatus.ALL)
{
- skip -= amount;
+ Logger.debug("getArticles: newsplus plugin active");
+ var markedIDs = m_api.NewsPlus(ArticleStatus.MARKED, settings_general.get_int("max-articles"));
+ db.updateArticlesByID(unreadIDs, "unread");
+ db.updateArticlesByID(markedIDs, "marked");
+ //updateArticleList();
}
- else
- {
- amount = skip;
- skip = 0;
- }
-
- var articles = new Gee.LinkedList<Article>();
- m_api.getHeadlines(articles, skip, amount, whatToGet, (feedID == null) ? ttrssUtils.TTRSSSpecialID.ALL : int.parse(feedID));
-
- // only update article states if they haven't been updated by the newsPlus-plugin
- if(unreadIDs == null || whatToGet != ArticleStatus.ALL)
+
+ if(cancellable != null && cancellable.is_cancelled())
{
- db.update_articles(articles);
- updateArticleList();
+ return;
}
-
- foreach(Article article in articles)
+
+ var articleIDs = new Gee.ArrayList<int>();
+ int skip = count;
+ int amount = 200;
+
+ while(skip > 0)
{
- var id = article.getArticleID();
- if(!db.article_exists(id))
+ if(cancellable != null && cancellable.is_cancelled())
{
- articleIDs.add(int.parse(id));
+ return;
+ }
+
+ if(skip >= amount)
+ {
+ skip -= amount;
+ }
+ else
+ {
+ amount = skip;
+ skip = 0;
+ }
+
+ var articles = new Gee.LinkedList<Article>();
+ m_api.getHeadlines(articles, skip, amount, whatToGet, (feedID == null) ? ttrssUtils.TTRSSSpecialID.ALL : int.parse(feedID));
+
+ // only update article states if they haven't been updated by the newsPlus-plugin
+ if(unreadIDs == null || whatToGet != ArticleStatus.ALL)
+ {
+ db.update_articles(articles);
+ updateArticleList();
+ }
+
+ foreach(Article article in articles)
+ {
+ var id = article.getArticleID();
+ if(!db.article_exists(id))
+ {
+ articleIDs.add(int.parse(id));
+ }
}
}
- }
- var articles = m_api.getArticles(articleIDs);
- var article_id_strings = new Gee.ArrayList<string>();
- foreach(int id in articleIDs)
- {
- article_id_strings.add(id.to_string());
- }
- Logger.info("Getting articles: " + StringUtils.join(article_id_strings, ","));
-
- articles.sort((a, b) => {
+ var articles = m_api.getArticles(articleIDs);
+ var article_id_strings = new Gee.ArrayList<string>();
+ foreach(int id in articleIDs)
+ {
+ article_id_strings.add(id.to_string());
+ }
+ Logger.info("Getting articles: " + StringUtils.join(article_id_strings, ","));
+
+ articles.sort((a, b) => {
return strcmp(a.getArticleID(), b.getArticleID());
});
-
- if(cancellable != null && cancellable.is_cancelled())
- {
- return;
- }
-
- if(articles.size > 0)
- {
- db.write_articles(articles);
- refreshFeedListCounter();
- updateArticleList();
+
+ if(cancellable != null && cancellable.is_cancelled())
+ {
+ return;
+ }
+
+ if(articles.size > 0)
+ {
+ db.write_articles(articles);
+ refreshFeedListCounter();
+ updateArticleList();
+ }
}
-}
-
+
}
[ModuleInit]
diff --git a/plugins/backend/ttrss/ttrssMessage.vala b/plugins/backend/ttrss/ttrssMessage.vala
index 8a5cf907..98d13b3f 100644
--- a/plugins/backend/ttrss/ttrssMessage.vala
+++ b/plugins/backend/ttrss/ttrssMessage.vala
@@ -14,235 +14,235 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.ttrssMessage : GLib.Object {
-
-private Soup.Session m_session;
-private Soup.Message m_message_soup;
-private Json.Object m_request_object = new Json.Object();
-private const string m_contenttype = "application/x-www-form-urlencoded";
-private Json.Object m_response_object;
-
-public ttrssMessage(Soup.Session session, string destination)
-{
- m_session = session;
-
- m_message_soup = new Soup.Message("POST", destination);
-
- if(m_message_soup == null)
- {
- Logger.error(@"ttrssMessage: can't parse URL $destination");
- }
-}
-
-public void add_int(string type, int val)
-{
- m_request_object.set_int_member(type, val);
-}
-
-public void add_comma_separated_int_array(string type, Gee.List<int> values)
-{
- var strings = new Gee.ArrayList<string>();
- foreach(int value in values)
- {
- strings.add(value.to_string());
- }
- m_request_object.set_string_member(type, StringUtils.join(strings, ","));
-}
-
-public void add_bool(string type, bool val)
-{
- m_request_object.set_boolean_member(type, val);
-}
-
-public void add_string(string type, string val)
-{
- m_request_object.set_string_member(type, val);
-}
-
-private static string object_to_string(Json.Object obj)
-{
- var root = new Json.Node(Json.NodeType.OBJECT);
- root.set_object(obj);
-
- var gen = new Json.Generator();
- gen.set_root(root);
- return gen.to_data(null);
-}
-
-public ConnectionError send(bool ping = false)
-{
- var error = send_impl(ping);
- if(error != ConnectionError.SUCCESS)
- {
- logError("Error response from TT-RSS API");
+
+ private Soup.Session m_session;
+ private Soup.Message m_message_soup;
+ private Json.Object m_request_object = new Json.Object();
+ private const string m_contenttype = "application/x-www-form-urlencoded";
+ private Json.Object m_response_object;
+
+ public ttrssMessage(Soup.Session session, string destination)
+ {
+ m_session = session;
+
+ m_message_soup = new Soup.Message("POST", destination);
+
+ if(m_message_soup == null)
+ {
+ Logger.error(@"ttrssMessage: can't parse URL $destination");
+ }
}
-
- return error;
-}
-
-public ConnectionError send_impl(bool ping)
-{
- if(m_message_soup == null)
+
+ public void add_int(string type, int val)
{
- Logger.error(@"ttrssMessage: can't send message");
- return ConnectionError.UNKNOWN;
+ m_request_object.set_int_member(type, val);
}
-
- var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-
- var data = object_to_string(m_request_object);
- m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, data.data);
-
- if(settingsTweaks.get_boolean("do-not-track"))
+
+ public void add_comma_separated_int_array(string type, Gee.List<int> values)
{
- m_message_soup.request_headers.append("DNT", "1");
+ var strings = new Gee.ArrayList<string>();
+ foreach(int value in values)
+ {
+ strings.add(value.to_string());
+ }
+ m_request_object.set_string_member(type, StringUtils.join(strings, ","));
}
-
- var status_code = m_session.send_message(m_message_soup);
-
- if(status_code == 401) // unauthorized
-
+
+ public void add_bool(string type, bool val)
{
- return ConnectionError.UNAUTHORIZED;
+ m_request_object.set_boolean_member(type, val);
}
-
- if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
+
+ public void add_string(string type, string val)
{
- Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
- return ConnectionError.CA_ERROR;
+ m_request_object.set_string_member(type, val);
}
-
- if(m_message_soup.status_code != 200)
+
+ private static string object_to_string(Json.Object obj)
{
- Logger.error("TTRSS Message: No response - status code: %s".printf(Soup.Status.get_phrase(m_message_soup.status_code)));
- return ConnectionError.NO_RESPONSE;
+ var root = new Json.Node(Json.NodeType.OBJECT);
+ root.set_object(obj);
+
+ var gen = new Json.Generator();
+ gen.set_root(root);
+ return gen.to_data(null);
}
-
- if(ping)
+
+ public ConnectionError send(bool ping = false)
{
- Logger.debug("TTRSS Message: ping successful");
- return ConnectionError.SUCCESS;
+ var error = send_impl(ping);
+ if(error != ConnectionError.SUCCESS)
+ {
+ logError("Error response from TT-RSS API");
+ }
+
+ return error;
}
-
- var parser = new Json.Parser();
- try
+
+ public ConnectionError send_impl(bool ping)
{
- parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+ if(m_message_soup == null)
+ {
+ Logger.error(@"ttrssMessage: can't send message");
+ return ConnectionError.UNKNOWN;
+ }
+
+ var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+
+ var data = object_to_string(m_request_object);
+ m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, data.data);
+
+ if(settingsTweaks.get_boolean("do-not-track"))
+ {
+ m_message_soup.request_headers.append("DNT", "1");
+ }
+
+ var status_code = m_session.send_message(m_message_soup);
+
+ if(status_code == 401) // unauthorized
+
+ {
+ return ConnectionError.UNAUTHORIZED;
+ }
+
+ if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
+ {
+ Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
+ return ConnectionError.CA_ERROR;
+ }
+
+ if(m_message_soup.status_code != 200)
+ {
+ Logger.error("TTRSS Message: No response - status code: %s".printf(Soup.Status.get_phrase(m_message_soup.status_code)));
+ return ConnectionError.NO_RESPONSE;
+ }
+
+ if(ping)
+ {
+ Logger.debug("TTRSS Message: ping successful");
+ return ConnectionError.SUCCESS;
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+ }
+ catch(Error e)
+ {
+ Logger.error("Could not load response from Message to ttrss");
+ Logger.error(e.message);
+ return ConnectionError.NO_RESPONSE;
+ }
+
+ m_response_object = parser.get_root().get_object();
+
+ if(m_response_object.has_member("error"))
+ {
+ parseError(m_response_object);
+ }
+
+
+ var status = UntypedJson.Object.get_int_member(m_response_object, "status");
+ if (status == 0)
+ {
+ return ConnectionError.SUCCESS;
+ }
+ else if (status == 1)
+ {
+ if(m_response_object.has_member("content"))
+ {
+ var content = m_response_object.get_object_member("content");
+ if(content.has_member("error"))
+ {
+ parseError(content);
+ }
+ }
+
+ return apiError();
+ }
+
+ logError("unknown error while sending ttrss message");
+ return ConnectionError.UNKNOWN;
}
- catch(Error e)
+
+ public Json.Object? get_response_object()
{
- Logger.error("Could not load response from Message to ttrss");
- Logger.error(e.message);
- return ConnectionError.NO_RESPONSE;
+ if(m_response_object.has_member("content"))
+ {
+ return m_response_object.get_object_member("content");
+ }
+ return null;
}
-
- m_response_object = parser.get_root().get_object();
-
- if(m_response_object.has_member("error"))
+
+ public int64? get_response_int()
{
- parseError(m_response_object);
+ return UntypedJson.Object.get_int_member(m_response_object, "content");
}
-
-
- var status = UntypedJson.Object.get_int_member(m_response_object, "status");
- if (status == 0)
+
+ public string? get_response_string()
{
- return ConnectionError.SUCCESS;
+ return UntypedJson.Object.get_string_member(m_response_object, "content");
}
- else if (status == 1)
+
+ public Json.Array? get_response_array()
{
if(m_response_object.has_member("content"))
{
- var content = m_response_object.get_object_member("content");
- if(content.has_member("error"))
- {
- parseError(content);
- }
+ return m_response_object.get_array_member("content");
}
-
- return apiError();
+ return null;
}
-
- logError("unknown error while sending ttrss message");
- return ConnectionError.UNKNOWN;
-}
-
-public Json.Object? get_response_object()
-{
- if(m_response_object.has_member("content"))
+
+ public uint getStatusCode()
{
- return m_response_object.get_object_member("content");
+ return m_message_soup.status_code;
}
- return null;
-}
-
-public int64? get_response_int()
-{
- return UntypedJson.Object.get_int_member(m_response_object, "content");
-}
-
-public string? get_response_string()
-{
- return UntypedJson.Object.get_string_member(m_response_object, "content");
-}
-
-public Json.Array? get_response_array()
-{
- if(m_response_object.has_member("content"))
+
+ private void logError(string prefix)
{
- return m_response_object.get_array_member("content");
- }
- return null;
-}
-
-public uint getStatusCode()
-{
- return m_message_soup.status_code;
-}
-
-private void logError(string prefix)
-{
- var url = m_message_soup.get_uri().to_string(false);
- var obj = m_request_object;
- if(obj.has_member("password"))
- {
- obj = new Json.Object();
- m_request_object.foreach_member((_, name, member) =>
- {
- if(name == "password")
- {
- obj.set_string_member("password", "[redacted]");
- }
- else
+ var url = m_message_soup.get_uri().to_string(false);
+ var obj = m_request_object;
+ if(obj.has_member("password"))
+ {
+ obj = new Json.Object();
+ m_request_object.foreach_member((_, name, member) =>
{
- obj.set_member(name, member);
- }
- });
- }
- var request = object_to_string(obj);
- var response = (string)m_message_soup.response_body.flatten().data;
- Logger.error(@"$prefix\nURL: $url\nRequest object: $request\nResponse: $response");
-}
-
-private ConnectionError parseError(Json.Object err)
-{
- string error = err.get_string_member("error");
- if(error == "NOT_LOGGED_IN")
- {
- Logger.error("invalid ttrss session id");
- return ConnectionError.INVALID_SESSIONID;
- }
- else if(error == "API_DISABLED")
- {
- Logger.error("ttrss api is disabled: please enable it first");
- return ConnectionError.API_DISABLED;
+ if(name == "password")
+ {
+ obj.set_string_member("password", "[redacted]");
+ }
+ else
+ {
+ obj.set_member(name, member);
+ }
+ });
+ }
+ var request = object_to_string(obj);
+ var response = (string)m_message_soup.response_body.flatten().data;
+ Logger.error(@"$prefix\nURL: $url\nRequest object: $request\nResponse: $response");
+ }
+
+ private ConnectionError parseError(Json.Object err)
+ {
+ string error = err.get_string_member("error");
+ if(error == "NOT_LOGGED_IN")
+ {
+ Logger.error("invalid ttrss session id");
+ return ConnectionError.INVALID_SESSIONID;
+ }
+ else if(error == "API_DISABLED")
+ {
+ Logger.error("ttrss api is disabled: please enable it first");
+ return ConnectionError.API_DISABLED;
+ }
+
+ return apiError();
+ }
+
+ private ConnectionError apiError()
+ {
+ logError("TT-RSS API error");
+ return ConnectionError.API_ERROR;
+ }
}
-
- return apiError();
-}
-
-private ConnectionError apiError()
-{
- logError("TT-RSS API error");
- return ConnectionError.API_ERROR;
-}
-}
diff --git a/plugins/backend/ttrss/ttrssUtils.vala b/plugins/backend/ttrss/ttrssUtils.vala
index ae10522d..dabc32b6 100644
--- a/plugins/backend/ttrss/ttrssUtils.vala
+++ b/plugins/backend/ttrss/ttrssUtils.vala
@@ -14,136 +14,136 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.ttrssUtils : GLib.Object {
-
-public enum TTRSSSpecialID {
- ARCHIVED = 0,
- STARRED = -1,
- PUBLISHED = -2,
- FRESH = -3,
- ALL = -4,
- RECENTLY_READ = -6
-}
-
-private GLib.Settings m_settings;
-private Password m_password;
-private Password m_htaccess_password;
-
-public ttrssUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-{
- if(settings_backend != null)
- {
- m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.ttrss", settings_backend);
+
+ public enum TTRSSSpecialID {
+ ARCHIVED = 0,
+ STARRED = -1,
+ PUBLISHED = -2,
+ FRESH = -3,
+ ALL = -4,
+ RECENTLY_READ = -6
}
- else
+
+ private GLib.Settings m_settings;
+ private Password m_password;
+ private Password m_htaccess_password;
+
+ public ttrssUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
{
- m_settings = new GLib.Settings("org.gnome.feedreader.ttrss");
- }
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING);
- m_password = new Password(secrets, pwSchema, "FeedReader: ttrss login", () => {
+ if(settings_backend != null)
+ {
+ m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.ttrss", settings_backend);
+ }
+ else
+ {
+ m_settings = new GLib.Settings("org.gnome.feedreader.ttrss");
+ }
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING);
+ m_password = new Password(secrets, pwSchema, "FeedReader: ttrss login", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getUser();
return attributes;
});
-
- var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
- "URL", Secret.SchemaAttributeType.STRING,
- "Username", Secret.SchemaAttributeType.STRING,
- "htaccess", Secret.SchemaAttributeType.BOOLEAN);
- m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: ttrss htaccess Authentication", () => {
+
+ var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+ "URL", Secret.SchemaAttributeType.STRING,
+ "Username", Secret.SchemaAttributeType.STRING,
+ "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+ m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: ttrss htaccess Authentication", () => {
var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
attributes["URL"] = getURL();
attributes["Username"] = getHtaccessUser();
attributes["htaccess"] = "true";
return attributes;
});
-}
-
-public string getURL()
-{
-
- string tmp_url = Utils.gsettingReadString(m_settings, "url");
-
- if(tmp_url != "")
+ }
+
+ public string getURL()
{
- if(!tmp_url.has_suffix("/"))
+
+ string tmp_url = Utils.gsettingReadString(m_settings, "url");
+
+ if(tmp_url != "")
{
- tmp_url = tmp_url + "/";
- }
-
- if(!tmp_url.has_suffix("/api/"))
- {
- tmp_url = tmp_url + "api/";
- }
-
- if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
- {
- tmp_url = "https://" + tmp_url;
+ if(!tmp_url.has_suffix("/"))
+ {
+ tmp_url = tmp_url + "/";
+ }
+
+ if(!tmp_url.has_suffix("/api/"))
+ {
+ tmp_url = tmp_url + "api/";
+ }
+
+ if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+ {
+ tmp_url = "https://" + tmp_url;
+ }
}
+
+ Logger.debug("ttrss URL: " + tmp_url);
+
+ return tmp_url;
+ }
+
+ public void setURL(string url)
+ {
+ Utils.gsettingWriteString(m_settings, "url", url);
+ }
+
+ public string getUser()
+ {
+ return Utils.gsettingReadString(m_settings, "username");
+ }
+
+ public void setUser(string user)
+ {
+ Utils.gsettingWriteString(m_settings, "username", user);
+ }
+
+ public string getHtaccessUser()
+ {
+ return Utils.gsettingReadString(m_settings, "htaccess-username");
+ }
+
+ public void setHtaccessUser(string ht_user)
+ {
+ Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+ }
+
+ public string getUnmodifiedURL()
+ {
+ return Utils.gsettingReadString(m_settings, "url");
+ }
+
+ public string getPasswd()
+ {
+ return m_password.get_password();
+ }
+
+ public void setPassword(string passwd)
+ {
+ m_password.set_password(passwd);
+ }
+
+ public void resetAccount()
+ {
+ Utils.resetSettings(m_settings);
+ m_password.delete_password();
+ m_htaccess_password.delete_password();
+ }
+
+ public string getHtaccessPasswd()
+ {
+ return m_htaccess_password.get_password();
+ }
+
+ public void setHtAccessPassword(string passwd)
+ {
+ m_htaccess_password.set_password(passwd);
}
-
- Logger.debug("ttrss URL: " + tmp_url);
-
- return tmp_url;
-}
-
-public void setURL(string url)
-{
- Utils.gsettingWriteString(m_settings, "url", url);
-}
-
-public string getUser()
-{
- return Utils.gsettingReadString(m_settings, "username");
-}
-
-public void setUser(string user)
-{
- Utils.gsettingWriteString(m_settings, "username", user);
-}
-
-public string getHtaccessUser()
-{
- return Utils.gsettingReadString(m_settings, "htaccess-username");
-}
-
-public void setHtaccessUser(string ht_user)
-{
- Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-}
-
-public string getUnmodifiedURL()
-{
- return Utils.gsettingReadString(m_settings, "url");
-}
-
-public string getPasswd()
-{
- return m_password.get_password();
-}
-
-public void setPassword(string passwd)
-{
- m_password.set_password(passwd);
-}
-
-public void resetAccount()
-{
- Utils.resetSettings(m_settings);
- m_password.delete_password();
- m_htaccess_password.delete_password();
-}
-
-public string getHtaccessPasswd()
-{
- return m_htaccess_password.get_password();
-}
-
-public void setHtAccessPassword(string passwd)
-{
- m_htaccess_password.set_password(passwd);
-}
}
diff --git a/plugins/share/Browser/Browser.vala b/plugins/share/Browser/Browser.vala
index 82f5b164..90428f60 100644
--- a/plugins/share/Browser/Browser.vala
+++ b/plugins/share/Browser/Browser.vala
@@ -15,91 +15,91 @@
public class FeedReader.Browser : ShareAccountInterface, Peas.ExtensionBase {
-
-public bool addBookmark(string id, string url, bool system)
-{
- try
+
+ public bool addBookmark(string id, string url, bool system)
+ {
+ try
+ {
+ Gtk.show_uri_on_window(MainWindow.get_default(), url, Gdk.CURRENT_TIME);
+ return true;
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("BrowserPlugin: Error opening url: " + e.message);
+ }
+
+ return false;
+ }
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+ {
+
+ }
+
+ public bool logout(string id)
+ {
+ return false;
+ }
+
+ public string getIconName()
+ {
+ if(Gtk.IconTheme.get_default().lookup_icon("applications-internet", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+ {
+ return "applications-internet";
+ }
+
+ return "feed-share-browser";
+ }
+
+ public string getUsername(string id)
+ {
+ return "Browser";
+ }
+
+ public bool needSetup()
+ {
+ return false;
+ }
+
+ public bool singleInstance()
{
- Gtk.show_uri_on_window(MainWindow.get_default(), url, Gdk.CURRENT_TIME);
return true;
}
- catch(GLib.Error e)
+
+ public bool useSystemAccounts()
{
- Logger.error("BrowserPlugin: Error opening url: " + e.message);
+ return false;
}
-
- return false;
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public bool logout(string id)
-{
- return false;
-}
-
-public string getIconName()
-{
- if(Gtk.IconTheme.get_default().lookup_icon("applications-internet", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+
+ public string pluginID()
{
- return "applications-internet";
+ return "browser";
+ }
+
+ public string pluginName()
+ {
+ return _("Open in Browser");
+ }
+
+ public ServiceSetup? newSetup_withID(string id, string username)
+ {
+ return null;
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return null;
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ return null;
}
-
- return "feed-share-browser";
-}
-
-public string getUsername(string id)
-{
- return "Browser";
-}
-
-public bool needSetup()
-{
- return false;
-}
-
-public bool singleInstance()
-{
- return true;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "browser";
-}
-
-public string pluginName()
-{
- return _("Open in Browser");
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return null;
-}
-
-public ServiceSetup? newSetup()
-{
- return null;
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- return null;
-}
}
[ModuleInit]
diff --git a/plugins/share/Email/Email.vala b/plugins/share/Email/Email.vala
index 3dd9c35e..e0bf3b7e 100644
--- a/plugins/share/Email/Email.vala
+++ b/plugins/share/Email/Email.vala
@@ -15,104 +15,104 @@
public class FeedReader.ShareMail : ShareAccountInterface, Peas.ExtensionBase {
-
-private string m_body;
-private string m_to;
-
-public bool addBookmark(string id, string url, bool system)
-{
- string subject = GLib.Uri.escape_string("Amazing article");
- string body = GLib.Uri.escape_string(m_body.replace("$URL", url));
- string mailto = @"mailto:$m_to?subject=$subject&body=$body";
- Logger.debug(mailto);
-
- try
+
+ private string m_body;
+ private string m_to;
+
+ public bool addBookmark(string id, string url, bool system)
+ {
+ string subject = GLib.Uri.escape_string("Amazing article");
+ string body = GLib.Uri.escape_string(m_body.replace("$URL", url));
+ string mailto = @"mailto:$m_to?subject=$subject&body=$body";
+ Logger.debug(mailto);
+
+ try
+ {
+ Gtk.show_uri_on_window(MainWindow.get_default(), mailto, Gdk.CURRENT_TIME);
+ return true;
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("share via mail failed: %s".printf(e.message));
+ }
+
+ return false;
+ }
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+ {
+
+ }
+
+ public bool logout(string id)
+ {
+ return false;
+ }
+
+ public string getIconName()
+ {
+ if(Gtk.IconTheme.get_default().lookup_icon("mail-send", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+ {
+ return "mail-send";
+ }
+
+ return "feed-share-mail";
+ }
+
+ public string getUsername(string id)
+ {
+ return "Email";
+ }
+
+ public bool needSetup()
+ {
+ return false;
+ }
+
+ public bool singleInstance()
{
- Gtk.show_uri_on_window(MainWindow.get_default(), mailto, Gdk.CURRENT_TIME);
return true;
}
- catch(GLib.Error e)
+
+ public bool useSystemAccounts()
{
- Logger.error("share via mail failed: %s".printf(e.message));
+ return false;
}
-
- return false;
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public bool logout(string id)
-{
- return false;
-}
-
-public string getIconName()
-{
- if(Gtk.IconTheme.get_default().lookup_icon("mail-send", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+
+ public string pluginID()
{
- return "mail-send";
+ return "mail";
}
-
- return "feed-share-mail";
-}
-
-public string getUsername(string id)
-{
- return "Email";
-}
-
-public bool needSetup()
-{
- return false;
-}
-
-public bool singleInstance()
-{
- return true;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "mail";
-}
-
-public string pluginName()
-{
- return "Email";
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return null;
-}
-
-public ServiceSetup? newSetup()
-{
- return null;
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- var widget = new EmailForm(url);
- widget.share.connect(() => {
+
+ public string pluginName()
+ {
+ return "Email";
+ }
+
+ public ServiceSetup? newSetup_withID(string id, string username)
+ {
+ return null;
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return null;
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ var widget = new EmailForm(url);
+ widget.share.connect(() => {
m_to = widget.getTo();
m_body = widget.getBody();
});
- return widget;
-}
+ return widget;
+ }
}
[ModuleInit]
diff --git a/plugins/share/Email/EmailForm.vala b/plugins/share/Email/EmailForm.vala
index 31f1cf8e..dec4f6ce 100644
--- a/plugins/share/Email/EmailForm.vala
+++ b/plugins/share/Email/EmailForm.vala
@@ -15,78 +15,78 @@
public class FeedReader.EmailForm : ShareForm {
-
-private Gtk.Entry m_entry;
-private Gtk.TextView m_textView;
-
-public EmailForm(string url)
-{
- string body = _("Hey,\n\nCheck out this interesting article I used FeedReader to read: $URL");
- string to = "john.doe@domain.com";
-
- var labelTo = new Gtk.Label(_("To:"));
- labelTo.set_alignment(0.0f, 0.5f);
- labelTo.get_style_context().add_class("h3");
- m_entry = new Gtk.Entry();
- m_entry.set_text(to);
- var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
- box.pack_start(labelTo, false, false);
- box.pack_start(m_entry, true, true);
-
- m_textView = new Gtk.TextView();
- m_textView.get_style_context().add_class("h3");
- m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
- m_textView.buffer.text = body;
- m_textView.border_width = 2;
-
- var scrolled = new Gtk.ScrolledWindow(null, null);
- scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
- scrolled.add(m_textView);
-
- int margin = 5;
- m_textView.left_margin = margin;
- m_textView.right_margin = margin;
- m_textView.top_margin = margin;
- m_textView.bottom_margin = margin;
-
- var button = new Gtk.Button.with_label(_("Send"));
- button.halign = Gtk.Align.END;
- button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- button.clicked.connect(() => { share(); });
-
- var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
- backButton.set_focus_on_click(false);
- backButton.set_relief(Gtk.ReliefStyle.NONE);
- backButton.halign = Gtk.Align.START;
- backButton.clicked.connect(() => {
+
+ private Gtk.Entry m_entry;
+ private Gtk.TextView m_textView;
+
+ public EmailForm(string url)
+ {
+ string body = _("Hey,\n\nCheck out this interesting article I used FeedReader to read: $URL");
+ string to = "john.doe@domain.com";
+
+ var labelTo = new Gtk.Label(_("To:"));
+ labelTo.set_alignment(0.0f, 0.5f);
+ labelTo.get_style_context().add_class("h3");
+ m_entry = new Gtk.Entry();
+ m_entry.set_text(to);
+ var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+ box.pack_start(labelTo, false, false);
+ box.pack_start(m_entry, true, true);
+
+ m_textView = new Gtk.TextView();
+ m_textView.get_style_context().add_class("h3");
+ m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+ m_textView.buffer.text = body;
+ m_textView.border_width = 2;
+
+ var scrolled = new Gtk.ScrolledWindow(null, null);
+ scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+ scrolled.add(m_textView);
+
+ int margin = 5;
+ m_textView.left_margin = margin;
+ m_textView.right_margin = margin;
+ m_textView.top_margin = margin;
+ m_textView.bottom_margin = margin;
+
+ var button = new Gtk.Button.with_label(_("Send"));
+ button.halign = Gtk.Align.END;
+ button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ button.clicked.connect(() => { share(); });
+
+ var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+ backButton.set_focus_on_click(false);
+ backButton.set_relief(Gtk.ReliefStyle.NONE);
+ backButton.halign = Gtk.Align.START;
+ backButton.clicked.connect(() => {
goBack();
});
-
- var headline = new Gtk.Label(_("Write Email"));
- headline.get_style_context().add_class("h2");
- headline.set_alignment(0.4f, 0.5f);
- var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box2.pack_start(backButton, false, false, 0);
- box2.pack_start(headline, true, true, 0);
-
- this.pack_start(box2, false, false, 0);
- this.pack_start(box, false, false);
- this.pack_start(scrolled);
- this.pack_end(button, false, false);
- this.orientation = Gtk.Orientation.VERTICAL;
- this.spacing = 5;
- this.margin = 10;
- this.show_all();
-}
-
-public string getTo()
-{
- return m_entry.get_text();
-}
-
-public string getBody()
-{
- return m_textView.buffer.text;
-}
-
+
+ var headline = new Gtk.Label(_("Write Email"));
+ headline.get_style_context().add_class("h2");
+ headline.set_alignment(0.4f, 0.5f);
+ var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box2.pack_start(backButton, false, false, 0);
+ box2.pack_start(headline, true, true, 0);
+
+ this.pack_start(box2, false, false, 0);
+ this.pack_start(box, false, false);
+ this.pack_start(scrolled);
+ this.pack_end(button, false, false);
+ this.orientation = Gtk.Orientation.VERTICAL;
+ this.spacing = 5;
+ this.margin = 10;
+ this.show_all();
+ }
+
+ public string getTo()
+ {
+ return m_entry.get_text();
+ }
+
+ public string getBody()
+ {
+ return m_textView.buffer.text;
+ }
+
}
diff --git a/plugins/share/Instapaper/InstapaperAPI.vala b/plugins/share/Instapaper/InstapaperAPI.vala
index 526a0b96..5ddc2961 100644
--- a/plugins/share/Instapaper/InstapaperAPI.vala
+++ b/plugins/share/Instapaper/InstapaperAPI.vala
@@ -14,297 +14,297 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.InstapaperSecrets {
-const string base_uri = "https://www.instapaper.com/api/";
-const string oauth_consumer_key = "b7681e07bf554b15813511217054e1b2";
-const string oauth_consumer_secret = "c5307cb359d54685904f6d38aaeede6f";
-const string oauth_callback = "feedreader://instapaper";
+ const string base_uri = "https://www.instapaper.com/api/";
+ const string oauth_consumer_key = "b7681e07bf554b15813511217054e1b2";
+ const string oauth_consumer_secret = "c5307cb359d54685904f6d38aaeede6f";
+ const string oauth_callback = "feedreader://instapaper";
}
public class FeedReader.InstaAPI : ShareAccountInterface, Peas.ExtensionBase {
-
-public InstaAPI()
-{
-
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public string getRequestToken()
-{
- return "";
-}
-
-public bool getAccessToken(string id, string username, string password)
-{
- string userID = "";
-
- var oauthObject = new Rest.OAuthProxy (
- InstapaperSecrets.oauth_consumer_key,
- InstapaperSecrets.oauth_consumer_secret,
- "https://www.instapaper.com/api/1/",
- false);
-
- var call = oauthObject.new_call();
- oauthObject.url_format = "https://www.instapaper.com/api/1/";
- call.set_function ("oauth/access_token");
- call.set_method("POST");
- call.add_param("x_auth_mode", "client_auth");
- call.add_param("x_auth_username", username);
- call.add_param("x_auth_password", password);
- try
+
+ public InstaAPI()
{
- call.run();
+
}
- catch(Error e)
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
{
- Logger.error("instapaper getAccessToken: " + e.message);
+
}
-
- string response = call.get_payload();
- int64 status = call.get_status_code();
-
- if(status != 200)
+
+ public string getRequestToken()
{
- return false;
+ return "";
}
-
-
- int secretStart = response.index_of_char('=')+1;
- int secretEnd = response.index_of_char('&', secretStart);
- int tokenStart = response.index_of_char('=', secretEnd)+1;
-
- string accessToken_secret = response.substring(secretStart, secretEnd-secretStart);
- string accessToken = response.substring(tokenStart);
-
- oauthObject.set_token(accessToken);
- oauthObject.set_token_secret(accessToken_secret);
-
- // get userID -------------------------------------------------------------------------------------------------
- var call2 = oauthObject.new_call();
- oauthObject.url_format = "https://www.instapaper.com/api/1/";
- call2.set_function("account/verify_credentials");
- call2.set_method("POST");
- try
+
+ public bool getAccessToken(string id, string username, string password)
{
- call2.run();
+ string userID = "";
+
+ var oauthObject = new Rest.OAuthProxy (
+ InstapaperSecrets.oauth_consumer_key,
+ InstapaperSecrets.oauth_consumer_secret,
+ "https://www.instapaper.com/api/1/",
+ false);
+
+ var call = oauthObject.new_call();
+ oauthObject.url_format = "https://www.instapaper.com/api/1/";
+ call.set_function ("oauth/access_token");
+ call.set_method("POST");
+ call.add_param("x_auth_mode", "client_auth");
+ call.add_param("x_auth_username", username);
+ call.add_param("x_auth_password", password);
+ try
+ {
+ call.run();
+ }
+ catch(Error e)
+ {
+ Logger.error("instapaper getAccessToken: " + e.message);
+ }
+
+ string response = call.get_payload();
+ int64 status = call.get_status_code();
+
+ if(status != 200)
+ {
+ return false;
+ }
+
+
+ int secretStart = response.index_of_char('=')+1;
+ int secretEnd = response.index_of_char('&', secretStart);
+ int tokenStart = response.index_of_char('=', secretEnd)+1;
+
+ string accessToken_secret = response.substring(secretStart, secretEnd-secretStart);
+ string accessToken = response.substring(tokenStart);
+
+ oauthObject.set_token(accessToken);
+ oauthObject.set_token_secret(accessToken_secret);
+
+ // get userID -------------------------------------------------------------------------------------------------
+ var call2 = oauthObject.new_call();
+ oauthObject.url_format = "https://www.instapaper.com/api/1/";
+ call2.set_function("account/verify_credentials");
+ call2.set_method("POST");
+ try
+ {
+ call2.run();
+ }
+ catch(Error e)
+ {
+ Logger.debug("getUserID: " + e.message);
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(call2.get_payload());
+ }
+ catch (Error e)
+ {
+ Logger.error("Could not load response to Message from instapaper");
+ Logger.error(e.message);
+ }
+
+ var root_node = parser.get_root();
+ var userArray = root_node.get_array();
+ var root_object = userArray.get_object_element(0);
+ if(root_object.has_member("user_id"))
+ {
+ userID = root_object.get_int_member("user_id").to_string();
+ }
+ else if(root_object.has_member("error"))
+ {
+ Logger.error(root_object.get_int_member("error_code").to_string());
+ Logger.error(root_object.get_string_member("message"));
+ }
+ //-------------------------------------------------------------------------------------------------------------
+
+
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+ settings.set_string("oauth-access-token", accessToken);
+ settings.set_string("oauth-access-token-secret", accessToken_secret);
+ settings.set_string("username", username);
+ settings.set_string("user-id", userID);
+
+ var array = Settings.share("instapaper").get_strv("account-ids");
+ array += id;
+ Settings.share("instapaper").set_strv("account-ids", array);
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE,
+ "userID", Secret.SchemaAttributeType.STRING);
+
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["userID"] = userID;
+ try
+ {
+ Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Instapaper login", password, null);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("InstaAPI - getAccessToken: " + e.message);
+ }
+
+ return true;
}
- catch(Error e)
+
+ public bool addBookmark(string id, string url, bool system)
{
- Logger.debug("getUserID: " + e.message);
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["userID"] = settings.get_string("user-id");
+
+ string password = "";
+ try
+ {
+ password = Secret.password_lookupv_sync(pwSchema, attributes, null);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("InstaAPI addBookmark: " + e.message);
+ }
+
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "user_id=" + settings.get_string("user-id")
+ + "&username=" + settings.get_string("username")
+ + "&password=" + password
+ + "&url=" + GLib.Uri.escape_string(url);
+
+ Logger.debug("InstaAPI: " + message);
+
+ var message_soup = new Soup.Message("POST", "https://www.instapaper.com/api/add");
+ message_soup.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message.data);
+
+ if(Settings.tweaks().get_boolean("do-not-track"))
+ {
+ message_soup.request_headers.append("DNT", "1");
+ }
+
+ session.send_message(message_soup);
+ string response = (string)message_soup.response_body.flatten().data;
+
+ if(response == null || response == "")
+ {
+ return false;
+ }
+
+ Logger.debug("InstaAPI: " + response);
+
+ return true;
}
-
- var parser = new Json.Parser();
- try
+
+ public bool logout(string id)
{
- parser.load_from_data(call2.get_payload());
+ Logger.debug(@"InstaAPI.logout($id)");
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", @"/org/gnome/feedreader/share/instapaper/$id/");
+ var pwSchema = new Secret.Schema("org.gnome.feedreader.instapaper.password",
+ Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
+
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["userID"] = settings.get_string("user-id");
+ bool removed = false;
+
+ Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
+ try
+ {
+ removed = Secret.password_clearv.end(async_res);
+ if(!removed)
+ {
+ Logger.error(@"Could not delete password of InstaAPI account $id");
+ }
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("InstaAPI.logout: %s".printf(e.message));
+ }
+ });
+
+ var keys = settings.list_keys();
+ foreach(string key in keys)
+ {
+ settings.reset(key);
+ }
+
+ var array = Settings.share("instapaper").get_strv("account-ids");
+
+ string[] array2 = {};
+ foreach(string i in array)
+ {
+ if(i != id)
+ {
+ array2 += i;
+ }
+ }
+ Settings.share("instapaper").set_strv("account-ids", array2);
+ deleteAccount(id);
+
+ return true;
}
- catch (Error e)
+
+ public string getIconName()
{
- Logger.error("Could not load response to Message from instapaper");
- Logger.error(e.message);
+ return "feed-share-instapaper";
}
-
- var root_node = parser.get_root();
- var userArray = root_node.get_array();
- var root_object = userArray.get_object_element(0);
- if(root_object.has_member("user_id"))
+
+ public string getUsername(string id)
{
- userID = root_object.get_int_member("user_id").to_string();
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+ return settings.get_string("username");
}
- else if(root_object.has_member("error"))
+
+ public bool needSetup()
{
- Logger.error(root_object.get_int_member("error_code").to_string());
- Logger.error(root_object.get_string_member("message"));
+ return true;
}
- //-------------------------------------------------------------------------------------------------------------
-
-
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
- settings.set_string("oauth-access-token", accessToken);
- settings.set_string("oauth-access-token-secret", accessToken_secret);
- settings.set_string("username", username);
- settings.set_string("user-id", userID);
-
- var array = Settings.share("instapaper").get_strv("account-ids");
- array += id;
- Settings.share("instapaper").set_strv("account-ids", array);
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE,
- "userID", Secret.SchemaAttributeType.STRING);
-
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["userID"] = userID;
- try
+
+ public bool singleInstance()
{
- Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Instapaper login", password, null);
+ return false;
}
- catch(GLib.Error e)
+
+ public bool useSystemAccounts()
{
- Logger.error("InstaAPI - getAccessToken: " + e.message);
+ return false;
}
-
- return true;
-}
-
-public bool addBookmark(string id, string url, bool system)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["userID"] = settings.get_string("user-id");
-
- string password = "";
- try
+
+ public string pluginID()
{
- password = Secret.password_lookupv_sync(pwSchema, attributes, null);
+ return "instapaper";
}
- catch(GLib.Error e)
+
+ public string pluginName()
{
- Logger.error("InstaAPI addBookmark: " + e.message);
+ return "Instapaper";
}
-
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "user_id=" + settings.get_string("user-id")
- + "&username=" + settings.get_string("username")
- + "&password=" + password
- + "&url=" + GLib.Uri.escape_string(url);
-
- Logger.debug("InstaAPI: " + message);
-
- var message_soup = new Soup.Message("POST", "https://www.instapaper.com/api/add");
- message_soup.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message.data);
-
- if(Settings.tweaks().get_boolean("do-not-track"))
+
+ public string getURL(string token)
{
- message_soup.request_headers.append("DNT", "1");
+ return "";
}
-
- session.send_message(message_soup);
- string response = (string)message_soup.response_body.flatten().data;
-
- if(response == null || response == "")
+
+ public ServiceSetup? newSetup_withID(string id, string username)
{
- return false;
+ return new InstapaperSetup(id, this, username);
}
-
- Logger.debug("InstaAPI: " + response);
-
- return true;
-}
-
-public bool logout(string id)
-{
- Logger.debug(@"InstaAPI.logout($id)");
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", @"/org/gnome/feedreader/share/instapaper/$id/");
- var pwSchema = new Secret.Schema("org.gnome.feedreader.instapaper.password",
- Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
-
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["userID"] = settings.get_string("user-id");
- bool removed = false;
-
- Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
- try
- {
- removed = Secret.password_clearv.end(async_res);
- if(!removed)
- {
- Logger.error(@"Could not delete password of InstaAPI account $id");
- }
- }
- catch(GLib.Error e)
- {
- Logger.error("InstaAPI.logout: %s".printf(e.message));
- }
- });
-
- var keys = settings.list_keys();
- foreach(string key in keys)
+
+ public ServiceSetup? newSetup()
{
- settings.reset(key);
+ return new InstapaperSetup(null, this);
}
-
- var array = Settings.share("instapaper").get_strv("account-ids");
-
- string[] array2 = {};
- foreach(string i in array)
+
+ public ServiceSetup? newSystemAccount(string id, string username)
{
- if(i != id)
- {
- array2 += i;
- }
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ return null;
}
- Settings.share("instapaper").set_strv("account-ids", array2);
- deleteAccount(id);
-
- return true;
-}
-
-public string getIconName()
-{
- return "feed-share-instapaper";
-}
-
-public string getUsername(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
- return settings.get_string("username");
-}
-
-public bool needSetup()
-{
- return true;
-}
-
-public bool singleInstance()
-{
- return false;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "instapaper";
-}
-
-public string pluginName()
-{
- return "Instapaper";
-}
-
-public string getURL(string token)
-{
- return "";
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return new InstapaperSetup(id, this, username);
-}
-
-public ServiceSetup? newSetup()
-{
- return new InstapaperSetup(null, this);
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- return null;
-}
}
[ModuleInit]
diff --git a/plugins/share/Instapaper/InstapaperSetup.vala b/plugins/share/Instapaper/InstapaperSetup.vala
index 5952e4a4..868dee67 100644
--- a/plugins/share/Instapaper/InstapaperSetup.vala
+++ b/plugins/share/Instapaper/InstapaperSetup.vala
@@ -14,113 +14,113 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.InstapaperSetup : ServiceSetup {
-
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passEntry;
-private Gtk.Revealer m_login_revealer;
-private InstaAPI m_api;
-
-public InstapaperSetup(string? id, InstaAPI api, string username = "")
-{
- bool loggedIN = false;
- if(username != "")
+
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passEntry;
+ private Gtk.Revealer m_login_revealer;
+ private InstaAPI m_api;
+
+ public InstapaperSetup(string? id, InstaAPI api, string username = "")
{
- loggedIN = true;
- }
-
- base("Instapaper", "feed-share-instapaper", loggedIN, username);
-
- //------------------------------------------------
- // XAuth revealer
- //------------------------------------------------
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
- grid.margin_bottom = 10;
- grid.margin_top = 5;
-
- m_userEntry = new Gtk.Entry();
- m_passEntry = new Gtk.Entry();
- m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passEntry.set_visibility(false);
-
- m_userEntry.activate.connect(() => {
+ bool loggedIN = false;
+ if(username != "")
+ {
+ loggedIN = true;
+ }
+
+ base("Instapaper", "feed-share-instapaper", loggedIN, username);
+
+ //------------------------------------------------
+ // XAuth revealer
+ //------------------------------------------------
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+ grid.margin_bottom = 10;
+ grid.margin_top = 5;
+
+ m_userEntry = new Gtk.Entry();
+ m_passEntry = new Gtk.Entry();
+ m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passEntry.set_visibility(false);
+
+ m_userEntry.activate.connect(() => {
m_passEntry.grab_focus();
});
-
- m_passEntry.activate.connect(() => {
+
+ m_passEntry.activate.connect(() => {
login();
});
-
- grid.attach(new Gtk.Label(_("Username:")), 0, 0, 1, 1);
- grid.attach(new Gtk.Label(_("Password:")), 0, 1, 1, 1);
- grid.attach(m_userEntry, 1, 0, 1, 1);
- grid.attach(m_passEntry, 1, 1, 1, 1);
-
- m_login_revealer = new Gtk.Revealer();
- m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
- m_login_revealer.add(grid);
- //------------------------------------------------
-
- m_seperator_box.pack_start(m_login_revealer, false, false, 0);
-
- m_api = api;
-
- if(id != null)
- {
- m_id = id;
+
+ grid.attach(new Gtk.Label(_("Username:")), 0, 0, 1, 1);
+ grid.attach(new Gtk.Label(_("Password:")), 0, 1, 1, 1);
+ grid.attach(m_userEntry, 1, 0, 1, 1);
+ grid.attach(m_passEntry, 1, 1, 1, 1);
+
+ m_login_revealer = new Gtk.Revealer();
+ m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
+ m_login_revealer.add(grid);
+ //------------------------------------------------
+
+ m_seperator_box.pack_start(m_login_revealer, false, false, 0);
+
+ m_api = api;
+
+ if(id != null)
+ {
+ m_id = id;
+ }
}
-}
-
-
-public override void login()
-{
- if(m_login_revealer.get_child_revealed())
+
+
+ public override void login()
{
- m_spinner.start();
- m_iconStack.set_visible_child_name("spinner");
- string id = Share.get_default().generateNewID();
- string username = m_userEntry.get_text();
- string password = m_passEntry.get_text();
-
- if(m_api.getAccessToken(id, username, password))
+ if(m_login_revealer.get_child_revealed())
{
- m_id = id;
- m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
- m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- m_login_revealer.set_reveal_child(false);
- m_isLoggedIN = true;
- m_iconStack.set_visible_child_name("loggedIN");
- m_spinner.stop();
- m_label.set_label(username);
- m_labelStack.set_visible_child_name("loggedIN");
- m_login_button.clicked.disconnect(login);
- m_login_button.clicked.connect(logout);
+ m_spinner.start();
+ m_iconStack.set_visible_child_name("spinner");
+ string id = Share.get_default().generateNewID();
+ string username = m_userEntry.get_text();
+ string password = m_passEntry.get_text();
+
+ if(m_api.getAccessToken(id, username, password))
+ {
+ m_id = id;
+ m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
+ m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ m_login_revealer.set_reveal_child(false);
+ m_isLoggedIN = true;
+ m_iconStack.set_visible_child_name("loggedIN");
+ m_spinner.stop();
+ m_label.set_label(username);
+ m_labelStack.set_visible_child_name("loggedIN");
+ m_login_button.clicked.disconnect(login);
+ m_login_button.clicked.connect(logout);
+ }
+ else
+ {
+ showInfoBar(_("Username or Password incorrect"));
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ }
+
}
else
{
- showInfoBar(_("Username or Password incorrect"));
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_login_revealer.set_reveal_child(true);
+ m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ m_userEntry.grab_focus();
}
-
}
- else
+
+ public override void logout()
{
- m_login_revealer.set_reveal_child(true);
- m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- m_userEntry.grab_focus();
+ Logger.debug("InstapaperSetup.logout()");
+ m_isLoggedIN = false;
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_labelStack.set_visible_child_name("loggedOUT");
+ m_api.logout(m_id);
+ removeRow();
}
}
-
-public override void logout()
-{
- Logger.debug("InstapaperSetup.logout()");
- m_isLoggedIN = false;
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- m_labelStack.set_visible_child_name("loggedOUT");
- m_api.logout(m_id);
- removeRow();
-}
-}
diff --git a/plugins/share/Pocket/PocketAPI.vala b/plugins/share/Pocket/PocketAPI.vala
index a2ce4b12..a1cce40b 100644
--- a/plugins/share/Pocket/PocketAPI.vala
+++ b/plugins/share/Pocket/PocketAPI.vala
@@ -14,288 +14,288 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.PocketSecrets {
-const string base_uri = "https://getpocket.com/v3/";
-const string oauth_consumer_key = "43273-30a11c29b5eeabfa905df168";
-const string oauth_callback = "feedreader://pocket";
+ const string base_uri = "https://getpocket.com/v3/";
+ const string oauth_consumer_key = "43273-30a11c29b5eeabfa905df168";
+ const string oauth_callback = "feedreader://pocket";
}
public class FeedReader.PocketAPI : ShareAccountInterface, Peas.ExtensionBase {
-
-public PocketAPI()
-{
-
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
- try
+
+ public PocketAPI()
+ {
+
+ }
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
{
- Goa.Client? client = new Goa.Client.sync();
- if(client != null)
+ try
{
- var goaAccounts = client.get_accounts();
- foreach(var object in goaAccounts)
+ Goa.Client? client = new Goa.Client.sync();
+ if(client != null)
{
- if(object.account.provider_type == "pocket"
- && !object.account.read_later_disabled)
+ var goaAccounts = client.get_accounts();
+ foreach(var object in goaAccounts)
{
- accounts.add(
- new ShareAccount(
- object.account.id,
- pluginID(),
- object.account.identity,
- getIconName(),
- pluginName(),
- true
+ if(object.account.provider_type == "pocket"
+ && !object.account.read_later_disabled)
+ {
+ accounts.add(
+ new ShareAccount(
+ object.account.id,
+ pluginID(),
+ object.account.identity,
+ getIconName(),
+ pluginName(),
+ true
)
);
+ }
}
}
+ else
+ {
+ Logger.error("PocketAPI: goa not available");
+ }
}
- else
+ catch(GLib.Error e)
{
- Logger.error("PocketAPI: goa not available");
+ Logger.error("PocketAPI.setupSystemAccounts: %s".printf(e.message));
}
}
- catch(GLib.Error e)
+
+ public string getRequestToken()
{
- Logger.error("PocketAPI.setupSystemAccounts: %s".printf(e.message));
+ Logger.debug("PocketAPI: get request token");
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&redirect_uri=" + PocketSecrets.oauth_callback;
+
+ var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/request");
+ message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+
+ if(Settings.tweaks().get_boolean("do-not-track"))
+ {
+ message_soup.request_headers.append("DNT", "1");
+ }
+
+ session.send_message(message_soup);
+
+ string response = (string)message_soup.response_body.flatten().data;
+ return response.substring(response.index_of_char('=')+1);
}
-}
-
-public string getRequestToken()
-{
- Logger.debug("PocketAPI: get request token");
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&redirect_uri=" + PocketSecrets.oauth_callback;
-
- var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/request");
- message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-
- if(Settings.tweaks().get_boolean("do-not-track"))
+
+ public bool getAccessToken(string id, string requestToken)
{
- message_soup.request_headers.append("DNT", "1");
- }
-
- session.send_message(message_soup);
-
- string response = (string)message_soup.response_body.flatten().data;
- return response.substring(response.index_of_char('=')+1);
-}
-
-public bool getAccessToken(string id, string requestToken)
-{
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&code=" + requestToken;
-
- var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/authorize");
- message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-
- if(Settings.tweaks().get_boolean("do-not-track"))
- {
- message_soup.request_headers.append("DNT", "1");
- }
-
- session.send_message(message_soup);
-
- if((string)message_soup.response_body.flatten().data == null
- || (string)message_soup.response_body.flatten().data == "")
- {
- return false;
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&code=" + requestToken;
+
+ var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/authorize");
+ message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+
+ if(Settings.tweaks().get_boolean("do-not-track"))
+ {
+ message_soup.request_headers.append("DNT", "1");
+ }
+
+ session.send_message(message_soup);
+
+ if((string)message_soup.response_body.flatten().data == null
+ || (string)message_soup.response_body.flatten().data == "")
+ {
+ return false;
+ }
+
+ string response = (string)message_soup.response_body.flatten().data;
+ Logger.debug(response);
+ int tokenStart = response.index_of_char('=')+1;
+ int tokenEnd = response.index_of_char('&', tokenStart);
+ int userStart = response.index_of_char('=', tokenEnd)+1;
+
+ string accessToken = response.substring(tokenStart, tokenEnd-tokenStart);
+ string user = GLib.Uri.unescape_string(response.substring(userStart));
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+ settings.set_string("oauth-access-token", accessToken);
+ settings.set_string("username", user);
+
+ var array = Settings.share("pocket").get_strv("account-ids");
+ array += id;
+ Settings.share("pocket").set_strv("account-ids", array);
+
+ return true;
}
-
- string response = (string)message_soup.response_body.flatten().data;
- Logger.debug(response);
- int tokenStart = response.index_of_char('=')+1;
- int tokenEnd = response.index_of_char('&', tokenStart);
- int userStart = response.index_of_char('=', tokenEnd)+1;
-
- string accessToken = response.substring(tokenStart, tokenEnd-tokenStart);
- string user = GLib.Uri.unescape_string(response.substring(userStart));
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
- settings.set_string("oauth-access-token", accessToken);
- settings.set_string("username", user);
-
- var array = Settings.share("pocket").get_strv("account-ids");
- array += id;
- Settings.share("pocket").set_strv("account-ids", array);
-
- return true;
-}
-
-
-public bool addBookmark(string id, string url, bool system)
-{
- string oauthToken = "";
-
- if(system)
+
+
+ public bool addBookmark(string id, string url, bool system)
{
- Logger.debug(@"PocketAPI.addBookmark: $id is system account");
- try
+ string oauthToken = "";
+
+ if(system)
{
- Goa.Client? client = new Goa.Client.sync();
- if(client != null)
+ Logger.debug(@"PocketAPI.addBookmark: $id is system account");
+ try
{
- var accounts = client.get_accounts();
- foreach(var object in accounts)
+ Goa.Client? client = new Goa.Client.sync();
+ if(client != null)
{
- if(object.account.provider_type == "pocket"
- && object.account.id == id)
+ var accounts = client.get_accounts();
+ foreach(var object in accounts)
{
- int expires = -1;
- object.oauth2_based.call_get_access_token_sync(out oauthToken, out expires);
- break;
+ if(object.account.provider_type == "pocket"
+ && object.account.id == id)
+ {
+ int expires = -1;
+ object.oauth2_based.call_get_access_token_sync(out oauthToken, out expires);
+ break;
+ }
}
}
+ else
+ {
+ Logger.error("PocketAPI: goa not available");
+ }
}
- else
+ catch(GLib.Error e)
{
- Logger.error("PocketAPI: goa not available");
+ Logger.error("PocketAPI GOA: %s".printf(e.message));
}
}
- catch(GLib.Error e)
+ else
{
- Logger.error("PocketAPI GOA: %s".printf(e.message));
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+ oauthToken = settings.get_string("oauth-access-token");
}
+
+
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "url=" + GLib.Uri.escape_string(url)
+ + "&consumer_key=" + PocketSecrets.oauth_consumer_key
+ + "&access_token=" + oauthToken;
+
+ Logger.debug("PocketAPI: " + message);
+
+ var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/add");
+ message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+
+ if(Settings.tweaks().get_boolean("do-not-track"))
+ {
+ message_soup.request_headers.append("DNT", "1");
+ }
+
+ session.send_message(message_soup);
+
+ if((string)message_soup.response_body.flatten().data == null
+ || (string)message_soup.response_body.flatten().data == "")
+ {
+ return false;
+ }
+
+ return true;
}
- else
+
+ public bool logout(string id)
{
+ Logger.debug(@"PocketAPI: logout($id)");
var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
- oauthToken = settings.get_string("oauth-access-token");
+ var keys = settings.list_keys();
+ foreach(string key in keys)
+ {
+ settings.reset(key);
+ }
+
+ var array = Settings.share("pocket").get_strv("account-ids");
+ string[] array2 = {};
+
+ foreach(string i in array)
+ {
+ if(i != id)
+ {
+ array2 += i;
+ }
+ }
+ Settings.share("pocket").set_strv("account-ids", array2);
+ deleteAccount(id);
+
+ return true;
}
-
-
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "url=" + GLib.Uri.escape_string(url)
- + "&consumer_key=" + PocketSecrets.oauth_consumer_key
- + "&access_token=" + oauthToken;
-
- Logger.debug("PocketAPI: " + message);
-
- var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/add");
- message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-
- if(Settings.tweaks().get_boolean("do-not-track"))
+
+ public string getURL(string token)
{
- message_soup.request_headers.append("DNT", "1");
+ return "https://getpocket.com/auth/authorize?request_token="
+ + token + "&redirect_uri="
+ + GLib.Uri.escape_string(PocketSecrets.oauth_callback);
}
-
- session.send_message(message_soup);
-
- if((string)message_soup.response_body.flatten().data == null
- || (string)message_soup.response_body.flatten().data == "")
+
+ public string getIconName()
{
- return false;
+ return "feed-share-pocket";
}
-
- return true;
-}
-
-public bool logout(string id)
-{
- Logger.debug(@"PocketAPI: logout($id)");
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
- var keys = settings.list_keys();
- foreach(string key in keys)
+
+ public string getUsername(string id)
{
- settings.reset(key);
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+ return settings.get_string("username");
}
-
- var array = Settings.share("pocket").get_strv("account-ids");
- string[] array2 = {};
-
- foreach(string i in array)
+
+ public bool needSetup()
{
- if(i != id)
- {
- array2 += i;
- }
+ return true;
}
- Settings.share("pocket").set_strv("account-ids", array2);
- deleteAccount(id);
-
- return true;
-}
-
-public string getURL(string token)
-{
- return "https://getpocket.com/auth/authorize?request_token="
- + token + "&redirect_uri="
- + GLib.Uri.escape_string(PocketSecrets.oauth_callback);
-}
-
-public string getIconName()
-{
- return "feed-share-pocket";
-}
-
-public string getUsername(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
- return settings.get_string("username");
-}
-
-public bool needSetup()
-{
- return true;
-}
-
-public bool singleInstance()
-{
- return false;
-}
-
-public bool useSystemAccounts()
-{
- try
+
+ public bool singleInstance()
{
- Goa.Client? client = new Goa.Client.sync();
- if(client != null)
+ return false;
+ }
+
+ public bool useSystemAccounts()
+ {
+ try
{
- return true;
+ Goa.Client? client = new Goa.Client.sync();
+ if(client != null)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ catch(GLib.Error e)
+ {
+ Logger.debug("PocketAPI.useSystemAccounts(): %s".printf(e.message));
+ return false;
}
-
- return false;
}
- catch(GLib.Error e)
+
+ public string pluginID()
{
- Logger.debug("PocketAPI.useSystemAccounts(): %s".printf(e.message));
- return false;
+ return "pocket";
+ }
+
+ public string pluginName()
+ {
+ return "Pocket";
+ }
+
+ public ServiceSetup? newSetup_withID(string id, string username)
+ {
+ return new PocketSetup(id, this, username);
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return new PocketSetup(null, this);
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return new PocketSetup(id, this, username, true);
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ return null;
}
-}
-
-public string pluginID()
-{
- return "pocket";
-}
-
-public string pluginName()
-{
- return "Pocket";
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return new PocketSetup(id, this, username);
-}
-
-public ServiceSetup? newSetup()
-{
- return new PocketSetup(null, this);
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return new PocketSetup(id, this, username, true);
-}
-
-public ShareForm? shareWidget(string url)
-{
- return null;
-}
}
[ModuleInit]
diff --git a/plugins/share/Pocket/PocketSetup.vala b/plugins/share/Pocket/PocketSetup.vala
index bbb95006..486028ad 100644
--- a/plugins/share/Pocket/PocketSetup.vala
+++ b/plugins/share/Pocket/PocketSetup.vala
@@ -14,77 +14,77 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.PocketSetup : ServiceSetup {
-
-private PocketAPI m_api;
-
-public PocketSetup(string? id, PocketAPI api, string username = "", bool system = false)
-{
- bool loggedIN = false;
- if(username != "")
- {
- loggedIN = true;
- }
-
- base("Pocket", "feed-share-pocket", loggedIN, username, system);
-
- m_api = api;
-
- if(id != null)
- {
- m_id = id;
- }
-}
-
-
-public override void login()
-{
- string id = Share.get_default().generateNewID();
- string requestToken = m_api.getRequestToken();
- string url = m_api.getURL(requestToken);
- m_spinner.start();
- m_iconStack.set_visible_child_name("spinner");
- try
+
+ private PocketAPI m_api;
+
+ public PocketSetup(string? id, PocketAPI api, string username = "", bool system = false)
{
- Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
+ bool loggedIN = false;
+ if(username != "")
+ {
+ loggedIN = true;
+ }
+
+ base("Pocket", "feed-share-pocket", loggedIN, username, system);
+
+ m_api = api;
+
+ if(id != null)
+ {
+ m_id = id;
+ }
}
- catch(GLib.Error e)
+
+
+ public override void login()
{
-
- }
-
-
- m_login_button.set_label(_("waiting"));
- m_login_button.set_sensitive(false);
- FeedReaderApp.get_default().callback.connect((content) => {
+ string id = Share.get_default().generateNewID();
+ string requestToken = m_api.getRequestToken();
+ string url = m_api.getURL(requestToken);
+ m_spinner.start();
+ m_iconStack.set_visible_child_name("spinner");
+ try
+ {
+ Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
+ }
+ catch(GLib.Error e)
+ {
+
+ }
+
+
+ m_login_button.set_label(_("waiting"));
+ m_login_button.set_sensitive(false);
+ FeedReaderApp.get_default().callback.connect((content) => {
if(content == PocketSecrets.oauth_callback)
{
- if(m_api.getAccessToken(id, requestToken))
- {
- m_id = id;
- m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
- m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
- m_spinner.stop();
- m_isLoggedIN = true;
- m_label.set_label(m_api.getUsername(id));
- m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
- m_login_button.clicked.disconnect(login);
- m_login_button.clicked.connect(logout);
+ if(m_api.getAccessToken(id, requestToken))
+ {
+ m_id = id;
+ m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
+ m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+ m_spinner.stop();
+ m_isLoggedIN = true;
+ m_label.set_label(m_api.getUsername(id));
+ m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+ m_login_button.clicked.disconnect(login);
+ m_login_button.clicked.connect(logout);
}
- else
- {
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ else
+ {
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
}
}
});
-}
-
-public override void logout()
-{
- m_isLoggedIN = false;
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- m_labelStack.set_visible_child_name("loggedOUT");
- m_api.logout(m_id);
- removeRow();
-}
-
+ }
+
+ public override void logout()
+ {
+ m_isLoggedIN = false;
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_labelStack.set_visible_child_name("loggedOUT");
+ m_api.logout(m_id);
+ removeRow();
+ }
+
}
diff --git a/plugins/share/Telegram/Telegram.vala b/plugins/share/Telegram/Telegram.vala
index defcf297..6f3e2aba 100644
--- a/plugins/share/Telegram/Telegram.vala
+++ b/plugins/share/Telegram/Telegram.vala
@@ -15,95 +15,95 @@
public class FeedReader.Telegram : ShareAccountInterface, Peas.ExtensionBase {
-
-string tg_text;
-
-public bool addBookmark(string id, string url, bool system)
-{
- string tg_msg = @"tg://msg_url?url=$url&text=$tg_text";
-
- try
+
+ string tg_text;
+
+ public bool addBookmark(string id, string url, bool system)
{
- Gtk.show_uri_on_window(MainWindow.get_default(), tg_msg, Gdk.CURRENT_TIME);
+ string tg_msg = @"tg://msg_url?url=$url&text=$tg_text";
+
+ try
+ {
+ Gtk.show_uri_on_window(MainWindow.get_default(), tg_msg, Gdk.CURRENT_TIME);
+ return true;
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("TelegramPlugin: Error opening url: " + e.message);
+ }
+ return false;
+ }
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+ {
+
+ }
+
+ public bool logout(string id)
+ {
+ Settings.share("telegram").set_boolean("enabled", false);
+ deleteAccount(id);
return true;
}
- catch(GLib.Error e)
+
+ public string getIconName()
{
- Logger.error("TelegramPlugin: Error opening url: " + e.message);
+ return "feed-share-telegram";
}
- return false;
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public bool logout(string id)
-{
- Settings.share("telegram").set_boolean("enabled", false);
- deleteAccount(id);
- return true;
-}
-
-public string getIconName()
-{
- return "feed-share-telegram";
-}
-
-public string getUsername(string id)
-{
- return "Telegram";
-}
-
-public bool needSetup()
-{
- return true;
-}
-
-public bool singleInstance()
-{
- return true;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "telegram";
-}
-
-public string pluginName()
-{
- return _("Telegram");
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return new TelegramSetup(id, this, username);
-}
-
-public ServiceSetup? newSetup()
-{
- return new TelegramSetup(null, this);
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- var widget = new TelegramForm();
- widget.share.connect(() => {
+
+ public string getUsername(string id)
+ {
+ return "Telegram";
+ }
+
+ public bool needSetup()
+ {
+ return true;
+ }
+
+ public bool singleInstance()
+ {
+ return true;
+ }
+
+ public bool useSystemAccounts()
+ {
+ return false;
+ }
+
+ public string pluginID()
+ {
+ return "telegram";
+ }
+
+ public string pluginName()
+ {
+ return _("Telegram");
+ }
+
+ public ServiceSetup? newSetup_withID(string id, string username)
+ {
+ return new TelegramSetup(id, this, username);
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return new TelegramSetup(null, this);
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ var widget = new TelegramForm();
+ widget.share.connect(() => {
tg_text = widget.getMessage();
});
- return widget;
-}
+ return widget;
+ }
}
[ModuleInit]
diff --git a/plugins/share/Telegram/TelegramForm.vala b/plugins/share/Telegram/TelegramForm.vala
index 21f2158b..d0d666f4 100644
--- a/plugins/share/Telegram/TelegramForm.vala
+++ b/plugins/share/Telegram/TelegramForm.vala
@@ -15,63 +15,63 @@
public class FeedReader.TelegramForm : ShareForm {
-
-private Gtk.TextView m_textView;
-
-public TelegramForm()
-{
- string tg_msg_text = _("Hey, check out this interesting article I used FeedReader to read");
- var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
-
- m_textView = new Gtk.TextView();
- m_textView.get_style_context().add_class("h3");
- m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
- m_textView.buffer.text = tg_msg_text;
- m_textView.border_width = 2;
-
- var scrolled = new Gtk.ScrolledWindow(null, null);
- scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
- scrolled.add(m_textView);
-
- int margin = 5;
- m_textView.left_margin = margin;
- m_textView.right_margin = margin;
- m_textView.top_margin = margin;
- m_textView.bottom_margin = margin;
-
- var button = new Gtk.Button.with_label(_("Send"));
- button.halign = Gtk.Align.END;
- button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- button.clicked.connect(() => { share(); });
-
- var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
- backButton.set_focus_on_click(false);
- backButton.set_relief(Gtk.ReliefStyle.NONE);
- backButton.halign = Gtk.Align.START;
- backButton.clicked.connect(() => {
+
+ private Gtk.TextView m_textView;
+
+ public TelegramForm()
+ {
+ string tg_msg_text = _("Hey, check out this interesting article I used FeedReader to read");
+ var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+
+ m_textView = new Gtk.TextView();
+ m_textView.get_style_context().add_class("h3");
+ m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+ m_textView.buffer.text = tg_msg_text;
+ m_textView.border_width = 2;
+
+ var scrolled = new Gtk.ScrolledWindow(null, null);
+ scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+ scrolled.add(m_textView);
+
+ int margin = 5;
+ m_textView.left_margin = margin;
+ m_textView.right_margin = margin;
+ m_textView.top_margin = margin;
+ m_textView.bottom_margin = margin;
+
+ var button = new Gtk.Button.with_label(_("Send"));
+ button.halign = Gtk.Align.END;
+ button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ button.clicked.connect(() => { share(); });
+
+ var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+ backButton.set_focus_on_click(false);
+ backButton.set_relief(Gtk.ReliefStyle.NONE);
+ backButton.halign = Gtk.Align.START;
+ backButton.clicked.connect(() => {
goBack();
});
-
- var headline = new Gtk.Label(_("Send Telegram"));
- headline.get_style_context().add_class("h2");
- headline.set_alignment(0.4f, 0.5f);
- var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box2.pack_start(backButton, false, false, 0);
- box2.pack_start(headline, true, true, 0);
-
- this.pack_start(box2, false, false, 0);
- this.pack_start(box, false, false);
- this.pack_start(scrolled);
- this.pack_end(button, false, false);
- this.orientation = Gtk.Orientation.VERTICAL;
- this.spacing = 5;
- this.margin = 10;
- this.show_all();
-}
-
-public string getMessage()
-{
- return m_textView.buffer.text;
-}
-
+
+ var headline = new Gtk.Label(_("Send Telegram"));
+ headline.get_style_context().add_class("h2");
+ headline.set_alignment(0.4f, 0.5f);
+ var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box2.pack_start(backButton, false, false, 0);
+ box2.pack_start(headline, true, true, 0);
+
+ this.pack_start(box2, false, false, 0);
+ this.pack_start(box, false, false);
+ this.pack_start(scrolled);
+ this.pack_end(button, false, false);
+ this.orientation = Gtk.Orientation.VERTICAL;
+ this.spacing = 5;
+ this.margin = 10;
+ this.show_all();
+ }
+
+ public string getMessage()
+ {
+ return m_textView.buffer.text;
+ }
+
}
diff --git a/plugins/share/Telegram/TelegramSetup.vala b/plugins/share/Telegram/TelegramSetup.vala
index 65717510..857e9cfe 100644
--- a/plugins/share/Telegram/TelegramSetup.vala
+++ b/plugins/share/Telegram/TelegramSetup.vala
@@ -14,48 +14,48 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.TelegramSetup : ServiceSetup {
-
-private Telegram m_tg;
-
-public TelegramSetup(string? id, Telegram tg, string username = "")
-{
- bool loggedIN = false;
- if(username != "")
+
+ private Telegram m_tg;
+
+ public TelegramSetup(string? id, Telegram tg, string username = "")
{
- loggedIN = true;
+ bool loggedIN = false;
+ if(username != "")
+ {
+ loggedIN = true;
+ }
+
+ base("Telegram", "feed-share-telegram", loggedIN, username);
+
+ m_tg = tg;
+ //no login, so change the labels
+ m_login_button.set_label(_("Add"));
+ m_logout_button.set_label(_("Remove"));
+ m_id = m_tg.pluginID();
}
-
- base("Telegram", "feed-share-telegram", loggedIN, username);
-
- m_tg = tg;
- //no login, so change the labels
- m_login_button.set_label(_("Add"));
- m_logout_button.set_label(_("Remove"));
- m_id = m_tg.pluginID();
-}
-
-
-public override void login()
-{
- showInfoBar(_("Info: Telegram would need to be installed for this plugin to work."));
- m_login_button.set_sensitive(false);
- Settings.share("telegram").set_boolean("enabled", true);
- m_tg.addAccount(m_id, m_tg.pluginID(), m_tg.getUsername(m_id), m_tg.getIconName(), m_tg.pluginName());
- m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
- m_isLoggedIN = true;
- m_label.set_label(m_tg.getUsername(m_id));
- m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
- m_login_button.clicked.disconnect(login);
- m_login_button.clicked.connect(logout);
-}
-
-public override void logout()
-{
- m_isLoggedIN = false;
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- m_labelStack.set_visible_child_name("loggedOUT");
- m_tg.logout(m_id);
- removeRow();
-}
-
+
+
+ public override void login()
+ {
+ showInfoBar(_("Info: Telegram would need to be installed for this plugin to work."));
+ m_login_button.set_sensitive(false);
+ Settings.share("telegram").set_boolean("enabled", true);
+ m_tg.addAccount(m_id, m_tg.pluginID(), m_tg.getUsername(m_id), m_tg.getIconName(), m_tg.pluginName());
+ m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+ m_isLoggedIN = true;
+ m_label.set_label(m_tg.getUsername(m_id));
+ m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+ m_login_button.clicked.disconnect(login);
+ m_login_button.clicked.connect(logout);
+ }
+
+ public override void logout()
+ {
+ m_isLoggedIN = false;
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_labelStack.set_visible_child_name("loggedOUT");
+ m_tg.logout(m_id);
+ removeRow();
+ }
+
}
diff --git a/plugins/share/Twitter/TwitterAPI.vala b/plugins/share/Twitter/TwitterAPI.vala
index f8a06777..a9f7747a 100644
--- a/plugins/share/Twitter/TwitterAPI.vala
+++ b/plugins/share/Twitter/TwitterAPI.vala
@@ -14,287 +14,287 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
namespace FeedReader.TwitterSecrets {
-const string base_uri = "https://api.twitter.com/";
-const string key = "hqScCfRLj5ImAtwypRKhbVpXo";
-const string secret = "wydD2zd6mgBUnlrdbqNqS0U0dJCWBJ9X0cqtdErk8Hn7aeperP";
-const string callback = "feedreader://twitter";
+ const string base_uri = "https://api.twitter.com/";
+ const string key = "hqScCfRLj5ImAtwypRKhbVpXo";
+ const string secret = "wydD2zd6mgBUnlrdbqNqS0U0dJCWBJ9X0cqtdErk8Hn7aeperP";
+ const string callback = "feedreader://twitter";
}
public class FeedReader.TwitterAPI : ShareAccountInterface, Peas.ExtensionBase {
-
-private Rest.OAuthProxy m_oauthObject;
-private string m_tweet;
-private int m_urlLength = 0;
-
-public TwitterAPI()
-{
-
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public string getRequestToken()
-{
- Logger.debug("TwitterAPI: get request token");
-
- m_oauthObject = new Rest.OAuthProxy (
- TwitterSecrets.key,
- TwitterSecrets.secret,
- "https://api.twitter.com/",
- false);
-
- try
+
+ private Rest.OAuthProxy m_oauthObject;
+ private string m_tweet;
+ private int m_urlLength = 0;
+
+ public TwitterAPI()
{
- m_oauthObject.request_token("oauth/request_token", TwitterSecrets.callback);
+
}
- catch(GLib.Error e)
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
{
- Logger.error("TwitterAPI.getRequestToken: %s".printf(e.message));
+
}
-
- return m_oauthObject.get_token();
-}
-
-public bool getAccessToken(string id, string verifier)
-{
- try
+
+ public string getRequestToken()
{
- m_oauthObject.access_token("oauth/access_token", verifier);
+ Logger.debug("TwitterAPI: get request token");
+
+ m_oauthObject = new Rest.OAuthProxy (
+ TwitterSecrets.key,
+ TwitterSecrets.secret,
+ "https://api.twitter.com/",
+ false);
+
+ try
+ {
+ m_oauthObject.request_token("oauth/request_token", TwitterSecrets.callback);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("TwitterAPI.getRequestToken: %s".printf(e.message));
+ }
+
+ return m_oauthObject.get_token();
}
- catch(GLib.Error e)
+
+ public bool getAccessToken(string id, string verifier)
{
- Logger.error("TwitterAPI.getAccessToken: %s".printf(e.message));
+ try
+ {
+ m_oauthObject.access_token("oauth/access_token", verifier);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("TwitterAPI.getAccessToken: %s".printf(e.message));
+ }
+
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+ string token = m_oauthObject.get_token();
+ string secret = m_oauthObject.get_token_secret();
+ settings.set_string("oauth-access-token", token);
+ settings.set_string("oauth-access-token-secret", secret);
+
+ var call = m_oauthObject.new_call();
+ call.set_function("1.1/account/verify_credentials.json");
+ call.set_method("GET");
+ call.add_param ("include_entities", "false");
+ call.add_param ("skip_status", "true");
+ call.add_param ("include_email", "true");
+
+ try
+ {
+ call.run();
+ }
+ catch(Error e)
+ {
+ Logger.error(e.message);
+ }
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(call.get_payload());
+ }
+ catch(Error e)
+ {
+ Logger.error("Could not load response to Message from twitter");
+ Logger.error(e.message);
+ }
+
+ var root_object = parser.get_root().get_object();
+
+ if(root_object.has_member("screen_name"))
+ {
+ string screenName = "@" + root_object.get_string_member("screen_name");
+ settings.set_string("username", screenName);
+ }
+ else
+ {
+ settings.set_string("username", root_object.get_string_member("name"));
+ }
+
+
+
+ var array = Settings.share("twitter").get_strv("account-ids");
+ array += id;
+ Settings.share("twitter").set_strv("account-ids", array);
+
+ return true;
}
-
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
- string token = m_oauthObject.get_token();
- string secret = m_oauthObject.get_token_secret();
- settings.set_string("oauth-access-token", token);
- settings.set_string("oauth-access-token-secret", secret);
-
- var call = m_oauthObject.new_call();
- call.set_function("1.1/account/verify_credentials.json");
- call.set_method("GET");
- call.add_param ("include_entities", "false");
- call.add_param ("skip_status", "true");
- call.add_param ("include_email", "true");
-
- try
+
+
+ public bool addBookmark(string id, string url, bool system)
{
- call.run();
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+ string token = settings.get_string("oauth-access-token");
+ string secret = settings.get_string("oauth-access-token-secret");
+
+ var oauthObject = new Rest.OAuthProxy.with_token (
+ TwitterSecrets.key,
+ TwitterSecrets.secret,
+ token,
+ secret,
+ "https://api.twitter.com/",
+ false);
+
+ var call = oauthObject.new_call();
+ call.set_function("1.1/statuses/update.json");
+ call.set_method("POST");
+ call.add_param ("status", m_tweet.replace("$URL", url));
+
+ try
+ {
+ call.run();
+ }
+ catch(Error e)
+ {
+ Logger.error(e.message);
+ return false;
+ }
+
+ return true;
}
- catch(Error e)
+
+ public bool logout(string id)
{
- Logger.error(e.message);
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+ var keys = settings.list_keys();
+ foreach(string key in keys)
+ {
+ settings.reset(key);
+ }
+
+ var array = Settings.share("twitter").get_strv("account-ids");
+ string[] array2 = {};
+
+ foreach(string i in array)
+ {
+ if(i != id)
+ {
+ array2 += i;
+ }
+ }
+ Settings.share("twitter").set_strv("account-ids", array2);
+ deleteAccount(id);
+
+ return true;
}
-
- var parser = new Json.Parser();
- try
+
+ public string getURL(string token)
{
- parser.load_from_data(call.get_payload());
+ return TwitterSecrets.base_uri
+ + "oauth/authenticate"
+ + "?oauth_token=" + token;
}
- catch(Error e)
+
+ public string getIconName()
{
- Logger.error("Could not load response to Message from twitter");
- Logger.error(e.message);
+ return "feed-share-twitter";
}
-
- var root_object = parser.get_root().get_object();
-
- if(root_object.has_member("screen_name"))
+
+ public string getUsername(string id)
{
- string screenName = "@" + root_object.get_string_member("screen_name");
- settings.set_string("username", screenName);
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+ return settings.get_string("username");
}
- else
+
+ public bool needSetup()
{
- settings.set_string("username", root_object.get_string_member("name"));
+ return true;
}
-
-
-
- var array = Settings.share("twitter").get_strv("account-ids");
- array += id;
- Settings.share("twitter").set_strv("account-ids", array);
-
- return true;
-}
-
-
-public bool addBookmark(string id, string url, bool system)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
- string token = settings.get_string("oauth-access-token");
- string secret = settings.get_string("oauth-access-token-secret");
-
- var oauthObject = new Rest.OAuthProxy.with_token (
- TwitterSecrets.key,
- TwitterSecrets.secret,
- token,
- secret,
- "https://api.twitter.com/",
- false);
-
- var call = oauthObject.new_call();
- call.set_function("1.1/statuses/update.json");
- call.set_method("POST");
- call.add_param ("status", m_tweet.replace("$URL", url));
-
- try
+
+ public bool singleInstance()
{
- call.run();
+ return false;
}
- catch(Error e)
+
+ public bool useSystemAccounts()
{
- Logger.error(e.message);
return false;
}
-
- return true;
-}
-
-public bool logout(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
- var keys = settings.list_keys();
- foreach(string key in keys)
+
+ public string pluginID()
{
- settings.reset(key);
+ return "twitter";
}
-
- var array = Settings.share("twitter").get_strv("account-ids");
- string[] array2 = {};
-
- foreach(string i in array)
+
+ public string pluginName()
{
- if(i != id)
- {
- array2 += i;
- }
+ return "Twitter";
}
- Settings.share("twitter").set_strv("account-ids", array2);
- deleteAccount(id);
-
- return true;
-}
-
-public string getURL(string token)
-{
- return TwitterSecrets.base_uri
- + "oauth/authenticate"
- + "?oauth_token=" + token;
-}
-
-public string getIconName()
-{
- return "feed-share-twitter";
-}
-
-public string getUsername(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
- return settings.get_string("username");
-}
-
-public bool needSetup()
-{
- return true;
-}
-
-public bool singleInstance()
-{
- return false;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "twitter";
-}
-
-public string pluginName()
-{
- return "Twitter";
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return new TwitterSetup(id, this, username);
-}
-
-public ServiceSetup? newSetup()
-{
- return new TwitterSetup(null, this);
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- var widget = new TwitterForm(url);
-
- widget.setAPI.begin(this, (obj, res) => {
+
+ public ServiceSetup? newSetup_withID(string id, string username)
+ {
+ return new TwitterSetup(id, this, username);
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return new TwitterSetup(null, this);
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ var widget = new TwitterForm(url);
+
+ widget.setAPI.begin(this, (obj, res) => {
widget.setAPI.end(res);
});
- widget.share.connect(() => {
+ widget.share.connect(() => {
m_tweet = widget.getTweet();
});
- return widget;
-}
-
-public int getUrlLength()
-{
- if(m_urlLength > 0)
- {
- return m_urlLength;
- }
-
- var array = Settings.share("twitter").get_strv("account-ids");
- string id = array[0];
-
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
- string token = settings.get_string("oauth-access-token");
- string secret = settings.get_string("oauth-access-token-secret");
-
- var oauthObject = new Rest.OAuthProxy.with_token (
- TwitterSecrets.key,
- TwitterSecrets.secret,
- token,
- secret,
- "https://api.twitter.com/",
- false);
-
- var call = oauthObject.new_call();
- call.set_function("1.1/help/configuration.json");
- call.set_method("GET");
-
- try
- {
- call.run();
+ return widget;
}
- catch(Error e) {}
-
- var parser = new Json.Parser();
- try
+
+ public int getUrlLength()
{
- parser.load_from_data(call.get_payload());
+ if(m_urlLength > 0)
+ {
+ return m_urlLength;
+ }
+
+ var array = Settings.share("twitter").get_strv("account-ids");
+ string id = array[0];
+
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+ string token = settings.get_string("oauth-access-token");
+ string secret = settings.get_string("oauth-access-token-secret");
+
+ var oauthObject = new Rest.OAuthProxy.with_token (
+ TwitterSecrets.key,
+ TwitterSecrets.secret,
+ token,
+ secret,
+ "https://api.twitter.com/",
+ false);
+
+ var call = oauthObject.new_call();
+ call.set_function("1.1/help/configuration.json");
+ call.set_method("GET");
+
+ try
+ {
+ call.run();
+ }
+ catch(Error e) {}
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(call.get_payload());
+ }
+ catch(Error e) {}
+
+ var root_object = parser.get_root().get_object();
+ m_urlLength = (int)root_object.get_int_member("short_url_length");
+ return m_urlLength;
}
- catch(Error e) {}
-
- var root_object = parser.get_root().get_object();
- m_urlLength = (int)root_object.get_int_member("short_url_length");
- return m_urlLength;
-}
}
[ModuleInit]
diff --git a/plugins/share/Twitter/TwitterForm.vala b/plugins/share/Twitter/TwitterForm.vala
index f44424dc..5d87ba25 100644
--- a/plugins/share/Twitter/TwitterForm.vala
+++ b/plugins/share/Twitter/TwitterForm.vala
@@ -15,127 +15,127 @@
public class FeedReader.TwitterForm : ShareForm {
-
-private Gtk.TextView m_textView;
-private int m_urlLength = 0;
-private string m_url;
-private Gtk.Stack m_stack;
-private Gtk.Label m_countLabel;
-
-public TwitterForm(string url)
-{
- m_url = url;
- m_stack = new Gtk.Stack();
- string body = _("Hey,\n\nCheck out this interesting article I just read: $URL");
-
- m_textView = new Gtk.TextView();
- m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
- m_textView.buffer.text = body;
- m_textView.border_width = 2;
- m_textView.get_style_context().add_class("h3");
-
- var scrolled = new Gtk.ScrolledWindow(null, null);
- scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
- scrolled.add(m_textView);
-
- int margin = 5;
- m_textView.left_margin = margin;
- m_textView.right_margin = margin;
- m_textView.top_margin = margin;
- m_textView.bottom_margin = margin;
-
- var limitLabel = new Gtk.Label(_("Limit: "));
- limitLabel.set_alignment(0.0f, 0.5f);
- limitLabel.get_style_context().add_class("h3");
-
- m_countLabel = new Gtk.Label("");
- m_countLabel.set_alignment(0.0f, 0.5f);
- m_countLabel.get_style_context().add_class("h3");
- var spinner = new Gtk.Spinner();
-
- m_stack.add_named(m_countLabel, "label");
- m_stack.add_named(spinner, "spinner");
-
- m_textView.buffer.changed.connect(() => {
+
+ private Gtk.TextView m_textView;
+ private int m_urlLength = 0;
+ private string m_url;
+ private Gtk.Stack m_stack;
+ private Gtk.Label m_countLabel;
+
+ public TwitterForm(string url)
+ {
+ m_url = url;
+ m_stack = new Gtk.Stack();
+ string body = _("Hey,\n\nCheck out this interesting article I just read: $URL");
+
+ m_textView = new Gtk.TextView();
+ m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+ m_textView.buffer.text = body;
+ m_textView.border_width = 2;
+ m_textView.get_style_context().add_class("h3");
+
+ var scrolled = new Gtk.ScrolledWindow(null, null);
+ scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+ scrolled.add(m_textView);
+
+ int margin = 5;
+ m_textView.left_margin = margin;
+ m_textView.right_margin = margin;
+ m_textView.top_margin = margin;
+ m_textView.bottom_margin = margin;
+
+ var limitLabel = new Gtk.Label(_("Limit: "));
+ limitLabel.set_alignment(0.0f, 0.5f);
+ limitLabel.get_style_context().add_class("h3");
+
+ m_countLabel = new Gtk.Label("");
+ m_countLabel.set_alignment(0.0f, 0.5f);
+ m_countLabel.get_style_context().add_class("h3");
+ var spinner = new Gtk.Spinner();
+
+ m_stack.add_named(m_countLabel, "label");
+ m_stack.add_named(spinner, "spinner");
+
+ m_textView.buffer.changed.connect(() => {
updateCount();
});
-
- var button = new Gtk.Button.with_label(_("Tweet"));
- button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- button.clicked.connect(() => { share(); });
-
- var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box.pack_start(limitLabel, false, false, 0);
- box.pack_start(m_stack, false, false, 0);
- box.pack_end(button, false, false, 0);
-
- var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
- backButton.set_focus_on_click(false);
- backButton.set_relief(Gtk.ReliefStyle.NONE);
- backButton.halign = Gtk.Align.START;
- backButton.clicked.connect(() => {
+
+ var button = new Gtk.Button.with_label(_("Tweet"));
+ button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ button.clicked.connect(() => { share(); });
+
+ var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box.pack_start(limitLabel, false, false, 0);
+ box.pack_start(m_stack, false, false, 0);
+ box.pack_end(button, false, false, 0);
+
+ var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+ backButton.set_focus_on_click(false);
+ backButton.set_relief(Gtk.ReliefStyle.NONE);
+ backButton.halign = Gtk.Align.START;
+ backButton.clicked.connect(() => {
goBack();
});
-
- var headline = new Gtk.Label(_("Tweet to Followers"));
- headline.get_style_context().add_class("h2");
- headline.set_alignment(0.4f, 0.5f);
- var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
- box2.pack_start(backButton, false, false, 0);
- box2.pack_start(headline, true, true, 0);
-
- this.pack_start(box2, false, false, 0);
- this.pack_start(scrolled);
- this.pack_end(box, false, false);
- this.orientation = Gtk.Orientation.VERTICAL;
- this.spacing = 5;
- this.margin = 10;
- this.show_all();
-
- m_stack.set_visible_child_name("spinner");
- spinner.start();
-}
-
-public string getTweet()
-{
- return m_textView.buffer.text;
-}
-
-public async void setAPI(TwitterAPI api)
-{
- SourceFunc callback = setAPI.callback;
-
- new Thread<void*>(null, () => {
+
+ var headline = new Gtk.Label(_("Tweet to Followers"));
+ headline.get_style_context().add_class("h2");
+ headline.set_alignment(0.4f, 0.5f);
+ var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+ box2.pack_start(backButton, false, false, 0);
+ box2.pack_start(headline, true, true, 0);
+
+ this.pack_start(box2, false, false, 0);
+ this.pack_start(scrolled);
+ this.pack_end(box, false, false);
+ this.orientation = Gtk.Orientation.VERTICAL;
+ this.spacing = 5;
+ this.margin = 10;
+ this.show_all();
+
+ m_stack.set_visible_child_name("spinner");
+ spinner.start();
+ }
+
+ public string getTweet()
+ {
+ return m_textView.buffer.text;
+ }
+
+ public async void setAPI(TwitterAPI api)
+ {
+ SourceFunc callback = setAPI.callback;
+
+ new Thread<void*>(null, () => {
m_urlLength = api.getUrlLength();
Idle.add((owned) callback, GLib.Priority.HIGH_IDLE);
return null;
});
-
- yield;
- updateCount();
- m_stack.set_visible_child_name("label");
-}
-
-private int calcLenght(string text)
-{
- if(text.contains("$URL"))
+
+ yield;
+ updateCount();
+ m_stack.set_visible_child_name("label");
+ }
+
+ private int calcLenght(string text)
{
- if(m_url.length >= m_urlLength)
+ if(text.contains("$URL"))
{
- return (text.length-3) + m_urlLength;
- }
- else
- {
- return (text.length-3) + m_url.length;
+ if(m_url.length >= m_urlLength)
+ {
+ return (text.length-3) + m_urlLength;
+ }
+ else
+ {
+ return (text.length-3) + m_url.length;
+ }
}
+
+ return text.length;
}
-
- return text.length;
-}
-
-private void updateCount()
-{
- m_countLabel.set_text(calcLenght(m_textView.buffer.text).to_string() + "/140");
-}
-
+
+ private void updateCount()
+ {
+ m_countLabel.set_text(calcLenght(m_textView.buffer.text).to_string() + "/140");
+ }
+
}
diff --git a/plugins/share/Twitter/TwitterSetup.vala b/plugins/share/Twitter/TwitterSetup.vala
index a1686802..d6549473 100644
--- a/plugins/share/Twitter/TwitterSetup.vala
+++ b/plugins/share/Twitter/TwitterSetup.vala
@@ -14,88 +14,88 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.TwitterSetup : ServiceSetup {
-
-private TwitterAPI m_api;
-
-public TwitterSetup(string? id, TwitterAPI api, string username = "")
-{
- bool loggedIN = false;
- if(username != "")
+
+ private TwitterAPI m_api;
+
+ public TwitterSetup(string? id, TwitterAPI api, string username = "")
{
- loggedIN = true;
+ bool loggedIN = false;
+ if(username != "")
+ {
+ loggedIN = true;
+ }
+
+ base("Twitter", "feed-share-twitter", loggedIN, username);
+
+ m_api = api;
+
+ if(id != null)
+ {
+ m_id = id;
+ }
}
-
- base("Twitter", "feed-share-twitter", loggedIN, username);
-
- m_api = api;
-
- if(id != null)
+
+
+ public override void login()
{
- m_id = id;
- }
-}
-
-
-public override void login()
-{
- string id = Share.get_default().generateNewID();
- string requestToken = m_api.getRequestToken();
- string url = m_api.getURL(requestToken);
- m_spinner.start();
- m_iconStack.set_visible_child_name("spinner");
- try
- {
- Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
- }
- catch(GLib.Error e)
- {
-
- }
-
- m_login_button.set_label(_("waiting"));
- m_login_button.set_sensitive(false);
- FeedReaderApp.get_default().callback.connect((content) => {
-
+ string id = Share.get_default().generateNewID();
+ string requestToken = m_api.getRequestToken();
+ string url = m_api.getURL(requestToken);
+ m_spinner.start();
+ m_iconStack.set_visible_child_name("spinner");
+ try
+ {
+ Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
+ }
+ catch(GLib.Error e)
+ {
+
+ }
+
+ m_login_button.set_label(_("waiting"));
+ m_login_button.set_sensitive(false);
+ FeedReaderApp.get_default().callback.connect((content) => {
+
if(content.has_prefix(TwitterSecrets.callback))
{
- int token_start = content.index_of("token=")+6;
- int token_end = content.index_of("&", token_start);
- string token = content.substring(token_start, token_end-token_start);
-
- int verifier_start = content.index_of("verifier=")+9;
- string verifier = content.substring(verifier_start);
-
- if(token == requestToken)
- {
- if(m_api.getAccessToken(id, verifier))
- {
- m_id = id;
- m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
- m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
- m_isLoggedIN = true;
- m_spinner.stop();
- m_label.set_label(m_api.getUsername(id));
- m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
- m_login_button.clicked.disconnect(login);
- m_login_button.clicked.connect(logout);
+ int token_start = content.index_of("token=")+6;
+ int token_end = content.index_of("&", token_start);
+ string token = content.substring(token_start, token_end-token_start);
+
+ int verifier_start = content.index_of("verifier=")+9;
+ string verifier = content.substring(verifier_start);
+
+ if(token == requestToken)
+ {
+ if(m_api.getAccessToken(id, verifier))
+ {
+ m_id = id;
+ m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
+ m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+ m_isLoggedIN = true;
+ m_spinner.stop();
+ m_label.set_label(m_api.getUsername(id));
+ m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+ m_login_button.clicked.disconnect(login);
+ m_login_button.clicked.connect(logout);
}
- else
- {
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ else
+ {
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
}
}
-
+
}
});
-}
-
-public override void logout()
-{
- m_isLoggedIN = false;
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- m_labelStack.set_visible_child_name("loggedOUT");
- m_api.logout(m_id);
- removeRow();
-}
-
+ }
+
+ public override void logout()
+ {
+ m_isLoggedIN = false;
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_labelStack.set_visible_child_name("loggedOUT");
+ m_api.logout(m_id);
+ removeRow();
+ }
+
}
diff --git a/plugins/share/Wallabag/WallabagAPI.vala b/plugins/share/Wallabag/WallabagAPI.vala
index edfc80b0..a1b9e5c7 100644
--- a/plugins/share/Wallabag/WallabagAPI.vala
+++ b/plugins/share/Wallabag/WallabagAPI.vala
@@ -14,318 +14,318 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.WallabagAPI : ShareAccountInterface, Peas.ExtensionBase {
-
-public WallabagAPI()
-{
-
-}
-
-public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-{
-
-}
-
-public bool getAccessToken(string id, string username, string password, string clientID, string clientSecret, string baseURL)
-{
- Logger.debug("WallabagAPI getAccessToken");
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "grant_type=password"
- + "&client_id=" + clientID
- + "&client_secret=" + clientSecret
- + "&username=" + GLib.Uri.escape_string(username)
- + "&password=" + GLib.Uri.escape_string(password);
-
-
- string url = baseURL + "oauth/v2/token";
- var message_soup = new Soup.Message("POST", url);
- message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
- session.send_message(message_soup);
-
- if((string)message_soup.response_body.flatten().data == null
- || (string)message_soup.response_body.flatten().data == "")
+
+ public WallabagAPI()
{
- Logger.error("WallabagAPI - getAccessToken: no response");
- Logger.error(url);
- Logger.error(message);
- return false;
+
}
-
- string response = (string)message_soup.response_body.flatten().data;
- Logger.debug(response);
-
- var parser = new Json.Parser();
- try
+
+ public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
{
- parser.load_from_data(response);
+
}
- catch (Error e)
+
+ public bool getAccessToken(string id, string username, string password, string clientID, string clientSecret, string baseURL)
{
- Logger.error("Could not load response to Message from Wallabag");
- Logger.error(e.message);
- return false;
+ Logger.debug("WallabagAPI getAccessToken");
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "grant_type=password"
+ + "&client_id=" + clientID
+ + "&client_secret=" + clientSecret
+ + "&username=" + GLib.Uri.escape_string(username)
+ + "&password=" + GLib.Uri.escape_string(password);
+
+
+ string url = baseURL + "oauth/v2/token";
+ var message_soup = new Soup.Message("POST", url);
+ message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+ session.send_message(message_soup);
+
+ if((string)message_soup.response_body.flatten().data == null
+ || (string)message_soup.response_body.flatten().data == "")
+ {
+ Logger.error("WallabagAPI - getAccessToken: no response");
+ Logger.error(url);
+ Logger.error(message);
+ return false;
+ }
+
+ string response = (string)message_soup.response_body.flatten().data;
+ Logger.debug(response);
+
+ var parser = new Json.Parser();
+ try
+ {
+ parser.load_from_data(response);
+ }
+ catch (Error e)
+ {
+ Logger.error("Could not load response to Message from Wallabag");
+ Logger.error(e.message);
+ return false;
+ }
+
+ var root_node = parser.get_root();
+ var root_object = root_node.get_object();
+
+ if(!root_object.has_member("access_token"))
+ {
+ Logger.error("WallabagAPI.getAccessToken: no member access_token in response");
+ return false;
+ }
+ string accessToken = root_object.get_string_member("access_token");
+
+
+ int64 now = (new DateTime.now_local()).to_unix();
+ if(!root_object.has_member("expires_in"))
+ {
+ Logger.error("WallabagAPI.getAccessToken: no member expires_in in response");
+ return false;
+ }
+ int64 expires = root_object.get_int_member("expires_in");
+ //string refreshToken = root_object.get_string_member("refresh_token");
+
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+ settings.set_string("oauth-access-token", accessToken);
+ settings.set_string("username", username);
+ settings.set_int("access-token-expires", (int)(now + expires));
+ settings.set_string("url", baseURL);
+ settings.set_string("client-id", clientID);
+ settings.set_string("client-secret", clientSecret);
+
+
+ var array = Settings.share("wallabag").get_strv("account-ids");
+ foreach(string i in array)
+ {
+ if(i == id)
+ {
+ Logger.warning("WallabagAPI - getAccessToken: id already part of array. Returning");
+ return true;
+ }
+ }
+ array += id;
+ Settings.share("wallabag").set_strv("account-ids", array);
+
+
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+ "username", Secret.SchemaAttributeType.STRING,
+ "id", Secret.SchemaAttributeType.STRING);
+
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["username"] = username;
+ attributes["id"] = id;
+ try
+ {
+ Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Wallabag login", password, null);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("WallabagAPI - getAccessToken: " + e.message);
+ }
+
+ return true;
}
-
- var root_node = parser.get_root();
- var root_object = root_node.get_object();
-
- if(!root_object.has_member("access_token"))
+
+
+ public bool addBookmark(string id, string url, bool system)
{
- Logger.error("WallabagAPI.getAccessToken: no member access_token in response");
- return false;
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+
+ Logger.debug("WallabagAPI - addBookmark: " + url);
+ if(!accessTokenValid(id))
+ {
+ string username = getUsername(id);
+ string password = getPasswd(id);
+ string clientID = settings.get_string("client-id");
+ string clientSecret = settings.get_string("client-secret");
+ string baseURL = settings.get_string("url");
+
+ getAccessToken(id, username, password, clientID, clientSecret, baseURL);
+ }
+
+ Logger.debug("WallabagAPI - addBookmark: token still valid");
+
+ var session = new Soup.Session();
+ session.user_agent = Constants.USER_AGENT;
+ string message = "url=" + GLib.Uri.escape_string(url);
+ string baseURL = settings.get_string("url");
+
+ var message_soup = new Soup.Message("POST", baseURL + "api/entries.json");
+ message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+ message_soup.request_headers.append("Authorization", "Bearer " + settings.get_string("oauth-access-token"));
+ session.send_message(message_soup);
+
+ if((string)message_soup.response_body.flatten().data == null
+ || (string)message_soup.response_body.flatten().data == "")
+ {
+ Logger.error("WallabagAPI - addBookmark: no response");
+ Logger.error(url);
+ Logger.error(message);
+ return false;
+ }
+
+ return true;
}
- string accessToken = root_object.get_string_member("access_token");
-
-
- int64 now = (new DateTime.now_local()).to_unix();
- if(!root_object.has_member("expires_in"))
+
+ public bool logout(string id)
{
- Logger.error("WallabagAPI.getAccessToken: no member expires_in in response");
- return false;
+ Logger.debug("WallabagAPI - logout");
+ deletePassword(id);
+
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+ var keys = settings.list_keys();
+ foreach(string key in keys)
+ {
+ settings.reset(key);
+ }
+
+ var array = Settings.share("wallabag").get_strv("account-ids");
+ string[] array2 = {};
+
+ foreach(string i in array)
+ {
+ if(i != id)
+ {
+ array2 += i;
+ }
+ }
+ Settings.share("wallabag").set_strv("account-ids", array2);
+ deleteAccount(id);
+
+ return true;
}
- int64 expires = root_object.get_int_member("expires_in");
- //string refreshToken = root_object.get_string_member("refresh_token");
-
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
- settings.set_string("oauth-access-token", accessToken);
- settings.set_string("username", username);
- settings.set_int("access-token-expires", (int)(now + expires));
- settings.set_string("url", baseURL);
- settings.set_string("client-id", clientID);
- settings.set_string("client-secret", clientSecret);
-
-
- var array = Settings.share("wallabag").get_strv("account-ids");
- foreach(string i in array)
+
+ private bool accessTokenValid(string id)
{
- if(i == id)
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+ var now = new DateTime.now_local();
+ int expires = settings.get_int("access-token-expires");
+
+ if((int)now.to_unix() > expires)
{
- Logger.warning("WallabagAPI - getAccessToken: id already part of array. Returning");
- return true;
+ Logger.warning("WallabagAPI: access token expired");
+ return false;
}
+
+ return true;
}
- array += id;
- Settings.share("wallabag").set_strv("account-ids", array);
-
-
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
- "username", Secret.SchemaAttributeType.STRING,
- "id", Secret.SchemaAttributeType.STRING);
-
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["username"] = username;
- attributes["id"] = id;
- try
+
+ public string getIconName()
{
- Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Wallabag login", password, null);
+ return "feed-share-wallabag";
}
- catch(GLib.Error e)
+
+ public string getUsername(string id)
{
- Logger.error("WallabagAPI - getAccessToken: " + e.message);
+ var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+ return settings.get_string("username");
}
-
- return true;
-}
-
-
-public bool addBookmark(string id, string url, bool system)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-
- Logger.debug("WallabagAPI - addBookmark: " + url);
- if(!accessTokenValid(id))
+
+ public string getPasswd(string id)
{
- string username = getUsername(id);
- string password = getPasswd(id);
- string clientID = settings.get_string("client-id");
- string clientSecret = settings.get_string("client-secret");
- string baseURL = settings.get_string("url");
-
- getAccessToken(id, username, password, clientID, clientSecret, baseURL);
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+ "username", Secret.SchemaAttributeType.STRING,
+ "id", Secret.SchemaAttributeType.STRING);
+
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["username"] = getUsername(id);
+ attributes["id"] = id;
+
+ string passwd = "";
+
+ try
+ {
+ passwd = Secret.password_lookupv_sync(pwSchema, attributes, null);
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error(e.message);
+ }
+
+ if(passwd == null)
+ {
+ return "";
+ }
+
+ return passwd;
}
-
- Logger.debug("WallabagAPI - addBookmark: token still valid");
-
- var session = new Soup.Session();
- session.user_agent = Constants.USER_AGENT;
- string message = "url=" + GLib.Uri.escape_string(url);
- string baseURL = settings.get_string("url");
-
- var message_soup = new Soup.Message("POST", baseURL + "api/entries.json");
- message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
- message_soup.request_headers.append("Authorization", "Bearer " + settings.get_string("oauth-access-token"));
- session.send_message(message_soup);
-
- if((string)message_soup.response_body.flatten().data == null
- || (string)message_soup.response_body.flatten().data == "")
+
+ private void deletePassword(string id)
{
- Logger.error("WallabagAPI - addBookmark: no response");
- Logger.error(url);
- Logger.error(message);
- return false;
+ bool removed = false;
+ var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+ "username", Secret.SchemaAttributeType.STRING,
+ "id", Secret.SchemaAttributeType.STRING);
+
+ var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+ attributes["username"] = getUsername(id);
+ attributes["id"] = id;
+
+ Logger.debug(getUsername(id));
+ Logger.debug(id);
+
+ Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
+ try
+ {
+ removed = Secret.password_clearv.end(async_res);
+
+ if(!removed)
+ {
+ Logger.error(@"WallabagAPI: could not delete password of account $id");
+ }
+ }
+ catch(GLib.Error e)
+ {
+ Logger.error("WallabagAPI.deletePassword: %s".printf(e.message));
+ }
+ });
}
-
- return true;
-}
-
-public bool logout(string id)
-{
- Logger.debug("WallabagAPI - logout");
- deletePassword(id);
-
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
- var keys = settings.list_keys();
- foreach(string key in keys)
+
+ public bool needSetup()
{
- settings.reset(key);
+ return true;
}
-
- var array = Settings.share("wallabag").get_strv("account-ids");
- string[] array2 = {};
-
- foreach(string i in array)
+
+ public bool singleInstance()
{
- if(i != id)
- {
- array2 += i;
- }
+ return false;
}
- Settings.share("wallabag").set_strv("account-ids", array2);
- deleteAccount(id);
-
- return true;
-}
-
-private bool accessTokenValid(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
- var now = new DateTime.now_local();
- int expires = settings.get_int("access-token-expires");
-
- if((int)now.to_unix() > expires)
+
+ public bool useSystemAccounts()
{
- Logger.warning("WallabagAPI: access token expired");
return false;
}
-
- return true;
-}
-
-public string getIconName()
-{
- return "feed-share-wallabag";
-}
-
-public string getUsername(string id)
-{
- var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
- return settings.get_string("username");
-}
-
-public string getPasswd(string id)
-{
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
- "username", Secret.SchemaAttributeType.STRING,
- "id", Secret.SchemaAttributeType.STRING);
-
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["username"] = getUsername(id);
- attributes["id"] = id;
-
- string passwd = "";
-
- try
+
+ public string pluginID()
{
- passwd = Secret.password_lookupv_sync(pwSchema, attributes, null);
+ return "wallabag";
}
- catch(GLib.Error e)
+
+ public string pluginName()
{
- Logger.error(e.message);
+ return "wallabag";
}
-
- if(passwd == null)
+
+ public ServiceSetup? newSetup_withID(string id, string username)
{
- return "";
+ return new WallabagSetup(id, this, username);
+ }
+
+ public ServiceSetup? newSetup()
+ {
+ return new WallabagSetup(null, this);
+ }
+
+ public ServiceSetup? newSystemAccount(string id, string username)
+ {
+ return null;
+ }
+
+ public ShareForm? shareWidget(string url)
+ {
+ return null;
}
-
- return passwd;
-}
-
-private void deletePassword(string id)
-{
- bool removed = false;
- var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
- "username", Secret.SchemaAttributeType.STRING,
- "id", Secret.SchemaAttributeType.STRING);
-
- var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
- attributes["username"] = getUsername(id);
- attributes["id"] = id;
-
- Logger.debug(getUsername(id));
- Logger.debug(id);
-
- Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
- try
- {
- removed = Secret.password_clearv.end(async_res);
-
- if(!removed)
- {
- Logger.error(@"WallabagAPI: could not delete password of account $id");
- }
- }
- catch(GLib.Error e)
- {
- Logger.error("WallabagAPI.deletePassword: %s".printf(e.message));
- }
- });
-}
-
-public bool needSetup()
-{
- return true;
-}
-
-public bool singleInstance()
-{
- return false;
-}
-
-public bool useSystemAccounts()
-{
- return false;
-}
-
-public string pluginID()
-{
- return "wallabag";
-}
-
-public string pluginName()
-{
- return "wallabag";
-}
-
-public ServiceSetup? newSetup_withID(string id, string username)
-{
- return new WallabagSetup(id, this, username);
-}
-
-public ServiceSetup? newSetup()
-{
- return new WallabagSetup(null, this);
-}
-
-public ServiceSetup? newSystemAccount(string id, string username)
-{
- return null;
-}
-
-public ShareForm? shareWidget(string url)
-{
- return null;
-}
}
[ModuleInit]
diff --git a/plugins/share/Wallabag/WallabagSetup.vala b/plugins/share/Wallabag/WallabagSetup.vala
index caaccddd..2a2d8746 100644
--- a/plugins/share/Wallabag/WallabagSetup.vala
+++ b/plugins/share/Wallabag/WallabagSetup.vala
@@ -14,201 +14,201 @@
// along with FeedReader. If not, see <http://www.gnu.org/licenses/>.
public class FeedReader.WallabagSetup : ServiceSetup {
-
-private Gtk.Entry m_urlEntry;
-private Gtk.Entry m_idEntry;
-private Gtk.Entry m_secretEntry;
-private Gtk.Entry m_userEntry;
-private Gtk.Entry m_passEntry;
-private Gtk.Revealer m_login_revealer;
-private WallabagAPI m_api;
-
-public WallabagSetup(string? id, WallabagAPI api, string username = "")
-{
- bool loggedIN = false;
- if(username != "")
+
+ private Gtk.Entry m_urlEntry;
+ private Gtk.Entry m_idEntry;
+ private Gtk.Entry m_secretEntry;
+ private Gtk.Entry m_userEntry;
+ private Gtk.Entry m_passEntry;
+ private Gtk.Revealer m_login_revealer;
+ private WallabagAPI m_api;
+
+ public WallabagSetup(string? id, WallabagAPI api, string username = "")
{
- loggedIN = true;
- }
-
- base("wallabag", "feed-share-wallabag", loggedIN, username);
-
- //------------------------------------------------
- // XAuth revealer
- //------------------------------------------------
- var grid = new Gtk.Grid();
- grid.set_column_spacing(10);
- grid.set_row_spacing(10);
- grid.set_valign(Gtk.Align.CENTER);
- grid.set_halign(Gtk.Align.CENTER);
- grid.margin_bottom = 10;
- grid.margin_top = 5;
-
- m_urlEntry = new Gtk.Entry();
- m_idEntry = new Gtk.Entry();
- m_secretEntry = new Gtk.Entry();
- m_userEntry = new Gtk.Entry();
- m_passEntry = new Gtk.Entry();
- m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
- m_passEntry.set_visibility(false);
-
- m_urlEntry.activate.connect(() => {
+ bool loggedIN = false;
+ if(username != "")
+ {
+ loggedIN = true;
+ }
+
+ base("wallabag", "feed-share-wallabag", loggedIN, username);
+
+ //------------------------------------------------
+ // XAuth revealer
+ //------------------------------------------------
+ var grid = new Gtk.Grid();
+ grid.set_column_spacing(10);
+ grid.set_row_spacing(10);
+ grid.set_valign(Gtk.Align.CENTER);
+ grid.set_halign(Gtk.Align.CENTER);
+ grid.margin_bottom = 10;
+ grid.margin_top = 5;
+
+ m_urlEntry = new Gtk.Entry();
+ m_idEntry = new Gtk.Entry();
+ m_secretEntry = new Gtk.Entry();
+ m_userEntry = new Gtk.Entry();
+ m_passEntry = new Gtk.Entry();
+ m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+ m_passEntry.set_visibility(false);
+
+ m_urlEntry.activate.connect(() => {
m_idEntry.grab_focus();
});
-
- m_idEntry.activate.connect(() => {
+
+ m_idEntry.activate.connect(() => {
m_secretEntry.grab_focus();
});
-
- m_secretEntry.activate.connect(() => {
+
+ m_secretEntry.activate.connect(() => {
m_userEntry.grab_focus();
});
-
- m_userEntry.activate.connect(() => {
+
+ m_userEntry.activate.connect(() => {
m_passEntry.grab_focus();
});
-
- m_passEntry.activate.connect(() => {
+
+ m_passEntry.activate.connect(() => {
login();
});
-
- var urlLabel = new Gtk.Label(_("URL:"));
- var idLabel = new Gtk.Label(_("Client ID:"));
- var secretLabel = new Gtk.Label(_("Client Secret:"));
- var userLabel = new Gtk.Label(_("Username:"));
- var pwLabel = new Gtk.Label(_("Password:"));
-
- urlLabel.set_alignment(1.0f, 0.5f);
- idLabel.set_alignment(1.0f, 0.5f);
- secretLabel.set_alignment(1.0f, 0.5f);
- userLabel.set_alignment(1.0f, 0.5f);
- pwLabel.set_alignment(1.0f, 0.5f);
-
- grid.attach(urlLabel, 0, 0, 1, 1);
- grid.attach(idLabel, 0, 1, 1, 1);
- grid.attach(secretLabel, 0, 2, 1, 1);
- grid.attach(userLabel, 0, 3, 1, 1);
- grid.attach(pwLabel, 0, 4, 1, 1);
- grid.attach(m_urlEntry, 1, 0, 1, 1);
- grid.attach(m_idEntry, 1, 1, 1, 1);
- grid.attach(m_secretEntry, 1, 2, 1, 1);
- grid.attach(m_userEntry, 1, 3, 1, 1);
- grid.attach(m_passEntry, 1, 4, 1, 1);
-
- m_login_revealer = new Gtk.Revealer();
- m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
- m_login_revealer.add(grid);
- //------------------------------------------------
-
- m_seperator_box.pack_start(m_login_revealer, false, false, 0);
-
- m_api = api;
-
- if(id != null)
- {
- m_id = id;
- }
-}
-
-
-public override void login()
-{
- if(m_login_revealer.get_child_revealed())
- {
- string id = Share.get_default().generateNewID();
- string username = m_userEntry.get_text();
- string password = m_passEntry.get_text();
- string clientID = m_idEntry.get_text();
- string clientSecret = m_secretEntry.get_text();
- string baseURL = m_urlEntry.get_text();
-
- // check each and every value
- if(baseURL == null || baseURL == "")
- {
- showInfoBar(_("Please fill in the URL."));
- m_urlEntry.grab_focus();
- return;
- }
- else if(GLib.Uri.parse_scheme(baseURL) == null)
- {
- showInfoBar(_("URL seems to not be valid."));
- m_urlEntry.grab_focus();
- return;
- }
-
- if(!baseURL.has_suffix("/"))
- {
- baseURL += "/";
- }
-
- if(clientID == null || clientID == "")
- {
- showInfoBar(_("Please fill in the clientID."));
- m_idEntry.grab_focus();
- return;
- }
-
- if(clientSecret == null || clientSecret == "")
- {
- showInfoBar(_("Please fill in the clientSecret."));
- m_secretEntry.grab_focus();
- return;
- }
-
- if(password == null || password == "")
+
+ var urlLabel = new Gtk.Label(_("URL:"));
+ var idLabel = new Gtk.Label(_("Client ID:"));
+ var secretLabel = new Gtk.Label(_("Client Secret:"));
+ var userLabel = new Gtk.Label(_("Username:"));
+ var pwLabel = new Gtk.Label(_("Password:"));
+
+ urlLabel.set_alignment(1.0f, 0.5f);
+ idLabel.set_alignment(1.0f, 0.5f);
+ secretLabel.set_alignment(1.0f, 0.5f);
+ userLabel.set_alignment(1.0f, 0.5f);
+ pwLabel.set_alignment(1.0f, 0.5f);
+
+ grid.attach(urlLabel, 0, 0, 1, 1);
+ grid.attach(idLabel, 0, 1, 1, 1);
+ grid.attach(secretLabel, 0, 2, 1, 1);
+ grid.attach(userLabel, 0, 3, 1, 1);
+ grid.attach(pwLabel, 0, 4, 1, 1);
+ grid.attach(m_urlEntry, 1, 0, 1, 1);
+ grid.attach(m_idEntry, 1, 1, 1, 1);
+ grid.attach(m_secretEntry, 1, 2, 1, 1);
+ grid.attach(m_userEntry, 1, 3, 1, 1);
+ grid.attach(m_passEntry, 1, 4, 1, 1);
+
+ m_login_revealer = new Gtk.Revealer();
+ m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
+ m_login_revealer.add(grid);
+ //------------------------------------------------
+
+ m_seperator_box.pack_start(m_login_revealer, false, false, 0);
+
+ m_api = api;
+
+ if(id != null)
{
- showInfoBar(_("Please fill in the password."));
- m_passEntry.grab_focus();
- return;
- }
-
- if(username == null || username == "")
- {
- showInfoBar(_("Please fill in the username."));
- m_userEntry.grab_focus();
- return;
+ m_id = id;
}
-
- m_spinner.start();
- m_iconStack.set_visible_child_name("spinner");
-
- if(m_api.getAccessToken(id, username, password, clientID, clientSecret, baseURL))
+ }
+
+
+ public override void login()
+ {
+ if(m_login_revealer.get_child_revealed())
{
- m_id = id;
- m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
- m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- m_login_revealer.set_reveal_child(false);
- m_isLoggedIN = true;
- m_iconStack.set_visible_child_name("loggedIN");
- m_spinner.stop();
- m_label.set_label(username);
- m_labelStack.set_visible_child_name("loggedIN");
- m_login_button.clicked.disconnect(login);
- m_login_button.clicked.connect(logout);
+ string id = Share.get_default().generateNewID();
+ string username = m_userEntry.get_text();
+ string password = m_passEntry.get_text();
+ string clientID = m_idEntry.get_text();
+ string clientSecret = m_secretEntry.get_text();
+ string baseURL = m_urlEntry.get_text();
+
+ // check each and every value
+ if(baseURL == null || baseURL == "")
+ {
+ showInfoBar(_("Please fill in the URL."));
+ m_urlEntry.grab_focus();
+ return;
+ }
+ else if(GLib.Uri.parse_scheme(baseURL) == null)
+ {
+ showInfoBar(_("URL seems to not be valid."));
+ m_urlEntry.grab_focus();
+ return;
+ }
+
+ if(!baseURL.has_suffix("/"))
+ {
+ baseURL += "/";
+ }
+
+ if(clientID == null || clientID == "")
+ {
+ showInfoBar(_("Please fill in the clientID."));
+ m_idEntry.grab_focus();
+ return;
+ }
+
+ if(clientSecret == null || clientSecret == "")
+ {
+ showInfoBar(_("Please fill in the clientSecret."));
+ m_secretEntry.grab_focus();
+ return;
+ }
+
+ if(password == null || password == "")
+ {
+ showInfoBar(_("Please fill in the password."));
+ m_passEntry.grab_focus();
+ return;
+ }
+
+ if(username == null || username == "")
+ {
+ showInfoBar(_("Please fill in the username."));
+ m_userEntry.grab_focus();
+ return;
+ }
+
+ m_spinner.start();
+ m_iconStack.set_visible_child_name("spinner");
+
+ if(m_api.getAccessToken(id, username, password, clientID, clientSecret, baseURL))
+ {
+ m_id = id;
+ m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
+ m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ m_login_revealer.set_reveal_child(false);
+ m_isLoggedIN = true;
+ m_iconStack.set_visible_child_name("loggedIN");
+ m_spinner.stop();
+ m_label.set_label(username);
+ m_labelStack.set_visible_child_name("loggedIN");
+ m_login_button.clicked.disconnect(login);
+ m_login_button.clicked.connect(logout);
+ }
+ else
+ {
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ showInfoBar(_("Something went wrong."));
+ }
+
}
else
{
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- showInfoBar(_("Something went wrong."));
+ m_login_revealer.set_reveal_child(true);
+ m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+ m_urlEntry.grab_focus();
}
-
}
- else
+
+ public override void logout()
{
- m_login_revealer.set_reveal_child(true);
- m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
- m_urlEntry.grab_focus();
+ Logger.debug("WallabagSetup: logout");
+ m_isLoggedIN = false;
+ m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+ m_labelStack.set_visible_child_name("loggedOUT");
+ m_api.logout(m_id);
+ removeRow();
}
-}
-
-public override void logout()
-{
- Logger.debug("WallabagSetup: logout");
- m_isLoggedIN = false;
- m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
- m_labelStack.set_visible_child_name("loggedOUT");
- m_api.logout(m_id);
- removeRow();
-}
-
+
}