static int run_ops(void) { int ret; op_type = FI_MIN; ret = run_op(); if (ret) return ret; op_type = FI_MAX; ret = run_op(); if (ret) return ret; op_type = FI_ATOMIC_READ; ret = run_op(); if (ret) return ret; op_type = FI_ATOMIC_WRITE; ret = run_op(); if (ret) return ret; op_type = FI_CSWAP; ret = run_op(); if (ret) return ret; return 0; }
std::vector<tagged_feedurl> ttrss_api::get_subscribed_urls() { std::vector<tagged_feedurl> feeds; struct json_object * content = run_op("getCategories", std::map<std::string, std::string>()); if (!content) return feeds; if (json_object_get_type(content) != json_type_array) return feeds; struct array_list * categories = json_object_get_array(content); int catsize = array_list_length(categories); // first fetch feeds within no category fetch_feeds_per_category(NULL, feeds); // then fetch the feeds of all categories for (int i=0;i<catsize;i++) { struct json_object * cat = (struct json_object *)array_list_get_idx(categories, i); fetch_feeds_per_category(cat, feeds); } json_object_put(content); return feeds; }
void ttrss_api::fetch_feeds_per_category(struct json_object * cat, std::vector<tagged_feedurl>& feeds) { const char * cat_name = NULL; struct json_object * cat_title_obj = NULL; int cat_id; if (cat) { struct json_object * cat_id_obj = json_object_object_get(cat, "id"); cat_id = json_object_get_int(cat_id_obj); // ignore special categories, for now if(cat_id < 0) return; cat_title_obj = json_object_object_get(cat, "title"); cat_name = json_object_get_string(cat_title_obj); LOG(LOG_DEBUG, "ttrss_api::fetch_feeds_per_category: id = %d title = %s", cat_id, cat_name); } else { // As uncategorized is a category itself (id = 0) and the default value // for a getFeeds is id = 0, the feeds in uncategorized will appear twice return; } std::map<std::string, std::string> args; if (cat) args["cat_id"] = utils::to_string<int>(cat_id); struct json_object * feed_list_obj = run_op("getFeeds", args); if (!feed_list_obj) return; struct array_list * feed_list = json_object_get_array(feed_list_obj); int feed_list_size = array_list_length(feed_list); for (int j=0;j<feed_list_size;j++) { struct json_object * feed = (struct json_object *)array_list_get_idx(feed_list, j); int feed_id = json_object_get_int(json_object_object_get(feed, "id")); const char * feed_title = json_object_get_string(json_object_object_get(feed, "title")); const char * feed_url = json_object_get_string(json_object_object_get(feed, "feed_url")); std::vector<std::string> tags; tags.push_back(std::string("~") + feed_title); if (cat_name) { tags.push_back(cat_name); } feeds.push_back(tagged_feedurl(utils::strprintf("%s#%d", feed_url, feed_id), tags)); // TODO: cache feed_id -> feed_url (or feed_url -> feed_id ?) } json_object_put(feed_list_obj); }
struct json_object * ttrss_api::run_op(const std::string& op, const std::map<std::string, std::string >& args, bool try_login) { std::string url = utils::strprintf("%s/api/", cfg->get_configvalue("ttrss-url").c_str()); std::string req_data = "{\"op\":\"" + op + "\",\"sid\":\"" + sid + "\""; for (std::map<std::string, std::string>::const_iterator it = args.begin(); it != args.end(); it++) { req_data += ",\"" + it->first + "\":\"" + it->second + "\""; } req_data += "}"; std::string result = utils::retrieve_url(url, cfg, auth_info_ptr, &req_data); LOG(LOG_DEBUG, "ttrss_api::run_op(%s,...): post=%s reply = %s", op.c_str(), req_data.c_str(), result.c_str()); struct json_object * reply = json_tokener_parse(result.c_str()); if (is_error(reply)) { LOG(LOG_ERROR, "ttrss_api::run_op: reply failed to parse: %s", result.c_str()); return NULL; } struct json_object * status = json_object_object_get(reply, "status"); if (is_error(status)) { LOG(LOG_ERROR, "ttrss_api::run_op: no status code"); return NULL; } struct json_object * content = json_object_object_get(reply, "content"); if (is_error(content)) { LOG(LOG_ERROR, "ttrss_api::run_op: no content part in answer from server"); return NULL; } if (json_object_get_int(status) != 0) { struct json_object * error = json_object_object_get(content, "error"); if ((strcmp(json_object_get_string(error), "NOT_LOGGED_IN") == 0) && try_login) { json_object_put(reply); if (authenticate()) return run_op(op, args, false); else return NULL; } else { json_object_put(reply); return NULL; } } // free the parent object, without freeing content as well: json_object_get(content); json_object_put(reply); return content; }
bool ttrss_api::mark_all_read(const std::string& feed_url) { std::map<std::string, std::string> args; args["feed_id"] = url_to_id(feed_url); struct json_object * content = run_op("catchupFeed", args); if(!content) return false; json_object_put(content); return true; }
bool ttrss_api::update_article(const std::string& guid, int field, int mode) { std::map<std::string, std::string> args; args["article_ids"] = guid; args["field"] = utils::to_string<unsigned int>(field); args["mode"] = utils::to_string<unsigned int>(mode); struct json_object * content = run_op("updateArticle", args); if (!content) return false; json_object_put(content); return true; }
std::string ttrss_api::retrieve_sid() { std::map<std::string, std::string> args; args["user"] = single ? "admin" : cfg->get_configvalue("ttrss-login"); args["password"] = cfg->get_configvalue("ttrss-password"); struct json_object * content = run_op("login", args); if (content == NULL) return ""; std::string sid; struct json_object * session_id = json_object_object_get(content, "session_id"); sid = json_object_get_string(session_id); json_object_put(content); LOG(LOG_DEBUG, "ttrss_api::retrieve_sid: sid = '%s'", sid.c_str()); return sid; }
static int run_test(void) { return run_all_ops ? run_ops() : run_op(); }
rsspp::feed ttrss_api::fetch_feed(const std::string& id) { rsspp::feed f; f.rss_version = rsspp::TTRSS_JSON; std::map<std::string, std::string> args; args["feed_id"] = id; args["show_content"] = "1"; struct json_object * content = run_op("getHeadlines", args); if (!content) return f; if (json_object_get_type(content) != json_type_array) { LOG(LOG_ERROR, "ttrss_api::fetch_feed: content is not an array"); return f; } struct array_list * items = json_object_get_array(content); int items_size = array_list_length(items); LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %d items", items_size); for (int i=0;i<items_size;i++) { struct json_object * item_obj = (struct json_object *)array_list_get_idx(items, i); int id = json_object_get_int(json_object_object_get(item_obj, "id")); const char * title = json_object_get_string(json_object_object_get(item_obj, "title")); const char * link = json_object_get_string(json_object_object_get(item_obj, "link")); const char * content = json_object_get_string(json_object_object_get(item_obj, "content")); time_t updated = (time_t)json_object_get_int(json_object_object_get(item_obj, "updated")); bool unread = json_object_get_boolean(json_object_object_get(item_obj, "unread")); rsspp::item item; if (title) item.title = title; if (link) item.link = link; if (content) item.content_encoded = content; item.guid = utils::strprintf("%d", id); if (unread) { item.labels.push_back("ttrss:unread"); } else { item.labels.push_back("ttrss:read"); } char rfc822_date[128]; strftime(rfc822_date, sizeof(rfc822_date), "%a, %d %b %Y %H:%M:%S %z", gmtime(&updated)); item.pubDate = rfc822_date; item.pubDate_ts = updated; f.items.push_back(item); } std::sort(f.items.begin(), f.items.end(), sort_by_pubdate); json_object_put(content); return f; }