newsblur can load list of feeds and categories
This commit is contained in:
parent
4ab483d14a
commit
2975f3d825
@ -12,5 +12,6 @@
|
|||||||
#define NEWSBLUR_API_LOGIN "api/login"
|
#define NEWSBLUR_API_LOGIN "api/login"
|
||||||
#define NEWSBLUR_API_LOGOUT "api/logout"
|
#define NEWSBLUR_API_LOGOUT "api/logout"
|
||||||
#define NEWSBLUR_API_SIGNUP "api/signup"
|
#define NEWSBLUR_API_SIGNUP "api/signup"
|
||||||
|
#define NEWSBLUR_API_FEEDS "reader/feeds"
|
||||||
|
|
||||||
#endif // NEWSBLUR_DEFINITIONS_H
|
#endif // NEWSBLUR_DEFINITIONS_H
|
||||||
|
@ -26,6 +26,90 @@ NewsBlurNetwork::NewsBlurNetwork(QObject* parent)
|
|||||||
clearCredentials();
|
clearCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RootItem* NewsBlurNetwork::categoriesFeedsLabelsTree(const QNetworkProxy& proxy) {
|
||||||
|
QJsonDocument json = feeds(proxy);
|
||||||
|
RootItem* root = new RootItem();
|
||||||
|
const auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
|
QMap<QString, RootItem*> cats;
|
||||||
|
QList<QPair<RootItem*, QJsonArray>> cats_array = {
|
||||||
|
{ root, json.object()["folders"].toArray() }
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!cats_array.isEmpty()) {
|
||||||
|
// Add direct descendants as categories to parent, then process their children.
|
||||||
|
QPair<RootItem*, QJsonArray> cats_for_parent = cats_array.takeFirst();
|
||||||
|
|
||||||
|
for (const QJsonValue& var : cats_for_parent.second) {
|
||||||
|
if (var.type() == QJsonValue::Type::Double) {
|
||||||
|
// We have feed.
|
||||||
|
Feed* feed = new Feed();
|
||||||
|
|
||||||
|
feed->setCustomId(QString::number(var.toInt()));
|
||||||
|
|
||||||
|
QJsonObject feed_json = json.object()["feeds"].toObject()[feed->customId()].toObject();
|
||||||
|
|
||||||
|
feed->setTitle(feed_json["feed_title"].toString());
|
||||||
|
feed->setSource(feed_json["feed_link"].toString());
|
||||||
|
|
||||||
|
QString favicon_url = feed_json["favicon_url"].toString();
|
||||||
|
|
||||||
|
if (!favicon_url.isEmpty()) {
|
||||||
|
QIcon icon;
|
||||||
|
|
||||||
|
if (NetworkFactory::downloadIcon({ { favicon_url, true } }, timeout, icon, {}, proxy) ==
|
||||||
|
QNetworkReply::NetworkError::NoError) {
|
||||||
|
feed->setIcon(icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cats_for_parent.first->appendChild(feed);
|
||||||
|
}
|
||||||
|
else if (var.type() == QJsonValue::Type::Object) {
|
||||||
|
const QString category_name = var.toObject().keys().first();
|
||||||
|
Category* category = new Category();
|
||||||
|
|
||||||
|
category->setTitle(category_name);
|
||||||
|
category->setCustomId(category_name);
|
||||||
|
|
||||||
|
cats_for_parent.first->appendChild(category);
|
||||||
|
cats_array.append({
|
||||||
|
category,
|
||||||
|
var.toObject()[category_name].toArray()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument NewsBlurNetwork::feeds(const QNetworkProxy& proxy) {
|
||||||
|
ensureLogin(proxy);
|
||||||
|
|
||||||
|
const QString full_url = generateFullUrl(Operations::Feeds);
|
||||||
|
const auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
|
QByteArray output;
|
||||||
|
auto network_result = NetworkFactory::performNetworkOperation(full_url,
|
||||||
|
timeout,
|
||||||
|
{},
|
||||||
|
output,
|
||||||
|
QNetworkAccessManager::Operation::GetOperation,
|
||||||
|
{},
|
||||||
|
false,
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
proxy);
|
||||||
|
|
||||||
|
if (network_result.m_networkError == QNetworkReply::NetworkError::NoError) {
|
||||||
|
ApiResult res; res.decodeBaseResponse(output);
|
||||||
|
|
||||||
|
return res.m_json;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw NetworkException(network_result.m_networkError, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LoginResult NewsBlurNetwork::login(const QNetworkProxy& proxy) {
|
LoginResult NewsBlurNetwork::login(const QNetworkProxy& proxy) {
|
||||||
const QString full_url = generateFullUrl(Operations::Login);
|
const QString full_url = generateFullUrl(Operations::Login);
|
||||||
const auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
const auto timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||||
@ -46,17 +130,9 @@ LoginResult NewsBlurNetwork::login(const QNetworkProxy& proxy) {
|
|||||||
proxy);
|
proxy);
|
||||||
|
|
||||||
if (network_result.m_networkError == QNetworkReply::NetworkError::NoError) {
|
if (network_result.m_networkError == QNetworkReply::NetworkError::NoError) {
|
||||||
QJsonParseError err;
|
LoginResult res; res.decodeBaseResponse(output);
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(output, &err);
|
|
||||||
|
|
||||||
if (err.error != QJsonParseError::ParseError::NoError) {
|
res.m_userId = res.m_json.object()["user_id"].toInt();
|
||||||
throw ApplicationException(err.errorString());
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginResult res;
|
|
||||||
|
|
||||||
res.decodeBaseResponse(doc);
|
|
||||||
res.m_userId = doc.object()["user_id"].toInt();
|
|
||||||
res.m_sessiodId = boolinq::from(network_result.m_cookies).firstOrDefault([](const QNetworkCookie& c) {
|
res.m_sessiodId = boolinq::from(network_result.m_cookies).firstOrDefault([](const QNetworkCookie& c) {
|
||||||
return c.name() == QSL(NEWSBLUS_AUTH_COOKIE);
|
return c.name() == QSL(NEWSBLUS_AUTH_COOKIE);
|
||||||
}).value();
|
}).value();
|
||||||
@ -146,6 +222,9 @@ QString NewsBlurNetwork::generateFullUrl(NewsBlurNetwork::Operations operation)
|
|||||||
case Operations::Login:
|
case Operations::Login:
|
||||||
return sanitizedBaseUrl() + QSL(NEWSBLUR_API_LOGIN);
|
return sanitizedBaseUrl() + QSL(NEWSBLUR_API_LOGIN);
|
||||||
|
|
||||||
|
case Operations::Feeds:
|
||||||
|
return sanitizedBaseUrl() + QSL(NEWSBLUR_API_FEEDS);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return sanitizedBaseUrl();
|
return sanitizedBaseUrl();
|
||||||
}
|
}
|
||||||
@ -163,7 +242,15 @@ void NewsBlurNetwork::setDownloadOnlyUnreadMessages(bool download_only_unread) {
|
|||||||
m_downloadOnlyUnreadMessages = download_only_unread;
|
m_downloadOnlyUnreadMessages = download_only_unread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiResult::decodeBaseResponse(const QJsonDocument& doc) {
|
void ApiResult::decodeBaseResponse(const QByteArray& json_data) {
|
||||||
|
QJsonParseError err;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(json_data, &err);
|
||||||
|
|
||||||
|
if (err.error != QJsonParseError::ParseError::NoError) {
|
||||||
|
throw ApplicationException(err.errorString());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_json = doc;
|
||||||
m_authenticated = doc.object()["authenticated"].toBool();
|
m_authenticated = doc.object()["authenticated"].toBool();
|
||||||
m_code = doc.object()["code"].toInt();
|
m_code = doc.object()["code"].toInt();
|
||||||
|
|
||||||
|
@ -13,8 +13,9 @@ struct ApiResult {
|
|||||||
bool m_authenticated;
|
bool m_authenticated;
|
||||||
int m_code;
|
int m_code;
|
||||||
QStringList m_errors;
|
QStringList m_errors;
|
||||||
|
QJsonDocument m_json;
|
||||||
|
|
||||||
void decodeBaseResponse(const QJsonDocument& doc);
|
void decodeBaseResponse(const QByteArray& json_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginResult : ApiResult {
|
struct LoginResult : ApiResult {
|
||||||
@ -27,11 +28,19 @@ class NewsBlurNetwork : public QObject {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Operations {
|
enum class Operations {
|
||||||
Login
|
Login,
|
||||||
|
Feeds
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit NewsBlurNetwork(QObject* parent = nullptr);
|
explicit NewsBlurNetwork(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
// Convenience methods.
|
||||||
|
RootItem* categoriesFeedsLabelsTree(const QNetworkProxy& proxy);
|
||||||
|
|
||||||
|
// API.
|
||||||
|
QJsonDocument feeds(const QNetworkProxy& proxy);
|
||||||
|
|
||||||
|
// Misc.
|
||||||
void clearCredentials();
|
void clearCredentials();
|
||||||
|
|
||||||
QString username() const;
|
QString username() const;
|
||||||
|
@ -139,7 +139,5 @@ void NewsBlurServiceRoot::updateTitleIcon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RootItem* NewsBlurServiceRoot::obtainNewTreeForSyncIn() const {
|
RootItem* NewsBlurServiceRoot::obtainNewTreeForSyncIn() const {
|
||||||
return nullptr;
|
return m_network->categoriesFeedsLabelsTree(networkProxy());;
|
||||||
|
|
||||||
//return m_network->categoriesFeedsLabelsTree(true, networkProxy());
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user